交叉熵、激活函数与 y − t:一套数学框架的三个侧面
先说结论
你的三个问题------"为什么都用交叉熵"、"sigmoid 和 softmax 有什么关系"、"y − t 是怎么来的"------答案是同一件事:
神经网络的输出层 + 损失函数,不是随便选的组合,而是从一个统计学原理(最大似然估计)出发,针对不同问题类型(回归/二分类/多分类)推导出来的唯一自然选择 。这个选择恰好保证了梯度的形式是 y−ty - ty−t。
下面从零开始,把每个概念讲透。
1. 回归与分类:两种根本不同的问题
回归:输出是一个连续的数
"明天气温多少度?" "这套房子值多少钱?"
模型输出一个实数,比如 25.3°C。这个数可以是任意值,没有范围限制。
分类:输出是一个类别
"这张图是猫还是狗?"(二分类)
"这个字是 A/B/C/.../Z 中的哪一个?"(多分类)
模型不能输出"猫"这个字,它需要输出一个数字来表达"我有多大把握认为这是猫"。
这就引出了一个关键需求:我们需要把模型的原始输出(任意实数)转换成概率(0到1之间,且所有类别概率之和为1)。
2. 均方误差(MSE):最直觉的损失函数
在讲交叉熵之前,先彻底理解最简单的损失函数。
什么是损失函数
损失函数回答一个问题:模型的预测和正确答案之间差多远?
差得越远,损失越大。训练的目标就是让损失尽可能小。
均方误差的定义
假设模型预测值是 yyy,正确答案是 ttt:
L=12(y−t)2 L = \frac{1}{2}(y - t)^2 L=21(y−t)2
(前面的 12\frac{1}{2}21 是为了求导时消掉指数 2,让公式更简洁,不影响最优解。)
如果有 NNN 个样本:
L=1N∑n=1N12(yn−tn)2 L = \frac{1}{N} \sum_{n=1}^{N} \frac{1}{2}(y_n - t_n)^2 L=N1n=1∑N21(yn−tn)2

图解 :每个红点是真实值,蓝线是模型预测。绿色虚线是每个点的误差 (y−t)(y - t)(y−t)。MSE 就是把所有误差平方后取平均------惩罚大误差(平方让大误差被放大),容忍小误差。
为什么回归用 MSE
直觉上很自然:预测 25°C,实际 27°C,误差就是 2,损失就是 22=42^2 = 422=4。
但为什么分类不用 MSE?这个问题留到第 7 节回答------先要理解交叉熵是怎么来的。
3. 最大似然估计(MLE):一切的起点
3.1 核心思想:一句话
既然这件事已经发生了,那么让它发生概率最大的那组参数,就是最好的参数。
3.2 抛硬币的例子
你捡到一枚硬币,不知道它是否均匀。你抛了 10 次,结果是 8 次正面、2 次反面。
问:这枚硬币正面朝上的概率 ppp 最可能是多少?
似然函数 :假设正面概率是 ppp,那么"10 次中恰好 8 次正面"的概率是:
L(p)=p8⋅(1−p)2 \mathcal{L}(p) = p^8 \cdot (1-p)^2 L(p)=p8⋅(1−p)2
这不是 ppp 的概率分布,而是"在不同的 ppp 取值下,观测到这个结果的可能性有多大"。
我们要找让 L(p)\mathcal{L}(p)L(p) 最大的 ppp。求导令其为零:
ddpp8(1−p)2=8p7(1−p)2−2p8(1−p)=0 \frac{d}{dp} p^8(1-p)^2 = 8p^7(1-p)^2 - 2p^8(1-p) = 0 dpdp8(1−p)2=8p7(1−p)2−2p8(1−p)=0
p7(1−p)[8(1−p)−2p]=0 ⟹ 8−10p=0 ⟹ p=0.8 p^7(1-p)[8(1-p) - 2p] = 0 \implies 8 - 10p = 0 \implies p = 0.8 p7(1−p)[8(1−p)−2p]=0⟹8−10p=0⟹p=0.8
直觉上也对:抛 10 次中 8 次正面,最合理的估计就是 p=0.8p = 0.8p=0.8。

