数据集文档
创建图像数据集
并获得增强的文档体验
开始使用
创建图像数据集
有两种方法可以创建和分享图像数据集。本指南将向你展示如何
使用 python 和 Dataset.push_to_hub() 从本地文件创建图像数据集。这是一种简单的方法,只需要在 python 中进行几个步骤。
使用
ImageFolder
和一些元数据创建图像数据集。这是一种无需代码的解决方案,可以快速创建包含数千张图像的图像数据集。
你可以通过要求用户先分享他们的联系信息来控制对数据集的访问。查看 Gated datasets 指南,了解有关如何在 Hub 上启用此功能的更多信息。
ImageFolder
ImageFolder
是一个数据集构建器,旨在快速加载包含数千张图像的图像数据集,而无需编写任何代码。
💡 查看 Split pattern hierarchy 以了解更多关于 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
如果数据集遵循 ImageFolder
结构,那么你可以使用 load_dataset() 直接加载它
>>> from datasets import load_dataset
>>> dataset = load_dataset("path/to/folder")
这等同于在 load_dataset() 中手动传递 imagefolder
,并在 data_dir
中传递目录
>>> 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
或 Parquet 文件 metadata.parquet
。
folder/train/metadata.csv
folder/train/0001.png
folder/train/0002.png
folder/train/0003.png
你也可以压缩你的图像,在这种情况下,每个 zip 文件都应包含图像和元数据
folder/train.zip
folder/test.zip
folder/validation.zip
你的 metadata.csv
文件必须具有 file_name
或 *_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"}
这里的 file_name
必须是元数据文件旁边图像文件的名称。更一般地,它必须是从包含元数据的目录到图像文件的相对路径。
每行数据集中可以指向多个图像,例如,如果你的输入和输出都是图像
{"input_file_name": "0001.png", "output_file_name": "0001_output.png"}
{"input_file_name": "0002.png", "output_file_name": "0002_output.png"}
{"input_file_name": "0003.png", "output_file_name": "0003_output.png"}
你也可以定义图像列表。在这种情况下,你需要将字段命名为 file_names
或 *_file_names
。这是一个例子
{"frames_file_names": ["0001_t0.png", "0001_t1.png"], label: "moving_up"}
{"frames_file_names": ["0002_t0.png", "0002_t1.png"], label: "moving_down"}
{"frames_file_names": ["0003_t0.png", "0003_t1.png"], label: "moving_right"}
图像描述
图像描述数据集包含描述图像的文本。一个 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,它将为每个文件后缀创建一个列(此处为“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]}
每个示例也可以有多个图像,如下所示
e39871fd9fd74f55.input.jpg
e39871fd9fd74f55.output.jpg
e39871fd9fd74f55.json
f18b91585c4d3f3e.input.jpg
f18b91585c4d3f3e.output.jpg
f18b91585c4d3f3e.json
...
有关 WebDataset 格式和 python 库的更多详细信息,请查看 WebDataset 文档。
(旧版) 加载脚本
编写数据集加载脚本以分享数据集。它定义了数据集的拆分和配置,并处理数据集的下载和生成。该脚本与数据集位于同一文件夹或仓库中,并且应具有相同的名称。
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_url
和 metadata_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 数据集中创建两个子集,基于它是早餐食物还是晚餐食物。
- 在
BUILDER_CONFIGS
的列表中使用Food101Config
定义你的子集。 - 对于每个配置,提供名称、描述以及从何处下载图像和标签。
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("ethz/food101", "breakfast", split="train")
添加数据集元数据
添加关于你的数据集的信息对于用户了解更多信息很有用。此信息存储在 DatasetInfo 类中,该类由 info
方法返回。用户可以通过以下方式访问此信息:
>>> from datasets import load_dataset_builder
>>> ds_builder = load_dataset_builder("ethz/food101")
>>> ds_builder.info
你可以指定关于数据集的许多信息,但一些重要的信息包括:
description
提供数据集的简洁描述。features
指定数据集列类型。由于你正在创建图像加载脚本,因此你需要包含 Image 特征。supervised_keys
指定输入特征和标签。homepage
提供数据集主页的链接。citation
是数据集的 BibTeX 引用。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,
)
下载并定义数据集拆分
既然您已经添加了一些关于数据集的信息,下一步是下载数据集并生成拆分。
使用 DownloadManager.download() 方法下载数据集以及您想要关联的任何其他元数据。此方法接受:
- Hub 数据集仓库中文件的名称(换句话说,
data/
文件夹) - 托管在其他位置的文件的 URL
- 文件名或 URL 的列表或字典
在 Food-101 加载脚本中,您会再次注意到 URL 在脚本的早期定义。
- Hub 数据集仓库中文件的名称(换句话说,
下载数据集后,使用 SplitGenerator 来组织每个拆分中的图像和标签。使用标准名称命名每个拆分,例如:
Split.TRAIN
、Split.TEST
和SPLIT.Validation
。在
gen_kwargs
参数中,指定要迭代和加载的images
文件路径。如有必要,您可以使用 DownloadManager.iter_archive() 来迭代 TAR 存档中的图像。您还可以在metadata_path
中指定关联的标签。images
和metadata_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
接受上一个方法中的 images
和 metadata_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 加载您的数据集了! 🥳
>>> from datasets import load_dataset
>>> load_dataset("<username>/my_dataset")