Datasets documentation

Особенности набора данных

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Особенности набора данных

Features определяет внутреннюю структуру набора данных. Он используется для указания базового формата сериализации. Однако для вас более интересным является то, что Features содержит высокоуровневую информацию обо всем: от имен и типов столбцов до ClassLabel. Можно считать Features основой набора данных.

Формат Features прост: dict[column_name, column_type]. Это словарь пар «имя столбца» и «тип столбца». Тип столбца предоставляет широкий набор вариантов для описания типа имеющихся данных.

Рассмотрим характеристики набора данных MRPC из бенчмарка GLUE:

>>> from datasets import load_dataset
>>> dataset = load_dataset('nyu-mll/glue', 'mrpc', split='train')
>>> dataset.features
{'idx': Value('int32'),
 'label': ClassLabel(names=['not_equivalent', 'equivalent']),
 'sentence1': Value('string'),
 'sentence2': Value('string'),
}

Функция Value сообщает 🤗 Datasets:

  • Тип данных idx — int32.
  • Типы данных sentence1 и sentence2 — это string.

🤗 Datasets поддерживает многие другие типы данных, такие как bool, float32 и binary, чтобы назвать лишь некоторые из них.

Список поддерживаемых типов данных см. в Value.

Функция ClassLabel сообщает 🤗 Datasets, что столбец label содержит два класса. Классы обозначены как not_equivalent и equivalent. Метки хранятся в наборе данных в виде целых чисел. При извлечении меток методы ClassLabel.int2str() и ClassLabel.str2int() выполняют преобразование из целочисленного значения в имя метки и обратно.

Если ваш тип данных содержит список объектов, вам следует использовать функцию List. Помните датасет SQuAD?

>>> from datasets import load_dataset
>>> dataset = load_dataset('rajpurkar/squad', split='train')
>>> dataset.features
{'id': Value('string'),
 'title': Value('string'),
 'context': Value('string'),
 'question': Value('string'),
 'answers': {'text': List(Value('string')),
  'answer_start': List(Value('int32'))}}

Поле answers строится с использованием словаря признаков, поскольку и содержит два подполя, text и answer_start, которые являются списками string и int32 соответственно.

См. раздел flatten, чтобы узнать, как извлечь вложенные подполя в виде отдельных независимых столбцов.

Тип данных массива полезен для создания массивов различных размеров. Вы можете создавать двумерные массивы с помощью Array2D, а также массивы с пятью измерениями с помощью Array5D.

>>> features = Features({'a': Array2D(shape=(1, 3), dtype='int32')})

Тип массива также позволяет сделать первый размер массива динамическим. Это полезно для работы с последовательностями переменной длины, такими как предложения, без необходимости дополнять или укорачивать входные данные до единой формы.

>>> features = Features({'a': Array3D(shape=(None, 5, 2), dtype='int32')})

Аудио-функция

Наборы данных аудио содержат столбец типа Audio, в котором есть три важных поля:

  • array: декодированные аудиоданные, представленные в виде одномерного массива.
  • path: путь к скачанному аудиофайлу.
  • sampling_rate: частота дискретизации аудиоданных.

При загрузке аудиодатасета и обращении к аудиоколонке функция Audio автоматически декодирует и ресемплирует аудиофайл:

>>> from datasets import load_dataset, Audio

>>> dataset = load_dataset("PolyAI/minds14", "en-US", split="train")
>>> dataset[0]["audio"]
<datasets.features._torchcodec.AudioDecoder object at 0x11642b6a0>

Обращайтесь к аудиодataset по индексу строки, а затем к колонке audio — dataset[0]["audio"] — чтобы избежать декодирования и ресемплинга всех аудиофайлов в датасете. В противном случае, если датасет большой, этот процесс может быть медленным и требовать много времени.

При decode=False тип Audio просто возвращает путь или байты аудиофайла, не декодируя их в объект torchcodec AudioDecoder,

>>> dataset = load_dataset("PolyAI/minds14", "en-US", split="train").cast_column("audio", Audio(decode=False))
>>> dataset[0]
{'audio': {'bytes': None,
  'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~JOINT_ACCOUNT/602ba55abb1e6d0fbce92065.wav'},
 'english_transcription': 'I would like to set up a joint account with my partner',
 'intent_class': 11,
 'lang_id': 4,
 'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~JOINT_ACCOUNT/602ba55abb1e6d0fbce92065.wav',
 'transcription': 'I would like to set up a joint account with my partner'}

Функция изображения

Наборы данных изображений содержат столбец типа Image, который загружает объекты PIL.Image из изображений, хранящихся в виде байтов:

При загрузке набора данных изображений и обращении к столбцу с изображениями функция Image автоматически декодирует файл изображения:

>>> from datasets import load_dataset, Image

>>> dataset = load_dataset("AI-Lab-Makerere/beans", split="train")
>>> dataset[0]["image"]
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=500x500 at 0x125506CF8>

Обращайтесь к набору данных изображений сначала по индексу строки, а затем по столбцу image — dataset[0]["image"] — чтобы избежать декодирования всех файлов изображений в наборе. В противном случае, если набор данных большой, этот процесс может быть медленным и требовать много времени.

При decode=False тип Image просто возвращает путь или байты файла изображения, не декодируя их в PIL.Image,

>>> dataset = load_dataset("AI-Lab-Makerere/beans", split="train").cast_column("image", Image(decode=False))
>>> dataset[0]["image"]
{'bytes': None,
 'path': '/Users/username/.cache/huggingface/datasets/downloads/extracted/772e7c1fba622cff102b85dd74bcce46e8168634df4eaade7bedd3b8d91d3cd7/train/healthy/healthy_train.265.jpg'}