图解:
- 左图 :似然函数 L(p)=p8(1−p)2\mathcal{L}(p) = p^8(1-p)^2L(p)=p8(1−p)2 的曲线。最高点在 p=0.8p = 0.8p=0.8,这就是最大似然估计。
- 右图 :取负对数后的曲线。最高点变成了最低点,但位置不变(还是 p=0.8p = 0.8p=0.8)。
3.3 为什么要取对数
似然函数是很多概率的连乘:
L(θ)=p(x1∣θ)⋅p(x2∣θ)⋯p(xN∣θ)=∏n=1Np(xn∣θ) \mathcal{L}(\theta) = p(x_1|\theta) \cdot p(x_2|\theta) \cdots p(x_N|\theta) = \prod_{n=1}^N p(x_n|\theta) L(θ)=p(x1∣θ)⋅p(x2∣θ)⋯p(xN∣θ)=n=1∏Np(xn∣θ)
连乘有两个问题:
- 数值下溢:很多小于 1 的数相乘,结果趋近于 0,计算机存不住
- 求导困难:乘积的导数要用乘法法则,非常复杂
取对数后,乘法变加法:
logL(θ)=∑n=1Nlogp(xn∣θ) \log \mathcal{L}(\theta) = \sum_{n=1}^N \log p(x_n|\theta) logL(θ)=n=1∑Nlogp(xn∣θ)
加法求导简单,数值也稳定。
关键性质 :对数是单调递增函数,所以 logL\log \mathcal{L}logL 的最大值点和 L\mathcal{L}L 的最大值点完全相同。取对数不改变答案。
3.4 为什么要取负号
深度学习框架(PyTorch、TensorFlow)统一用梯度下降来优化,即最小化目标函数。
- 我们想最大化 对数似然 logL\log \mathcal{L}logL
- 加个负号变成最小化 −logL-\log \mathcal{L}−logL
最大化logL ⟺ 最小化(−logL) \text{最大化} \log \mathcal{L} \iff \text{最小化} (-\log \mathcal{L}) 最大化logL⟺最小化(−logL)
这里的 ⟺ \iff⟺ 表示"完全等价"------找到的最优参数是同一组,只是优化方向反了。
所以:
最大化似然=最小化负对数似然=最小化损失函数 \boxed{\text{最大化似然} = \text{最小化负对数似然} = \text{最小化损失函数}} 最大化似然=最小化负对数似然=最小化损失函数
这三个等号的含义是:它们是同一个优化问题的三种说法,找到的最优参数完全相同。就像"往北走 100 米"和"往南走 -100 米"是同一件事。
4. 从 MLE 推导出交叉熵(分类的损失函数)
4.1 多分类情况
设定 :KKK 个类别,正确答案用 one-hot 编码 t=[0,0,1,0,...,0]t = [0, 0, 1, 0, \ldots, 0]t=[0,0,1,0,...,0](只有正确类别位置为 1)。模型经过 softmax 后输出概率 y=[y1,y2,...,yK]y = [y_1, y_2, \ldots, y_K]y=[y1,y2,...,yK]。
这个样本的似然(模型认为正确答案出现的概率):
因为 ttt 是 one-hot 的,正确类别(假设是第 ccc 类)的概率就是 ycy_cyc。用数学技巧统一写成:
p(t∣x;θ)=∏k=1Kyktk p(t|x;\theta) = \prod_{k=1}^K y_k^{t_k} p(t∣x;θ)=k=1∏Kyktk
验证:因为 tkt_ktk 只有一个是 1 其余是 0,所以这个连乘实际上只剩 yc1=ycy_c^1 = y_cyc1=yc。
取负对数:
L=−logp=−log∏k=1Kyktk=−∑k=1Ktklogyk L = -\log p = -\log \prod_{k=1}^K y_k^{t_k} = -\sum_{k=1}^K t_k \log y_k L=−logp=−logk=1∏Kyktk=−k=1∑Ktklogyk
这就是多分类交叉熵。它不是凭空定义的公式,而是"最大似然估计 → 取负对数"的直接结果。
具体数字 :3 分类,正确答案是第 0 类,t=[1,0,0]t = [1, 0, 0]t=[1,0,0]。
- 模型输出 y=[0.7,0.2,0.1]y = [0.7, 0.2, 0.1]y=[0.7,0.2,0.1](预测对了):L=−1⋅log0.7−0−0=0.357L = -1 \cdot \log 0.7 - 0 - 0 = 0.357L=−1⋅log0.7−0−0=0.357
- 模型输出 y=[0.1,0.2,0.7]y = [0.1, 0.2, 0.7]y=[0.1,0.2,0.7](预测错了):L=−1⋅log0.1−0−0=2.303L = -1 \cdot \log 0.1 - 0 - 0 = 2.303L=−1⋅log0.1−0−0=2.303
预测越错,损失越大。
4.2 二分类情况
设定 :只有两个类别(0 和 1)。模型输出 yyy 表示"属于类别 1 的概率",那么属于类别 0 的概率自动是 1−y1 - y1−y。正确标签 t∈{0,1}t \in \{0, 1\}t∈{0,1}。
这个样本的似然(伯努利分布):
p(t∣x;θ)=yt⋅(1−y)1−t p(t|x;\theta) = y^t \cdot (1-y)^{1-t} p(t∣x;θ)=yt⋅(1−y)1−t
验证:
- t=1t = 1t=1 时:p=y1⋅(1−y)0=yp = y^1 \cdot (1-y)^0 = yp=y1⋅(1−y)0=y(正确答案是 1,似然就是模型输出的 yyy)
- t=0t = 0t=0 时:p=y0⋅(1−y)1=1−yp = y^0 \cdot (1-y)^1 = 1-yp=y0⋅(1−y)1=1−y(正确答案是 0,似然就是 1−y1-y1−y)
取负对数:
L=−logp=−[tlogy+(1−t)log(1−y)] L = -\log p = -[t \log y + (1-t) \log(1-y)] L=−logp=−[tlogy+(1−t)log(1−y)]
这就是二元交叉熵(Binary Cross-Entropy, BCE)。

