Datasets 文件
載入影片資料
並獲得增強的文件體驗
開始使用
載入影片資料
影片支援是實驗性的,可能會發生變化。
影片資料集具有 Video 型別的列,其中包含 torchvision
物件。
要處理影片資料集,您需要安裝 torchvision
和 av
包。請檢視 安裝 指南以瞭解如何安裝它們。
當您載入影片資料集並呼叫影片列時,影片會解碼為 torchvision
影片。
>>> from datasets import load_dataset, Video
>>> dataset = load_dataset("path/to/video/folder", split="train")
>>> dataset[0]["video"]
<torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61d5a0>
請先使用行索引,然後使用 video
列來索引影片資料集 - dataset[0]["video"]
- 以避免在資料集中建立所有影片物件。否則,如果資料集很大,這可能是一個緩慢且耗時的過程。
有關如何載入任何型別資料集的指南,請參閱通用載入指南。
讀取幀
使用 VideoReader
並透過 next()
直接從影片訪問幀。
>>> video = dataset[0]["video"]
>>> first_frame = video.get_frame_at(0)
>>> first_frame.data.shape
(3, 240, 320)
>>> first_frame.pts_seconds # timestamp
0.0
要一次獲取多個幀,您可以呼叫 .get_frames_in_range(start: int, stop: int, step: int)
。這將返回一個幀批次。這是獲取長幀列表的有效方法,請參閱 torchcodec 文件 以檢視更多有效訪問資料的功能。
>>> import torch
>>> frames = video.get_frames_in_range(0, 6, 1)
>>> frames.data.shape
torch.Size([5, 3, 240, 320])
還有一個 .get_frames_played_in_range(start_seconds: float, stop_seconds: float)
函式,用於訪問在特定時間範圍內播放的所有幀。
>>> frames = video.get_frames_played_in_range(.5, 1.2)
>>> frames.data.shape
torch.Size([42, 3, 240, 320])
本地檔案
您可以從影片路徑載入資料集。使用 cast_column() 函式接受一列影片檔案路徑,並使用 Video 特徵將其解碼為 torchcodec
影片。
>>> from datasets import Dataset, Video
>>> dataset = Dataset.from_dict({"video": ["path/to/video_1", "path/to/video_2", ..., "path/to/video_n"]}).cast_column("video", Video())
>>> dataset[0]["video"]
<torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61e080>
如果您只想載入影片資料集的底層路徑而不解碼影片物件,請在 Video 特徵中設定 decode=False
。
>>> dataset = dataset.cast_column("video", Video(decode=False))
>>> dataset[0]["video"]
{'bytes': None,
'path': 'path/to/video/folder/video0.mp4'}
VideoFolder
您還可以使用 VideoFolder
資料集構建器載入資料集,它不需要編寫自定義的資料載入器。這使得 VideoFolder
成為快速為不同視覺任務建立和載入包含數千個影片的影片資料集的理想選擇。您的影片資料集結構應如下所示:
folder/train/dog/golden_retriever.mp4
folder/train/dog/german_shepherd.mp4
folder/train/dog/chihuahua.mp4
folder/train/cat/maine_coon.mp4
folder/train/cat/bengal.mp4
folder/train/cat/birman.mp4
如果資料集遵循 VideoFolder
結構,則可以直接使用 load_dataset() 載入它。
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_name")
>>> # OR locally:
>>> dataset = load_dataset("/path/to/folder")
對於本地資料集,這相當於在 load_dataset() 中手動傳遞 videofolder
,並在 data_dir
中傳遞目錄。
>>> dataset = load_dataset("videofolder", data_dir="/path/to/folder")
然後,您可以將影片作為 torchcodec.decoders._video_decoder.VideoDecoder
物件進行訪問。
>>> dataset["train"][0]
{"video": <torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61e080>, "label": 0}
>>> dataset["train"][-1]
{"video": <torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61e090>, "label": 1}
要忽略元資料檔案中的資訊,請在 load_dataset() 中設定 drop_metadata=True
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_with_metadata", drop_metadata=True)
如果您沒有元資料檔案,VideoFolder
會自動從目錄名稱中推斷標籤名稱。如果要刪除自動建立的標籤,請設定 drop_labels=True
。在這種情況下,您的資料集將只包含一個影片列。
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_without_metadata", drop_labels=True)
最後,filters
引數允許您僅載入資料集的子集,基於標籤或元資料的條件。如果元資料是 Parquet 格式,這特別有用,因為該格式支援快速過濾。還建議將此引數與 streaming=True
一起使用,因為預設情況下,資料集在過濾前會完全下載。
>>> filters = [("label", "=", 0)]
>>> dataset = load_dataset("username/dataset_name", streaming=True, filters=filters)
有關建立自己的 VideoFolder
資料集的更多資訊,請檢視 建立影片資料集 指南。
WebDataset
WebDataset 格式基於 TAR 歸檔檔案的資料夾,適用於大型影片資料集。由於其大小,WebDataset 通常以流式模式載入(使用 streaming=True
)。
您可以像這樣載入 WebDataset:
>>> from datasets import load_dataset
>>> dataset = load_dataset("webdataset", data_dir="/path/to/folder", streaming=True)
影片解碼
預設情況下,當您迭代資料集時,影片會按順序解碼為 torchvision VideoReaders
。它會順序解碼影片的元資料,並且在您訪問影片幀之前不會讀取它們。
然而,使用多執行緒解碼可以顯著加快資料集的處理速度。
>>> 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 !
... ...
您可以使用 num_threads
啟用多執行緒。這對於加快遠端資料流傳輸特別有用。但是,對於快速磁碟上的本地資料,它可能比 num_threads=0
慢。
如果您對解碼為 torchvision VideoReaders
的影片不感興趣,而是想訪問路徑/位元組,您可以停用解碼。
>>> dataset = dataset.decode(False)
注意:目前 IterableDataset.decode() 僅適用於流式資料集。
< > 在 GitHub 上更新