2
import tensorflow as tf

def f(x):
    return tf.multiply(x, x)

x = tf.Variable([3.])

with tf.GradientTape() as test_tape:
    test_tape.watch(x)

    with tf.GradientTape() as train_tape:
        train_tape.watch(x)
        fx = f(x)

    gradient = train_tape.gradient(fx, x)  # df(x)/x = d(x^2)/dx = 2x
    x_prime = x.__copy__()  # x' = x
    x_prime = tf.subtract(x_prime, tf.multiply(gradient, 0.01))  # x' = x' - 0.01 * 2x = 0.98x
    fx_prime = f(x_prime)

gradient = test_tape.gradient(fx_prime, x)  # df(x')/dx = df(0.98x)/dx = 1.9208 * x = 5.7624
print(gradient)

我正在学习 tensorflow2.0 GradientTape() 并测试此代码,它计算二阶导数 d(x-0.01*df(x)/dx)/dx。给定 x = 3 和 f(x) = x*x,结果为 5.7624。上面的代码得到了正确的答案。然后我尝试更换线路

x_prime = tf.subtract(x_prime, tf.multiply(gradient, 0.01))

经过

optimizer = tf.optimizers.SGD()
optimizer.apply_gradients(zip([gradient], [x_prime]))

并得到了错误的答案 5.88,我无法解决这个问题并猜测 GradientTape 不跟踪 apply_gradients?有人知道为什么吗?

python-3.7,张量流-2.0.0

4

1 回答 1

1

好的,我自己得到答案。optimizer.apply_gradients 操作不会在 Graph 中生成节点,它只是改变原始内存空间中的值,因此 x_prime 和之前的节点之间不会有任何联系。此外,其他一些操作或函数在 GradientTape 中也不起作用,例如 tf.Varaible().assign()、.assign_add()、.assign_sub()、tf.keras.Layers.Layer.set_weights() 等。

于 2020-03-31T07:40:44.197 回答