การแบ่งไฟล์ TFRecord เป็นส่วนช่วยให้คุณสลับชุดข้อมูลขนาดใหญ่ที่ไม่พอดีกับหน่วยความจำ
ลองนึกภาพคุณมีตัวอย่างการฝึกอบรมนับล้านบันทึกไว้ในดิสก์และคุณต้องการเรียกใช้ซ้ำ ๆ ผ่านกระบวนการฝึกอบรม นอกจากนี้สมมติว่าสำหรับการทำซ้ำแต่ละครั้งของข้อมูลการฝึกอบรม (เช่นแต่ละยุค) คุณต้องการโหลดข้อมูลในลำดับที่สมบูรณ์แบบสุ่ม
วิธีหนึ่งคือการมีหนึ่งไฟล์ต่อตัวอย่างการฝึกอบรมและสร้างรายการของชื่อไฟล์ทั้งหมด จากนั้นที่จุดเริ่มต้นของแต่ละยุคคุณสลับรายชื่อไฟล์และโหลดไฟล์แต่ละไฟล์ ปัญหาของวิธีนี้คือคุณกำลังโหลดไฟล์หลายล้านไฟล์จากตำแหน่งสุ่มบนดิสก์ของคุณ ซึ่งอาจช้าโดยเฉพาะอย่างยิ่งในฮาร์ดดิสก์ แม้แต่อาเรย์ RAID 0 ก็ไม่สามารถช่วยได้ถ้าคุณโหลดไฟล์ขนาดเล็กนับล้านจากตำแหน่งสุ่ม ปัญหาจะยิ่งแย่ลงถ้าคุณกำลังเข้าถึงไฟล์ผ่านการเชื่อมต่อเครือข่าย
อีกวิธีหนึ่งคือการอ่านตัวอย่างการฝึกอบรมตามลำดับจากไฟล์ TFRecord ขนาดใหญ่หนึ่งไฟล์และสุ่มตัวอย่างในหน่วยความจำโดยใช้บัฟเฟอร์แบบสุ่ม อย่างไรก็ตามโดยทั่วไปแล้วบัฟเฟอร์การสับเปลี่ยนไม่สามารถมีขนาดใหญ่กว่าหน่วยความจำ DDR ที่มีให้สำหรับ CPU ของคุณ และหากบัฟเฟอร์แบบสุ่มมีขนาดเล็กกว่าชุดข้อมูลของคุณอย่างมากอาจไม่สามารถสลับข้อมูลได้อย่างเพียงพอ ข้อมูลอาจมีการสับ "ในเครื่อง" แต่ไม่สามารถสลับแบบ "ทั่วโลก" ได้ นั่นคือตัวอย่างจากจุดเริ่มต้นของชุดข้อมูลอาจไม่ได้สับด้วยตัวอย่างจากจุดสิ้นสุดของชุดข้อมูล
ทางออกที่ดีคือการใช้การผสมผสานที่สมดุลของสองวิธีข้างต้นโดยแยกชุดข้อมูลของคุณออกเป็นไฟล์ TFRecord หลายไฟล์ (เรียกว่าเศษ) ในระหว่างแต่ละยุคคุณสามารถสลับชื่อไฟล์ shard เพื่อรับ shuffling ทั่วโลกและใช้ shuffle buffer เพื่อรับ shuffling ในเครื่อง ความสมดุลที่ดีจะทำให้เศษมีขนาดใหญ่พอที่จะป้องกันปัญหาความเร็วดิสก์ แต่จะทำให้เศษเล็ก ๆ พอที่จะอนุญาตให้มีการสับแบบสับเปลี่ยนโดยบัฟเฟอร์แบบสุ่ม
นี่คือขั้นตอนที่แน่นอน:
- วางตัวอย่างการฝึกอบรมทั้งหมดลงในไฟล์ TFRecord หลายไฟล์ (เศษ)
- ที่จุดเริ่มต้นของแต่ละยุคให้สลับรายชื่อไฟล์ที่มีชาร์ด
- อ่านตัวอย่างการฝึกอบรมจากเศษและส่งตัวอย่างผ่านบัฟเฟอร์แบบสุ่ม โดยทั่วไปบัฟเฟอร์ shuffle ควรมีขนาดใหญ่กว่าขนาดของ shard เพื่อให้แน่ใจว่ามีการสับที่ดีข้ามเศษ
- ส่งตัวอย่างที่สับเข้าไปในกระบวนการฝึกอบรมของคุณ
.shuffle()
เมธอดไม่ใช่โซลูชันที่เหมาะสมถ้าคุณมีไฟล์ tfrecord ขนาดใหญ่หนึ่งไฟล์ เอาท์พุทแบบสับจะค่อนข้างเกี่ยวข้องกับคำสั่งเดิมถ้าคุณไม่ได้ใช้ขนาดบัฟเฟอร์ขนาดใหญ่ ฉันคิดว่าการสับเปลี่ยนข้อมูลก่อนบันทึกเป็น tfrecord หรือแยกเป็นส่วนที่จำเป็นเมื่อคุณมีชุดข้อมูลขนาดใหญ่