不会针对存储在TensorArray中的变量计算梯度

时间:2017-06-18 20:35:29

标签: python tensorflow recurrent-neural-network

对于y = x ** 2,如果从TensorArray中检索到x,则不会计算梯度dy_dx。

如何将x和y操作存储在TensorArray中,然后检索它们,并调用tf.gradients来计算渐变?

用例是:一个构建一个while_loop,在迭代中生成一堆不同的值(即x,y),它们被推入TensorArrays,然后在循环之外我想获得导数一个数组相对于另一个数组。

说明问题的示例:

import tensorflow as tf
import numpy as np

x = tf.Variable(np.array([3]).astype(np.float32), trainable=False)
y = x ** 2
xa = tf.TensorArray(tf.float32, 1).write(0, x)
ya = tf.TensorArray(tf.float32, 1).write(0, y)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

# these work as expected:
print(sess.run(tf.gradients(y, x)))  # stdout: [array([ 6.], dtype=float32)]
print(sess.run(tf.gradients(ya.stack(), x)))  # stdout: [array([ 6.], dtype=float32)]

# why no gradient?
print(tf.gradients(ya.stack(), xa.stack()))  # stdout: [None]
print(tf.gradients(ya.read(0), xa.read(0)))  # stdout: [None]

# desperate attempt, doesn't work either
za = tf.TensorArray(tf.float32, 1).write(0, xa.read(0) ** 2)
print(tf.gradients(za.read(0), xa.read(0)))  # stdout: [None]

1 个答案:

答案 0 :(得分:1)

原因是函数tf.gradients用词不当。实际上,tf.gradients实现了backprop算法;并且只能在图中连接在一起的节点之间提供梯度计算。因为ya绝不依赖于xa,所以没有连接,backprop不起作用。该示例将提供渐变:

x = tf.Variable(np.array([3]).astype(np.float32), trainable=False)
y = x ** 2
xa = tf.TensorArray(tf.float32, 1).write(0, x)
ya = tf.TensorArray(tf.float32, 1).write(0, xa.read(0))
tf.gradients(ya.stack(), x)

但以下不会:

y = x ** 2
z = x + 1
tf.gradients(y, z)  # None

因为从z到y没有DAG路径。

后一个示例与您在问题中尝试的内容更相似。