图解:
- 蓝线:正确答案是 1 时的损失。模型输出 yyy 越接近 1,损失越小;yyy 越接近 0,损失爆炸式增长。
- 红线:正确答案是 0 时的损失。模型输出 yyy 越接近 0,损失越小。
- 关键特征:损失是非线性的------从 0.9 错到 0.1,惩罚远大于从 0.9 错到 0.5。这比 MSE 的平方惩罚更激进。
4.3 统一本质:永远只算正确类别的概率
不管多分类还是二分类,交叉熵做的事情只有一件:
L=−log(正确类别的概率) L = -\log(\text{正确类别的概率}) L=−log(正确类别的概率)
模型给正确答案的概率越高,损失越小。就这么简单。
多分类 :3 个类,正确答案是第 2 类。模型有 3 个输出 y0,y1,y2y_0, y_1, y_2y0,y1,y2,每个类别有自己的变量名。
L=−logy2 L = -\log y_2 L=−logy2
直接取正确类别的概率,取负对数,完事。
公式 L=−∑ktklogykL = -\sum_k t_k \log y_kL=−∑ktklogyk 看起来是求和,但因为 t=[0,0,1]t = [0, 0, 1]t=[0,0,1],乘以 0 的项全部消失,只剩正确类别那一项。求和只是数学上的统一写法。
二分类 :只有 2 个类(0 和 1),但模型只有 1 个 输出神经元 yyy,表示"类别 1 的概率"。类别 0 的概率没有自己的变量名,只能写成 1−y1 - y1−y。
- 正确答案是类别 1 → 正确类别的概率是 yyy → L=−logyL = -\log yL=−logy
- 正确答案是类别 0 → 正确类别的概率是 1−y1-y1−y → L=−log(1−y)L = -\log(1-y)L=−log(1−y)
公式 L=−[tlogy+(1−t)log(1−y)]L = -[t\log y + (1-t)\log(1-y)]L=−[tlogy+(1−t)log(1−y)] 不是"同时算两项",而是一个 if-else 的数学写法 :ttt 和 (1−t)(1-t)(1−t) 充当开关,每次只有一项生效。
为什么二分类看起来"更复杂"? 因为多分类每个类别有自己的输出 yky_kyk,可以直接写 −logyc-\log y_c−logyc。二分类只有一个输出,另一个类别的概率必须手动写成 1−y1-y1−y,所以公式里出现了两项。但本质完全一样------都是 −log(正确类别的概率)-\log(\text{正确类别的概率})−log(正确类别的概率)。
如果你给二分类也用 2 个输出神经元(y0,y1y_0, y_1y0,y1,过 softmax),公式就变成 L=−[t0logy0+t1logy1]L = -[t_0 \log y_0 + t_1 \log y_1]L=−[t0logy0+t1logy1],和多分类一模一样。书上说"只是写法不同",就是这个意思。
4.4 常见误解:"交叉熵只看正例,所以负例不参与学习"?
4.3 节说交叉熵简化为 L=−logycL = -\log y_cL=−logyc,看起来只和正确类别 ycy_cyc 有关。于是一个自然的疑问:
既然 tk=0t_k = 0tk=0 的项全被消掉了,负例的权重怎么会被更新?
关键在于 ycy_cyc 不是一个独立的值,它是 softmax 的输出,分母包含所有词的得分。
展开 ycy_cyc:
L=−logyc=−logesc∑j=1Vesj=−sc⏟正例得分+log∑j=1Vesj⏟所有词都在这里 L = -\log y_c = -\log\frac{e^{s_c}}{\sum_{j=1}^V e^{s_j}} = \underbrace{-s_c}{\text{正例得分}} + \underbrace{\log\sum{j=1}^V e^{s_j}}_{\text{所有词都在这里}} L=−logyc=−log∑j=1Vesjesc=正例得分 −sc+所有词都在这里 logj=1∑Vesj
第二项 log∑esj\log\sum e^{s_j}log∑esj 是全部 V 个词得分的函数。对任意负例 kkk 求梯度:
∂L∂sk=esk∑jesj=yk(k≠c) \frac{\partial L}{\partial s_k} = \frac{e^{s_k}}{\sum_j e^{s_j}} = y_k \quad (k \neq c) ∂sk∂L=∑jesjesk=yk(k=c)
这个梯度不为零------每个负例的权重都会被更新。
用具体数字验证
假设词汇表只有 3 个词,得分 s=[2,1,3]s = [2, 1, 3]s=[2,1,3],正例是第 0 个词。
y0=e2e2+e1+e3=7.397.39+2.72+20.09=0.245 y_0 = \frac{e^2}{e^2 + e^1 + e^3} = \frac{7.39}{7.39 + 2.72 + 20.09} = 0.245 y0=e2+e1+e3e2=7.39+2.72+20.097.39=0.245
L=−log(0.245)=1.41 L = -\log(0.245) = 1.41 L=−log(0.245)=1.41
现在把负例的得分 s2s_2s2 从 3 改成 10:
y0=e2e2+e1+e10=7.397.39+2.72+22026=0.000335 y_0 = \frac{e^2}{e^2 + e^1 + e^{10}} = \frac{7.39}{7.39 + 2.72 + 22026} = 0.000335 y0=e2+e1+e10e2=7.39+2.72+220267.39=0.000335
L=−log(0.000335)=8.0 L = -\log(0.000335) = 8.0 L=−log(0.000335)=8.0
负例得分变大,正例的 loss 剧烈增大。 所以 softmax 通过分母,隐式地让每个负例都参与了梯度更新。
这和负采样(Negative Sampling)的关系
Softmax 的问题不是"没看负例",而是看了太多负例------每次前向/反向都要计算全部 V 个词的得分。当 V = 100 万时,计算量太大。
负采样的思路:既然 softmax 隐式地"推低"了所有负例,那我只挑 5~20 个负例来显式推低,近似达到同样效果:
- 正例:让 σ(sc)→1\sigma(s_c) \to 1σ(sc)→1(拉高)
- 随机采样 K 个负例:让 σ(sk)→0\sigma(s_k) \to 0σ(sk)→0(推低)
计算量从 O(V) 降到 O(K)。两者目标相同,负采样是 softmax 的廉价近似。
5. 从 MLE 推导出 MSE(回归的损失函数)
回归问题的概率假设:真实值 = 模型预测 + 随机噪声,噪声服从高斯分布:
t=y+ϵ,ϵ∼N(0,σ2) t = y + \epsilon, \quad \epsilon \sim \mathcal{N}(0, \sigma^2) t=y+ϵ,ϵ∼N(0,σ2)
即:给定输入 xxx,真实值 ttt 服从以 yyy 为均值的高斯分布:
p(t∣x;θ)=12πσexp(−(t−y)22σ2) p(t|x;\theta) = \frac{1}{\sqrt{2\pi}\sigma} \exp\left(-\frac{(t - y)^2}{2\sigma^2}\right) p(t∣x;θ)=2π σ1exp(−2σ2(t−y)2)
取负对数:
−logp=(t−y)22σ2+12log(2πσ2) -\log p = \frac{(t - y)^2}{2\sigma^2} + \frac{1}{2}\log(2\pi\sigma^2) −logp=2σ2(t−y)2+21log(2πσ2)
第二项是常数(不含模型参数 θ\thetaθ),最小化时可以忽略。σ2\sigma^2σ2 也是常数系数,不影响最优解的位置。所以:
最小化 −logp ⟺ 最小化 12(y−t)2 \text{最小化} \; -\log p \iff \text{最小化} \; \frac{1}{2}(y - t)^2 最小化−logp⟺最小化21(y−t)2
均方误差就是"假设噪声服从高斯分布"时的负对数似然。
统一图景
| 问题类型 | 概率假设 | 输出层 | 负对数似然 = 损失函数 |
|---|---|---|---|
| 回归 | 高斯分布 N(y,σ2)\mathcal{N}(y, \sigma^2)N(y,σ2) | 恒等函数 y=zy = zy=z | 均方误差 12(y−t)2\frac{1}{2}(y-t)^221(y−t)2 |
| 二分类 | 伯努利分布 Ber(y)\text{Ber}(y)Ber(y) | sigmoid | 二元交叉熵 |
| 多分类 | 类别分布 Cat(y)\text{Cat}(y)Cat(y) | softmax | 多分类交叉熵 |
所有损失函数都是同一个原理(MLE 取负对数)在不同概率假设下的特例。 "为什么都用交叉熵"的答案是:分类问题的概率模型是伯努利/类别分布,它们的负对数似然恰好就是交叉熵的形式。
6. sigmoid 与 softmax:同一件事的不同维度
6.1 sigmoid 做了什么
sigmoid 把一个实数 zzz 映射到 (0,1)(0, 1)(0,1):
σ(z)=11+e−z \sigma(z) = \frac{1}{1 + e^{-z}} σ(z)=1+e−z1
输出解释为"属于正类的概率"。负类概率自动是 1−σ(z)1 - \sigma(z)1−σ(z)。
6.2 softmax 做了什么
softmax 把 KKK 个实数 z1,z2,...,zKz_1, z_2, \ldots, z_Kz1,z2,...,zK 映射到 KKK 个概率:
softmax(zi)=ezi∑k=1Kezk \text{softmax}(z_i) = \frac{e^{z_i}}{\sum_{k=1}^K e^{z_k}} softmax(zi)=∑k=1Kezkezi
所有输出之和 = 1,每个输出 > 0。
6.3 严格证明:2 类 softmax = sigmoid
当 K=2K = 2K=2 时,softmax 对第 1 类的输出:
softmax(z1)=ez1ez0+ez1 \text{softmax}(z_1) = \frac{e^{z_1}}{e^{z_0} + e^{z_1}} softmax(z1)=ez0+ez1ez1
分子分母同时除以 ez0e^{z_0}ez0:
=ez1/ez01+ez1/ez0=ez1−z01+ez1−z0 = \frac{e^{z_1} / e^{z_0}}{1 + e^{z_1}/e^{z_0}} = \frac{e^{z_1 - z_0}}{1 + e^{z_1 - z_0}} =1+ez1/ez0ez1/ez0=1+ez1−z0ez1−z0
令 z=z1−z0z = z_1 - z_0z=z1−z0(两个类别的分数之差):
=ez1+ez = \frac{e^z}{1 + e^z} =1+ezez
分子分母同除以 eze^zez:
=1e−z+1=11+e−z=σ(z) = \frac{1}{e^{-z} + 1} = \frac{1}{1 + e^{-z}} = \sigma(z) =e−z+11=1+e−z1=σ(z)
结论:2 类 softmax 对"两类分数之差"的运算结果,就是 sigmoid。
实际使用中,二分类网络只输出一个 logit zzz(隐含地设 z0=0z_0 = 0z0=0,z1=zz_1 = zz1=z),然后过 sigmoid。这和用 2 个输出神经元过 softmax 是完全等价的。
6.4 为什么要分开命名
既然数学上等价,为什么有两个名字?
- 效率:二分类只需要 1 个输出神经元 + sigmoid,而不是 2 个输出神经元 + softmax。参数少一半。
- 使用场景不同:sigmoid 还用于多标签分类(一张图可以同时是"户外"和"有狗"),此时各标签独立,不需要概率和为 1。softmax 用于互斥分类(一张图只能是猫或狗或鸟中的一个)。
- 历史原因:sigmoid 在神经网络中的使用(1980s)早于 softmax 被广泛采用。

