张量为什么能自动求导

介绍

因为张量不是“死的数据”,它会记录自己参与过的所有计算,形成一张“计算图”,反向传播时沿着这张图一步步算出梯度。

张量会“记住自己从哪来”(记录计算历史)

当你写:

x = torch.tensor(2.0, requires_grad=True)
y = x ** 2
z = 2 * y + 3

张量 z 并不是只知道自己的值是 11,它还知道:

  • 我是由 2 * y + 3 得到的
  • y 是由 x ** 2 得到的
  • x 是一个叶子节点(用户输入)

也就是说,每个张量都保存着自己的“诞生过程”。

这就是自动求导的基础。


每个张量都有一个 grad_fn:它的“求导函数”

当你打印 z.grad_fn,会看到类似:

<AddBackward0 object at 0x...>

这说明 z 是通过一个加法操作产生的。

同理,y.grad_fn 会显示:

<PowBackward0 object at 0x...>

说明 y 是通过幂运算产生的。

这些 grad_fn 就是反向传播时用来计算梯度的函数。

它们构成了一条链:

z → AddBackward → y → PowBackward → x

这就是“计算图”。


调用 backward() 时,会沿着计算图反向“链式求导”

当你执行:

z.backward()

它会从 z 开始,沿着 grad_fn 链,反向一步步计算梯度。

过程像这样:

  1. z 对 y 的导数是 2
  2. y 对 x 的导数是 2x
  3. 所以 z 对 x 的导数是 2 * 2x = 4x
  4. 代入 x=2,得到梯度 8

所以 x.grad 最终是:

tensor(8.)

这就是自动求导的全部秘密。

总结

张量能自动求导,是因为它具备三件事:

  1. 记录计算历史(知道自己怎么来的)
  2. 保存 grad_fn(知道怎么求导)
  3. 调用 backward() 时沿计算图反向链式求导

这三件事组合在一起,就实现了“自动求导”。

更形象的比喻(非常好理解)

你可以把张量想象成一个“有记忆的计算器”:

  • 你每按一次按钮(做一次运算),它都会记录“我刚才做了什么操作”
  • 当你说“算梯度”时,它会根据记录的操作,从结果倒推每一步的导数
  • 最终把梯度存到叶子节点(如 x.grad)里

原文出处:/show_1GW2Z8GaRIct.html