回答:
まだ疑問に思っている人のために:それはあなたのデータをシャッフルできるようにするためです。1つのファイルにTFrecordsがあると、注文をシャッフルできません。これは通常、SGDで必要です。
ただし、シャードを使用すると、シャードの順序を入れ替えることができます。これにより、個々のTFRecordにアクセスできるかのようにデータをシャッフルできます。これは、何もないよりも明らかに優れており、明らかに破片が多いほどこの近似値が優れています。
別の方法は、データを複製してデータを事前にシャッフルするか、TFRecordsをまったく使用しないことです。
TFRecordファイルをシャードに分割すると、メモリに収まらない大きなデータセットをシャッフルできます。
数百万のトレーニングサンプルがディスクに保存されており、トレーニングプロセスを繰り返し実行したいとします。さらに、トレーニングデータの各反復(つまり各エポック)に対して、完全にランダムな順序でデータをロードするとします。
1つのアプローチは、トレーニング例ごとに1つのファイルを用意し、すべてのファイル名のリストを生成することです。次に、各エポックの開始時に、ファイル名のリストをシャッフルし、個々のファイルをロードします。このアプローチの問題は、ディスク上のランダムな場所から何百万ものファイルをロードしていることです。これは、特にハードディスクドライブで遅くなる可能性があります。ランダムな場所から何百万もの小さなファイルをロードしている場合、RAID 0アレイでさえ速度の向上には役立ちません。ネットワーク接続を介してファイルにアクセスしている場合、問題はさらに悪化します。
別のアプローチは、1つの大きなTFRecordファイルからトレーニングサンプルを順番に読み取り、シャッフルバッファーを使用してメモリ内のサンプルをシャッフルすることです。ただし、シャッフルバッファーは通常、CPUで使用可能なDDRメモリより大きくすることはできません。また、シャッフルバッファーがデータセットよりも大幅に小さい場合、データが適切にシャッフルされない可能性があります。データは「ローカルに」シャッフルされますが、「グローバルに」シャッフルされない場合があります。つまり、データセットの最初のサンプルは、データセットの最後のサンプルとシャッフルされない場合があります。
良い解決策は、データセットを複数のTFRecordファイル(シャードと呼ばれる)に分割することにより、上記の2つのアプローチのバランスの取れた組み合わせを使用することです。各エポック中に、シャードファイル名をシャッフルしてグローバルシャッフルを取得し、シャッフルバッファーを使用してローカルシャッフルを取得できます。適切なバランスにより、ディスク速度の問題を防ぐのに十分な大きさの断片が作成されますが、シャッフルバッファーによる適切なシャッフルを可能にするのに十分なほど断片が小さく保持されます。
正確な手順は次のとおりです。
TFRecordsファイルを複数のシャードに分割することには、本質的に3つの利点があります。
.shuffle()
1つの大きなtfrecordファイルがある場合、この方法は理想的なソリューションではありません。シャッフルされた出力は、大きなバッファーサイズを使用しない場合、元の順序に多少関連しています。大きなデータセットがある場合は、tfrecordに保存する前、またはシャードに分割する前にデータを事前にシャッフルする必要があると思います。