tf.gradients() 不适用于 'tf.assign()',但适用于 '='

tf.gradients() won't work with 'tf.assign()', but works with '='

在下面的简单代码中,梯度计算正确。

import tensorflow as tf

x = tf.constant([1, 2, 3, 4], dtype=tf.float32)
y = tf.Variable(tf.ones_like(x), dtype=tf.float32)

y = 2*x
grad = tf.gradients(y, x)

ini = tf.global_variables_initializer()


with tf.Session() as ses:
    ses.run(ini)
    print(ses.run(grad))

如预期的那样,结果是 [array([ 2., 2., 2., 2.], dtype=float32)]。 尝试使用 tf.assign 进行函数计算时遇到问题。下面的代码:

import tensorflow as tf

x = tf.constant([1, 2, 3, 4], dtype=tf.float32)
y = tf.Variable(tf.ones_like(x), dtype=tf.float32)

func = tf.assign(y, 2*x)
grad = tf.gradients(y, x)

ini = tf.global_variables_initializer()

with tf.Session() as ses:
    ses.run(ini)
    ses.run(func)
    print(ses.run(grad))

...产生错误:

TypeError: Fetch argument None has invalid type <class 'NoneType'>.

为什么会这样? xy 节点之间的连接是否通过 tf.assign 操作以某种方式 "lost"?

在第二个示例中,xy 之间没有依赖关系。 func 是一个 依赖于 并且碰巧修改 y 的操作。如果您检查相应的 tf.assign 操作,您会看到:

op: "Assign"
input: "Variable"   # this is y
input: "mul"        # this is 2*x

但是xy是独立的,这就是为什么引擎无法获取梯度的原因。