Python 对于存储在张量数组中的变量,不会计算梯度

Python 对于存储在张量数组中的变量,不会计算梯度,python,tensorflow,recurrent-neural-network,Python,Tensorflow,Recurrent Neural Network,对于y=x**2,如果从张量阵列检索x,则不会计算梯度dy_dx 如何将x和y运算存储在一个张量数组中,然后检索它们,并调用tf.gradients来计算梯度 用例是:一个人构建一个while_循环,在迭代中生成一组不同的值(即x,y),它们被推到tensorarray中,然后在循环之外,我想得到一个数组相对于另一个数组的导数 举例说明问题: import tensorflow as tf import numpy as np x = tf.Variable(np.array([3]).ast

对于y=x**2,如果从张量阵列检索x,则不会计算梯度dy_dx

如何将x和y运算存储在一个张量数组中,然后检索它们,并调用tf.gradients来计算梯度

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

举例说明问题:

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]

原因是函数
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路径


后一个例子与您在问题中试图做的更为相似。

原因是函数
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路径


后一个例子与您在问题中试图做的更为相似。

是的,Tensorary似乎没有跟踪依赖关系。否则,
za=tf.TensorArray(tf.float32,1).write(0,xa.read(0)**2)print(tf.gradients(za.read(0),xa.read(0))
应该可以清楚地工作,不仅仅是
TensorArray
没有跟踪依赖关系:是backprop算法没有这样工作(这种类型的TensorFlow计算不会工作).在上一个示例中,za是从xa构建的,因此存在从xa到za的直接路径。不清楚为什么za相对于xa没有梯度。是的,TensorArray似乎没有跟踪依赖关系。否则,
za=tf.TensorArray(tf.float32,1).write(0,xa.read(0)**2)print(tf.gradients(za.read(0),xa.read(0))
应该可以清楚地工作,不仅仅是
TensorArray
没有跟踪依赖关系:是backprop算法没有这样工作(这种类型的TensorFlow计算不会工作).在上一个示例中,za是从xa构建的,因此存在从xa到za的直接路径。不清楚为什么za相对于xa没有梯度。