Datasets documentation
Tải dữ liệu ảnh
Tải dữ liệu ảnh
Bộ dữ liệu ảnh có các cột kiểu Image, chứa các đối tượng PIL.
Để làm việc với các bộ dữ liệu hình ảnh, bạn cần cài đặt phụ thuộc
vision. Xem hướng dẫn cài đặt để biết cách cài đặt.
Khi bạn tải một bộ dữ liệu ảnh và gọi cột ảnh, các ảnh sẽ được giải mã thành các ảnh PIL:
>>> from datasets import load_dataset, Image
>>> dataset = load_dataset("AI-Lab-Makerere/beans", split="train")
>>> dataset[0]["image"]Truy cập vào bộ dữ liệu ảnh bằng chỉ số hàng trước, sau đó là cột
image-dataset[0]["image"]- để tránh việc giải mã và lấy mẫu lại tất cả các đối tượng ảnh trong bộ dữ liệu. Nếu không, đây có thể là một quy trình chậm và tốn thời gian nếu bạn có một bộ dữ liệu lớn.
Để tìm hiểu cách tải bất kỳ loại bộ dữ liệu nào, hãy xem hướng dẫn tải chung.
Tệp cục bộ
Bạn có thể tải một tập dữ liệu từ đường dẫn ảnh. Sử dụng hàm cast_column() để nhận một cột chứa các đường dẫn tệp ảnh, và giải mã nó thành ảnh PIL với tính năng Image:
>>> from datasets import Dataset, Image
>>> dataset = Dataset.from_dict({"image": ["path/to/image_1", "path/to/image_2", ..., "path/to/image_n"]}).cast_column("image", Image())
>>> dataset[0]["image"]
<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=1200x215 at 0x15E6D7160>]Nếu bạn chỉ muốn tải đường dẫn gốc của bộ dữ liệu ảnh mà không giải mã đối tượng ảnh, hãy đặt decode=False trong tính năng Image:
>>> dataset = load_dataset("AI-Lab-Makerere/beans", split="train").cast_column("image", Image(decode=False))
>>> dataset[0]["image"]
{'bytes': None,
'path': '/root/.cache/huggingface/datasets/downloads/extracted/b0a21163f78769a2cf11f58dfc767fb458fc7cea5c05dccc0144a2c0f0bc1292/train/bean_rust/bean_rust_train.29.jpg'}ImageFolder
Bạn cũng có thể tải một dataset bằng trình tạo dataset ImageFolder, không yêu cầu viết dataloader tùy chỉnh. Điều này khiến ImageFolder trở nên lý tưởng để nhanh chóng tạo và tải các dataset ảnh gồm vài nghìn hình ảnh cho các tác vụ thị giác khác nhau. Cấu trúc dataset ảnh của bạn nên trông như sau:
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.pngHoặc nó nên có metadata, ví dụ:
folder/train/metadata.csv
folder/train/0001.png
folder/train/0002.png
folder/train/0003.pngNếu bộ dữ liệu tuân theo cấu trúc ImageFolder, bạn có thể tải nó trực tiếp bằng load_dataset():
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_name")
>>> # OR locally:
>>> dataset = load_dataset("/path/to/folder")Với các bộ dữ liệu cục bộ, điều này tương đương với việc truyền imagefolder thủ công trong load_dataset() và thư mục trong data_dir:
>>> dataset = load_dataset("imagefolder", data_dir="/path/to/folder")Sau đó, bạn có thể truy cập các video dưới dạng các đối tượng PIL.Image:
>>> dataset["train"][0]
{"image": <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=1200x215 at 0x15E6D7160>, "label": 0}
>>> dataset["train"][-1]
{"image": <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=1200x215 at 0x15E8DAD30>, "label": 1}Để bỏ qua thông tin trong tệp metadata, đặt drop_metadata=True trong load_dataset():
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_with_metadata", drop_metadata=True)Nếu bạn không có tệp metadata, ImageFolder sẽ tự động suy ra tên nhãn từ tên thư mục.
Nếu bạn muốn loại bỏ các nhãn được tạo tự động, hãy đặt drop_labels=True.
Trong trường hợp này, tập dữ liệu của bạn sẽ chỉ chứa một cột ảnh:
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_without_metadata", drop_labels=True)Cuối cùng, đối số filters cho phép bạn chỉ tải một tập con của bộ dữ liệu, dựa trên điều kiện về nhãn hoặc metadata. Điều này đặc biệt hữu ích nếu metadata ở định dạng Parquet, vì định dạng này cho phép lọc nhanh. Cũng nên sử dụng đối số này cùng với streaming=True, vì mặc định bộ dữ liệu sẽ được tải xuống hoàn toàn trước khi lọc.
>>> filters = [("label", "=", 0)]
>>> dataset = load_dataset("username/dataset_name", streaming=True, filters=filters)Để biết thêm thông tin về việc tạo bộ dữ liệu
ImageFoldercủa riêng bạn, hãy xem hướng dẫn Tạo bộ dữ liệu ảnh.
WebDataset
Định dạng WebDataset dựa trên một thư mục chứa các tệp lưu trữ TAR và phù hợp cho các bộ dữ liệu ảnh lớn.
Do kích thước của chúng, WebDataset thường được tải ở chế độ streaming (sử dụng streaming=True).
Bạn có thể nạp một WebDataset như sau:
>>> from datasets import load_dataset
>>> dataset = load_dataset("webdataset", data_dir="/path/to/folder", streaming=True)Lance
Lance là định dạng bảng lakehouse đa phương thức mã nguồn mở. Bảng Lance có thể lưu trữ bản địa không chỉ văn bản và giá trị vô hướng, mà còn cả các đối tượng nhị phân lớn (blobs) như hình ảnh, âm thanh và video cùng với dữ liệu bảng của bạn.
Lance giữ metadata và các blob ảnh của bạn cùng nhau ở một nơi, trong khi vẫn cho phép bạn quét hiệu quả chỉ các cột metadata bạn quan tâm mà không cần nạp byte của ảnh. Khi sẵn sàng, bạn có thể lấy một tập con nhỏ các dòng (bao gồm cả các blob ảnh) và ghi chúng trực tiếp vào các tệp trên hệ thống tệp cục bộ của bạn.
from datasets import load_dataset
# Return as a Hugging Face dataset
ds = load_dataset(
"lance-format/laion-1m",
split="train",
streaming=True
)
dir_name = "laion_samples"
Path(dir_name).mkdir(exist_ok=True)
for idx, row in enumerate(ds.take(3)):
with open(f"{dir_name}/{idx}.jpg", "wb") as f:
f.write(row["image"])Trong ví dụ này, cột image chứa các byte hình ảnh đã được mã hóa, vì vậy bạn có thể ghi chúng trực tiếp vào các tệp .jpg.
API
datasetshiện chưa đẩy các thao tác xuống bảng Lance, do đó với các bộ dữ liệu lớn, hiệu suất có thể chậm. Hiện tại, bạn sẽ đạt hiệu suất tốt hơn nhiều khi sử dụng trực tiếp gói Pythonlance. Xem tài liệu trên the Hub để có các ví dụ về cách sử dụng.
Giải mã hình ảnh
Mặc định, các hình ảnh được giải mã tuần tự dưới dạng PIL.Images khi bạn lặp qua một tập dữ liệu.
Tuy nhiên, bạn có thể tăng tốc đáng kể tập dữ liệu bằng cách sử dụng giải mã đa luồng:
>>> import os
>>> num_threads = num_threads = min(32, (os.cpu_count() or 1) + 4)
>>> dataset = dataset.decode(num_threads=num_threads)
>>> for example in dataset: # up to 20 times faster !
... ...Bạn có thể bật đa luồng bằng cách sử dụng num_threads. Điều này đặc biệt hữu ích để tăng tốc độ truyền dữ liệu từ xa.
Tuy nhiên, nó có thể chậm hơn so với num_threads=0 đối với dữ liệu cục bộ trên các ổ đĩa nhanh.
Nếu bạn không quan tâm đến các hình ảnh được giải mã dưới dạng PIL.Images và muốn truy cập đường dẫn/bytes thay vào đó, bạn có thể tắt giải mã:
>>> dataset = dataset.decode(False)Lưu ý: IterableDataset.decode() hiện chỉ khả dụng cho các bộ dữ liệu dạng streaming.
Update on GitHub