请考虑以下代码:
x = tf.placeholder("float", shape=[42, 4])
y = tf.zeros([42, 4], "float")
xy_stacked = tf.concat(1, [x, y])
print(x.get_shape())
print(y.get_shape())
print(xy_stacked.get_shape())
这将产生以下输出,如预期的那样:
TensorShape([Dimension(42), Dimension(4)])
TensorShape([Dimension(42), Dimension(4)])
TensorShape([Dimension(42), Dimension(8)])
但是,如果占位符具有动态维度,该维度在运行时由传递给的值确定feed_dict=
,如占位符通常那样:
x = tf.placeholder("float", shape=[None, 4])
y = tf.zeros([None, 4], "float")
xy_stacked = tf.concat(1, [x, y])
这会产生错误tf.zeros([None, 4], "float")
.显然Dimension(None)
不允许tf.zeros
:
TypeError Traceback (most recent call last)
in ()
2
3 x = tf.placeholder("float", shape=[None, 4])
----> 4 y = tf.zeros([None, 4], "float")
5 xy_stacked = tf.concat(1, [x, y])
6
[...]
/usr/local/lib/python3.4/dist-packages/numpy/core/_methods.py in _prod(a, axis, dtype, out, keepdims)
33
34 def _prod(a, axis=None, dtype=None, out=None, keepdims=False):
---> 35 return umr_prod(a, axis, dtype, out, keepdims)
36
37 def _any(a, axis=None, dtype=None, out=None, keepdims=False):
TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'
我已经发现,如果我将零点张量的第一个维度设置为非无,例如1,则不会产生错误:
x = tf.placeholder("float", shape=[None, 4])
y = tf.zeros([1, 4], "float")
xy_stacked = tf.concat(1, [x, y])
但随后产生的xy_stacked
张量被截断为这个大小:
TensorShape([Dimension(None), Dimension(4)])
TensorShape([Dimension(1), Dimension(4)])
TensorShape([Dimension(1), Dimension(8)])
如何用零填充占位符张量,这样我TensorShape([Dimension(None), Dimension(8)])
在这个例子中得到一个张量的形状?
到目前为止,我发现的唯一"解决方案"是以下内容:
x = tf.placeholder("float", shape=[None, 4])
y = 0 * x
xy_stacked = tf.concat(1, [x, y])
或者只是声明y
为占位符并始终传递正确大小的零数组.
但是这两个问题看起来都不是一个干净的解决方案,而且像这样的黑客在比这个简单的例子更复杂的应用程序中快速失控.
我正在使用tensorflow-0.6.0-py3
.
建议使用与另一个张量相同形状的零张量的方法是使用tf.zeros_like()
op:
x = tf.placeholder(tf.float32, shape=[None, 4])
y = tf.zeros_like(x)
得到的张量y
似乎具有[None, None]
根据的形状Tensor.get_shape()
,但在运行时它将扩展到与以下相同的形状x
:
print y.get_shape()
# ==> TensorShape([Dimension(None), Dimension(None)])
sess = tf.Session()
y_result = sess.run(y, feed_dict={x: np.random.rand(4, 4)})
print y_result.shape
# ==> (4, 4)
在[None, None]
返回静态的形状,因为形状推断还没有专门针对tf.zeros_like()
.我已经为此提交了一个GitHub问题,应尽快解决.
编辑:在你的评论中,你问过如何处理零张量的形状基于但不同于原始张量的情况.这也是可能的,使用tf.shape()
和tf.stack()
构建尺寸,并tf.fill()
产生零张量:
x = tf.placeholder(tf.float32, shape=[None, 4]) # Use tf.shape() to get the runtime size of `x` in the 0th dimension. zeros_dims = tf.stack([tf.shape(x)[0], 7]) y = tf.fill(zeros_dims, 0.0) sess = tf.Session() y_result = sess.run(y, feed_dict={x: np.random.rand(4, 4)}) print y_result.shape # ==> (4, 7)