根据以下代码,m0是一个形状为(3,1)的常量,但在while循环中改变了它的形状。 因此,在while循环之后,Tensorflow不知道它的形状,但我使用set_shape将其更改为正确的形状。 但是,当您通过优化(采用渐变)运行它时,会弹出错误:
Incompatible shapes between op input and calculated input gradient. Forward operation: while_29/Enter_1. Input index: 0. Original input shape: (3, 1). Calculated input gradient shape: (15, 1)
似乎渐变仍将形状视为(3,1),但我们的set_shape将其更改为形状(15,1)。谁能告诉我如何解决?
sess = tf.Session()
i0 = tf.constant(0)
m0 = tf.ones([3, 1])
x = tf.get_variable('www', shape=(3,1), initializer=tf.zeros_initializer)
loop = 5
def _cond(i0, m0):
return tf.less(i0, loop-1)
def _res(i0, m0):
n = tf.ones([3, 1]) + x
m0 = tf.concat([m0, n], axis=0)
return i0+1, m0
i0, m0 = tf.while_loop(
_cond, _res, loop_vars=[i0, m0],
shape_invariants=[i0.get_shape(), tf.TensorShape([None, 1])])
m0.set_shape([loop*3,1])
opt = tf.train.AdagradOptimizer(1)
grad = opt.compute_gradients(m0)
sess.run(tf.global_variables_initializer())
print(sess.run(grad))
答案 0 :(得分:0)
简短的回答是,通过像这样创建m0
可以有效地解决您的问题:
m0 = 1 + tf.tile( x, (loop,1) )
但是,您在上面遇到的根本问题的答案是您在循环中增长m0
。但是,您知道自己需要m0
的大小,所以如果您真的必须使用while_loop
,那么您应该使用TensorArray。像这样:
def mystack(x, n):
loop_vars = [
tf.constant(0, tf.int32),
tf.TensorArray(x.dtype, size=n),
]
_, fx = tf.while_loop(
lambda j, _: j < n,
lambda j, result: (j + 1, result.write(j, 1+x)),
loop_vars
)
return tf.reshape( fx.stack(), (-1,1) )
x = tf.constant( numpy.random.randn(3,1), tf.float32 )
loop = 5
m = mystack(x,loop)
with tf.Session() as sess:
print(sess.run(m).shape)