Tensorflow重塑张量给出无维度

Jac*_*edt 4 tensorflow

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

在我的代码中,我创建了两个模型,一个用于训练,一个用于验证,与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')
Run Code Online (Sandbox Code Playgroud)

第一个模型,一个用于训练,似乎创建得很好,但第二个用于验证,但没有.输出获得None维度!我所引用的行位于链接代码的第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])
Run Code Online (Sandbox Code Playgroud)

这给了我这个:

Model num_steps: 400
Model batch_size: 1
Output dims Dimension(None) Dimension(650)
Run Code Online (Sandbox Code Playgroud)

这个问题只发生在'验证模型'上,而不是'训练模型'.对于'训练模型',我得到了预期的输出:

Model num_steps: 400
Model batch_size: 2
Output dims Dimension(800) Dimension(650)
Run Code Online (Sandbox Code Playgroud)

(注意,使用'验证模型'我使用的是batch_size=1代替batch_size=2我用于训练模型的那个)

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

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

mrr*_*rry 6

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

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

形状推断基于"形状函数"应用局部规则,该"形状函数"将输入的形状取为操作并计算操作输出的(可能不完整的)形状.为了弄清楚为什么tf.reshape()给出一个不完整的形状,我们必须看看它的输入,并向后工作:

  • 包含a 的shape参数,意思是"根据输入的形状自动计算输出形状" .tf.reshape()[-1]tensor
  • tensor输入是的输出tf.concat()上的同一条线上.
  • 输入tf.concat()tf.mul()in 计算BasicLSTMCell.__call__().该tf.mul()运算相乘的结果tf.tanh()tf.sigmoid()运算.
  • tf.tanh()运算产生大小的输出[?, hidden_size],并且tf.sigmoid()运算产生大小的输出[batch_size, hidden_size].

tf.mul()运算执行NumPy的风格的广播.如果尺寸为1,则仅广播尺寸.考虑我们计算的三种情况tf.mul(x, y):

  1. 如果x有形状[1, 10],并且y有形状[5, 10],则会发生广播,输出形状将是[5, 10].
  2. 如果x有形状[1, 10],并且y有形状[1, 10],则不会有广播,输出形状也会[1, 10].
  3. 但是,如果x有形状[1, 10],并且y有形状[?, 10],则没有足够的静态信息来判断是否会发生广播(即使我们碰巧知道情况2在运行时适用).

因此,当batch_size为1时,tf.mul()op产生具有该形状的输出[?, hidden_size]; 但是当batch_size大于1时,输出形状为[batch_size, hidden_size].

在形状推断出现故障的情况下,使用该Tensor.set_shape()方法添加信息是合适的.这在BasicLSTMCell实现中可能是有用的,我们知道的不仅仅是可以推断出输出的形状.