数据集:

red_caps

任务:

图生文

语言:

en

计算机处理:

monolingual

大小:

10M<n<100M

语言创建人:

found

批注创建人:

found

源数据集:

original

预印本库:

arxiv:2111.11431

许可:

cc-by-4.0
英文

RedCaps 数据集卡片

数据集概述

RedCaps 是一个大规模的数据集,包含了来自 Reddit 的 1200 万张图像 - 文本对。Reddit 的图像和标题描述了各种各样的对象和场景。数据集是从一个手动筛选的子论坛集合(共 350 个)中收集而来的,这些子论坛提供了粗略的图像标签,并允许根据需求调整数据集组成,而不需要对每个实例进行标注。RedCaps 数据集是由人民创建的、为人民所用的——其中包含了用户喜欢在社交媒体上分享的日常事物,例如爱好(r/crafts)和宠物(r/shiba)。标题通常包含特定和精细的描述(北美红雀,泰姬陵)。子论坛名称提供了相关的图像标签(r/shiba),即使标题可能没有提供(mlem!),有时也可能通过共同语义意义将许多视觉上无关的图像分组在一起(r/perfectfit)。

数据集预处理

默认情况下,该数据集不会将图像下载到本地。相反,它提供了图像的 URL。要获取图像,请使用以下代码:

from concurrent.futures import ThreadPoolExecutor
from functools import partial
import io
import urllib

import PIL.Image

from datasets import load_dataset
from datasets.utils.file_utils import get_datasets_user_agent


USER_AGENT = get_datasets_user_agent()


def fetch_single_image(image_url, timeout=None, retries=0):
    for _ in range(retries + 1):
        try:
            request = urllib.request.Request(
                image_url,
                data=None,
                headers={"user-agent": USER_AGENT},
            )
            with urllib.request.urlopen(request, timeout=timeout) as req:
                image = PIL.Image.open(io.BytesIO(req.read()))
            break
        except Exception:
            image = None
    return image


def fetch_images(batch, num_threads, timeout=None, retries=0):
    fetch_single_image_with_args = partial(fetch_single_image, timeout=timeout, retries=retries)
    with ThreadPoolExecutor(max_workers=num_threads) as executor:
        batch["image"] = list(executor.map(fetch_single_image_with_args, batch["image_url"]))
    return batch


num_threads = 20
dset = load_dataset("red_caps", "rabbits_2017")
dset = dset.map(fetch_images, batched=True, batch_size=100, fn_kwargs={"num_threads": num_threads})

一些图像链接指向多个图像。您可以使用以下方式处理和下载它们:

from concurrent.futures import ThreadPoolExecutor
from functools import partial
import io
import os
import re
import urllib

import PIL.Image

import datasets
from datasets import load_dataset
from datasets.utils.file_utils import get_datasets_user_agent


USER_AGENT = get_datasets_user_agent()


def fetch_single_image(image_url, timeout=None, retries=0):
    for _ in range(retries + 1):
        try:
            request = urllib.request.Request(
                image_url,
                data=None,
                headers={"user-agent": USER_AGENT},
            )
            with urllib.request.urlopen(request, timeout=timeout) as req:
                image = PIL.Image.open(io.BytesIO(req.read()))
            break
        except Exception:
            image = None
    return image


def fetch_images(batch, num_threads, timeout=None, retries=0):
    fetch_single_image_with_args = partial(fetch_single_image, timeout=timeout, retries=retries)
    with ThreadPoolExecutor(max_workers=num_threads) as executor:
        batch["image"] = list(executor.map(lambda image_urls: [fetch_single_image_with_args(image_url) for image_url in image_urls], batch["image_url"]))
    return batch


def process_image_urls(batch):
    processed_batch_image_urls = []
    for image_url in batch["image_url"]:
        processed_example_image_urls = []
        image_url_splits = re.findall(r"http\S+", image_url)
        for image_url_split in image_url_splits:
            if "imgur" in image_url_split and "," in image_url_split:
                for image_url_part in image_url_split.split(","):
                    if not image_url_part:
                        continue
                    image_url_part = image_url_part.strip()
                    root, ext = os.path.splitext(image_url_part)
                    if not root.startswith("http"):
                      root = "http://i.imgur.com/" + root
                    root = root.split("#")[0]
                    if not ext:
                      ext = ".jpg"
                    ext = re.split(r"[?%]", ext)[0]
                    image_url_part = root + ext
                    processed_example_image_urls.append(image_url_part)
            else:
                processed_example_image_urls.append(image_url_split)
        processed_batch_image_urls.append(processed_example_image_urls)
    batch["image_url"] = processed_batch_image_urls
    return batch


dset = load_dataset("red_caps", "rabbits_2017")
dset = dset.map(process_image_urls, batched=True, num_proc=4)
features = dset["train"].features.copy()
features["image"] = datasets.Sequence(datasets.Image())
num_threads = 20
dset = dset.map(fetch_images, batched=True, batch_size=100, features=features, fn_kwargs={"num_threads": num_threads})

请注意,在上述代码中,我们使用 datasets.Sequence 功能来表示多图像链接的列表。

支持的任务和排行榜

按照论文中的说法:

