Durch das Aufteilen von TFRecord-Dateien in Shards können Sie große Datasets mischen, die nicht in den Arbeitsspeicher passen.
Stellen Sie sich vor, Sie haben Millionen von Trainingsbeispielen auf der Festplatte gespeichert und möchten sie wiederholt durch einen Trainingsprozess führen. Angenommen, Sie möchten die Daten für jede Wiederholung der Trainingsdaten (dh für jede Epoche) in einer völlig zufälligen Reihenfolge laden.
Ein Ansatz ist, eine Datei pro Trainingsbeispiel zu haben und eine Liste aller Dateinamen zu generieren. Dann mischen Sie zu Beginn jeder Epoche die Liste der Dateinamen und laden die einzelnen Dateien. Das Problem bei diesem Ansatz ist, dass Sie Millionen von Dateien von zufälligen Speicherorten auf Ihrer Festplatte laden. Dies kann insbesondere auf einer Festplatte langsam sein. Selbst ein RAID 0-Array hilft nicht bei der Geschwindigkeit, wenn Sie Millionen kleiner Dateien von zufälligen Speicherorten laden. Das Problem wird noch schlimmer, wenn Sie über eine Netzwerkverbindung auf die Dateien zugreifen.
Ein anderer Ansatz besteht darin, die Trainingsbeispiele nacheinander aus einer großen TFRecord-Datei zu lesen und die Beispiele mit einem Zufallspuffer im Speicher zu mischen. Der Zufallspuffer kann jedoch normalerweise nicht größer sein als der DDR-Speicher, der Ihrer CPU zur Verfügung steht. Wenn der Zufallspuffer erheblich kleiner ist als Ihr Dataset, werden die Daten möglicherweise nicht ausreichend gemischt. Die Daten können "lokal", aber nicht "global" gemischt werden. Das heißt, Beispiele vom Anfang des Datensatzes werden möglicherweise nicht mit Beispielen vom Ende des Datensatzes gemischt.
Eine gute Lösung besteht darin, eine ausgewogene Kombination der beiden oben genannten Ansätze zu verwenden, indem Sie Ihr Dataset in mehrere TFRecord-Dateien (so genannte Shards) aufteilen. Während jeder Epoche können Sie die Shard-Dateinamen mischen, um ein globales Mischen zu erhalten, und einen Shuffle-Puffer verwenden, um ein lokales Mischen zu erhalten. Eine gute Balance sorgt dafür, dass die Shards groß genug sind, um Probleme mit der Festplattengeschwindigkeit zu vermeiden, hält sie jedoch klein genug, um ein angemessenes Mischen durch einen Shuffle-Puffer zu ermöglichen.
Hier sind die genauen Schritte:
- Platzieren Sie alle Trainingsbeispiele nach dem Zufallsprinzip in mehreren TFRecord-Dateien (Shards).
- Mische zu Beginn jeder Epoche die Liste der Shard-Dateinamen.
- Lesen Sie Trainingsbeispiele aus den Shards und leiten Sie die Beispiele durch einen Shuffle-Puffer. In der Regel sollte der Shuffle-Puffer größer als die Shard-Größe sein, um ein gutes Shuffle über die Shards hinweg zu gewährleisten.
- Übergeben Sie die gemischten Beispiele in Ihren Trainingsprozess.
.shuffle()
Methode ist keine ideale Lösung, wenn Sie eine große tfrecord-Datei haben. Die gemischte Ausgabe hat etwas mit der ursprünglichen Reihenfolge zu tun, wenn Sie keine große Puffergröße verwenden. Ich denke, die Daten müssen vor dem Speichern auf tfrecord oder dem Aufteilen in Shards gemischt werden, wenn Sie einen großen Datensatz haben.