我在玩tensorflow,遇到了以下代码的问题:
def _init_parameters(self, input_data, labels):
# the input shape is (batch_size, input_size)
input_size = tf.shape(input_data)[1]
# labels in one-hot format have shape (batch_size, num_classes)
num_classes = tf.shape(labels)[1]
stddev = 1.0 / tf.cast(input_size, tf.float32)
w_shape = tf.pack([input_size, num_classes], 'w-shape')
normal_dist = tf.truncated_normal(w_shape, stddev=stddev, name='normaldist')
self.w = tf.Variable(normal_dist, name='weights')
(我正在使用tf.pack
中建议的this question,因为我得到了相同的错误)
当我运行它(从调用此脚本的较大脚本中)时,会出现以下错误:
ValueError: initial_value must have a shape specified: Tensor("normaldist:0", shape=TensorShape([Dimension(None), Dimension(None)]), dtype=float32)
我试图在交互式shell中复制这个过程。实际上,normal_dist
的维度是未指定的,尽管提供的值确实存在:
In [70]: input_size.eval()
Out[70]: 4
In [71]: num_classes.eval()
Out[71]: 3
In [72]: w_shape.eval()
Out[72]: array([4, 3], dtype=int32)
In [73]: normal_dist.eval()
Out[73]:
array([[-0.27035281, -0.223277 , 0.14694688],
[-0.16527176, 0.02180306, 0.00807841],
[ 0.22624688, 0.36425814, -0.03099642],
[ 0.25575709, -0.02765726, -0.26169327]], dtype=float32)
In [78]: normal_dist.get_shape()
Out[78]: TensorShape([Dimension(None), Dimension(None)])
这很奇怪。Tensorflow生成矢量,但不能说出它的形状。我做错什么了吗?
正如Ishamael所说,所有的张量都有一个静态的形状,这个形状在图形构造时是已知的,并且可以使用^{} 访问;而动态的形状只有在运行时才知道,并且可以通过获取张量的值或将其传递给类似^{} 的运算符来访问。在许多情况下,静态形状和动态形状是相同的,但它们可以不同-静态形状可以部分定义-以便允许动态形状在一个步骤到下一个步骤之间变化。
在代码中,
normal_dist
具有部分定义的静态形状,因为w_shape
是一个计算值。(TensorFlow有时试图评估 这些计算值是在图构造时计算出来的,但它被卡在tf.pack
)处,它推断出形状TensorShape([Dimension(None), Dimension(None)])
,这意味着“一个具有未知行数和列数的矩阵”,因为它知道w_shape
是一个长度为2的向量,所以得到的normal_dist
必须是二维的。你有两个选择。您可以按照Ishamael的建议设置静态形状,但这需要您在图形构建时知道该形状。例如,以下方法可能有效:
或者,可以将} constructor 。这允许您使用部分定义的形状创建变量,但它限制了稍后可以在图形中推断的静态形状信息量。
validate_shape=False
传递给^{类似的问题在TF FAQ中得到了很好的解释:
因此^{} 返回一个张量,其大小始终为
shape=(N,)
,可以在会话中计算:另一方面,可以使用
x.get_shape().as_list()
提取静态形状,这可以在任何地方计算。变量可以具有动态形状。
get_shape()
返回静态形状。在你的例子中,你有一个张量,它有一个动态的形状,并且当前恰好持有一个4x3的值(但是在另一个时间它可以持有一个不同形状的值——因为这个形状是动态的)。要设置静态形状,请使用^{} 。之后,将强制执行您设置的形状,并且张量将是有效的
initial_value
。相关问题 更多 >
编程相关推荐