我们使用我们的数据集来训练了深度神经网络,用于图像字幕生成,并学习了对各种下游视觉识别任务(图像分类、目标检测、实例分割)具有可转移性的视觉表示。我们预计该数据集可用于各种视觉与语言(V&L)任务,例如图像或文本检索,或文本到图像的合成。

语言

RedCaps 中的所有子论坛都使用英语作为主要语言。

数据集结构

数据实例

RedCaps 中的每个实例表示单个 Reddit 图像帖子:

{
  'image_id': 'bpzj7r',
  'author': 'djasz1',
  'image_url': 'https://i.redd.it/ho0wntksivy21.jpg',
  'raw_caption': 'Found on a friend’s property in the Keys FL. She is now happily living in my house.',
  'caption': 'found on a friend's property in the keys fl. she is now happily living in my house.', 'subreddit': 3,
  'score': 72,
  'created_utc': datetime.datetime(2019, 5, 18, 1, 36, 41),
  'permalink': '/r/airplants/comments/bpzj7r/found_on_a_friends_property_in_the_keys_fl_she_is/', 'crosspost_parents': None
}

数据字段

  • image_id:图像帖子的唯一字母数字 ID(由 Reddit 分配)。
  • author:图像帖子作者的 Reddit 用户名。
  • image_url:下载与帖子关联的图像的静态 URL。
  • raw_caption:由帖子作者撰写的图像的文本描述。
  • caption:由我们清理后的 "raw_caption" 的版本(参见问题35)。
  • subreddit:提交帖子的子论坛名称。
  • score:帖子收到的网络赞(扣除踩)的数量。如果图像帖子是一篇转载,此字段为 None。
  • created_utc:帖子提交到 Reddit 的时间戳(UTC 时间)。
  • permalink:Reddit 帖子的部分 URL( https://reddit.com/ )。
  • crosspost_parents:父级帖子的列表。此字段是可选的。

数据拆分

所有数据都包含在训练集中。训练集共有近 1200 万(12,011,111)个实例。

按照论文中的说法:

我们打算将我们的数据集主要用于预训练,同时考虑一个或多个特定的下游任务。因此,我们会使用数据集中的所有实例进行训练,而验证集则从下游任务中派生。如果用户需要验证集,我们建议对其进行采样,以确保遵循与整个数据集相同的子论坛分布。

数据集创建

策划理由

按照论文中的说法:

大规模的图像 - 文本对数据集被广泛用于预训练通用表示,可以迁移到各种下游视觉和视觉 - 语言任务。现有的此类公共数据集是从搜索引擎结果(SBU Captions [1])或任意网页的 HTML 字代(Conceptual Captions [2, 31])中策划的。它们进行了复杂的数据过滤以处理嘈杂的网络数据。由于过滤掉了大量数据,它们的数据收集效率低下,多样性被人为压制。我们认为数据的质量取决于其来源以及人为策划的意图。在这项工作中,我们探索了 Reddit——一个社交媒体平台,用于策划高质量数据。我们引入了 RedCaps——一个来自 Reddit 的 1200 万个图像 - 文本对的大规模数据集。尽管我们预计 RedCaps 的用途类似于现有的数据集,但我们讨论了 Reddit 作为数据来源的优势,它可以快速和轻量级地收集数据、提供更好的数据质量、让我们轻松地引导数据分布,并促进道德负责的数据策划。

来源数据

初始数据收集和标准化

按照论文中的说法:

数据收集流程Reddit 的统一结构使我们能够将数据收集并行化为独立任务——每个任务涉及收集在一年内提交到单个子论坛的帖子。我们的收集流程分为三个步骤:(1) 子论坛选择,(2) 图像帖子筛选,和 (3) 标题清理。 步骤 1 . 子论坛选择:我们从手动策划的子论坛集合中收集数据。子论坛有自己的规则、社区规范和版主,因此策划子论坛允许我们在不对每个实例进行标注的情况下引导数据集的组成。我们选择具有大量图像帖子的子论坛,其中图像倾向于是照片(而不是模因、绘画、截图等),并且帖子标题倾向于描述图像内容(而不是讲笑话、发表政治评论等)。我们不选择任何 NSFW(不适宜上班)的、被禁止的或被隔离的子论坛。我们希望尽量减少出现在 RedCaps 中的人物图像的数量,因此我们不包括那些主要用于共享或评论人物图像的子论坛(如名人照片或用户自拍)。我们选择着重于一般摄影(r/pics, r/itookapicture)、动物(r/axolotls, r/birdsofprey, r/dachshund)、植物(r/roses, r/succulents)、物体(r/classiccars, r/trains, r/mechanicalkeyboards)、食物(r/steak, r/macarons)、景色(r/cityporn1, r/desertporn)或活动(r/carpentry, r/kayaking)的子论坛。总共我们从350个子论坛收集数据;完整列表可以在附录A中找到。 步骤 2 . 图像帖子筛选:我们使用 Pushshift [41] 和 Reddit [42, 43] API 下载所有提交到我们选定的子论坛的图像帖子(时间跨度为 2008–2020)。我们只收集托管在三个域名上的图像帖子:Reddit (i.redd.it)、Imgur (i.imgur.com) 和 Flickr (staticflickr.com)。一些图像帖子包含多个图像(图库帖子)——在这种情况下,我们只收集第一张图像并将其与标题关联起来。我们排除掉具有