TensorFlow 2.0 GradientTape求导结果为何为张量元素之和?
为什么TensorFlow GradientTape求导返回的是向量元素之和而非向量本身?
这个问题其实是TensorFlow GradientTape.gradient()方法的默认行为导致的,我来给你拆解清楚:
核心原因
当你调用gradient(y, x)时,如果目标张量y是非标量(比如你的例子里是形状为(2,)的向量),TensorFlow默认会先对y的所有元素求和,再计算这个总和对自变量x的梯度。
在你的代码里:
y = x * inc得到的是[3., 6.],求和后是9.- 对
x求导的话,sum(y) = x * sum(inc),所以导数就是sum(inc) = 1 + 2 = 3.0,这就是你看到的输出结果。
如何得到你预期的结果(即inc本身)
如果你想获取y的每个元素对x的梯度(也就是和inc相同的结果),可以使用GradientTape.jacobian()方法——它专门用来计算向量/张量对自变量的雅可比矩阵,能保留每个维度的梯度信息。
修正后的代码如下:
import tensorflow as tf print(tf.__version__) x = tf.constant(3.0) inc = tf.constant([1.,2.]) with tf.GradientTape() as t: t.watch(x) y = x * inc # 使用jacobian代替gradient dy_dx = t.jacobian(y, x) print(dy_dx) print(y) print(inc)
运行后输出会是:
2.2.0 tf.Tensor([1. 2.], shape=(2,), dtype=float32) tf.Tensor([3. 6.], shape=(2,), dtype=float32) tf.Tensor([1. 2.], shape=(2,), dtype=float32)
补充说明
TensorFlow设计这个默认行为是因为在绝大多数机器学习场景中,我们的损失函数都是标量(比如所有样本损失的总和或平均值),直接求和后求导更符合常规需求。如果需要处理非标量目标的梯度,就需要用到雅可比矩阵或者逐个元素求导的方式。
内容的提问来源于stack exchange,提问作者parisjohn
相关产品推荐
相关产品推荐

