首页 > 解决方案 > 使用 TensorFlow Interleave 提高性能

问题描述

我的输入管道在 CPU、GPU 和磁盘利用率较低的情况下性能不佳。我一直在阅读 tensorflow "Better performance with tf.data API" 文档和 Dataset 文档,但我不明白发生了什么足以将其应用于我的情况。这是我当前的设置:

img_files = sorted(tf.io.gfile.glob(...))
imgd = tf.data.FixedLengthRecordDataset(img_files, inrez*inrez)
#POINT1A
imgd = imgd.map(lambda s: tf.reshape(tf.io.decode_raw(s, tf.int8), (inrez,inrez,1)))
imgd = imgd.map(lambda x: tf.cast(x, dtype=tf.float32))

out_files = sorted(tf.io.gfile.glob(...))
outd = tf.data.FixedLengthRecordDataset(out_files, 4, compression_type="GZIP")
#POINT1B
outd = outd.map(lambda s: tf.io.decode_raw(s, tf.float32))

xsrc = tf.data.Dataset.zip((imgd, outd)).batch(batchsize)
xsrc = xsrc.repeat()        # indefinitely
#POINT2
xsrc = xsrc.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)

我应该在预取之前将整个管道交错到最后(POINT2)吗?或者在每个 FixedLengthRecordDataset (POINT1A, POINT1B) 之后分别交错 imgd 和 outd,并并行化地图?(需要保持 imgd 和 outd 同步!) Dataset.range(rvalue) 怎么了——似乎有必要但不明显使用什么右值?有没有更好的总体规划?

请注意,数据集非常大,不适合 RAM。

标签: pythontensorflowtensorflow2.0tensorflow-datasets

解决方案


Interleave 允许您在单独的逻辑线程(并行)中处理每个文件,然后将文件中的数据组合到单个数据集中。由于您的数据来自两个相应的文件,因此您需要小心保留顺序。

这是一个如何将交错放置在数据集末尾附近的示例:

img_files = ...
out_files = ...
files = tf.data.Dataset.zip(img_files, out_files)

def parse_img_file(img_file):
  imgd = tf.data.FixedLengthRecordDataset(img_files, inrez*inrez)
  ...

def parse_out_file(out_file):
  ...

def parse_files_fn(img_file, out_file):
  img_file_dataset = parse_img_file(img_file)
  out_file_dataset = parse_out_file(out_file)
  return tf.data.Dataset.zip(img_file_dataset, out_file_dataset)

dataset = files.interleave(parse_files_fn, num_parallel_calls=tf.data.experimental.AUTOTUNE)
dataset = dataset.repeat()

interleave 的每个线程都会从不同的 (img, out) 文件对中产生元素,并且从每对文件中产生的元素将被交织在一起。


推荐阅读