我试图计算模型损失相对于其输入的梯度,以创建一个对抗性示例。由于模型的输入是不可训练的,因此我需要针对张量(而不是变量)计算梯度。但是,我发现如果张量不是可训练的变量,TensorFlow的GradientTape
返回None
梯度:
import numpy as np
import tensorflow as tf
tf.enable_eager_execution()
a = tf.convert_to_tensor(np.array([1., 2., 3.]), dtype=tf.float32)
b = tf.constant([1., 2., 3.])
c = tf.Variable([1., 2., 3.], trainable=False)
d = tf.Variable([1., 2., 3.], trainable=True)
with tf.GradientTape() as tape:
result = a + b + c + d
grads = tape.gradient(result, [a, b, c, d])
print(grads)
打印:
[None, None, None, <tf.Tensor: id=26, shape=(3,), dtype=float32, numpy=array([1., 1., 1.], dtype=float32)>]
我经历了TensorFlow的Eager Execution tutorial和Eager Execution guide,但是找不到用于计算梯度w.r.t的解决方案。张量。
答案 0 :(得分:0)
tf.GradientTape
文档揭示了简单的解决方案:
可训练变量(由
tf.Variable
或tf.get_variable
创建,在两种情况下均默认为trainable=True
)。通过在此上下文管理器上调用watch
方法,可以手动监视张量。
在这种情况下,
with tf.GradientTape() as tape:
tape.watch(a)
tape.watch(b)
tape.watch(c)
result = a + b + c + d
grads = tape.gradient(result, [a, b, c, d])
将导致print(grads)
:
[<tf.Tensor: id=26, shape=(3,), dtype=float32, numpy=array([1., 1., 1.], dtype=float32)>,
<tf.Tensor: id=26, shape=(3,), dtype=float32, numpy=array([1., 1., 1.], dtype=float32)>,
<tf.Tensor: id=26, shape=(3,), dtype=float32, numpy=array([1., 1., 1.], dtype=float32)>,
<tf.Tensor: id=26, shape=(3,), dtype=float32, numpy=array([1., 1., 1.], dtype=float32)>]