图解:蓝色实线是 sigmoid,红色虚线是 2 类 softmax。两条线完全重合(红色被蓝色覆盖),验证了数学等价性。
7. y − t 的推导:三种配对,同一个结果
这是最核心的部分。我们要证明:无论是回归还是分类,只要输出层和损失函数"正确配对",反向传播到 logit zzz 的梯度都是 y−ty - ty−t。
7.1 最简单的情况:恒等函数 + MSE
输出层:y=zy = zy=z(不做任何变换)
损失:L=12(y−t)2L = \frac{1}{2}(y - t)^2L=21(y−t)2
求梯度:
∂L∂z=∂L∂y⋅∂y∂z=(y−t)⋅1=y−t \frac{\partial L}{\partial z} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial z} = (y - t) \cdot 1 = y - t ∂z∂L=∂y∂L⋅∂z∂y=(y−t)⋅1=y−t
没有任何技巧,直接就是 y−ty - ty−t。
7.2 sigmoid + 二元交叉熵 → y − t
输出层:y=σ(z)=11+e−zy = \sigma(z) = \frac{1}{1 + e^{-z}}y=σ(z)=1+e−z1
损失:L=−[tlogy+(1−t)log(1−y)]L = -[t \log y + (1-t) \log(1-y)]L=−[tlogy+(1−t)log(1−y)]
用链式法则:∂L∂z=∂L∂y⋅∂y∂z\frac{\partial L}{\partial z} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial z}∂z∂L=∂y∂L⋅∂z∂y
第一步 :求 ∂L∂y\frac{\partial L}{\partial y}∂y∂L(损失对输出的导数)
∂L∂y=−ty+1−t1−y \frac{\partial L}{\partial y} = -\frac{t}{y} + \frac{1-t}{1-y} ∂y∂L=−yt+1−y1−t
第二步 :求 ∂y∂z\frac{\partial y}{\partial z}∂z∂y(sigmoid 的导数)
sigmoid 有一个著名的性质:
dσdz=σ(z)⋅(1−σ(z))=y(1−y) \frac{d\sigma}{dz} = \sigma(z) \cdot (1 - \sigma(z)) = y(1-y) dzdσ=σ(z)⋅(1−σ(z))=y(1−y)
第三步:链式法则相乘
∂L∂z=(−ty+1−t1−y)⋅y(1−y) \frac{\partial L}{\partial z} = \left(-\frac{t}{y} + \frac{1-t}{1-y}\right) \cdot y(1-y) ∂z∂L=(−yt+1−y1−t)⋅y(1−y)
展开第一项:−ty⋅y(1−y)=−t(1−y)-\frac{t}{y} \cdot y(1-y) = -t(1-y)−yt⋅y(1−y)=−t(1−y)
展开第二项:1−t1−y⋅y(1−y)=(1−t)⋅y\frac{1-t}{1-y} \cdot y(1-y) = (1-t) \cdot y1−y1−t⋅y(1−y)=(1−t)⋅y
合并:
=−t(1−y)+(1−t)y=−t+ty+y−ty=y−t = -t(1-y) + (1-t)y = -t + ty + y - ty = y - t =−t(1−y)+(1−t)y=−t+ty+y−ty=y−t

