一个结果,很多输入
问题:把向量 x 的每个分量稍微改动,标量损失 L 会变多少?
定义:把所有偏导排成梯度 (n,)。
梯度与改变量做点积,预测损失变化。
你已经会标量求导,也会矩阵乘法。这节课只搭中间的桥:先看“谁对谁求导”和结果形状,再用一个全连接层推导 ∂L/∂W、∂L/∂x,最后连接到反向传播。
01 / 先理解为什么要求导
你熟悉的标量导数已经表达了这个意思。例如 f(w)=w²,在 w=3 时 f′(3)=6:把 w 增加很小的 0.01,f 大约增加 6×0.01=0.06。实际从 9 变成 9.0601;导数给的是当前位置附近的一阶近似。
问题:把向量 x 的每个分量稍微改动,标量损失 L 会变多少?
定义:把所有偏导排成梯度 (n,)。
梯度与改变量做点积,预测损失变化。
问题:输入向量 x 有一点变化时,输出向量 y 的每个分量怎样变?
定义:所有输出对所有输入的偏导组成雅可比矩阵 (m,n)。
雅可比像一个局部线性变换,把输入变化映射为输出变化。
问题:把权重矩阵 W 的每个格子稍微改动,损失会变多少?
定义:每格的偏导组成与 W 同形的梯度 (m,n)。
负梯度告诉优化器该怎样同时调整整张权重表。
02 / 一个标量如何随多个数变化
令 L(x₁,x₂)=x₁²+2x₂²。你会分别求两个标量偏导:
把它们按 x 的顺序排在一起,就是梯度:
假设准备把当前位置改成 x+Δx。梯度不必重新完整计算函数,就能预测损失大约变化 ∇L·Δx。把改动调大、再调小,比较预测和真实变化。
Δx=−η∇L,用学习率 η 控制步长。03 / 多个输出对多个输入
雅可比矩阵的意义不是“把偏导摆好看”,而是用一个矩阵把输入的小变化换算成输出的小变化:Δy≈JΔx。第 j 列直接回答“只改变第 j 个输入时,所有输出如何变化”。
设 x=[x₁,x₂],y=Wx+b,其中 W 有 2 行 2 列:
展开后 y₁=x₁+2x₂,y₂=−x₁+3x₂+1。每行对应该输出对所有输入的偏导:
本例是线性函数,所以 Δy=JΔx 完全相等。非线性函数中它是当前位置附近的近似,而且雅可比会随输入变化。
04 / 训练真正需要的形式
矩阵 W 可以看成一张参数表。∂L/∂Wᵢⱼ 的定义是:只把第 i,j 个参数增加一个极小量,其余参数不动时,损失变化量与这个极小量的比值。把每一格的结果放回原位置,就得到矩阵梯度。
直接写“向量 y 对矩阵 W 求导”会得到三维对象,很难使用。训练最终有一个标量损失 L,因此通常直接求 ∂L/∂W:它与 W 同形,每一格就是对应权重的局部敏感度。
| 要求的梯度 | 公式 | 本例结果 | 形状 |
|---|---|---|---|
| ∂L/∂W | e xᵀ | [[-2,-1,1],[4,2,-2]] | (2,3) |
| ∂L/∂b | e | [-1,2] | (2,) |
| ∂L/∂x | Wᵀe | [0,3,-4] | (3,) |
第 i 个输出为 yᵢ=ΣⱼWᵢⱼxⱼ+bᵢ。损失对 yᵢ 的偏导是 eᵢ。
因此梯度矩阵第 i,j 格就是 eᵢxⱼ,把所有格子合起来便是 e xᵀ。
这正是 Wᵀe 的第 j 个分量。
权重 Wᵢⱼ 连接“输入 xⱼ”和“输出 yᵢ”。它的梯度同时需要两条信息:
eᵢ:第 i 个输出收到多大的上游梯度;xⱼ:这条连接当时接收到多大的输入。把每个输出信号与每个输入值两两相乘,刚好形成一个 (输出数, 输入数) 的表,这就是外积 e xᵀ。
选择一个权重并改变一点。矩阵梯度对应位置的数字乘改变量,会预测损失怎样变化。负梯度表示增加这个权重会让损失下降;正梯度表示增加它会让损失上升。
W 是 (2,3),所以 ∂L/∂W 也必须是 (2,3)。如果得到 (3,2),通常是外积次序或转置写反了。05 / 从一个样本到一批样本
PyTorch 把 nn.Linear(in,out).weight 存成 (out,in)。一批输入 X 的每行是一个样本,所以前向是:
设上游梯度 G=∂L/∂Z,它和 Z 同形。批次公式是:
| 梯度 | 公式 | 形状检查 | 含义 |
|---|---|---|---|
∂L/∂weight | G.T @ X | (out,B) @ (B,in) → (out,in) | 把每条样本的外积贡献加起来 |
∂L/∂b | G.sum(axis=0) | (B,out) → (out,) | 同一个偏置被一批中的所有样本共用 |
∂L/∂X | G @ weight | (B,out) @ (out,in) → (B,in) | 把梯度继续传向上一层 |
G 中已经包含除以批次大小的因子;如果损失使用求和,则没有这个因子。二者方向相同但大小不同。06 / 不建立巨大的导数矩阵
考虑 z=Wx+b、h=ReLU(z)、L=½‖h−t‖²。从右向左,每个节点只回答:“已经收到 ∂L/∂输出,怎样算 ∂L/∂输入?”
⊙ 表示逐元素乘法。虽然 ReLU 作为“向量对向量函数”有雅可比矩阵,但它是对角矩阵;实际程序直接做逐元素乘法,不会创建一张巨大的对角矩阵。
07 / 先理解结果,不要求背
softmax 的每个输出都依赖所有输入,因此它的雅可比不是单纯的逐元素导数。若 p=softmax(z):
与单个样本的交叉熵 L=−Σᵢyᵢlog pᵢ 合起来后,对 logits 的梯度会化简:
这不是“softmax 的导数就是 p−y”。p−y 是 softmax 与交叉熵组合后的结果。
08 / 手推之后让代码检查
如果把矩阵中某个元素 Wᵢⱼ 增加和减少一个很小的 ε,就能近似该位置的偏导:
打开或下载配套代码。它会核对向量梯度、雅可比、单样本与批次矩阵梯度,并和 PyTorch 自动求导比较。在项目根目录运行:
uv run python lessons/lesson-math-matrix-calculus.py
∂L/∂W、∂L/∂b 和 ∂L/∂x。09 / 检查是否真正理解