语言模型的每一层输出最后都要过一道 softmax + 交叉熵,而它的梯度 $\partial\ell/\partial z=p-y$ 大概是整个深度学习里出镜率最高的公式。这个结果干净得反常:两个各自形状都不简单的梯度相乘,居然只剩一个差。这不是巧合,背后有明确的代数机制,而且搞清楚机制之后,"为什么 logsumexp 的梯度是 softmax"、"数值稳定为什么要减最大值"这些周边问题会一起迎刃而解。这篇把整条链推完。
softmax 雅可比的逐分量推导
softmax 把 logits $z\in\mathbb{R}^n$ 映成概率向量:
$$ p_i=\frac{e^{z_i}}{\sum_j e^{z_j}}=\frac{e^{z_i}}{Z},\qquad Z=\sum_j e^{z_j}. $$
求雅可比 $J_{ik}=\partial p_i/\partial z_k$,分两种情况。$i=k$ 时用商的求导法则:
$$ \frac{\partial p_i}{\partial z_i}=\frac{e^{z_i}Z-e^{z_i}e^{z_i}}{Z^2}=p_i-p_i^2=p_i(1-p_i). $$
$i\neq k$ 时分子与 $z_k$ 无关,只有分母动:
$$ \frac{\partial p_i}{\partial z_k}=-\frac{e^{z_i}e^{z_k}}{Z^2}=-p_ip_k. $$
两种情况合成一个矩阵:
$$ \boxed{\;J=\mathrm{diag}(p)-pp^\top\;} $$
对角线 $p_i(1-p_i)$、非对角 $-p_ip_k$。这个结构值得多看一眼:对角项是"自己的份额乘以别人的总份额",非对角项是"两两份额的乘积取负"——softmax 是个零和游戏,抬高一个 logit 必然压低所有其他概率,非对角的负号就是这个挤压效应的代数表达。
J 的谱结构:对称、半正定、缺一维
$J$ 有三个性质在后面的推导里反复用到。
对称性:$J=J^\top$,从表达式直接看出。所以 VJP 里 $J^\top\bar p=J\bar p$,写不写转置无所谓——这是个令人愉快的例外,大部分层的雅可比没这个待遇。
零空间:$J\mathbf{1}=\mathrm{diag}(p)\mathbf{1}-p(p^\top\mathbf{1})=p-p\cdot 1=0$。全 1 向量在零空间里,对应的正是 softmax 的平移不变性:$z\leftarrow z+c\mathbf{1}$ 不改变输出。softmax 把 $\mathbb{R}^n$ 映到 $n-1$ 维的概率单纯形,必然有一维信息被丢弃,秩最多 $n-1$。
半正定性:对任意向量 $u$,
$$ u^\top Ju=\sum_i p_iu_i^2-\Big(\sum_i p_iu_i\Big)^2=\mathrm{Var}_p[u]\geq 0, $$
恰好是 $u$ 在分布 $p$ 下的方差。等号成立当且仅当 $u$ 是常向量——与零空间结论一致。方差形式还顺带给出直觉:分布越均匀($p_i$ 接近 $1/n$),各方向的方差越大,$J$ 越"有分量";分布越尖锐(某个 $p_i\to1$),方差趋零,梯度消失。softmax 饱和时梯度死亡,根源就在这。
与交叉熵相乘:p − y 的诞生
交叉熵损失 $\ell=-\log p_y$($y$ 为正确类别),它对 $p$ 的梯度是
$$ \frac{\partial\ell}{\partial p}=-\frac{e_y}{p}\quad\text{(逐元素除,第 }y\text{ 个分量为 }-1/p_y\text{)}. $$
这个梯度本身就带着隐患:$p_y\to0$ 时 $1/p_y\to\infty$。现在把 VJP 算出来,$\bar z=J^\top\bar p=J\bar p$(用了对称性),逐分量:
$$ \bar z_i=p_i\bar p_i-p_i\sum_j p_j\bar p_j=p_i\Big({-}\frac{\mathbb{1}[i=y]}{p_y}\Big)+p_i\cdot 1=p_i-\mathbb{1}[i=y]. $$
第一步展开 $J\bar p$ 的两项:对角部分贡献 $p_i\bar p_i$,外积部分贡献 $-p_i\langle p,\bar p\rangle$。关键在第二项的内积:
$$ \langle p,\bar p\rangle=\sum_j p_j\cdot\Big({-}\frac{\mathbb{1}[j=y]}{p_y}\Big)=-1, $$
求和里只有 $j=y$ 非零,$p_y$ 与 $1/p_y$ 恰好对消。发散的 $1/p_y$ 被 softmax 雅可比里乘上来的 $p_y$ 抵消——分母消分母,这就是整个化简的支点。最终:
$$ \boxed{\;\frac{\partial\ell}{\partial z}=p-e_y\;} $$
一个随时会爆的梯度和一个结构复杂的雅可比相乘,负号对负号、概率对概率,全部抵消,剩一个差。广义线性模型理论里这是普遍现象:指数族分布配其正则联结函数(canonical link),对数似然的梯度恒等于"预测减观测"。softmax 是多项分布的正则联结,交叉熵是对数似然,$p-y$ 是这个一般定理的实例。它也解释了为什么 logits 被称为"对数几率的线性化"——梯度直接住在 logit 空间里最自然。
logsumexp 视角与数值稳定
把交叉熵直接在 logit 上展开:
$$ \ell=-\log\frac{e^{z_y}}{\sum_j e^{z_j}}=\underbrace{\log\sum_j e^{z_j}}_{\mathrm{logsumexp}(z)}-z_y. $$
对 $z_i$ 求导:logsumexp 的梯度是 $\frac{e^{z_i}}{\sum_j e^{z_j}}=p_i$——logsumexp 的梯度恰好是 softmax。这不是巧合而是共轭关系:logsumexp 与负熵互为凸共轭,求导互逆。softmax 的另一个名字 soft-argmax 也由此而来:logsumexp 是 max 的光滑化($\max_i z_i\leq\mathrm{lse}(z)\leq\max_i z_i+\log n$),它的梯度自然就是 argmax 的光滑化。
数值稳定的标准做法也从这条展开式长出来。直接算 $e^{z_i}$ 在 $z_i>709$ 时 float64 都会溢出(float32 只要 88),而 $\mathrm{lse}$ 满足恒等式
$$ \log\sum_j e^{z_j}=m+\log\sum_j e^{z_j-m},\qquad m=\max_j z_j, $$
减最大值不改变结果(softmax 的平移不变性保证了这点),却把最大指数压到 $e^0=1$。PyTorch 的 F.cross_entropy 内部就是融合实现的 logsumexp:前向不实例化 $p$,反向直接算 $p-y$,整个 VJP 是 $O(n)$ 而从不碰 $n\times n$ 的雅可比。上一篇说的"雅可比只活在纸面上",这里是最经典的一次兑现。
温度参数的梯度效应
带温度的 softmax $p_i\propto e^{z_i/T}$ 等价于 logits 缩放 $z/T$,链式法则立刻给出雅可比 $J_T=\frac{1}{T}\big(\mathrm{diag}(p)-pp^\top\big)$。温度对梯度的作用是双重的:$T$ 大一方面压低 $1/T$ 因子,另一方面让分布变平、$\mathrm{Var}_p[u]$ 变大(半正定性的方差形式),两者有竞争。知识蒸馏用高温软化教师分布,正是利用变平后暗类(dark knowledge)的相对差异被梯度放大这一面。采样侧的温度效应大纲里有专篇,这里只点出它与雅可比结构的联系。
一个推论:label smoothing 只是换了个 $y$
交叉熵的目标分布不必是 one-hot。label smoothing 把 $e_y$ 换成 $q=(1-\epsilon)e_y+\frac{\epsilon}{n}\mathbf{1}$,而上面 VJP 推导里唯一的结构性步骤是内积 $\langle p,\bar p\rangle=-1$ 的对消——对一般的 $q$,$\ell=-\sum q_i\log p_i$,梯度 $\bar p=-q\oslash p$,同样的计算给出
$$ \frac{\partial\ell}{\partial z}=p-q. $$
代数机制对任意目标分布都成立(因为 $\langle p,q\oslash p\rangle=\sum q_i=1$ 只用了归一性),所以"预测减目标"的形态在 soft label、蒸馏($q$ 是教师的高温 soft 分布)、mixup 里原样保留。蒸馏损失对 student logits 的梯度就是 $p_{\text{student}}-q_{\text{teacher}}$——理解 $p-y$ 的来历之后,这一整族变体都不需要重新推导。
小结
这篇的三块内容其实是一条链:逐分量求导给出 $J=\mathrm{diag}(p)-pp^\top$;谱分析给出对称、半正定、零空间含 $\mathbf{1}$ 三条性质;VJP 里内积 $\langle p,\bar p\rangle=-1$ 的对消给出 $p-y$。记住这个"分母消分母"的机制,比记住结论本身有用——凡是"指数族 + 对数损失"的组合(logistic 回归、Poisson 回归、交叉熵)都会出现同样的净化,下次见到可以直接预期梯度的干净形态。下一篇把同样的 VJP 技术用在一个不那么干净的层上:LayerNorm,它的均值-方差耦合会让梯度多出两项修正。