图解 :推导的关键在于 ∂L∂y\frac{\partial L}{\partial y}∂y∂L 中的分母 yyy 和 (1−y)(1-y)(1−y),恰好被 sigmoid 导数中的 y(1−y)y(1-y)y(1−y) 约掉了。这个"完美约分"不是巧合------见第 8 节。
7.3 softmax + 多分类交叉熵 → y − t
输出层:yi=ezi∑kezky_i = \frac{e^{z_i}}{\sum_k e^{z_k}}yi=∑kezkezi(KKK 个输出)
损失:L=−∑ktklogykL = -\sum_k t_k \log y_kL=−∑ktklogyk
我们要求 ∂L∂zi\frac{\partial L}{\partial z_i}∂zi∂L(损失对第 iii 个 logit 的梯度)。
第一步 :softmax 的 Jacobian(yjy_jyj 对 ziz_izi 的偏导)
∂yj∂zi={yi(1−yi)if i=j−yiyjif i≠j \frac{\partial y_j}{\partial z_i} = \begin{cases} y_i(1 - y_i) & \text{if } i = j \\ -y_i y_j & \text{if } i \neq j \end{cases} ∂zi∂yj={yi(1−yi)−yiyjif i=jif i=j
推导(以 i=ji = ji=j 为例):
∂∂zieziS=ezi⋅S−ezi⋅eziS2=eziS−(eziS)2=yi−yi2=yi(1−yi) \frac{\partial}{\partial z_i} \frac{e^{z_i}}{S} = \frac{e^{z_i} \cdot S - e^{z_i} \cdot e^{z_i}}{S^2} = \frac{e^{z_i}}{S} - \left(\frac{e^{z_i}}{S}\right)^2 = y_i - y_i^2 = y_i(1-y_i) ∂zi∂Sezi=S2ezi⋅S−ezi⋅ezi=Sezi−(Sezi)2=yi−yi2=yi(1−yi)
第二步:链式法则
∂L∂zi=∑j∂L∂yj⋅∂yj∂zi \frac{\partial L}{\partial z_i} = \sum_j \frac{\partial L}{\partial y_j} \cdot \frac{\partial y_j}{\partial z_i} ∂zi∂L=j∑∂yj∂L⋅∂zi∂yj
其中 ∂L∂yj=−tjyj\frac{\partial L}{\partial y_j} = -\frac{t_j}{y_j}∂yj∂L=−yjtj
分成 j=ij = ij=i 和 j≠ij \neq ij=i 两部分:
=(−tiyi)⋅yi(1−yi)+∑j≠i(−tjyj)⋅(−yiyj) = \left(-\frac{t_i}{y_i}\right) \cdot y_i(1-y_i) + \sum_{j \neq i} \left(-\frac{t_j}{y_j}\right) \cdot (-y_i y_j) =(−yiti)⋅yi(1−yi)+j=i∑(−yjtj)⋅(−yiyj)
=−ti(1−yi)+∑j≠itj⋅yi = -t_i(1-y_i) + \sum_{j \neq i} t_j \cdot y_i =−ti(1−yi)+j=i∑tj⋅yi
=−ti+tiyi+yi∑j≠itj = -t_i + t_i y_i + y_i \sum_{j \neq i} t_j =−ti+tiyi+yij=i∑tj
提取公因子 yiy_iyi:
=−ti+yi(ti+∑j≠itj) = -t_i + y_i \left(t_i + \sum_{j \neq i} t_j\right) =−ti+yi ti+j=i∑tj
因为 ttt 是 one-hot 向量,∑jtj=1\sum_j t_j = 1∑jtj=1:
=−ti+yi⋅1=yi−ti = -t_i + y_i \cdot 1 = y_i - t_i =−ti+yi⋅1=yi−ti
7.4 三种配对的统一结果
∂L∂zi=yi−ti \boxed{\frac{\partial L}{\partial z_i} = y_i - t_i} ∂zi∂L=yi−ti
无论是回归、二分类还是多分类,梯度都是"预测值减去真实值"。
这意味着:
- 预测对了(y≈ty \approx ty≈t)→ 梯度 ≈ 0 → 几乎不更新(已经学好了)
- 预测错了(yyy 远离 ttt)→ 梯度大 → 大幅更新(还需要学)
- 梯度的方向和大小完全由误差决定,没有任何"刹车"因子
8. 为什么是"设计"而非"巧合"
8.1 如果不配对会怎样
假设我们"不配对"------用 sigmoid 输出 + MSE 损失:
L=12(y−t)2,y=σ(z) L = \frac{1}{2}(y - t)^2, \quad y = \sigma(z) L=21(y−t)2,y=σ(z)
∂L∂z=(y−t)⋅∂y∂z=(y−t)⋅y(1−y) \frac{\partial L}{\partial z} = (y - t) \cdot \frac{\partial y}{\partial z} = (y - t) \cdot y(1-y) ∂z∂L=(y−t)⋅∂z∂y=(y−t)⋅y(1−y)
多了一个 y(1−y)y(1-y)y(1−y) 因子。这个因子的问题:
- 当 zzz 很大时,y≈1y \approx 1y≈1,y(1−y)≈0y(1-y) \approx 0y(1−y)≈0
- 当 zzz 很小时,y≈0y \approx 0y≈0,y(1−y)≈0y(1-y) \approx 0y(1−y)≈0
即使模型预测完全错误(比如正确答案是 1,但 z=−10z = -10z=−10,y≈0y \approx 0y≈0),梯度也接近 0!
这就是梯度消失:模型犯了大错,但收到的学习信号极弱,几乎学不动。

图解:
- 左图 :sigmoid 导数 σ′(z)=y(1−y)\sigma'(z) = y(1-y)σ′(z)=y(1−y) 的形状。两端趋近于 0,只有中间(z≈0z \approx 0z≈0)附近有较大值。红色阴影区域就是"梯度消失区"。
- 右图 :正确答案 t=1t = 1t=1 时的梯度对比。
- 蓝线(sigmoid + 交叉熵):zzz 越负(预测越错),梯度绝对值越大。错得越多,学习信号越强。
- 红线(sigmoid + MSE):zzz 很负时,梯度反而趋近于 0。模型犯了大错却学不动。
这就是为什么分类问题要用交叉熵而不是 MSE。 交叉熵的 −log-\log−log 恰好产生 1y\frac{1}{y}y1 和 11−y\frac{1}{1-y}1−y1,与 sigmoid 导数中的 y(1−y)y(1-y)y(1−y) 约分,消除了梯度消失。
8.2 指数族:统一的数学解释
为什么交叉熵能和 sigmoid/softmax 完美配对?因为它们都来自同一个数学结构------指数族分布。
伯努利分布、类别分布、高斯分布都属于指数族。指数族有一个统一形式:
p(x∣η)=h(x)⋅exp(ηTT(x)−A(η)) p(x|\eta) = h(x) \cdot \exp\left(\eta^T T(x) - A(\eta)\right) p(x∣η)=h(x)⋅exp(ηTT(x)−A(η))
其中 η\etaη 是自然参数 ,A(η)A(\eta)A(η) 是对数配分函数(保证概率归一化)。
指数族有一个关键数学性质:
∂A(η)∂η=E[T(x)] \frac{\partial A(\eta)}{\partial \eta} = \mathbb{E}[T(x)] ∂η∂A(η)=E[T(x)]
即 A(η)A(\eta)A(η) 对自然参数的导数 = 模型的期望输出 = yyy。
因此,负对数似然对自然参数的梯度:
∂∂η(−logp)=∂A∂η−T(x)=y−t \frac{\partial}{\partial \eta}(-\log p) = \frac{\partial A}{\partial \eta} - T(x) = y - t ∂η∂(−logp)=∂η∂A−T(x)=y−t
这就是 y−ty - ty−t 的根源。 只要:
- 输出分布属于指数族
- 损失函数是负对数似然
- 求导对象是自然参数
梯度就一定是 y−ty - ty−t。
8.3 三种情况在指数族框架下的对应
| 分布 | 自然参数 η\etaη | 对数配分函数 A(η)A(\eta)A(η) | ∂A∂η\frac{\partial A}{\partial \eta}∂η∂A = 输出层 |
|---|---|---|---|
| 伯努利 | zzz(logit) | log(1+ez)\log(1 + e^z)log(1+ez) | σ(z)\sigma(z)σ(z) = sigmoid |
| 类别分布 | z1,...,zKz_1, \ldots, z_Kz1,...,zK | log∑kezk\log \sum_k e^{z_k}log∑kezk | softmax |
| 高斯 | μ/σ2\mu/\sigma^2μ/σ2 | μ2/(2σ2)\mu^2/(2\sigma^2)μ2/(2σ2) | μ\muμ = 恒等函数 |
sigmoid、softmax、恒等函数不是随便选的激活函数------它们分别是伯努利、类别、高斯分布的规范链接函数(canonical link function)。这个概念来自统计学中的广义线性模型(GLM,1970s),比深度学习早了十几年。
8.4 历史脉络
- 1930s-1940s:统计学家(Fisher, Pitman, Darmois)发展指数族理论,发现上述梯度性质
- 1972年:Nelder & Wedderburn 提出广义线性模型(GLM),明确使用规范链接函数
- 1986年:Rumelhart, Hinton & Williams 的反向传播论文选择 sigmoid + 交叉熵配对------他们知道这个统计学结论
- 深度学习时代:这个配对被继承下来,成为标准做法
不是"碰巧算出 y − t",而是"因为统计学早就证明了指数族有这个性质,所以神经网络的设计者选了这些函数配对"。
9. 完整的知识地图
问题类型 概率假设 输出层函数 损失函数 梯度
─────────────────────────────────────────────────────────────────────────
回归 高斯分布 恒等函数 MSE y − t
y = z ½(y−t)²
二分类 伯努利分布 sigmoid 二元交叉熵 y − t
y = σ(z) −[t·log y +
(1−t)·log(1−y)]
多分类 类别分布 softmax 多分类交叉熵 y − t
yᵢ = eᶻⁱ/Σeᶻᵏ −Σ tₖ·log yₖ
─────────────────────────────────────────────────────────────────────────
↑ ↑ ↑ ↑
指数族分布 规范链接函数 负对数似然 指数族性质
一句话总结 :选什么输出层、选什么损失函数,不是经验主义的"试试哪个好用",而是从"数据服从什么分布"这一个假设出发,经过最大似然估计,数学上唯一确定的结果。y−ty - ty−t 是这个数学结构的必然产物。