実際、それは翻訳された
公式ウェブサイトです:https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader
Pytorchのデータ読み込みツールでは、torch.utils.data.DataLoader
クラスが中心的な役割を果たします。これは、データセットに対するPythonイテレーターであり、以下をサポートします。
- マップおよびイテレータタイプのデータセット。
- カスタムデータの読み込み手順。
- 自動バッチ処理
- シングルプロセスおよびマルチプロセスのデータ読み込み。
- 自動メモリピン留め
DataLoader
クラスコンストラクターと呼ばれるコンストラクターパラメーターを構成 することによるこれらのオプション:
DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,
batch_sampler=None, num_workers=0, collate_fn=None,
pin_memory=False, drop_last=False, timeout=0,
worker_init_fn=None, *, prefetch_factor=2,
persistent_workers=False)
次の章では、これらのオプションの効果と使用法について詳しく説明します。
1.データセットタイプ
そのDataLoader
中で最も重要なのはDataset
、たとえばデータをロードするためのデータセットを指定するコンストラクターパラメーターでした。Pytorchでは2つの異なるデータセットタイプが提供されています。
- マップタイプのデータセット
- イテレータタイプのデータセット
1.1。マップタイプのデータセット
データセットのマップタイプは、キーまたはインデックスをデータサンプルにマッピングするクラスで実現さ__getitem__()
れ__len__()
ます。
たとえば、画像と関連タグのdataset[idx]
ディスクフォルダからの最初の読み取りを表しi
ます。
詳細については、データセットを参照してください。
1.2。イテレータタイプのデータセット
イテレータタイプのデータセットはIterableDataset
、インターフェイス関数を実装するクラスのサブセットであり__iter__()
、データサンプルのイテレータを表します。ランダムな読み取りと書き込みが困難または可能性が低く、バッチサイズがフェッチするデータに依存する状況では、このタイプのデータセットがより適しています。
たとえばiter(dataset)
、リモートデータベースから読み取ったデータストリームやリアルタイムログを返すことができます。
詳細については、IterableDatasetを参照してください。
注:クラス中に
使用されるマルチスキームによるデータ読み込みプロセスIterableDataset
で、同じデータに対して、異なるワークプロセスがそれぞれ同じレプリカを生成する場合、重複データを排除するために、データを異なる方法で配置する必要があります。特定の操作方法は、IterableDatasetドキュメントを参照できます。
2.データ読み込み手順とサンプリングツール
イテレータタイプのデータセットの場合、データロード命令はユーザー定義のイテレータによって完全に決定されます。これにより、データの大きなブロックの読み取りやバッチサイズの動的設定の実装が非常に簡単になります(たとえば、一度に1つのサンプルバッチを選択(歩留まり)できます)。
このセクションの残りの部分では、主にマップタイプのデータセットについて説明します。torch.utils.data.Sampler
このクラスは、データのロードプロセスで使用されるインデックスまたはキー値のシーケンスを指定するために使用されます。これは、インデックスからデータセットまでの反復可能なオブジェクトを表します。たとえば、SGDを使用する場合Sampler
、インデックスをランダムに配置して、一度に1つのサンプルを選択(生成)したり、ミニバッチSGDのサンプルの小さなグループを選択(生成)したりできます。パラメータに
基づいて、サンプリングツールのスクランブルされたシーケンスまたは値が自動的に作成されDataLoader
ますshuffle
。さらに、ユーザーパラメータはsampler
、カスタムwhereSampler
インスタンスを指定して、サンプリングごとにキーまたはインデックスを取得することもできます。
batch_sampler
パラメータを使用して、毎回一連のインデックス値を生成できるカスタムサンプリングツールを設定できます。自動操作はバッチパラメータにすることができbatch_size
、drop_last
詳細については次のセクションを参照してください。
注:
データセットのイテレータータイプであり、必ずしもインデックスキーである必要はないため、パラメーターは反復タイプのデータセット用ではbatch_size
ありdrop_last
ません。
2.1バッチデータまたは非バッチデータをロードする
DataLoader
パラメータbatch_size
、drop_last
およびbatch_sampler
バッチに統合された自動的にサンプリングされたデータ。
2.1.1。自動バッチ処理(デフォルト)
このアイテムは最も一般的に使用されます。これは、最小のバッチデータのいくつかを取得し、それらを同じサンプルのバッチに統合することと同じです。つまり、テンソルの次元の1つはバッチ次元(通常は最初の項目)です。
パラメータbatch_size
(デフォルトは1)がないNone
場合、データは個別のデータではなく、バッチロードツールデータとして返されます。データバッチロードツール取得モードキーを指定するためのパラメータbatch_size
とdrop_last
データ。マップタイプのデータの場合、ユーザーはbatch_sampler
一度にキーのリストを返すように設定することもできます。
ノート
パラメータbatch_size
とdrop_last
実際のパラメータに基づいてsampler
構築batch_sampler
。データセットのマップタイプはsampler
、ユーザーが設定することも、パラメーターshuffle
構造に基づいて設定することもできます。データセットのイテレータータイプsampler
は、仮想の無制限サンプラーです。サンプラーの詳細については、を参照してくださいここに。
注
データセットから取得した複数のタイプのデータをマナー反復処理する場合、各プロセスで、データの最後のバッチの数がbatch_size
設定されたパラメーター値よりも少ない場合、パラメーターdrop_last
はバッチを破棄します。
サンプリングツールを使用してサンプルのリストを取得した後collate_fn
、データのリストをバッチに並べ替える機能によって設定されたパラメーター。集中型マップデータからデータをロードする方法の後に
パラメータcollate_fn
を設定することは、次のことと同等です。
for indices in batch_sampler:
yield collate_fn([dataset[i] for i in indices])
イテレータタイプのデータセットからデータをロードする方法は、次と同等です。
dataset_iter = iter(dataset)
for indices in batch_sampler:
yield collate_fn([next(dataset_iter) for _ in indices])
collate_fn
関数に 渡されるパラメーターはカスタマイズできます。たとえば、シーケンスデータをバッチの最大長まで入力します。collate_fn
詳細に関するパラメータ、参照はここにあります。
2.1.2。自動バッチ処理をキャンセルします
場合によっては、ユーザーはデータセットコードでバッチ操作を手動で制御したい場合や、分離されたサンプルをロードしたい場合があります。たとえば、データのバッチを直接ロードする方が便利な場合があります(たとえば、データベースから大量のデータを読み取る、またはメモリから連続データを読み取る)、またはバッチのサイズはデータまたはプログラムに依存します分離されたサンプル上にあります。これらのシナリオでは、自動バッチを適用しなくなる可能性があります(collate_fn
仕上げサンプルを使用します)。ツールロードデータによる各操作は、インスタンスのデータセットを直接返す方が便利な場合があります。
ときセットが同時にとき(デフォルト)、バッチは自動的に閉じられます。データセットからのサンプルは、パラメータ処理機能によって取得されます。 自動バッチ機能をオフにすると、デフォルトではNumPy配列のみがTensorタイプのPyTorchになり、他の配列は変更されません。 この時点で、マップタイプのデータセットからデータをロードする方法は次のようになります。batch_size
batch_sampler
None
batch_sampler
None
collate_fn
collate_fn
for index in sampler:
yield collate_fn(dataset[index])
イテレータタイプのデータセットからデータをロードする方法は、次と同等です。
for data in iter(dataset):
yield collate_fn(data)
collate_fn
詳細に関するパラメータ、参照はここにあります。
3.collate_fn
使用する
バッチでの自動ターンオンとターンオフの場合collate_fn
、効果は異なります。
自動バッチ処理がオフになっている場合collate_fn
、関数は分離されたデータサンプルによって呼び出され、結果はデータ読み込みイテレータを介して返されます。
自動バッチ処理がオンになっている場合collate_fn
、関数はデータサンプルのリストによって呼び出され、入力データサンプルを1つのバッチに統合して、データ読み込みイテレータからの戻りを容易にします。自動バッチオープンcollate_fn
パフォーマンスのデフォルトについての次の説明。
説明した一例では、画像データの各サンプルと整数タグが3チャネルの場合、それぞれがタプルデータセットを返します。つまり(图像,标签)
、collate_fn
これらのタプルをタプルに統合したデフォルトのリストです。タプルは、バッチ処理された画像テンソルとバッチラベルテンソル。デフォルトcollate_fn
には次の機能があります。
- テンソルの最初の位置にバッチの寸法を作成します
- 常にNumPy配列とPyTorch数値データをPyTorchのテンソルタイプに変換します
- データ構造を変更しないでください。たとえば、各サンプルがディクショナリタイプの場合、同じキーセットを含むディクショナリが返されますが、値としてバッチテンソルが使用されます(元の値セットを量子化できない場合は、辞書の値としてリストします)。リスト、タプル、名前付きタプルなどは類似しています。
ユーザーはカスタムのものを使用できますcollate_fn
。例:最初のディメンション以外のディメンションに沿った並べ替え、異なる長さのシーケンスの入力、カスタムタイプのサポートの追加など。
4.シングルプロセスおよびマルチプロセスのデータ読み込み
DataLoader
デフォルトでは、単一のプロセスが使用されます。
PythonのGILは、スレッドの同時実行を疑似同時実行にします。データのロード時にコードブロックが発生しないようにするために、PyTorchはnum_workers
、正の整数を使用するために必要なパラメーターのみを使用して、マルチプロセスデータのロードを実現する簡単な方法を提供します。
4.1。単一プロセスのデータ読み込み
このモードでは、初期化で取得したデータはDataLoader
同じプロセスで完了します。したがって、データの読み込みによって計算がブロックされる場合があります。ただし、データがプロセス間で共有されるシナリオ(共有メモリ、データ記述子など)、またはデータの量がメモリに完全にロードされるほど少ないシナリオでは、このモードの方が適切な場合があります。さらに、単一プロセスのロード方法で異常な中断が発生した場合、提供されるエラー情報が理解しやすくなり、デバッグが容易になります。
4.2。マルチプロセスデータの読み込み
正の整数パラメータ設定num_workers
を使用すると、指定された数のロードプロセスマルチプロセスロードツールが返されます。
このモードでは、DataLoader
(呼び出しのようにenumerate(dataloader)
)イテレータを作成するたびにnum_workers
、作業プロセスが作成されます。dataset
、collate_fn
そしてworker_init_fn
各プロセスに転送され、データの初期化とアクセスに使用されます。これは、内部IOとともにデータアクセスと変換がワークプロセスで実行されることを意味します。
子プロセスで実行される作業では、呼び出し時にプロセスが返すtorch.utils.data.get_worker_info()
情報(プロセスID、データセットへのコピー、初期化シードなど)を取得できます。ユーザーはデータコードを設定するか、関数を呼び出すことができます。これにより、各サブプロセスがデータセットの例の独自のコピーとは独立して動作できるようになり、子プロセスで実行するかどうかを決定するためにコードを使用できます。たとえば、この関数は、データセットをスライスするときに役立ちます。 マップタイプのデータセットの場合、メインプロセスはサンプラーを使用してシーケンス番号のリストを生成し、それらを子プロセスに渡します。したがって、シーケンスを中断する操作はメインプロセスで完了し、メインプロセスはロードのシーケンス番号を割り当てることによってロードプロセスをガイドします。 イテレータタイプのデータセットの場合、各ワーカープロセスはデータセットインスタンスのコピーを取得するため、これにより、単純なマルチプロセスで結果が繰り返されます。またはを使用することにより、ユーザーは各コピーを個別に構成できます。(ドキュメントを参照してください。)同様に、マルチプロセスロードでは、最後のバッチ容量バッチの各プロセスが破棄するというパラメータが不満になります。 反復が完了するか、イテレータがガベージコレクションされると、子プロセスは閉じられます。main
None
worker_init_fn
torch.utils.data.get_worker_info()
worker_init_fn
IterableDataset
drop_last
マルチプロセスのロードプロセスでCUDAテンソルを返すように警告することはお勧めしません。細かい場所がたくさんあるためです(複数のプロセスを参照するか、CUDA CUDAテンソルCUDAマルチプロセスを使用する場合は共有します)。マルチプロセスロードの場合は、自動メモリピン留め(つまりpin_memory=True
)を使用することをお勧めします。これにより、CUDAを使用できるグラフィックカードにデータが転送されます。
4.2.1。プラットフォームでの異なるパフォーマンス
子プロセスがPythonのマルチプロセスに依存している場合でも、WindowsプラットフォームとUnixプラットフォームでのパフォーマンスは異なります。
- Unixのデフォルトのマルチプロセススタートアッププログラムは
fork()
です。これにより、子プロセスは、コピーされたアドレス空間を介してデータセットとPythonパラメータ関数に直接アクセスできます。 - Windowsではデフォルトでマルチプロセスプログラムが開始され
spawn()
、それは別のインタプリタを起動し、その中でメインスクリプトの実行は、その後、通訳を通して、pickle
モジュールのシリアル化の道受け取るためにdataset
、collate_fn
だけでなく、他のパラメータの内部サブプロセス機能。
この個別のシリアル化は、マルチプロセスデータがロードされるときにWindowsとの互換性を確保するために、次の2つの手順を実行する必要があることを意味します。
if __name__ == '__main__':
子プロセスがロードされた後に複数回実行されないようにするために、メインスクリプトがラップされました。たとえば、DataLoader
ここでデータを設定して論理インスタンスを作成できます。- カスタムを確認
collate_fn
、worker_init_fn
またはdataset
コードがトップに定義されているとされている__main__
子プロセスでの可用性を確保することができ文の外で検証。
4.2.2。マルチプロセスデータロードのランダム性
デフォルトでは、各サブプロセスはbase_seed + worker_id
モードを使用しています。ランダムシードが提供されます。これbase_seed
は、メインプロセスによって長整数RNGモジュールを使用して生成されます。ただし、子プロセスを初期化するプロセスでは、他のライブラリ(NumPyなど)のシードもコピーされるため、各子プロセスから返される乱数は同じになります。(ここで参照により解決されます)
ではworker_init_fn
、PyTorchシードを取得できるtorch.utils.data.get_worker_info().seed
か、torch.initial_seed()
取得できます。また、データが他のパッケージのシードにロードされる前に取得できます。
5.メモリの固定(固定)
固定メモリ領域(ページロック領域など)を使用してホストからグラフィックカードにデータをコピーすると、速度が速くなります。使用方法については、こちらを参照してください。固定メモリに配置された選択されたデータテンソルを自動的
にDataLoader
設定するためのデータをロードするためpin_memory=True
、CUDA対応のグラフィックスにデータをより速く転送できます。
デフォルトの固定メモリロジックは、テンソルまたはテンソルを含むMap / Iterableタイプのみを認識できます。バッチがカスタムタイプ(collate_fn
返されるのはカスタムタイプ)であるか、その中の各アイテムがカスタムタイプである場合、固定化ロジックはそれらを認識できず、返される結果はメモリに固定されません。カスタムバッチタイプのサポートを実装する場合は、カスタムタイプのpin_memory()
メソッドでデータのタイプを実装する必要があります。
例えば
# 自定义类
class SimpleCustomBatch:
def __init__(self, data):
transposed_data = list(zip(*data))
self.inp = torch.stack(transposed_data[0], 0)
self.tgt = torch.stack(transposed_data[1], 0)
# 自定义内存 pinning 方法
def pin_memory(self):
self.inp = self.inp.pin_memory()
self.tgt = self.tgt.pin_memory()
return self
def collate_wrapper(batch):
return SimpleCustomBatch(batch)
inps = torch.arange(10 * 5, dtype=torch.float32).view(10, 5)
tgts = torch.arange(10 * 5, dtype=torch.float32).view(10, 5)
dataset = TensorDataset(inps, tgts)
loader = DataLoader(dataset, batch_size=2, collate_fn=collate_wrapper,
pin_memory=True)
for batch_ndx, sample in enumerate(loader):
print(sample.inp.is_pinned())
print(sample.tgt.is_pinned())
公式ウェブサイトの後半では、データセットに関連するクラスをリストして紹介します。その中には、いくつかのクラスのユースケースが引用されています。
ユースケースのあるクラスは次のとおりです。
- torch.utils.data.IterableDataset
- torch.utils.data.BufferedShuffleDataset(dataset、buffer_size)
- torch.utils.data.WeightedRandomSampler(weights、num_samples、replacement = True、generator = None)
- torch.utils.data.BatchSampler(sampler、batch_size、drop_last)
- torch.utils.data.distributed.DistributedSampler(dataset、num_replicas = None、rank = None、shuffle = True、seed = 0、drop_last = False)