十维未指定张量

2024-04-26 07:06:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我在玩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生成矢量,但不能说出它的形状。我做错什么了吗?


Tags: innoneinputsizelabelsdisttfeval
3条回答

正如Ishamael所说,所有的张量都有一个静态的形状,这个形状在图形构造时是已知的,并且可以使用^{}访问;而动态的形状只有在运行时才知道,并且可以通过获取张量的值或将其传递给类似^{}的运算符来访问。在许多情况下,静态形状和动态形状是相同的,但它们可以不同-静态形状可以部分定义-以便允许动态形状在一个步骤到下一个步骤之间变化。

在代码中,normal_dist具有部分定义的静态形状,因为w_shape是一个计算值。(TensorFlow有时试图评估 这些计算值是在图构造时计算出来的,但它被卡在tf.pack)处,它推断出形状TensorShape([Dimension(None), Dimension(None)]),这意味着“一个具有未知行数和列数的矩阵”,因为它知道w_shape是一个长度为2的向量,所以得到的normal_dist必须是二维的。

你有两个选择。您可以按照Ishamael的建议设置静态形状,但这需要您在图形构建时知道该形状。例如,以下方法可能有效:

normal_dist.set_shape([input_data.get_shape()[1], labels.get_shape()[1]])

或者,可以将validate_shape=False传递给^{} constructor。这允许您使用部分定义的形状创建变量,但它限制了稍后可以在图形中推断的静态形状信息量。

类似的问题在TF FAQ中得到了很好的解释:

In TensorFlow, a tensor has both a static (inferred) shape and a dynamic (true) shape. The static shape can be read using the tf.Tensor.get_shape method: this shape is inferred from the operations that were used to create the tensor, and may be partially complete. If the static shape is not fully defined, the dynamic shape of a Tensor t can be determined by evaluating tf.shape(t).

因此^{}返回一个张量,其大小始终为shape=(N,),可以在会话中计算:

a = tf.Variable(tf.zeros(shape=(2, 3, 4)))
with tf.Session() as sess:
    print sess.run(tf.shape(a))

另一方面,可以使用x.get_shape().as_list()提取静态形状,这可以在任何地方计算。

变量可以具有动态形状。get_shape()返回静态形状。

在你的例子中,你有一个张量,它有一个动态的形状,并且当前恰好持有一个4x3的值(但是在另一个时间它可以持有一个不同形状的值——因为这个形状是动态的)。要设置静态形状,请使用^{}。之后,将强制执行您设置的形状,并且张量将是有效的initial_value

相关问题 更多 >