Tensorflow重塑张量给出无维度

时间:2016-03-22 10:58:14

标签: tensorflow

我在0.6.0分支上使用了here描述的模型。代码可以找到here。我对链接代码做了一些小改动。

在我的代码中,我创建了两个模型,一个用于训练,一个用于验证,与Tensorflow教程中的模型非常相似。

with tf.variable_scope("model", reuse=None, initializer=initializer):
    m = PTBModel_User(is_training=True, config=config, name='Training model')
with tf.variable_scope("model", reuse=True, initializer=initializer):
    mtest = PTBModel_User(is_training=False, config=config_valid, name='Validation model')

第一个模型,一个用于训练,似乎创建得很好,但第二个用于验证,但没有。输出获得None维度!我引用的行位于linked代码中的第134行:

output = tf.reshape(tf.concat(1, outputs), [-1, size])

我在输出重塑后立即添加了这些行:

output_shape = output.get_shape()
print("Model num_steps:", num_steps)
print("Model batch_size:", batch_size)
print("Output dims", output_shape[0], output_shape[1])

这给了我这个:

Model num_steps: 400
Model batch_size: 1
Output dims Dimension(None) Dimension(650)

此问题仅发生在“验证模式”中,而不是“培训模型”。对于培训模式'我得到预期的输出:

Model num_steps: 400
Model batch_size: 2
Output dims Dimension(800) Dimension(650)

(请注意,使用'验证模型'我使用batch_size=1代替我用于培训模型的batch_size=2

根据我的理解,使用-1作为reshape函数的输入,将自动计算出输出形状!但是为什么我会得到无?馈送到模型的配置中没有任何内容具有None值。

感谢您提供所有帮助和提示!

1 个答案:

答案 0 :(得分:6)

TL; DR:维度None只是意味着形状推断无法确定output张量的精确形状,在图形构建时。运行图形时,张量将具有相应的运行时形状。

如果您对形状推断的工作方式不感兴趣,可以立即停止阅读。

形状推断基于“形状函数”应用局部规则,该形状函数将输入的形状取为操作并计算操作输出的(可能不完整的)形状。要弄清楚tf.reshape()给出不完整形状的原因,我们必须查看其输入,并向后工作:

  • shape的{​​{1}}参数包含tf.reshape(),表示“根据[-1]输入的形状”自动计算输出形状。
  • tensor输入是tf.concat()same line的输出。
  • tensor的输入由tf.mul()中的BasicLSTMCell.__call__()计算。 tf.concat()操作符会将tf.tanh()tf.sigmoid()操作的结果相乘。
  • tf.mul()操作会生成大小为tf.tanh()的输出,[?, hidden_size]操作会生成大小为tf.sigmoid()的输出。

[batch_size, hidden_size]操作执行NumPy-style broadcasting。只有尺寸为1时才会广播尺寸。请考虑我们计算tf.mul()的三种情况:

  1. 如果tf.mul(x, y)的形状为x,而[1, 10]的形状为y,则会进行广播,输出形状为[5, 10]
  2. 如果[5, 10]的形状为x,而[1, 10]的形状为y,则不会进行广播,输出形状将为[1, 10]
  3. 但是,如果[1, 10]的形状为x,而[1, 10]的形状为y,则静态信息不足以判断广播是否会发生(即使我们碰巧发生了知道案例2适用于运行时)。
  4. 因此,当[?, 10]为1时,batch_size op会生成形状为tf.mul()的输出;但是当[?, hidden_size]大于1时,输出形状为batch_size

    如果形状推断出现故障,可以使用Tensor.set_shape()方法添加信息。这可能在[batch_size, hidden_size]实现中很有用,我们知道的不仅仅是可以推断出输出的形状。