张量流中未指定维度的张量
Tensor with unspecified dimension in tensorflow
我在玩 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
,因为我遇到了同样的错误)
当我 运行 它(从调用这个脚本的更大的脚本)时,我得到这个错误:
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 生成向量但不能说出它的形状。我做错了什么吗?
变量可以具有动态形状。 get_shape()
returns 静态形状。
在你的情况下,你有一个具有动态形状的张量,并且当前恰好持有 4x3 的值(但在其他时间它可以持有不同形状的值 - 因为形状是动态的) .要设置静态形状,请使用 set_shape(w_shape)
。之后你设置的形状将被强制执行,张量将是一个有效的 initial_value
.
正如 Ishamael 所说,所有张量都有一个静态形状,这在图形构建时是已知的并且可以使用 Tensor.get_shape()
; and a dynamic shape, which is only known at runtime and is accessible by fetching the value of the tensor, or passing it to an operator like tf.shape
访问。在许多情况下,静态和动态形状是相同的,但它们可以不同 - 静态形状可以 部分定义 - 为了允许动态形状从一步到一步变化接下来。
在您的代码中,normal_dist
具有部分定义的静态形状,因为 w_shape
是一个计算值。 (TensorFlow 有时会尝试评估
这些在图形构建时计算的值,但它卡在 tf.pack
。)它推断形状 TensorShape([Dimension(None), Dimension(None)])
,这意味着 "a matrix with an unknown number of rows and columns," 因为它知道 w_shape
是向量长度为 2,因此结果 normal_dist
必须是二维的。
你有两种选择来处理这个问题。您可以按照 Ishamael 的建议设置静态形状,但这需要您在图形构建时知道形状。例如,以下可能有效:
normal_dist.set_shape([input_data.get_shape()[1], labels.get_shape()[1]])
或者,您可以将 validate_shape=False
传递给 tf.Variable
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)
.
所以tf.shape()
returns你是一个张量,大小总是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()
提取静态形状,这可以在任何地方计算。
我在玩 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
,因为我遇到了同样的错误)
当我 运行 它(从调用这个脚本的更大的脚本)时,我得到这个错误:
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 生成向量但不能说出它的形状。我做错了什么吗?
变量可以具有动态形状。 get_shape()
returns 静态形状。
在你的情况下,你有一个具有动态形状的张量,并且当前恰好持有 4x3 的值(但在其他时间它可以持有不同形状的值 - 因为形状是动态的) .要设置静态形状,请使用 set_shape(w_shape)
。之后你设置的形状将被强制执行,张量将是一个有效的 initial_value
.
正如 Ishamael 所说,所有张量都有一个静态形状,这在图形构建时是已知的并且可以使用 Tensor.get_shape()
; and a dynamic shape, which is only known at runtime and is accessible by fetching the value of the tensor, or passing it to an operator like tf.shape
访问。在许多情况下,静态和动态形状是相同的,但它们可以不同 - 静态形状可以 部分定义 - 为了允许动态形状从一步到一步变化接下来。
在您的代码中,normal_dist
具有部分定义的静态形状,因为 w_shape
是一个计算值。 (TensorFlow 有时会尝试评估
这些在图形构建时计算的值,但它卡在 tf.pack
。)它推断形状 TensorShape([Dimension(None), Dimension(None)])
,这意味着 "a matrix with an unknown number of rows and columns," 因为它知道 w_shape
是向量长度为 2,因此结果 normal_dist
必须是二维的。
你有两种选择来处理这个问题。您可以按照 Ishamael 的建议设置静态形状,但这需要您在图形构建时知道形状。例如,以下可能有效:
normal_dist.set_shape([input_data.get_shape()[1], labels.get_shape()[1]])
或者,您可以将 validate_shape=False
传递给 tf.Variable
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 evaluatingtf.shape(t)
.
所以tf.shape()
returns你是一个张量,大小总是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()
提取静态形状,这可以在任何地方计算。