【问题标题】:Tensorflow: Getting scalar tensor value as int for pass to set_shape()Tensorflow:将标量张量值作为 int 传递给 set_shape()
【发布时间】:2017-08-18 14:14:13
【问题描述】:

我正在尝试将 3D 图像及其标签从 numpy 数组加载到 TensorFlow 记录,然后在训练我的网络时从队列中读取它们。转换代码基于TensorFlow的Inception model的转换。

每个图像都有不同的高度、宽度和深度值,因此在重塑数组时我需要知道这些值。但是,当我尝试使用 set_shape 时出现错误,因为正在使用 int() 行的某处,并且它不接受张量值。

reader = tf.TFRecordReader()
_, value = reader.read(filename_queue)


# Features in Example proto
feature_map = {
    'height': tf.VarLenFeature(dtype=tf.int64),
    'width': tf.VarLenFeature(dtype=tf.int64),
    'depth': tf.VarLenFeature(dtype=tf.int64),
    'label': tf.VarLenFeature(dtype=tf.int64),
    'image_raw': tf.VarLenFeature(dtype=tf.string)
}

features = tf.parse_single_example(value, feature_map)
result.label = tf.cast(features['label'].values[0], dtype=tf.int32)
result.height = tf.cast(features['height'].values[0], dtype=tf.int32)
result.width = tf.cast(features['width'].values[0], dtype=tf.int32)
result.depth = tf.cast(features['depth'].values[0], dtype=tf.int32)

image = tf.decode_raw(features['image_raw'].values[0], tf.int16)

image = tf.reshape(image, [result.depth, result.height, result.width])
image = tf.cast(tf.transpose(image, [1, 2, 0]), tf.float32)
result.image = tf.expand_dims(image, 3)

result.image.set_shape([result.height, result.width, result.depth, 1])
result.label = tf.expand_dims(result.label, 0)
result.label.set_shape([1])

错误跟踪:

Traceback (most recent call last):
  File "dsb17_multi_gpu_train.py", line 227, in <module>
    tf.app.run()
  File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/platform/app.py", line 44, in run
    _sys.exit(main(_sys.argv[:1] + flags_passthrough))
  File "dsb17_multi_gpu_train.py", line 223, in main
    train()
  File "dsb17_multi_gpu_train.py", line 129, in train
    loss = tower_loss(scope)
  File "dsb17_multi_gpu_train.py", line 34, in tower_loss
    images, labels = dsb17.inputs(False)
  File "/home/ubuntu/dsb17/model/dsb17.py", line 104, in inputs
    batch_size=FLAGS.batch_size)
  File "/home/ubuntu/dsb17/model/dsb17_input.py", line 161, in inputs
    read_input = read_data(filename_queue)
  File "/home/ubuntu/dsb17/model/dsb17_input.py", line 62, in read_data
    result.image.set_shape([result.height, result.width, result.depth, 1])
  File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/ops.py", line 425, in set_shape
    self._shape = self._shape.merge_with(shape)
  File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/tensor_shape.py", line 573, in merge_with
    other = as_shape(other)
  File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/tensor_shape.py", line 821, in as_shape
    return TensorShape(shape)
  File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/tensor_shape.py", line 457, in __init__
    self._dims = [as_dimension(d) for d in dims_iter]
  File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/tensor_shape.py", line 457, in <listcomp>
    self._dims = [as_dimension(d) for d in dims_iter]
  File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/tensor_shape.py", line 378, in as_dimension
    return Dimension(value)
  File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/tensor_shape.py", line 33, in __init__
    self._value = int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'Tensor'

我最初认为这是因为 Tensor 在会话中评估之前没有值,但是损失正在 sess.run() 中评估,这需要调用 tower_loss()。我的训练代码和cifar10_multi_gpu_train.py在结构上是一样的,整体文件结构也很相似。

那么问题是:它实际上是在会话中进行评估,还是尚未构建图表?我是否需要以某种方式从零维张量中提取一个值?更一般地说,我对张量和会话有什么误解,导致我的代码无法按预期工作?

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    实际上,您可以将图像形状传递给reshape 函数,但您需要多一步。换行就好了:

    image = tf.reshape(image, [result.depth, result.height, result.width])
    

    到:

    image_shape = tf.stack([result.depth, result.height, result.width])
    image = tf.reshape(image, image_shape)
    

    【讨论】:

      【解决方案2】:

      一般情况下,您不能使用tf.Tensor.set_shape() 执行此操作,因为该方法需要静态形状。张量 result.heightresult.widthresult.depth 表示从文件读取的值,在运行时它们可以计算为许多不同的整数(取决于文件中的内容),因此没有一个 int可以通过他们。在这种情况下,您目前能做的最好的就是将这些维度表示为静态未知,使用 None 表示未知维度:

      result.image.set_shape([None, None, None, 1])
      

      请注意,此语句不应更改任何内容,因为 TensorFlow 应该已经能够推断出形状是 4-D,最后一维的大小为 1。

      有关静态和动态形状的更多详细信息,请参阅this answer

      【讨论】:

        【解决方案3】:

        根据 TensorFlow 的tf.cast docs,tf.cast 返回一个张量。

        您的错误表明,当使用set_shape() 时,您不能将张量作为参数,而是使用 int。

        您可以尝试强制 Tensorflow 评估演员表。这个简单的例子对我有用:

        a = tf.constant(2.0)
        b = tf.constant([1.0,2.0])
        b.set_shape(a.eval())
        

        如果不调用eval(),我会得到和你一样的错误。

        【讨论】:

        • 这是一个很好的建议,但是如果我在我的代码的那个部分创建一个会话(使用 allow_soft_placement = True,否则它根本不起作用),然后是 .eval(),代码运行,但没有任何反应。如果它工作正常,我会收到一条消息,说图像正在添加到队列中,但不知道代码在做什么。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-01
        • 2021-08-14
        • 2016-11-29
        • 1970-01-01
        • 1970-01-01
        • 2020-05-26
        相关资源
        最近更新 更多