【问题标题】:tf.data.Dataset input pipeline delivering bad results compared to Threading/Queue与线程/队列相比,tf.data.Dataset 输入管道提供了糟糕的结果
【发布时间】:2019-02-18 11:59:05
【问题描述】:

之前我使用线程和队列作为我的数据管道,我在两个 GPU 上都获得了非常高的 Util(数据是动态创建的)。我想使用 tf 数据集,但我很难重现结果。

我尝试了很多方法。因为我动态创建数据,所以 from_generator() 方法看起来很完美。您在下面看到的代码是我最后一次尝试。尽管我使用 map() 函数来处理生成的图像,但似乎在创建数据方面存在瓶颈。我在下面的代码中尝试了什么,我想以某种方式“多线程”生成器,因此同时有更多数据进入。但目前还没有更好的结果。

def generator(n):
    with tf.device('/cpu:0'):
        while True:
            ...
            yield image, label

def get_generator(n):
    return partial(generator, n)

def dataset(n):
    return tf.data.Dataset.from_generator(get_generator(n), output_types=(tf.float32, tf.float32), output_shapes=(tf.TensorShape([None,None,1]),tf.TensorShape([None,None,1])))

def input_fn():
# ds = tf.data.Dataset.from_generator(generator, output_types=(tf.float32, tf.float32), output_shapes=(tf.TensorShape([None,None,1]),tf.TensorShape([None,None,1])))
    ds = tf.data.Dataset.range(BATCH_SIZE).apply(tf.data.experimental.parallel_interleave(dataset, cycle_length=BATCH_SIZE))
    ds = ds.map(map_func=lambda img, lbl: processImage(img, lbl))
    ds = ds.shuffle(SHUFFLE_SIZE)
    ds = ds.batch(BATCH_SIZE)
    ds = ds.prefetch(1)
return ds

预期结果将是较高的 GPU Util (>80%),但目前确实很低 10/20%。

【问题讨论】:

  • 为什么需要from_generator?它有一些限制,继承自 py_func tensorflow.org/api_docs/python/tf/data/Dataset#from_generator
  • @Sharky 因为我认为我正在动态生成数据,这将是完美的。尽管另一种解决方法是将我从 thredas 生成的数据放入数据集中,如果它以某种方式起作用的话。所以我可以使用旧架构和数据集 API 的混合体
  • 如果我没记错的话,你的数据是图片。试试 from_tensor_slices。
  • @Sharky 但是我必须让我的图像已经生成对吗?
  • 不,您可以通过随机播放缓冲区大小来控制它。调用迭代器时将加载图像。此外,您可以添加预取操作,并指定并行生产的批次数。看一看。 tensorflow.org/guide/performance/datasets

标签: tensorflow tensorflow-datasets


【解决方案1】:

您可以改用tf.data.Dataset.from_tensor_slices。 只需传递图像/标签路径。该函数接受文件名作为参数。

def input_func():
    dataset = tf.data.Dataset.from_tensor_slices(images_path, labels_path)
    dataset = dataset.shuffle().repeat()
    ...
    return dataset 

【讨论】:

  • 抱歉,我的图像没有路径,因为它们是在训练运行的同时生成并从队列中取出的......
  • @craft 您的图像存储方式和位置?
  • 它们只是以 jpg 格式存储并在训练前加载到内存中。当训练开始时,我将它们预处理,将它们放入队列等等
  • 那就试试我的建议吧。根本不需要使用队列。
  • 嗯。是的,也许你是对的。我明天试试看。
猜你喜欢
  • 2015-06-22
  • 2018-08-12
  • 2016-01-25
  • 2016-10-09
  • 1970-01-01
  • 2014-06-30
  • 1970-01-01
  • 2018-06-27
  • 1970-01-01
相关资源
最近更新 更多