Datasets documentation
動画データの読み込み
動画データの読み込み
動画サポートは実験的であり、変更される可能性があります。
Videoデータセットにはtorchcodecオブジェクトを含むVideo型の列があります。
動画データセットを扱うには、
torchcodecおよびffmpegパッケージのインストールが必要です。インストール方法については、インストールガイドを参照してください。
動画データセットを読み込み、動画カラムを呼び出すと、動画はtorchcodecのVideosとしてデコードされます:
>>> 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 データセットビルダーを使用して、カスタムdataloaderの作成を必要とせずにデータセットを読み込むこともできます。これにより、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")ローカルデータセットの場合、data_dirにディレクトリを指定してvideofolderを手動で渡すload_dataset()を呼び出すことと同等です:
>>> 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)For more information about creating your own
VideoFolderdataset, take a look at the Create a video dataset guide.
WebDataset
WebDataset形式はTARアーカイブのフォルダーを基盤としており、大規模な動画データセットに適しています。
そのサイズのため、WebDatasetは一般的にストリーミングモード(streaming=Trueを使用)で読み込まれます。
WebDatasetは次のように読み込むことができます。
>>> from datasets import load_dataset
>>> dataset = load_dataset("webdataset", data_dir="/path/to/folder", streaming=True)Lance
Lance は、オープンなマルチモーダルなレイクハウス用テーブル形式です。Lance テーブルでは、テキストやスカラー値だけでなく、画像、音声、動画などの大きなバイナリオブジェクト(blob)も、タブラーデータと並んでネイティブに保存できます。Lance テーブル内部では、動画のような大きな blob はオフセット付きのバイト列として保存されます(詳細は blob ガイド を参照してください)。これにより、重い動画 blob を読み込まずにメタデータをスキャン・フィルタリングしやすく、必要に応じて特定の動画 blob のみを取得できます。
また、Lance はカラムナフォーマットであるため、関心のあるメタデータのカラムのみを投影・フィルタリングし(大きな動画ファイルを取得せずに)、準備が整った時点で、動画を含む行の小さなサブセットを取得できます。これにより、個別のファイルストアや外部インデックスを必要とせずに、メタデータと動画を1つの場所に保持できます。
import lance
ds = lance.dataset("hf://datasets/lance-format/openvid-lance/data/train.lance")
# 1. Browse metadata without loading video blobs.
metadata = ds.scanner(
columns=["caption", "aesthetic_score"],
filter="aesthetic_score >= 4.5",
limit=2,
).to_table().to_pylist()
# 2. Fetch a single video blob by row index.
selected_index = 0
blob_file = ds.take_blobs("video_blob", ids=[selected_index])[0]
with open("video_0.mp4", "wb") as f:
f.write(blob_file.read())この例では、動画はLanceテーブルにネイティブ形式(エンコードされたバイト列)で保存されているため、追加の変換ステップなしで、ローカルファイルシステム上のmp4ファイルに直接書き込むことができます。
Lanceデータセットの取り扱いに関する詳細については、Lanceのドキュメントを参照してください。
動画のデコード
デフォルトでは、データセットをイテレーションする際、動画は VideoDecoders として torchcodec によって逐次的にデコードされます。
動画のメタデータは逐次的にデコードされ、フレームにアクセスするまで動画フレームは読み込まれません。
ただし、マルチスレッドデコーディングを使用することで、データセットを大幅に高速化できます。
>>> 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 よりも遅くなる可能性があります。
torchcodecのVideoDecodersとしてデコードされた動画に関心がない場合、代わりにパス/バイトにアクセスしたい場合は、デコードを無効化できます。
>>> dataset = dataset.decode(False)注: IterableDataset.decode() は現在、ストリーミングデータセットでのみ利用可能です。
Update on GitHub