В зависимости от набора данных вы можете получить путь к локально загруженному изображению или содержимое изображения в виде байтов, если набор данных не состоит из отдельных файлов.

Вы также можете определить набор данных изображений из массивов numpy:

>>> ds = Dataset.from_dict({"i": [np.zeros(shape=(16, 16, 3), dtype=np.uint8)]}, features=Features({"i": Image()}))

В этом случае массивы numpy кодируются в PNG (или в TIFF, если важна точность значений пикселей).

Для многоканальных массивов, таких как RGB или RGBA, поддерживается только uint8. Если вы используете более высокую точность, вы получите предупреждение, а массив будет приведён к uint8. Для чёрно-белых изображений вы можете использовать любую целочисленную или вещественную точность, совместимую с Pillow. Если точность целочисленных или вещественных значений вашего изображения слишком высока, выводится предупреждение, и в этом случае массив приводится к более низкой точности: массив int64 приводится к int32, а массив float64 — к float32.

Функция Mesh

Наборы данных Mesh содержат столбец типа Mesh, который загружает файлы 3D-сеток как объекты trimesh.

При загрузке набора данных с мешами и обращении к столбцу меша функция Mesh автоматически декодирует файл меша:

>>> from datasets import load_dataset, Mesh

>>> dataset = load_dataset("VINAY-UMRETHE/My-Mesh-Dataset", split="train")
>>> dataset[0]["mesh"]
<trimesh.Scene(len(geometry)=33)>

В зависимости от содержимого файла trimesh может вернуть объект trimesh.Trimesh или объект trimesh.Scene.

Обращайтесь к набору данных мешей сначала по индексу строки, а затем по столбцу mesh — dataset[0]["mesh"] — чтобы избежать декодирования всех файлов мешей в наборе данных. В противном случае, если набор данных большой, этот процесс может быть медленным и требовать много времени.

При decode=False тип Mesh возвращает путь или байты файла меша без его декодирования с помощью trimesh:

>>> dataset = load_dataset("VINAY-UMRETHE/My-Mesh-Dataset", split="train").cast_column("mesh", Mesh(decode=False))
>>> dataset[0]["mesh"]
{'bytes': b'...',
 'path': '00001.glb'}

Функция Mesh поддерживает файлы .glb, .gltf, .ply и .stl. Для встроенных байтов для определения типа файла меша используется сохранённый path.

Функция Json

Датасеты основаны на Arrow, который является колоночным форматом, поэтому ожидается, что каждый пример имеет одинаковый тип и подтипы, а словари — одинаковые ключи и типы значений. При загрузке датасета возникает ошибка, если типы полей не совпадают, а отсутствующие поля в словарях заполняются значением None, чтобы все словари имели одинаковые ключи и типы значений.

Чтобы избежать этого и разрешить смешанные типы без ошибок, вы можете использовать on_mixed_types="use_json" или указать features= с типом Json:

>>> ds = Dataset.from_dict({"a": [0, "foo", {"subfield": "bar"}]})
Traceback (most recent call last):
  ...
  File "pyarrow/error.pxi", line 92, in pyarrow.lib.check_status
pyarrow.lib.ArrowInvalid: Could not convert 'foo' with type str: tried to convert to int64

>>> features = Features({"a": Json()})
>>> ds = Dataset.from_dict({"a": [0, "foo", {"subfield": "bar"}]}, features=features)
>>> ds.features
{'a': Json()}
>>> list(ds["a"])
[0, "foo", {"subfield": "bar"}]

Это также полезно для списков словарей с произвольными ключами и значениями, чтобы избежать заполнения отсутствующих полей значением None:

>>> ds = Dataset.from_dict({"a": [[{"b": 0}, {"c": 0}]]})
>>> ds.features
{'a': List({'b': Value('int64'), 'c': Value('int64')})}
>>> list(ds["a"])
[[{'b': 0, 'c': None}, {'b': None, 'c': 0}]]  # missing fields are filled with None

>>> features = Features({"a": List(Json())})
>>> ds = Dataset.from_dict({"a": [[{"b": 0}, {"c": 0}]]}, features=features)
>>> ds.features
{'a': List(Json())}
>>> list(ds["a"])
[[{'b': 0}, {'c': 0}]]  # OK

Ещё один пример с данными для вызова инструментов и аргументом on_mixed_types="use_json" (полезно, чтобы не указывать features= вручную):

>>> messages = [
...     {"role": "user", "content": "Turn on the living room lights and play my electronic music playlist."},
...     {"role": "assistant", "tool_calls": [
...         {"type": "function", "function": {
...             "name": "control_light",
...             "arguments": {"room": "living room", "state": "on"}
...         }},
...         {"type": "function", "function": {
...             "name": "play_music",
...             "arguments": {"playlist": "electronic"}  # mixed-type here since keys ["playlist"] and ["room", "state"] are different
...         }}]
...     },
...     {"role": "tool", "name": "control_light", "content": "The lights in the living room are now on."},
...     {"role": "tool", "name": "play_music", "content": "The music is now playing."},
...     {"role": "assistant", "content": "Done!"}
... ]
>>> ds = Dataset.from_dict({"messages": [messages]}, on_mixed_types="use_json")
>>> ds.features
{'messages': List({'role': Value('string'), 'content': Value('string'), 'tool_calls': List(Json()), 'name': Value('string')})}
>>> ds[0][1]["tool_calls"][0]["function"]["arguments"]
{"room": "living room", "state": "on"}
Update on GitHub