数据集文档

创建图像数据集

Hugging Face's logo
加入 Hugging Face 社区

并获得增强文档体验

开始使用

创建图像数据集

有两种方法可以创建和共享图像数据集。本指南将向您展示如何

  • 使用 Dataset.push_to_hub() 从 Python 中的本地文件创建音频数据集。这是一种简单的方法,只需在 Python 中执行几个步骤。

  • 使用 ImageFolder 和一些元数据创建图像数据集。这是一种无需代码的解决方案,可以快速创建包含数千张图像的图像数据集。

您可以通过要求用户首先共享其联系信息来控制对数据集的访问。查看 受限数据集 指南,以获取有关如何在中心启用此功能的更多信息。

ImageFolder

ImageFolder 是一个数据集构建器,旨在快速加载包含数千张图像的图像数据集,无需编写任何代码。

💡 查看 分割模式层次结构,了解 ImageFolder 如何根据数据集存储库结构创建数据集分割。

ImageFolder 会根据目录名称自动推断数据集的类别标签。将您的数据集存储在如下所示的目录结构中:

folder/train/dog/golden_retriever.png
folder/train/dog/german_shepherd.png
folder/train/dog/chihuahua.png

folder/train/cat/maine_coon.png
folder/train/cat/bengal.png
folder/train/cat/birman.png

然后,用户可以通过在 load_dataset() 中指定 imagefolder 并在 data_dir 中指定目录来加载您的数据集。

>>> from datasets import load_dataset

>>> dataset = load_dataset("imagefolder", data_dir="/path/to/folder")

您还可以使用 imagefolder 加载涉及多个分割的数据集。为此,您的数据集目录应具有以下结构:

folder/train/dog/golden_retriever.png
folder/train/cat/maine_coon.png
folder/test/dog/german_shepherd.png
folder/test/cat/bengal.png

如果所有图像文件都包含在单个目录中,或者它们不在目录结构的同一级别,则不会自动添加 label 列。如果需要,请显式设置 drop_labels=False

如果您想包含有关数据集的其他信息,例如文本标题或边界框,请将其作为 metadata.csv 文件添加到您的文件夹中。这使您可以快速创建用于不同计算机视觉任务(如文本标题或目标检测)的数据集。您也可以使用 JSONL 文件 metadata.jsonl

folder/train/metadata.csv
folder/train/0001.png
folder/train/0002.png
folder/train/0003.png

您还可以压缩图像:

folder/metadata.csv
folder/train.zip
folder/test.zip
folder/valid.zip

您的 metadata.csv 文件必须包含一个 file_name 列,该列将图像文件与其元数据关联。

file_name,additional_feature
0001.png,This is a first value of a text feature you added to your images
0002.png,This is a second value of a text feature you added to your images
0003.png,This is a third value of a text feature you added to your images

或使用 metadata.jsonl

{"file_name": "0001.png", "additional_feature": "This is a first value of a text feature you added to your images"}
{"file_name": "0002.png", "additional_feature": "This is a second value of a text feature you added to your images"}
{"file_name": "0003.png", "additional_feature": "This is a third value of a text feature you added to your images"}

如果存在元数据文件,则默认情况下会删除根据目录名称推断的标签。要包含这些标签,请在 load_dataset 中设置 drop_labels=False

图像字幕

图像字幕数据集包含描述图像的文本。一个示例 metadata.csv 可能如下所示:

file_name,text
0001.png,This is a golden retriever playing with a ball
0002.png,A german shepherd
0003.png,One chihuahua

使用 ImageFolder 加载数据集,它将为图像字幕创建一个 text 列。

>>> dataset = load_dataset("imagefolder", data_dir="/path/to/folder", split="train")
>>> dataset[0]["text"]
"This is a golden retriever playing with a ball"

目标检测

目标检测数据集包含边界框和类别,用于识别图像中的目标。一个示例 metadata.jsonl 可能如下所示:

{"file_name": "0001.png", "objects": {"bbox": [[302.0, 109.0, 73.0, 52.0]], "categories": [0]}}
{"file_name": "0002.png", "objects": {"bbox": [[810.0, 100.0, 57.0, 28.0]], "categories": [1]}}
{"file_name": "0003.png", "objects": {"bbox": [[160.0, 31.0, 248.0, 616.0], [741.0, 68.0, 202.0, 401.0]], "categories": [2, 2]}}

使用 ImageFolder 加载数据集,它将创建一个 objects 列,其中包含边界框和类别。

>>> dataset = load_dataset("imagefolder", data_dir="/path/to/folder", split="train")
>>> dataset[0]["objects"]
{"bbox": [[302.0, 109.0, 73.0, 52.0]], "categories": [0]}

将数据集上传到 Hub

创建数据集后,您可以使用 push_to_hub() 方法将其共享到 Hub。确保已安装 huggingface_hub 库并登录到您的 Hugging Face 帐户(有关更多详细信息,请参阅 使用 Python 上传教程)。

使用 push_to_hub() 上传您的数据集。

>>> from datasets import load_dataset

