【问题标题】:How can I use values read from TFRecords as arguments to tf.reshape?如何使用从 TFRecords 读取的值作为 tf.reshape 的参数?
【发布时间】:2016-02-25 06:41:45
【问题描述】:
def read_and_decode(filename_queue):
  reader = tf.TFRecordReader()
  _, serialized_example = reader.read(filename_queue)
  features = tf.parse_single_example(
      serialized_example,
      # Defaults are not specified since both keys are required.
      features={
          'image_raw': tf.FixedLenFeature([], tf.string),
          'label': tf.FixedLenFeature([], tf.int64),
          'height': tf.FixedLenFeature([], tf.int64),
          'width': tf.FixedLenFeature([], tf.int64),
          'depth': tf.FixedLenFeature([], tf.int64)
      })
  # height = tf.cast(features['height'],tf.int32)
  image = tf.decode_raw(features['image_raw'], tf.uint8)
  image = tf.reshape(image,[32, 32, 3])
  image = tf.cast(image,tf.float32)
  label = tf.cast(features['label'], tf.int32)
  return image, label

我正在使用 TFRecord 来存储我的所有数据。函数 read_and_decode 来自 TensorFlow 提供的 TFRecords 示例。目前我通过预定义的值来重塑:

image = tf.reshape(image,[32, 32, 3])

但是,我现在将使用的数据具有不同的维度。例如,我可以有一个 [40, 30, 3] 的图像(缩放这不是一个选项,因为我不希望它被扭曲)。我想读入不同维度的数据,并在数据增强阶段使用 random_crop 来规避这个问题。我需要的是类似下面的东西。

height = tf.cast(features['height'], tf.int32)
width = tf.cast(features['width'], tf.int32)
image = tf.reshape(image,[height, width, 3])

但是,我似乎无法找到一种方法来做到这一点。感谢您的帮助!

编辑:

ValueError: All shapes must be fully defined: [TensorShape([Dimension(None), Dimension(None), Dimension(None)]), TensorShape([])]

image = tf.reshape(image, tf.pack([height, width, 3]))
image = tf.reshape(image, [32,32,3])

问题肯定出在这两行。硬编码的变量有效,但 tf.pack() 的变量无效。

【问题讨论】:

  • 回复:编辑。看起来您正在使用一种图像操作,它需要在图形构建时知道所有形状(如裁剪或填充形状)。但是,这似乎与原始问题(关于从 TFRecords 中读取内容)无关,因此您应该提出一个关于如何处理这个问题的新问题。确保在错误消息中包含完整的堆栈跟踪!
  • @mrry,你说得对,是 tf.random_crop 导致了这个问题。根据您的建议,我在stackoverflow.com/questions/35691102/… 提出了一个新问题。

标签: python tensorflow


【解决方案1】:

您已经非常接近找到可行的解决方案了!目前还没有自动方法可以为 TensorFlow 提供一个由张量和数字组成的列表并从中生成张量,这是 tf.reshape() 所期待的。答案是使用tf.stack(),它显式地获取一个 N 维张量(或可转换为张量的东西)的列表,并将它们打包成一个 (N+1) 维张量。

这意味着你可以写:

features = ...  # Parse from an example proto.
height = tf.cast(features['height'], tf.int32)
width = tf.cast(features['width'], tf.int32)

image = tf.reshape(image, tf.stack([height, width, 3]))

【讨论】:

  • 感谢您的修复。它最初有效。但现在我收到了这个错误。详情请参阅编辑。
  • 我也有同样的问题,因为 tf.pack 被删除并且 tf.stack 被它替换,我使用了 tf.stack,但是在硬编码尺寸之后一切正常。这是 Tensorflow 的预期行为吗
  • 我在这里阅读了您的答案后发现了它的工作原理[github.com/tensorflow/tensorflow/issues/2604],谢谢
【解决方案2】:

我也遇到过同样的问题。根据Tensorflow documentation,如果你尝试使用shuffle_batch,你会遇到这种情况 读取所需数据后进行操作。

和本例一样,如果不使用 shuffle_batch 处理,可以加载动态维度文件。

    reader = tf.TFRecordReader()
    _, serialized_example = reader.read(filename_queue)
    features = tf.parse_single_example(
        serialized_example,
        features={
             'clip_height': tf.FixedLenFeature([], tf.int64),
             'clip_width': tf.FixedLenFeature([], tf.int64),
             'clip_raw': tf.FixedLenFeature([], tf.string),
             'clip_label_raw': tf.FixedLenFeature([], tf.int64)
        })
    image = tf.decode_raw(features['clip_raw'], tf.float64)
    label = tf.cast(features['clip_label_raw'], tf.int32)
    height = tf.cast(features['clip_height'], tf.int32)
    width = tf.cast(features['clip_width'], tf.int32)
    im_shape = tf.stack([height, width, -1])
    new_image = tf.reshape(image, im_shape )

但是如果要使用shuffle批处理,就不能使用tf.stack。您必须定义与此类似的静态尺寸。

    reader = tf.TFRecordReader()
    _, serialized_example = reader.read(filename_queue)
    features = tf.parse_single_example(
        serialized_example,
        features={
             'clip_height': tf.FixedLenFeature([], tf.int64),
             'clip_width': tf.FixedLenFeature([], tf.int64),
             'clip_raw': tf.FixedLenFeature([], tf.string),
             'clip_label_raw': tf.FixedLenFeature([], tf.int64)
        })
    image = tf.decode_raw(features['clip_raw'], tf.float64)
    label = tf.cast(features['clip_label_raw'], tf.int32)
    height = tf.cast(features['clip_height'], tf.int32)
    width = tf.cast(features['clip_width'], tf.int32)
    image = tf.reshape(image, [1, 512, 1])
    images, sparse_labels = tf.train.shuffle_batch(
            [image, label], batch_size=batch_size, num_threads=2,
            capacity=1000 + 3 * batch_size,
            min_after_dequeue=100)

@mrry 如果我错了,请纠正我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 2018-04-17
    • 2018-12-28
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多