设计最优数据输入管道
-
使用 prefetch 函数去重叠 数据读取器 和 数据消耗器的工作。推荐在输入管道的末端添加 prefetch(n) (n是batch size),以重叠 CPU 上的变换 及 GPU/TPU设备上的训练。
dataset = dataset.batch(batch_size=FLAGS.batch_size) dataset = dataset.prefetch(buffer_size=FLAGS.prefetch_buffer_size) # last transformation return dataset ```
-
通过设置 num_parallel_calls 参数,来并行 map 变换。我们建议使用将该参数设置为 CPU 的核心数。
dataset = dataset.map(map_func=parse_fn, num_parallel_calls=FLAGS.num_parallel_calls)
如果使用 batch 变换来将预处理好的元素 batching,建议使用融合op:map_and_batch 变换;尤其是使用大的batch size。
dataset = dataset.apply(tf.contrib.data.map_and_batch(map_func=parse_fn,batch_size=FLAGS.batch_size))
-
如果数据存在远程存储上,(且有时需要解析),建议使用 parallel_interleave 来并行数据的读取和解析。
dataset = files.apply(tf.contrib.data.parallel_interleave( tf.data.TFRecordDataset, cycle_length=FLAGS.num_parallel_readers))
-
将简单的用户自定义函数进行向量化,然后传递给 map 变换去分摊 用户自定义函数有关的调用、执行的负载。
-
如果数据能够加载到内存,使用 cache 变化去在训练的第一个 epoch 将数据集缓存到内存,所以能避免后来的 epoch 读取、解析、变换数据的负载。
-
如果预处理会增加你数据的 size,建议首先使用 interleave、prefetch、shuffle 变换去减少内存使用量(如果可能)。
-
建议在 repeat 变换之前使用 shuffle 变换,最好使用融合op: shuffle_and_repeat 变换。