>>> dataset = load_dataset("imagefolder", data_dir="/path/to/folder", split="train")
>>> dataset.push_to_hub("stevhliu/my-image-captioning-dataset")

WebDataset

WebDataset 格式基于 TAR 档案,适用于大型图像数据集。实际上,您可以将图像分组到 TAR 档案中(例如,每个 TAR 档案 1GB 的图像),并拥有数千个 TAR 档案。

folder/train/00000.tar
folder/train/00001.tar
folder/train/00002.tar
...

在档案中,每个示例都由共享相同前缀的文件组成:

e39871fd9fd74f55.jpg
e39871fd9fd74f55.json
f18b91585c4d3f3e.jpg
f18b91585c4d3f3e.json
ede6e66b2fb59aab.jpg
ede6e66b2fb59aab.json
ed600d57fcee4f94.jpg
ed600d57fcee4f94.json
...

例如,您可以使用 JSON 或文本文件来放置图像标签/标题/边界框。

有关 WebDataset 格式和 Python 库的更多详细信息,请查看 WebDataset 文档

加载您的 WebDataset,它将为每个文件后缀(此处为“jpg”和“json”)创建一个列:

>>> from datasets import load_dataset

>>> dataset = load_dataset("webdataset", data_dir="/path/to/folder", split="train")
>>> dataset[0]["json"]
{"bbox": [[302.0, 109.0, 73.0, 52.0]], "categories": [0]}

(旧版)加载脚本

编写数据集加载脚本以共享数据集。它定义数据集的分割和配置,并处理下载和生成数据集。该脚本位于与数据集相同的文件夹或存储库中,并且应具有相同的名称。

my_dataset/
├── README.md
├── my_dataset.py
└── data/  # optional, may contain your images or TAR archives

此结构允许您在一行中加载数据集:

>>> from datasets import load_dataset
>>> dataset = load_dataset("path/to/my_dataset")

本指南将向您展示如何为图像数据集创建数据集加载脚本,这与 为文本数据集创建加载脚本 略有不同。您将学习如何:

  • 创建数据集构建器类。
  • 创建数据集配置。
  • 添加数据集元数据。
  • 下载并定义数据集分割。
  • 生成数据集。
  • 生成数据集元数据(可选)。
  • 将数据集上传到 Hub。

最好的学习方法是打开现有的图像数据集加载脚本,例如 Food-101,并跟随操作!

为了帮助您入门,我们创建了一个加载脚本 模板,您可以复制并用作起点!

创建数据集构建器类

GeneratorBasedBuilder 是从字典生成器生成数据集的基本类。在此类中,有三种方法可以帮助创建数据集:

  • info 存储有关数据集的信息,例如其描述、许可证和特征。
  • split_generators 下载数据集并定义其分割。
  • generate_examples 为每个分割生成图像和标签。

首先,将您的数据集类创建为 GeneratorBasedBuilder 的子类,并添加这三种方法。不必担心现在就填充每个方法,您将在接下来的几个部分中开发它们。

class Food101(datasets.GeneratorBasedBuilder):
    """Food-101 Images dataset"""

    def _info(self):

    def _split_generators(self, dl_manager):

    def _generate_examples(self, images, metadata_path):

多个配置

在某些情况下,数据集可能有多个配置。例如,如果您查看Imagenette 数据集,您会注意到它有三个子集。

要创建不同的配置,请使用BuilderConfig 类为您的数据集创建子类。在data_urlmetadata_urls 中提供下载图像和标签的链接。

class Food101Config(datasets.BuilderConfig):
    """Builder Config for Food-101"""
 
    def __init__(self, data_url, metadata_urls, **kwargs):
        """BuilderConfig for Food-101.
        Args:
          data_url: `string`, url to download the zip file from.
          metadata_urls: dictionary with keys 'train' and 'validation' containing the archive metadata URLs
          **kwargs: keyword arguments forwarded to super.
        """
        super(Food101Config, self).__init__(version=datasets.Version("1.0.0"), **kwargs)
        self.data_url = data_url
        self.metadata_urls = metadata_urls

现在您可以在GeneratorBasedBuilder 的顶部定义您的子集。假设您想在 Food-101 数据集中根据食物是早餐还是晚餐创建两个子集。

  1. BUILDER_CONFIGS 中的列表中使用Food101Config 定义您的子集。
  2. 对于每个配置,提供名称、描述以及从哪里下载图像和标签。
