Hook:一次梯度核对失败的复盘
上海某量化私募的小组复盘会上,工程师摊开一张 PnL 时序图:基于沪深300 成分股的因子神经网络回测里,梯度核对(gradient check)数值在第三层之后开始与解析梯度系统性偏离一个常数倍。CFFEX 主力合约的日线策略本来 7 月稳得像一块表,过完一个版本后突然走样——根因追下来是一行被写反的 transpose:在某一层把 JWh 写成了 WTJh 的形式。一个把雅可比矩阵(Jacobian)摆错位置的失误,可以让一整条反向传播链路系统性偏差。下面我们把多元链式法则从一元情形重新搭起来,让你之后写每一行梯度都知道矩阵该乘在哪一边。
一、回到一元链式法则
设 y=f(g(x)),其中 f,g:R→R 都可导。一元链式法则告诉你
dxdy=f′(g(x))⋅g′(x)
这条式子的解读:要把 x 的一个微小变化 dx 翻译成 y 的变化 dy,先用 g′(x) 把 dx 变换到中间变量空间里的 dg=g′(x)dx,再用 f′(g(x)) 把 dg 翻译成 dy=f′(g(x))⋅dg。两个标量乘子按从外到内的顺序相乘——一元世界里乘法可交换,所以你不必担心顺序,到了多元世界这个余地就消失了。
二、把标量乘子升级成矩阵:雅可比
设 f:Rn→Rm 是一个向量值函数。它的雅可比矩阵(Jacobian) Jf(x) 是一个 m×n 的矩阵,其 (i,j) 元为
Jf(x)ij=∂xj∂fi(x)
每一行(共 m 行)是输出分量 fi 对全体输入 x1,…,xn 的梯度向量的转置;每一列(共 n 列)是「只让 xj 动」时输出向量在 Rm 里的瞬时位移方向。两种读法各有用处:训练神经网络时按行思考更自然,做敏感性分析时按列思考更直观。
关键事实:在 f 光滑的前提下,
f(x+h)=f(x)+Jf(x)⋅h+o(∥h∥)
它把多元函数的一阶变化压缩成一次矩阵乘法(matrix multiplication)。当 m=1 时雅可比退化成一个行向量,即 ∇f(x)T——也就是上一课讲的梯度转置。雅可比是梯度向高维输出的自然推广。
三、多元链式法则
设 g:Rn→Rp、f:Rp→Rm,复合函数 h=f∘g:Rn→Rm。多元链式法则断言
Jf∘g(x)=Jf(g(x))⋅Jg(x)
形状自洽性验证:Jf(g(x)) 是 m×p,Jg(x) 是 n→p(即 p×n),相乘得到 m×n,正是 f∘g 的雅可比应有的形状。乘法的顺序是「外层在左、内层在右」——这与一元情形对应,但在多元世界里矩阵乘法不可交换(matrix multiplication is not commutative),写反就是另一个函数的梯度。
把这条规则特化到神经网络里常见的「标量损失对参数向量」情形:设损失 L=ℓ(h(W⋅x)),其中 W⋅x∈Rp、h:Rp→Rq、ℓ:Rq→R。把 L 对 W 的梯度按链式法则展开,会涉及把矩阵转置(matrix transpose)按从后往前的顺序乘起来——这就是反向传播(backpropagation)公式的全部内容。
四、正向 vs 反向:在一张小图上数一数
考虑一个三节点计算图:x∈R10,y=Ax(A 是 5×10 矩阵),z=cos(y)(按元素),L=1Tz(标量损失)。从 x 到 L 经过两层雅可比再到一个 1×5 的行向量。
- 正向模式(forward-mode):从 x 端开始,维护一个「方向导数向量」,每经过一个节点做一次雅可比—向量乘积。在本例中:先算 Jy⋅v=Av(5×10⋅10×1=5×1,约 50 次乘加);再算 Jz⋅(Jy⋅v)(对角矩阵作用,约 5 次乘加);最后再做一次内积。要拿到对 x 全部 10 个分量的偏导,需要把 v 取成 10 个单位向量分别跑一遍,总计 10 次正向。
- 反向模式(reverse-mode):从 L 端开始,维护一个「梯度行向量」,每经过一个节点做一次向量—雅可比乘积。在本例中:先算 1TJz(约 5 次乘加),再算 (1TJz)⋅Jy(1×5⋅5×10,约 50 次乘加)。一遍反向就拿到对 x 全部 10 个分量的偏导。
通用法则:当输出维度(这里 1)远小于输入维度(这里 10)时,反向模式更便宜;反之则正向模式更便宜。深度学习里损失永远是标量、参数动辄上百万维——这就是为什么标准做法是反向模式自动微分,也就是反向传播。
下方滑块可以扫一遍输出维度 m 与输入维度 n 之比的两种成本估计:正向模式约为 n*c,反向模式约为 m*c(c 是一遍前向的算子开销)。
Formula Explorer
(n - m) * c
五、自检
Exercise
设 f(u)=uTu(其中 u∈Rp),g(x)=Ax(其中 A 是 p×n 常矩阵)。
(i) 用链式法则求复合函数 h(x)=f(g(x))=xTATAx 的梯度 ∇h(x)。
(ii) 取 n=p=2、A=(1021)、x=(1,1)T,先用解析式算梯度,再用中心差分 (h(x+ϵek)−h(x−ϵek))/(2ϵ)(ϵ=10−4)逐分量做数值对比,确认两者匹配到 4 位有效数字。
提示
先单独算两层的雅可比:
Jf(u) 是
1×p 的行向量
2uT;
Jg(x) 是
p×n 的常矩阵
A。
提示
按多元链式法则
Jh=Jf(g(x))⋅Jg(x)=2(Ax)TA,转置成列向量即得
∇h(x)=2ATAx。代入
A,x 得解析梯度;中心差分按公式逐分量算两次再做减法。
通往下一节
到这里你已经能把任意一条计算图上的梯度按正确顺序乘出来。但梯度只回答了「在当前点往哪个方向走会变化最快」,没有回答「这条方向走出去之后曲面会怎么弯」。后一个问题需要二阶信息——海森矩阵(Hessian)。下一课从一元泰勒展开出发,把它升级到多元二阶展开,并展示为什么海森的特征值(eigenvalue)就是局部曲率沿对应主轴的二阶导数。