【问题标题】:Add data to tf.data.Dataset API in batches批量添加数据到 tf.data.Dataset API
【发布时间】:2019-08-01 18:25:00
【问题描述】:

我有一个数据集,我想将它传递给tf.data.Dataset API 进行调度。但是,在传递给tf.data.Dataset 之前,我需要读取大量数据文件并对其进行预处理。我不想一次将所有数据读入内存。目前,我一直在一次读取一个文件,对它们进行批处理,然后读取下一个文件。即

import itertools

class DataBatcher:
    def __init__(self, list_of_files):
        self.list_of_files = list_of_files
        self.init_index = 0
        self.x, self.y =  self.loop_files()

    def loop_files(self):
        for one_part in itertools.cycle(self.list_of_files):
             # read in one_part file, which has N examples
             # doing some prepocessing
             # self.x and self.y will be of shape [N, feature_num], [N,] respectively
             yield self.x, self.y

    def gen_batch(self, batch_size):
        # discard remaining data if it't not enough for a batch
        if (self.init_index + batch_size) > self.y.shape[0]:
            self.x, self.y =  self.loop_files()
            self.init_index = 0
        x_batch, y_batch = self.x[self.init_index: self.init_index + batch_size, :], self.y[self.init_index: self.init_index + batch_size]
        self.init_index += batch_size
        return x_batch, y_batch 

data_batcher = DataBatcher(files)
x_sample, y_sample = data_batcher.gen_batch(10)

x_sampley_sample 然后通过 feed_dict 传递给 tensorflow 模型。但我想更改为tf.data.Dataset 以提高性能。我发现tf.data.Dataset.from_tensor_slices 在调度之前读入整个数据集,tf.data.Dataset.from_generator 一次读入一个示例,两者都没有有效地使用资源,有什么办法吗?类似于使用生成器生成数据集的一部分?

【问题讨论】:

  • from_generator 可以包装任意 Python 代码。这意味着是的,您可以一次完全生成数据集的一部分。但最终,您需要确保从数据集中进入您的模型的任何内容都具有“合理”的结构。
  • 是的,我试图让生成器产生部分数据,但在批处理期间,该部分被视为一个数据示例,而不是多个示例

标签: tensorflow tensorflow-datasets


【解决方案1】:

如果使用数据集 API,则不需要您的批处理逻辑。可能最好:

  1. 在现有的生成器函数上使用Dataset.from_generator
  2. 然后使用dataset.batch() 方法批处理到您需要的任何大小的批处理。

大概是这样的:

data_batcher = DataBatcher(files)

dataset = tf.data.Dataset.from_generator(data_batcher.loop_files, output_types=(tf.float32, tf.float32))
batched_data = dataset.batch(BATCH_SIZE)

【讨论】:

  • data_batcher.loop_files 传递给from_generator 的问题在于,它会将loop_files 的每个输出视为一个示例,实际上是一个文件中的N 个示例。我的代码示例对此不清楚,我将对其添加注释。
  • 是的,我能做到。我只是假设这可能比仅使用feed_dict 和我自己的批处理效率更低。虽然我没有测试过。 ://
  • 我无意中删除了该评论!对不起,优柔寡断和点击错误的组合! :-) 认为你已经明白了我想说的话!
猜你喜欢
  • 2020-01-13
  • 2015-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-15
  • 2016-08-28
相关资源
最近更新 更多