首页 > 解决方案 > 如何在 TensorFlow 的急切执行模式下计算非变量的梯度?

问题描述

我正在尝试计算模型的损失相对于其输入的梯度,以创建一个对抗性示例。由于模型的输入是不可训练的,我需要计算相对于张量而不是变量的梯度。但是,我发现如果张量不是可训练变量,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 教程Eager Execution guide,但找不到计算张量梯度的解决方案。

标签: pythontensorflow

解决方案


tf.GradientTape文档揭示了简单的解决方案:

可训练变量(由tf.Variableor创建tf.get_variabletrainable=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)>]

推荐阅读