如何优化动态形状的变量?

时间:2018-02-02 00:04:06

标签: tensorflow machine-learning deep-learning

根据以下代码,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))

1 个答案:

答案 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)