Answers:
将TFRecord文件拆分为碎片可帮助您重新整理不适合内存的大型数据集。
想象一下,您已经在磁盘上保存了数百万个培训示例,并且您想在培训过程中重复运行它们。此外,假设对于训练数据的每次重复(即每个时期),您都希望以完全随机的顺序加载数据。
一种方法是每个训练示例拥有一个文件,并生成所有文件名的列表。然后,在每个纪元的开始,您将随机排列文件名列表并加载各个文件。这种方法的问题在于,您正在从磁盘上的随机位置加载数百万个文件。这可能会很慢,尤其是在硬盘驱动器上。如果要从随机位置加载数百万个小文件,则即使RAID 0阵列也无法提高速度。如果您通过网络连接访问文件,问题将变得更加严重。
另一种方法是从一个大TFRecord文件中依次读取训练示例,然后使用随机缓冲将随机示例洗入内存。但是,混洗缓冲区通常不能大于CPU可用的DDR内存。并且,如果混洗缓冲区远小于数据集,则可能无法充分混洗数据。数据可以“本地”混洗,而不能“全局”混洗。也就是说,数据集开头的示例可能不会与数据集结尾的示例混在一起。
一个好的解决方案是通过将数据集拆分为多个TFRecord文件(称为分片)来使用上述两种方法的平衡组合。在每个时期,您可以对分片文件名进行混排以获得全局混排,并使用混排缓冲区获得局部混排。良好的平衡将使分片足够大以防止磁盘速度问题,但将使分片保持足够小以允许混洗缓冲区充分混洗。
具体步骤如下:
.shuffle()
如果您有一个大的tfrecord文件,则此方法不是理想的解决方案。如果您不使用较大的缓冲区大小,则经过改组的输出在某种程度上与原始顺序有关。我认为,如果您的数据集很大,则在存储到tfrecord或拆分为碎片之前,必须先对数据进行预混洗。