1. 三分类为什么要输出三个数?
之前预测一个数,公式是 y^=w⊤x+b 。现在判断评论的正面、负面、中性,让每个类别有自己的一组权重和偏置,各算一个分数:
zi=wi⊤x+bi
一起写就是:
z=Wx+b
z 是 logits,也就是还没有转换成概率的原始分数。
z 是等于 W * x + b 吗?
对。这里的 z 是分数,后面的 p 才是概率。两者要分开。
如果一个样本有 d 个特征,任务有 C 个类别,我们统一把单样本输入写成列向量:
C×1z=C×dWd×1x+C×1b
在这个写法里,W 每行负责一个类别,每列对应一个输入特征,即有多少个分类W就有多少行。
假如有(正面,负面,中性)三个分类,W就会有三行。
那输入特征个数又是怎么决定的?
由我们怎样用数字表示样本决定。比如评论用“正面词数量、负面词数量”表示,输入就是两个数;再加“感叹号数量”,输入就是三个数。这只是方便理解的人为特征,后面还会学习词向量。
三个类别、三个输入特征,W 就是 3×3。这里两个 3 恰好一样,但行数和列数的意义不同。
2. 原始分数为什么不能直接当概率?
假设三个 logits 是:
z=(2,−1,0)⊤
我认为不能当概率,因为相加不是百分之百。
这里我算漏了:2−1+0 恰好等于 1。真正的问题是它有负数,还有大于 1 的数。
类别概率既要每个值都在 [0,1] 之间,也要总和等于 1。Softmax 做的就是这个转换:
pi=∑j=1Cezjezi
先取指数,让每项变成正数;再除以总和,让最终总和等于 1:
i∑pi=∑jezj∑iezi=1
代入刚才的分数:
| 类别 | Logit | 指数值(约) | 概率(约) |
|---|
| 正面 | 2 | 7.389 | 0.8438 |
| 负面 | −1 | 0.3679 | 0.0420 |
| 中性 | 0 | 1 | 0.1142 |
分数最高的类别,概率仍然最高。不过 softmax 反映的是分数之间的相对关系。如果所有 logits 同时加同一个常数 c:
∑jezj+cezi+c=ec∑jezjecezi=pi
概率完全不变。所以不能脱离其他类别的变化,只看某一个 logit 有没有变大。
3. 分类的 loss 怎么算?
对于每个样本只有一个正确类别的情况,交叉熵可以写成:
L=−lnp正确类别
正确类别的概率越高,loss 越小:
| 正确类别的概率 | Loss(约) |
|---|
| 0.9 | 0.105 |
| 0.5 | 0.693 |
| 0.1 | 2.303 |
当概率为 1,−ln1=0;这是理想边界值,有限实数 logits 的普通 softmax 概率严格小于 1,可以不断接近它。
假设正确标签是“负面”,模型却给负面约 0.042 的概率:
L=−ln(0.042)≈3.17
取的是正确标签对应的概率,不是模型预测最高的概率。模型即使选错了类别,也照样能计算 loss。
4. 所以有三个类别,就算三遍 loss?
我看到完整公式时,又有点混淆:
L=−i=1∑Cyilnpi
按正面、负面、中性的顺序,如果正确答案是负面,one-hot 标签就是:
y=(0,1,0)⊤
展开后:
L=−[0lnp1+1lnp2+0lnp3]=−lnp2
原来是三个交叉熵之和。
这里还要改一下:是一个交叉熵里的三个类别项相加,不是三个独立的交叉熵 loss。One-hot 标签让不正确类别的项为零,保留正确类别的一项。
一个样本、三个类别:输出三个概率,得到一个 loss。两个样本、每个三个类别:各得到一个 loss,再求 batch 平均。
用不同下标分清类别和样本:
Lˉ=−B1n=1∑Bi=1∑Cyi(n)lnpi(n)
B 是 batch 大小,C 是类别数。本文后面的推导先针对单个样本,标签是固定的 one-hot 向量,不加入正则化项。
5. 为什么 Softmax + Cross-entropy 的梯度就是 p − y?
这部分值得详细记。直接记结论很容易忘,代进去推一遍反而不复杂。
仍然假设第二个类别是正确答案:
p2=ez1+ez2+ez3ez2,L=−lnp2
代入,并使用 ln(a/b)=lna−lnb:
L=−lnez1+ez2+ez3ez2=−z2+ln(ez1+ez2+ez3)
对正确类别的分数 z2 求偏导:
∂z2∂L=−1+ez1+ez2+ez31⋅ez2=p2−1
后半部分是链式法则:lnu 求导是 1/u,再乘里面对 z2 的导数 ez2。
对错误类别 z1,−z2 的导数是零:
∂z1∂L=0+ez1+ez2+ez3ez1=p1
对 z3 同理,得到 p3。三个结果放一起是:
∂z∂L=p1p2−1p3=p−y
所以:
∂zi∂L=pi−yi
虽然 loss 最后只剩 −lnp2,但 p2 的分母包含所有 logits,因此其他类别也有梯度。
6. 从 logit 的梯度到参数的梯度
这个区别很重要:pi−yi 是对 zi 的梯度,还不是对权重的梯度。
因为:
zi=j∑Wijxj+bi
再用链式法则:
∂Wij∂L=(pi−yi)xj,∂bi∂L=pi−yi
拿今天的练习算:只有一个输入特征 x=2,正确类别是负面,负面概率约为 0.042:
∂z负面∂L=0.042−1=−0.958
∂w负面∂L=−0.958×2=−1.916,∂b负面∂L=−0.958
学习率 0.1 时:
w新=w旧+0.1916,b新=b旧+0.0958
所以 w、b 都变大,负面的 logit 就变大,softmax 概率就变大了?
在这个单样本、单层分类器的更新里,是的。这里 x>0,两个参数增大让负面 logit 提高。另外两个类别的梯度为正,它们的 logits 降低,所以正确类别的概率提高。
补充:更新参数后,logit 到底改变多少?
这里的公式是啥意思?
先定义变化量:Δzi=zi′−zi,其中带撇号表示更新后的值。这不是新的更新规则,而是把参数更新代回 logit 公式,算出分数的变化。
先只看一个输入特征,原来的分数是:
zi=wix+bi
我们已经知道单样本梯度下降的更新:
wi′=wi−η(pi−yi)x,bi′=bi−η(pi−yi)
这里的概率和梯度都在更新前计算。对同一个输入 x,代回更新后的分数:
zi′=wi′x+bi′=[wi−η(pi−yi)x]x+[bi−η(pi−yi)]=ziwix+bi−η(pi−yi)x2−η(pi−yi)
减去旧分数,合并两项:
Δzi=−η(pi−yi)(x2+1)
x2 来自权重变化的贡献,1 来自偏置变化的贡献。 权重更新里乘了一次输入,代回 wix 时又乘了一次,所以出现平方。
拿前面的负面类别核对:x=2,η=0.1,pi−yi=−0.958,因此:
Δz负面=−0.1×(−0.958)×(22+1)=0.479
也就是负面 logit 增加了 0.479。直接使用之前算出的参数变化,也会得到同样的结果:
Δz负面=Δw0.1916×2+Δb0.0958=0.479
多个输入特征时,每个权重变化的贡献相加:
Δzi=j=1∑dΔWijxj+Δbi=−η(pi−yi)(j=1∑dxj2+1)
而 ∥x∥2=∑j=1dxj2 就是向量各分量的平方和,所以简写为:
Δzi=−η(pi−yi)(∥x∥2+1)
因为 ∥x∥2+1 一定为正,学习率也为正,变化方向就由 −(pi−yi) 决定:正确类别的 logit 提高,错误类别的 logit 降低。
这里的前提是:输入向量保持不变,只用这个样本的梯度,同时以相同学习率更新这一层的权重和偏置,且使用不带动量或正则化的普通梯度下降。 Batch 更新会混入其他样本的梯度;整个 MLP 同时更新时,这一层接收到的隐藏表示也可能改变。因此不能直接推广为“任何 batch 或整个 MLP 的每一步都保证每个样本的 loss 降低”。
7. 加 hidden layer 之前,为什么先讲 ReLU?
假设只是多加一次线性计算:
h=2x+1,z=3h+4
合起来:
z=3(2x+1)+4=6x+7
算了两层,但还是同一种加权求和加偏置的形式。严格说带偏置叫仿射变换,课程里常把这种层称为线性层。
矩阵形式也能合并:
W2(W1x+b1)+b2=(W2W1)x+(W2b1+b2)
因此中间需要非线性。ReLU 是:
ReLU(a)=max(0,a)
负数变零,正数保持不变。加进去以后:
h=ReLU(2x+1),z=3h+4
我算出 x=−1 时 h=0,x=1 时 h=3。整个函数变成:
z={4,6x+7,x≤−0.5x>−0.5
出现了一个折点,不再是全局的一条直线。这就是这个例子里非线性带来的变化。
8. 从一个隐藏单元扩展到四个
今天用的完整结构是:三个输入特征,四个 ReLU 隐藏单元,三个类别。
a=W1x+b1
h=ReLU(a)
z=W2h+b2,p=softmax(z)
| 量 | 形状 | 含义 |
|---|
| x | 3×1 | 输入特征 |
| W1 | 4×3 | 每行给一个隐藏单元算加权和 |
| b1,a,h | 4×1 | 第一层偏置、激活前结果、激活后结果 |
| W2 | 3×4 | 每行给一个类别算分数 |
| b2,z,p,y | 3×1 | 输出偏置、分数、概率、标签 |
如果转置 h 的话,W2 就是 3×4?
W2 的形状对,但这里不需要转置 h:
(3×4)(4×1)⟶(3×1)
如果转置 h,反而乘不起来。先固定自己用列向量的约定,再检查中间维度。
没有隐藏层,直接 softmax 分类,通常叫 Softmax Regression;现在加了 ReLU 隐藏层,是用于多分类的 MLP。隐藏层单元数是我们选的结构设置,不等于类别数。
9. Backpropagation:一条路径相乘,多条路径相加
先看单个隐藏单元:
a=w1x+b1,h=ReLU(a),z=w2h+b2
如果已经知道后面传来的 ∂L/∂z,那么:
∂w1∂L=∂z∂L∂h∂z∂a∂h∂w1∂a
也就是:
∂w1∂L=∂z∂Lw2ReLU′(a)x
当 a>0,ReLU 导数为 1;a<0 时为 0。a=0 处不可导,实现时通常选 0。
今天的局部练习给定 ∂L/∂z=2,w2=3,x=1,a=3,所以结果为 6。这是单独练习链式法则的上游梯度示例,不是前面那个三分类样本的 softmax 梯度。
如果同一个 h 影响两个输出:
z1=v1h+b1,z2=v2h+b2
那么:
∂h∂L=∂z1∂Lv1+∂z2∂Lv2
练习里两条路径分别贡献 2×3=6 和 (−1)×4=−4,总梯度为 2。不同路径可以部分抵消。
因此反向传播的两个规则是:沿路径相乘,多条路径汇总时相加。
10. 今天最有收获的地方:反向传播为什么用转置?
前向是:
z=W2h+b2
记 gz=∂L/∂z=p−y。传回隐藏层的梯度是:
gh=W2⊤gz
形状检查:
4×3W2⊤3×1gz=4×1gh
但只说“为了维度能乘”还不够。真正的原因要看一个隐藏单元 hj:
∂hj∂L=i=1∑3W2,ij∂zi∂L
hj 连到三个输出,三条连接的权重在 W2 的第 j 列。我们需要用这一列与输出梯度逐项相乘再求和。
转置把这列变成一行,就可以用矩阵乘法一次性完成所有隐藏单元的汇总。
前向时,每行权重收集输入,算一个输出;反向时,每列权重收集各输出对同一个输入的梯度贡献。
这不是求逆,也不是把前向计算倒着解回原始输入。矩阵甚至不是方阵。我们计算的是 loss 对中间量有多敏感。
11. 梯度经过 ReLU:对应位置相乘
还需要从 h 传到激活前的 a:
ga=gh⊙ReLU′(a)
⊙ 是对应位置相乘,不是矩阵乘法。
今天的另一个局部练习给定:
a=2−13−2,gh=0.5−0.2−0.80.4
于是:
ga=0.5−0.2−0.80.4⊙1010=0.50−0.80
第二、四个单元激活前为负,这个样本在这里的梯度被截成零。不是说这些参数永远不会改变:其他样本可能激活它们;带动量、正则化等更新也不能只凭当前这一项判断。
12. 最后怎么得到第一层的权重梯度?
因为:
ai=j∑W1,ijxj+b1,i
所以:
∂W1,ij∂L=ga,ixj,∂b1,i∂L=ga,i
给定输入:
x=21−1
第一个隐藏单元的权重梯度是 0.5[2,1,−1]=[1,0.5,−0.5]。
第三个是 −1.6、−0.8、0.8 吗?
对,−0.8[2,1,−1]=[−1.6,−0.8,0.8]。四行放在一起:
∂W1∂L=gax⊤=10−1.600.50−0.80−0.500.80
形状是 (4×1)(1×3)=4×3,和 W1 一样。这种列向量乘行向量叫外积。
这里的转置和前面用途不同:
- W2⊤gz:汇总不同输出路径,得到对隐藏输出的梯度。
- gax⊤:把每个隐藏单元的梯度分别乘每个输入,得到每条连接的权重梯度。
13. 算出了梯度,不等于更新了参数
还要用之前那个 1 − 学习率 × 梯度更新参数。
操作理解对了,但 1 只是之前例子的初始权重。通用公式是:
θ新=θ旧−η∂θ∂L
还有一个关键区别:h 和 a 是计算出来的中间结果,不是直接学习的参数。算出 gh 后,要继续求 W1,b1 的梯度,再更新参数。下一次前向计算会重新算出隐藏层结果。
对于这里的网络,学习的是 W1,b1,W2,b2。
反向传播负责求梯度,梯度下降负责使用梯度更新参数。 一次普通训练 step 应先用同一组前向参数算完所有梯度,再统一更新,不要先改掉 W2,再用新的 W2 计算这次的 gh。
14. 完整公式放在一起,复习时可以逐行解释
这里补齐输出层参数梯度,它和第一层的“梯度乘输入”是同样的规则;输出层的输入是 h。
前向:算预测和 loss
ahzpL=W1x+b1=ReLU(a)=W2h+b2=softmax(z)=−i∑yilnpi
反向:算中间量和参数的梯度
gz∇W2L∇b2Lghga∇W1L∇b1L=p−y=gzh⊤=gz=W2⊤gz=gh⊙ReLU′(a)=gax⊤=ga
更新:每个参数减去学习率乘自己的梯度
Wℓ←Wℓ−η∇WℓL,bℓ←bℓ−η∇bℓL,ℓ∈{1,2}
对于 batch 平均 loss,把各样本对同一参数的梯度求平均,再更新。所有样本都要基于这次更新前的参数计算。
15. 我现在学到哪儿了,以及怎么复习
今天初步走通的是“一个 ReLU 隐藏层 + softmax 多分类输出”的 MLP。能手算局部例子、理解梯度路径和形状,但还没有独立完成一个全网络的数值计算或代码训练。
复习时可以先遮住答案,问自己:
- 三个类别为什么是一个单样本 loss,而不是三个独立 loss?
- 能不能从 −lnp正确类别 推出 p−y?
- W2 的一列代表什么,为什么反向要用它来汇总?
- ReLU 截掉的是哪个中间量的梯度?
- 为什么权重梯度是“传来的梯度乘这一层的输入”?
- gh 算出来以后,为什么还不能直接说参数已经更新?
把这些解释清楚,再自己算一个完整例子,比只认得公式更能检验理解。后面再接词向量时,就能继续问:输入向量从哪里来,它本身能不能也通过梯度学习?
对应课件
来源为课程 Lecture3_DeepLearning_Background.pdf,页码按 PDF 阅读器计数,封面是第 1 页。
| 页码 | 对应内容 |
|---|
| 17–20 | 多分类、one-hot、类别分数和 softmax |
| 22–24 | 非线性与为什么需要激活函数 |
| 27–38 | 多层网络、层的记号和前向计算 |
| 39–42 | Loss、前向与反向传播、链式法则 |
| 44–60 | 分层计算和传播梯度 |
本文的 ReLU 数值例子、softmax 交叉熵推导和 W1,W2 记号来自今天的补充讲解,并非课件逐字转录。今天上传的 Lecture 5 是 Sequence Modeling;本次先补齐理解它所需的 MLP 基础,还没有开始 CNN、RNN、LSTM 和 GRU。