一、反向传播算法回顾
反向传播算法利用矩阵运算快速计算输出层的梯度,并逐层向前传播误差。定义如下核心符号:
| 符号 | 含义 |
|---|
| wjkl | 第 l 层第 j 个神经元与第 l−1 层第 k 个神经元之间的权重 |
| bjl | 第 l 层第 j 个神经元的偏置 |
| ajl | 第 l 层第 j 个神经元的激活值 |
| zjl | 第 l 层第 j 个神经元的加权输入:zjl=∑kwjklakl−1+bjl |
| δjl | 第 l 层第 j 个神经元的误差 |
BP 四个核心方程(必记)
- BP1(输出层误差):δL=∇aC⊙σ′(zL)
- BP2(误差传播):δl=((wl+1)Tδl+1)⊙σ′(zl)
- BP3(代价对偏置的梯度):∂bjl∂C=δjl
- BP4(代价对权重的梯度):∂wjkl∂C=akl−1δjl
- 输入:设置输入层激活值 a1=x
- 前馈:对每一层 l=2,3,…,L,计算 zl=wlal−1+bl 和 al=σ(zl)
- 输出层误差:计算 δL=∇aC⊙σ′(zL)
- 反向传播误差:对每一层 l=L−1,L−2,…,2,计算 δl=((wl+1)Tδl+1)⊙σ′(zl)
- 输出梯度:得到 ∂wjkl∂C=akl−1δjl 和 ∂bjl∂C=δjl
从全局视角理解反向传播:权重的变化如何影响激活值的变化,进而影响代价函数的变化。可以用"路径求和"的方式理解梯度的计算:
∂wjkl∂C=∑paths(path contributions from wjkl to C)
每一条从权重 wjkl 到代价 C 的路径,其贡献为路径上所有偏导数的乘积。反向传播算法本质上是高效地计算这些路径求和。
二、交叉熵代价函数
使用均方误差(MSE)作为代价函数时,当神经元输出严重错误且饱和时,学习速度非常缓慢。
问题示例
单个神经元,期望输出 0,使用 MSE 代价函数:
- 当 w=0.6,b=0.9 时:初始输出 σ(0.6×1+0.9)=σ(1.5)≈0.82,学习缓慢
- 当 w=2.0,b=2.0 时:初始输出 σ(2.0×1+2.0)=σ(4.0)≈0.98,学习更加缓慢!
原因:MSE 梯度中含有 σ′(z) 项,当神经元饱和时 σ′(z)≈0,梯度趋近于零。
为解决学习缓慢问题,引入交叉熵代价函数:
C=−n1∑x[ylna+(1−y)ln(1−a)]
其中 n 为训练样本总数,a 为神经元输出,y 为期望输出。
优势:梯度中不含 σ′(z)
计算交叉熵对权重的偏导数:
∂wj∂C=n1∑xxj(σ(z)−y)
梯度仅取决于输出误差 (σ(z)−y),误差越大学习越快
对单个训练样本,代价函数为:
C=−[ylna+(1−y)ln(1−a)]
其中 a=σ(z)=σ(wx+b)。计算偏导数:
∂wj∂C=−[σ(z)y−1−σ(z)1−y]⋅σ′(z)⋅xj
利用 σ′(z)=σ(z)(1−σ(z)):
∂wj∂C=−[σ(z)y−1−σ(z)1−y]⋅σ(z)(1−σ(z))⋅xj
=−[y(1−σ(z))−(1−y)σ(z)]⋅xj
=−[y−yσ(z)−σ(z)+yσ(z)]⋅xj
=(σ(z)−y)⋅xj
类似地,对偏置的偏导数为:
∂b∂C=n1∑x(σ(z)−y)
如果我们希望代价函数满足以下性质:
∂w∂C=x(a−y)
从这个期望出发,通过积分可以推导出交叉熵的形式。由 ∂a∂C=a(1−a)a−y,对 a 积分得:
C=−[ylna+(1−y)ln(1−a)]+const
对于输出层有多个神经元的网络,交叉熵推广为:
C=−n1∑x∑j[yjlnajL+(1−yj)ln(1−ajL)]
其中 j 遍历输出层所有神经元。
三、Softmax 与对数似然
Softmax 是一种输出层激活函数,用来替代 sigmoid。它把输出层的原始值 zjL 转换成概率分布
ajL=∑kezkLezjL
输出范围:每个 ajL∈(0,1)
和为 1:∑jajL=1(天然是概率分布)
放大差异:z 最大的那个类别会得到最大的概率
假设输出层有 3 个神经元(3 分类),加权输入为:
zL=(2.0, 1.0, 0.5)
计算 softmax:
∑kezkL=e2.0+e1.0+e0.5=7.389+2.718+1.649=11.756
| 神经元 | zjL | ezjL | ajL(softmax 输出) | 解释 |
|---|
| j=1 | 2.0 | 7.389 | 7.389/11.756 = 0.629 | 最大 → 最高概率 |
| j=2 | 1.0 | 2.718 | 2.718/11.756 = 0.231 | |
| j=3 | 0.5 | 1.649 | 1.649/11.756 = 0.140 | |
输出 (0.629,0.231,0.140),和为 1
网络预测:最可能是第 1 类(概率 62.9%)
Softmax 通常搭配对数似然代价函数(Log-likelihood cost):C=−lnayL
其中 y 是正确类别的索引。当网络对正确类别预测的概率越高,代价越低。
也就是只关注"正确类别的概率"有多大
| ayL(正确类别的概率) | C=−lnayL | |
|---|
| 0.9 | 0.105 | 很自信且正确 → 损失小 |
| 0.5 | 0.693 | 不太确定 → 损失中等 |
| 0.1 | 2.303 | 把正确答案排很低 → 损失很大 |
| → 0 | → ∞ | 完全错误 → 惩罚趋于无穷 |
Softmax + 对数似然的梯度同样具有简洁的形式:
∂wjkL∂C=akl−1(ajL−yj)
∂bjL∂C=ajL−yj
与交叉熵相同的优势都是梯度同样不含 σ′(z),由误差 (ajL−yj) 驱动,避免学习缓慢。
Sigmoid + 交叉熵
- 输出层使用 Sigmoid
- 代价函数:C=−n1∑[ylna+(1−y)ln(1−a)]
- 适合二分类或多标签任务
- 各输出独立
Softmax + 对数似然
- 输出层使用 Softmax
- 代价函数:C=−lnayL
- 适合多分类(互斥)任务
- 各输出竞争(和为 1)
四、过拟合问题
当模型参数远多于训练数据时,网络会记住训练数据的噪声而非学习通用规律。
实验示例
使用 30 个隐藏神经元的网络(共 23860 个参数),仅用 1000 张图片训练:
- 训练准确率持续上升(接近 100%)
- 测试准确率很快达到平台期并停止提升
- 训练代价持续下降,但测试代价开始上升
- 跟踪测试集(或验证集)上的准确率
- 当测试准确率不再提升时,停止训练(早停法 Early Stopping)
- 观察训练代价与测试代价的差距是否持续增大
将训练数据从 1000 张增加到 50000 张后,过拟合现象大幅缓解,测试准确率显著提升。
更多的数据几乎总是比更复杂的模型更有效。但获取更多数据并非总是可行,因此需要正则化等技术。
五、正则化方法
当网络参数太多、训练数据太少时,网络会过拟合—— 在训练集上表现很好,但在新数据上很差(相当于 "死记硬背" 而不是 "学会规律")。
正则化的核心思想是给代价函数加一个 "惩罚项",让网络倾向于用更小、更简单的权重,从而避免过拟合。
L1 正则化使用权重的绝对值之和作为惩罚项:
C=C0+nλ∑w∣w∣
其中 C0 为原始代价函数,λ>0 为正则化参数,求和遍历网络中所有权重。
w→w−nηλsgn(w)−η∂w∂C0
sgn 是符号函数(Sign Function)
在原始代价函数基础上添加权重惩罚项:
C=C0+2nλ∑ww2
其中 C0 为原始代价函数,λ>0 为正则化参数,求和遍历网络中所有权重。
| 参数 | 更新规则 |
|---|
| 权重 w | w→w(1−nηλ)−η∂w∂C0 |
| 偏置 b | b→b−η∂b∂C0(偏置不正则化) |
λ 越大,权重被压得越小,网络越简单。太小则正则化没效果(过拟合),太大则网络能力被压垮(欠拟合)。需要通过验证集调参找到最优的 λ。
| 特性 | L1 正则化 | L2 正则化 |
|---|
| 惩罚项 | nλ∑∣w∣ | 2nλ∑w2 |
| 梯度贡献 | nλsgn(w)(常数大小) | nλw(与 w 成正比) |
| 权重缩减方式 | 等量缩减(固定步长) | 等比缩减(按比例衰减) |
| 结果特征 | 产生稀疏权重(许多权重为 0) | 权重普遍较小但不为 0 |
| 适用场景 | 特征选择 | 防止过拟合(通用) |
训练时,每次前向传播随机 "关掉" 一部分隐藏层神经元,让它们的输出变为 0。被关掉的神经元这一轮不参与计算,也不更新权重。强迫网络中的每个神经元都独立学到有用的特征,而不是依赖特定的搭配。效果相当于同时训练了大量不同的子网络,最终取平均,显著减轻过拟合
- 训练时,以概率 p 随机将隐藏层神经元的输出置零
- 输入层和输出层保持不变
- 测试时,使用所有神经元但将权重乘以 (1−p) 进行缩放
Dropout 的直觉理解
- 相当于训练了指数级数量的"瘦"网络的集成(Ensemble)
- 每个神经元不能依赖于特定其他神经元的存在,必须学习更鲁棒的特征
- 减少神经元之间的"共适应"(co-adaptation)
六、数据增强
通过对已有训练数据进行变换来扩充数据集,是对抗过拟合的有效手段。
| 方法 | 描述 |
|---|
| 平移(Translation) | 将图像在水平或垂直方向偏移若干像素 |
| 旋转(Rotation) | 将图像按一定角度旋转(如 ±15°) |
| 镜像翻转(Flip) | 水平或垂直翻转图像 |
| 弹性形变(Elastic Deformation) | 对图像施加随机弹性变换,模拟手写变体 |
数据增强能有效增加训练数据的多样性,提升模型的泛化能力。实验表明,使用弹性形变增强后的手写数字识别准确率显著提升。
关键原则:增强变换应模拟真实世界中可能出现的数据变体,同时保持标签不变。
七、权重初始化
创建网络后,在开始训练之前需要给权重和偏置设定初始值。初始化方式直接影响训练能否顺利开始以及收敛速度。
使用标准正态分布 N(0,1) 初始化所有权重时:
- 加权输入 z=∑jwjxj+b 的标准差为 nin+1(nin 为输入连接数)
- 当 nin 较大时,∣ z∣ 很大时,σ(z) 接近 0 或 1(饱和)
- 饱和导致 σ′(z)≈0,学习极其缓慢
改进方案:使用 N(0,1/nin) 初始化权重
此时 z 的标准差约为 3/2≈1.22(假设偏置用 N(0,1)),神经元不再轻易饱和。
标准初始化 N(0,1)
- 初始时大量神经元饱和
- 学习起步极慢
- 需要更多 epoch 才能收敛
改进初始化 N(0,1/nin)
- 初始时神经元处于非饱和区
- 学习从一开始就很快
- 更快收敛到更好的结果
八、数据预处理
良好的数据预处理可以显著加速训练并提升模型性能。
x^=x−xˉ
将每个特征减去其在训练集上的均值,使数据以零为中心。
x^=σx−μ
进一步除以标准差,使每个特征的方差为 1。预处理后数据满足:均值为 0,方差为 1。
白化将数据去相关化,使协方差矩阵变为单位矩阵:
y=Wx
ZCA 白化的变换矩阵为:
WZCA=Σ−1/2
其中 Σ 为数据的协方差矩阵。
| 预处理方法 | 效果 | 适用场景 |
|---|
| 均值减法 | 中心化(均值=0) | 几乎所有情况 |
| 均一化 | 中心化 + 等方差 | 特征尺度差异大时 |
| ZCA 白化 | 去相关 + 等方差 | 特征间相关性强时 |
九、其他优化算法
利用代价函数的二阶泰勒展开来优化:
C(w+Δw)≈C(w)+∇C⋅Δw+21ΔwTHΔw
其中 H 为 Hessian 矩阵(二阶偏导矩阵),Hij=∂wi∂wj∂2C
令梯度为零,求得最优步长:
Δw=−H−1∇C
Hessian 方法的优缺点
- 优点:收敛速度快,不需要手动调节学习率
- 缺点:Hessian 矩阵计算和存储成本极高(O(n2) 存储,O(n3) 求逆),实际中常用近似方法
引入"速度"变量 v,模拟物理中的动量效应:
v→μv−η∇C
w→w+v
其中 μ∈[0,1) 为动量系数(通常取 0.9),η 为学习率
| 特性 | 标准梯度下降 | 动量梯度下降 |
|---|
| 更新规则 | w→w−η∇C | v→μv−η∇C,w→w+v |
| 梯度噪声 | 容易震荡 | 平滑梯度方向 |
| 平坦区域 | 缓慢通过 | 积累速度快速通过 |
| 收敛速度 | 较慢 | 更快 |
十、其他激活函数
定义:
tanh(z)=ez+e−zez−e−z
与 Sigmoid 的关系:
σ(z)=21+tanh(z/2)
| 特性 | Sigmoid σ(z) | tanh(z) |
|---|
| 输出范围 | (0,1) | (−1,1) |
| 零中心 | 否(输出总为正) | 是(零中心输出) |
| 饱和问题 | 存在 | 存在(但零中心有助于训练) |
| 典型应用 | 输出层(二分类概率) | 隐藏层 |
定义:
ReLU(z)=max(0,z)
ReLU 的优势
- 无饱和问题(正区间梯度恒为 1)
- 计算高效(仅需比较和取零操作)
- 稀疏激活(负输入直接输出零,天然正则化效果)
- 收敛速度通常比 Sigmoid/tanh 快 6 倍
ReLU 的潜在问题:Dead ReLU
当某个神经元的输入始终为负时,该神经元永远输出 0,梯度也为 0,永远无法恢复。解决方案:使用 Leaky ReLU max(0.01z,z) 或适当的学习率。
| 函数 | 公式 | 范围 | 零中心 | 主要问题 |
|---|
| Sigmoid | 1+e−z1 | (0,1) | 否 | 饱和、非零中心 |
| tanh | ez+e−zez−e−z | (-1,1) | 是 | 饱和 |
| ReLU | max(0,z) | [0,+∞) | 否 | Dead ReLU |
- 交叉熵:C=−n1∑[ylna+(1−y)ln(1−a)],梯度:∂wj∂C=n1∑xj(σ(z)−y)
- Softmax:ajL=ezjL/∑kezkL,对数似然:C=−lnayL
- L2 正则化:C=C0+2nλ∑w2,更新:w→w(1−nηλ)−η∂w∂C0
- L1 正则化:C=C0+nλ∑∣w∣,更新:w→w−nηλsgn(w)−η∂w∂C0
- 改进初始化:w∼N(0,1/nin)
- 动量:v→μv−η∇C,w→w+v