深度学习进阶:自然语言处理|4.2.3 QA|交叉熵、激活函数与 y − t:一套数学框架的三个侧面

交叉熵、激活函数与 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. 数值下溢:很多小于 1 的数相乘,结果趋近于 0,计算机存不住
  2. 求导困难:乘积的导数要用乘法法则,非常复杂

取对数后,乘法变加法:

log⁡L(θ)=∑n=1Nlog⁡p(xn∣θ) \log \mathcal{L}(\theta) = \sum_{n=1}^N \log p(x_n|\theta) logL(θ)=n=1∑Nlogp(xn∣θ)

加法求导简单,数值也稳定。

关键性质 :对数是单调递增函数,所以 log⁡L\log \mathcal{L}logL 的最大值点和 L\mathcal{L}L 的最大值点完全相同。取对数不改变答案。

3.4 为什么要取负号

深度学习框架(PyTorch、TensorFlow)统一用梯度下降来优化,即最小化目标函数。

  • 我们想最大化 对数似然 log⁡L\log \mathcal{L}logL
  • 加个负号变成最小化 −log⁡L-\log \mathcal{L}−logL

最大化log⁡L  ⟺  最小化(−log⁡L) \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=−log⁡p=−log⁡∏k=1Kyktk=−∑k=1Ktklog⁡yk 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⋅log⁡0.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⋅log⁡0.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=−log⁡p=−[tlog⁡y+(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=−log⁡y2 L = -\log y_2 L=−logy2

直接取正确类别的概率,取负对数,完事。

公式 L=−∑ktklog⁡ykL = -\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=−log⁡yL = -\log yL=−logy
  • 正确答案是类别 0 → 正确类别的概率是 1−y1-y1−y → L=−log⁡(1−y)L = -\log(1-y)L=−log(1−y)

公式 L=−[tlog⁡y+(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,可以直接写 −log⁡yc-\log y_c−logyc。二分类只有一个输出,另一个类别的概率必须手动写成 1−y1-y1−y,所以公式里出现了两项。但本质完全一样------都是 −log⁡(正确类别的概率)-\log(\text{正确类别的概率})−log(正确类别的概率)。

如果你给二分类也用 2 个输出神经元(y0,y1y_0, y_1y0,y1,过 softmax),公式就变成 L=−[t0log⁡y0+t1log⁡y1]L = -[t_0 \log y_0 + t_1 \log y_1]L=−[t0logy0+t1logy1],和多分类一模一样。书上说"只是写法不同",就是这个意思。

4.4 常见误解:"交叉熵只看正例,所以负例不参与学习"?

4.3 节说交叉熵简化为 L=−log⁡ycL = -\log y_cL=−logyc,看起来只和正确类别 ycy_cyc 有关。于是一个自然的疑问:

既然 tk=0t_k = 0tk=0 的项全被消掉了,负例的权重怎么会被更新?

关键在于 ycy_cyc 不是一个独立的值,它是 softmax 的输出,分母包含所有词的得分。

展开 ycy_cyc:

L=−log⁡yc=−log⁡esc∑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)

取负对数:

−log⁡p=(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 也是常数系数,不影响最优解的位置。所以:

最小化  −log⁡p  ⟺  最小化  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=−[tlog⁡y+(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=−∑ktklog⁡ykL = -\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。

因此,负对数似然对自然参数的梯度:

∂∂η(−log⁡p)=∂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 的根源。 只要:

  1. 输出分布属于指数族
  2. 损失函数是负对数似然
  3. 求导对象是自然参数

梯度就一定是 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 历史脉络

  1. 1930s-1940s:统计学家(Fisher, Pitman, Darmois)发展指数族理论,发现上述梯度性质
  2. 1972年:Nelder & Wedderburn 提出广义线性模型(GLM),明确使用规范链接函数
  3. 1986年:Rumelhart, Hinton & Williams 的反向传播论文选择 sigmoid + 交叉熵配对------他们知道这个统计学结论
  4. 深度学习时代:这个配对被继承下来,成为标准做法

不是"碰巧算出 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 是这个数学结构的必然产物。

相关推荐
malog_8 小时前
Milvus向量数据库:AI时代的搜索革命
数据库·人工智能·后端·milvus
lizhihai_998 小时前
股市学习心得-技术指标学习(布林线+MACD)
大数据·人工智能·学习
徐安安_ye18 小时前
FlashAttention遇上旋转位置编码:RoPE是怎么跟注意力计算配合的?
人工智能·深度学习·机器学习
放下华子我只抽RuiKe58 小时前
React 从入门到生产(八):测试与部署
前端·javascript·深度学习·react.js·前端框架·ecmascript·集成学习
qq_411262428 小时前
Minimax WebSocket TTS 文档里 bitrate / sample_rate 的真实取值
人工智能
嗝o゚8 小时前
昇腾CANN elec-ops-inspection 仓:电力巡检AI算子实战
人工智能·cann·电力巡检
zhangxingchao8 小时前
AI 大模型面试核心二:微调、RAG、MCP、Agent 与工程落地
前端·人工智能·后端
zhangxingchao8 小时前
AI 大模型面试核心三: RAG、Agent 到 Prompt Engineering 的工程化理解
前端·人工智能·后端
救救孩子把8 小时前
66-机器学习与大模型开发数学教程-6-2 矩阵运算的数值误差分析
人工智能·机器学习·矩阵