【问题标题】:How to correctly map a python function and then batch the Dataset in Tensorflow如何正确映射 python 函数,然后在 Tensorflow 中批处理数据集
【发布时间】:2018-12-05 05:21:33
【问题描述】:

我希望创建一个管道来向神经网络提供非标准文件(例如扩展名为 *.xxx)。 目前我的代码结构如下:

  1) 我定义了一个查找训练文件的路径列表

2) 我定义了一个包含这些路径的 tf.data.Dataset 对象的实例

3) 我将一个 python 函数映射到数据集,该函数采用每个路径并返回关联的 numpy 数组(从 pc 上的文件夹加载);这个数组是一个维度为 [256, 256, 192] 的矩阵。

4) 我定义了一个可初始化的迭代器,然后在网络训练期间使用它。

我怀疑我提供给网络的批次的大小。我想向网络提供大小为 64 的批次。我该怎么办? 例如,如果我将函数 train_data.batch(b_size) 与 b_size = 1 一起使用,结果是当迭代时,迭代器给出一个形状为 [256, 256, 192] 的元素;如果我想用这个数组的 64 个切片来喂神经网络呢?

这是我的代码的摘录:

    with tf.name_scope('data'):
        train_filenames = tf.constant(list_of_files_train)

        train_data = tf.data.Dataset.from_tensor_slices(train_filenames)
        train_data = train_data.map(lambda filename: tf.py_func(
            self._parse_xxx_data, [filename], [tf.float32]))

        train_data.shuffle(buffer_size=len(list_of_files_train))
        train_data.batch(b_size)

        iterator = tf.data.Iterator.from_structure(train_data.output_types, train_data.output_shapes)

        input_data = iterator.get_next()
        train_init = iterator.make_initializer(train_data)

  [...]

  with tf.Session() as sess:
      sess.run(train_init)
      _ = sess.run([self.train_op])

提前致谢

---------

我在下面的 cmets 中发布了我的问题的解决方案。我仍然很乐意收到有关可能改进的任何意见或建议。谢谢;)

【问题讨论】:

    标签: python tensorflow iterator dataset


    【解决方案1】:

    已经很久了,但我会发布一个可能的解决方案,在 TensorFlow 中使用自定义形状对数据集进行批处理,以防有人需要。

    模块tf.data 提供unbatch() 方法来解开每个数据集元素的内容。可以先取消批处理,然后以所需的方式再次批处理数据集对象。通常,一个好主意也可能是在再次批处理之前对未批处理的数据集进行洗牌(这样我们就可以从每批中的随机元素中获得随机切片):

    with tf.name_scope('data'):
        train_filenames = tf.constant(list_of_files_train)
    
        train_data = tf.data.Dataset.from_tensor_slices(train_filenames)
        train_data = train_data.map(lambda filename: tf.py_func(
            self._parse_xxx_data, [filename], [tf.float32]))
    
        # un-batch first, then batch the data
        train_data = train_data.apply(tf.data.experimental.unbatch())
    
        train_data.shuffle(buffer_size=BSIZE)
        train_data.batch(b_size)
    
        # [...]
    

    【讨论】:

      【解决方案2】:

      如果我清楚地理解您的问题,您可以尝试在 self._parse_xxx_data 函数中将数组切成您想要的形状。

      【讨论】:

      • 感谢您的回复。不幸的是,由于时间限制,最好在调用此函数后对数组进行批处理。事实上,由于许多限制,我必须在 self.parse_xxx_data() 函数中生成一个 [256, 256, 192] 数组。具体来说,这些是 192 张大小为 256x256 的图像,其制作非常耗时:所以我不想只拍摄 64 张图像,因为这会浪费“制作”(因为丢弃的图像可以用于训练神经净)。
      • 也许你应该在训练之前先将 1 张图像放入 1 个文件中,因为在训练神经网络时,你必须确保每批中的图像是从整个数据集中随机采样的。
      • 不幸的是,在我的情况下,这也是一个糟糕的选择,因为我需要将卷作为一个整体进行预处理(即进行随机 3D 旋转、对整个卷统计进行标准化等),然后在运行时切片这些 3D 体积,因为我想使用神经网络处理 2D 切片。保存如此大量的 2D 切片对我来说绝对是一个次优且不切实际的选择。
      猜你喜欢
      • 2018-10-30
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 2020-10-29
      • 1970-01-01
      • 2023-01-30
      • 1970-01-01
      • 2020-04-23
      相关资源
      最近更新 更多