class Food101(datasets.GeneratorBasedBuilder):
    """Food-101 Images dataset"""
 
    BUILDER_CONFIGS = [
        Food101Config(
            name="breakfast",
            description="Food types commonly eaten during breakfast.",
            data_url="https://link-to-breakfast-foods.zip",
            metadata_urls={
                "train": "https://link-to-breakfast-foods-train.txt", 
                "validation": "https://link-to-breakfast-foods-validation.txt"
            },
        ,
        Food101Config(
            name="dinner",
            description="Food types commonly eaten during dinner.",
            data_url="https://link-to-dinner-foods.zip",
            metadata_urls={
                "train": "https://link-to-dinner-foods-train.txt", 
                "validation": "https://link-to-dinner-foods-validation.txt"
            },
        )...
    ]

现在,如果用户想要加载breakfast 配置,他们可以使用配置名称。

>>> from datasets import load_dataset
>>> ds = load_dataset("food101", "breakfast", split="train")

添加数据集元数据

添加有关数据集的信息对于用户了解数据集很有用。此信息存储在DatasetInfo 类中,该类由info 方法返回。用户可以通过以下方式访问此信息:

>>> from datasets import load_dataset_builder
>>> ds_builder = load_dataset_builder("food101")
>>> ds_builder.info

您可以指定许多有关数据集的信息,但一些重要的信息包括:

  1. description 提供数据集的简洁描述。
  2. features 指定数据集列类型。由于您正在创建图像加载脚本,因此您需要包含Image 特性。
  3. supervised_keys 指定输入特征和标签。
  4. homepage 提供数据集主页的链接。
  5. citation 是数据集的 BibTeX 引用。
  6. license 说明数据集的许可证。

您会注意到许多数据集信息是在加载脚本的前面定义的,这使得它更容易阅读。您还可以输入其他~Datasets.Features,因此请务必查看完整列表以获取更多详细信息。

def _info(self):
    return datasets.DatasetInfo(
        description=_DESCRIPTION,
        features=datasets.Features(
            {
                "image": datasets.Image(),
                "label": datasets.ClassLabel(names=_NAMES),
            }
        ),
        supervised_keys=("image", "label"),
        homepage=_HOMEPAGE,
        citation=_CITATION,
        license=_LICENSE,

    )

下载并定义数据集拆分

现在您已经添加了一些有关数据集的信息,下一步是下载数据集并生成拆分。

  1. 使用DownloadManager.download() 方法下载数据集以及您想与其关联的任何其他元数据。此方法接受:

    • Hub 数据集存储库中文件的名称(换句话说,data/ 文件夹)
    • 托管在其他地方的文件的 URL
    • 文件名或 URL 的列表或字典

    在 Food-101 加载脚本中,您会再次注意到 URL 在脚本的前面定义。

  2. 下载数据集后,使用SplitGenerator 来组织每个拆分中的图像和标签。使用标准名称为每个拆分命名,例如:Split.TRAINSplit.TESTSPLIT.Validation

    gen_kwargs 参数中,指定要迭代和加载的images 的文件路径。如有必要,您可以使用DownloadManager.iter_archive() 来迭代 TAR 存档中的图像。您还可以在metadata_path 中指定关联的标签。imagesmetadata_path 实际上传递到下一步,您将在其中实际生成数据集。

要流式传输 TAR 存档文件,您需要使用DownloadManager.iter_archive()DownloadManager.download_and_extract() 函数不支持流式模式下的 TAR 存档。

def _split_generators(self, dl_manager):
    archive_path = dl_manager.download(_BASE_URL)
    split_metadata_paths = dl_manager.download(_METADATA_URLS)
    return [
        datasets.SplitGenerator(
            name=datasets.Split.TRAIN,
            gen_kwargs={
                "images": dl_manager.iter_archive(archive_path),
                "metadata_path": split_metadata_paths["train"],
            },
        ),
        datasets.SplitGenerator(
            name=datasets.Split.VALIDATION,
            gen_kwargs={
                "images": dl_manager.iter_archive(archive_path),
                "metadata_path": split_metadata_paths["test"],
            },
        ),
    ]

生成数据集

GeneratorBasedBuilder 类中的最后一个方法实际上生成数据集中图像和标签。它根据info 方法中features 中指定的结构生成数据集。如您所见,generate_examples 将上一个方法中的imagesmetadata_path 作为参数。

要流式传输 TAR 存档文件,需要首先打开并读取metadata_path。TAR 文件是按顺序访问和生成的。这意味着您需要先准备好元数据信息,以便您可以将其与相应的图像一起生成。

现在您可以编写一个函数来打开和加载数据集中的示例。

def _generate_examples(self, images, metadata_path):
    """Generate images and labels for splits."""
    with open(metadata_path, encoding="utf-8") as f:
        files_to_keep = set(f.read().split("\n"))
    for file_path, file_obj in images:
        if file_path.startswith(_IMAGES_DIR):
            if file_path[len(_IMAGES_DIR) : -len(".jpg")] in files_to_keep:
                label = file_path.split("/")[2]
                yield file_path, {
                    "image": {"path": file_path, "bytes": file_obj.read()},
                    "label": label,
                }

生成数据集元数据(可选)

数据集元数据可以在数据集卡片(README.md 文件)中生成和存储。

运行以下命令在README.md 中生成您的数据集元数据,并确保您的新加载脚本正常工作。

datasets-cli test path/to/<your-dataset-loading-script> --save_info --all_configs

如果您的加载脚本通过了测试,您现在应该在数据集文件夹中README.md 文件的标题中拥有dataset_info YAML 字段。

将数据集上传到 Hub

脚本准备就绪后,创建数据集卡片将其上传到 Hub

恭喜,您现在可以从 Hub 加载您的数据集!🥳

>>> from datasets import load_dataset
>>> load_dataset("<username>/my_dataset")
< > 在 GitHub 上更新