深度学习笔记-4:梯度下降、反向传播与正则化 - MuxiaoWF跳到主要内容

深度学习笔记-4:梯度下降、反向传播与正则化

深度学习笔记-4,涵盖梯度下降、反向传播与正则化。对应《深度学习:基础与概念》第7-9章。

周一 9月 01 2025
13672 字 · 50 分钟

系列第 4/8 篇 ← 上一篇 | 下一篇 | 术语表

建议先看第1-3篇,尤其是第1篇的误差函数和正则化概念。本篇讲神经网络怎么训练(梯度下降+反向传播),以及怎么防过拟合(正则化)。

Chapter 7 梯度下降

直觉先行——想象你站在一座大山上,四周全是浓雾,什么也看不见。 你想下到山谷(误差最小的地方),怎么办?你用脚感受脚下的坡度——哪边低就往哪边迈一步。反复这样做,最终就能走到谷底。这就是梯度下降(Gradient Descent,一种通过沿误差下降最快的方向迭代更新参数来最小化误差的优化算法)的核心思想。

有关梯度等推荐学习:《最优化导论》 反正俺也只学会了前几章的皮毛(


误差曲面

我们的目标是找到一组参数向量 w\mathbf{w}(权重和偏置组成的向量,可以理解为网络的”旋钮”),使得误差函数 E(w)E(\mathbf{w})(衡量网络预测与真实值差距的函数)最小。可以将 E(w)E(\mathbf{w}) 想象为一个”地形图”,其中横轴是高维权重空间,纵轴是误差值。站在山上任何一个点,你都能感受到脚下的”坡度”——这就是梯度(Gradient,函数在某点处变化最快的方向和大小)。

  • 在任意点 wC\mathbf{w}_C,误差函数的梯度 E(wC)\nabla E(\mathbf{w}_C) 指向误差上升最快的方向(也就是”上坡”方向)。
  • 为了减小误差,我们应沿着梯度的反方向更新权重(也就是”下坡”): Δw=ηE(w)\Delta \mathbf{w} = -\eta \nabla E(\mathbf{w}) 其中 η>0\eta > 0学习率(Learning Rate,控制每一步走多远的超参数)。学习率就像你的”步长”——太大会跨过谷底到对面山上(发散),太小则走得太慢、还没到谷底就放弃了。

梯度下降

局部最小值(wA)、全局最小值(wB)、梯度方向(∇E)如何引导更新方向

当梯度为零(E(w)=0\nabla E(\mathbf{w}) = 0)时,我们到达了驻点(Stationary Point,梯度为零的点),可能是局部最小、最大或鞍点(Saddle Point,某个方向是最小、另一个方向是最大的点,形状像马鞍)。理想情况下,我们希望找到全局最小值,但实际中常满足于一个良好的局部最小。


局部二次近似

点击展开:局部二次近似的数学推导(进阶内容)

为了深入理解优化过程,可在某点 w^\hat{\mathbf{w}} 附近对误差函数进行泰勒展开(Taylor Expansion,用多项式近似复杂函数的方法),保留至二次项:

E(w)E(w^)+(ww^)Tb+12(ww^)TH(ww^)E(\mathbf{w}) \approx E(\hat{\mathbf{w}}) + (\mathbf{w} - \hat{\mathbf{w}})^T \mathbf{b} + \frac{1}{2} (\mathbf{w} - \hat{\mathbf{w}})^T \mathbf{H} (\mathbf{w} - \hat{\mathbf{w}})

其中 b=Ew=w^\mathbf{b} = \nabla E|_{\mathbf{w}=\hat{\mathbf{w}}} 是梯度,H\mathbf{H}Hessian 矩阵(Hessian Matrix,由误差函数对所有参数的二阶偏导数组成的方阵,描述误差曲面的局部弯曲程度)。

w^=w\hat{\mathbf{w}} = \mathbf{w}_* 是一个极小值点,则梯度 b=0\mathbf{b} = 0,近似变为:

E(w)E(w)+12(ww)TH(ww)E(\mathbf{w}) \approx E(\mathbf{w}_*) + \frac{1}{2} (\mathbf{w} - \mathbf{w}_*)^T \mathbf{H} (\mathbf{w} - \mathbf{w}_*)

Hessian 的特征向量 ui\mathbf{u}_i 构成正交基。令 αi\alpha_i(ww)(\mathbf{w} - \mathbf{w}_*)ui\mathbf{u}_i 方向的分量,则:

E(w)E(w)+12iλiαi2E(\mathbf{w}) \approx E(\mathbf{w}_*) + \frac{1}{2} \sum_i \lambda_i \alpha_i^2

其中 λi\lambda_i 是 Hessian 的特征值(Eigenvalue,矩阵沿特定方向的缩放因子)。

  • 若所有 λi>0\lambda_i > 0,则 w\mathbf{w}_* 是局部极小值。
  • 若所有 λi<0\lambda_i < 0,则是局部极大值。
  • 若有正有负,则是鞍点。

Hessian 正定(所有 λi>0\lambda_i > 0)是局部极小值的充要条件。

二次近似

在极小值附近,等误差线为椭圆,主轴由Hessian特征向量决定


梯度下降优化

由于神经网络的误差函数极其复杂(参数量动辄百万级),无法直接解方程 E(w)=0\nabla E(\mathbf{w}) = 0,必须采用迭代数值方法(Iterative Numerical Method,通过反复更新参数逐步逼近最优解的方法)。

通用迭代公式:

w(τ)=w(τ1)+Δw(τ1)下一个等于上一个+变化量\mathbf{w}^{(\tau)} = \mathbf{w}^{(\tau-1)} + \Delta \mathbf{w}^{(\tau-1)} \quad \text{下一个等于上一个+变化量…}

其中 τ\tau 表示迭代步数(Iteration,每更新一次参数算一步)。


梯度信息的利用

梯度信息能显著提升优化效率。原因如下:

  • 不使用梯度:需 O(W2)O(W^2) 次函数评估(WW 为参数数),每次评估 O(W)O(W),总代价 O(W3)O(W^3)
  • 使用梯度:每次梯度评估提供 WW 个信息,理论上 O(W)O(W) 次评估即可定位最小值。结合高效的反向传播(O(W)O(W) ),总代价降至 O(W2)O(W^2)

因此,梯度是训练神经网络的基础。


批梯度下降(最速下降)

最简单的梯度下降形式,使用整个训练集计算梯度:

w(τ)=w(τ1)ηE(w(τ1))\mathbf{w}^{(\tau)} = \mathbf{w}^{(\tau-1)} - \eta \nabla E(\mathbf{w}^{(\tau-1)})

其中 E(w)=n=1NEn(w)E(\mathbf{w}) = \sum_{n=1}^N E_n(\mathbf{w}) 是全数据集的误差。每次更新需遍历全部数据,计算开销大。


随机梯度下降(SGD)

直觉:批梯度下降就像要调查全国人的平均身高——你得问遍每个人,太慢了。随机梯度下降(Stochastic Gradient Descent,每次只随机抽取一个样本来估计梯度)则像随机抽样调查——虽然每次估计没那么准,但快得多,多抽几次总体趋势是对的。

为解决批梯度下降的低效问题,SGD 每次仅用一个数据点(随机)更新:

w(τ)=w(τ1)ηEn(w(τ1))\mathbf{w}^{(\tau)} = \mathbf{w}^{(\tau-1)} - \eta \nabla E_n(\mathbf{w}^{(\tau-1)})

算法步骤:

  1. 设置当前数据点索引 n1n \leftarrow 1
  2. 重复以下过程直到收敛:
    • 更新权重向量: wwηEn(w)w \leftarrow w - \eta \nabla E_n(w) (即:用当前数据点的梯度反方向更新权重)
    • 更新数据点索引: nn+1(modN)n \leftarrow n + 1 \pmod{N} (即:遍历所有数据点,循环使用。modNmod{N}表示取余数,当索引 n 达到数据集大小 N 时,通过取模运算将其重置为 0)
  3. 返回最终的权重向量 ww

优点:

  • 计算效率高,适合大规模数据。
  • 梯度噪声有助于逃离局部极小和鞍点。
  • 对数据冗余不敏感(如数据重复,SGD 不受影响)。

缺点:梯度估计方差大,更新路径震荡。


小批量

SGD 与批梯度的折中方案:每次使用一个小批量(Mini-Batch,一小批数据样本,比如32或64个)计算梯度。

  • 梯度估计更稳定(方差与 1/B1/\sqrt{B} 成正比,BB 为批量大小)。
  • 可高效利用硬件并行计算(如GPU)。
  • 推荐批量大小为 2 的幂(如 32, 64, 128)以优化内存访问。

算法步骤:

  1. 设置当前数据点起始索引 n1n \leftarrow 1
  2. 重复以下过程直到收敛:
    • 更新权重向量: 使用当前小批量的数据计算梯度,并更新权重: wwηEn:n+B1(w)w \leftarrow w - \eta \nabla E_{n:n+B-1}(w) (即:用当前小批量的平均梯度来更新模型参数)
    • 移动到下一个小批量: nn+Bn \leftarrow n + B 从索引 n 开始的 B 个样本
  3. 如果已遍历完所有数据:
    • 打乱训练数据顺序,防止样本间的相关性影响收敛
    • 重置起始索引:n1n \leftarrow 1
  4. 继续循环
  5. 返回最终的权重向量 ww

关键:每次迭代前应随机打乱数据,避免样本间的相关性影响收敛。


参数初始化

  • 对称性破坏(Symmetry Breaking):若所有权重初始化为相同值(如0),则对称性导致隐藏单元学习相同特征,成为冗余。因此需随机初始化。
  • 常用分布:均匀分布 [ϵ,ϵ][-\epsilon, \epsilon] 或高斯分布 N(0,σ2)\mathcal{N}(0, \sigma^2)
  • He 初始化:针对 ReLU(Rectified Linear Unit,一种激活函数,定义为 f(x)=max(0,x)f(x)=\max(0,x))激活函数,推荐 ϵ=2/M\epsilon = \sqrt{2/M},其中 MM 是前一层神经元数。这能保持信号在层间传播时的方差稳定。
  • 偏置初始化:通常设为小正数(如0.1),尤其对 ReLU,可确保初始激活非零,便于梯度流动。

收敛性分析

山谷问题:

当误差曲面在不同方向曲率差异巨大时(如“山谷”形),标准梯度下降效率低下:

  • 学习率 η\eta 太小:沿谷底方向收敛极慢。
  • η\eta 太大:在谷壁间震荡,甚至发散。

山谷问题

山谷问题


动量

直觉:想象一个球从山上滚下来。普通的梯度下降像一个没有惯性的点——每一步只看当前坡度。而动量(Momentum,利用历史更新方向的”惯性”来加速收敛的技术)就像给球加上了惯性——即使遇到小坑小包,球也能借着惯性冲过去,而在真正平坦的谷底才会停下来。

为加速收敛并抑制震荡,引入动量项:

Δw(τ1)=ηE(w(τ1))+μΔw(τ2)\Delta \mathbf{w}^{(\tau-1)} = -\eta \nabla E(\mathbf{w}^{(\tau-1)}) + \mu \Delta \mathbf{w}^{(\tau-2)} w(τ)=w(τ1)+Δw(τ1)\mathbf{w}^{(\tau)} = \mathbf{w}^{(\tau-1)} + \Delta \mathbf{w}^{(\tau-1)}

其中 μ\mu 是动量系数(0μ<10 \leq \mu < 1,通常取 0.9)。μΔw(τ2)\mu \Delta \mathbf{w}^{(\tau-2)}保留了之前更新方向的”惯性”

学习率将从η\eta提高到η/(1μ)\eta/(1-\mu)

  • 低曲率方向:梯度方向稳定,动量累积,等效学习率增大,加速前进。
  • 高曲率方向:梯度方向频繁变化,动量项相互抵消,等效学习率接近 η\eta,抑制震荡。

动量类似于物理中的惯性,使更新更平滑,收敛更快。

动量效果

动量帮助更快穿越山谷

Nesterov 动量: 改进的动量方法:先根据历史动量“预走”一步,再计算该位置的梯度。

  • 更及时地修正方向,减少超调。
  • 理论收敛速度更快,在实践中常优于标准动量。

自适应学习率算法

直觉:前面的算法对所有参数用同一个学习率,但不同参数可能需要不同的步长——有的参数已经接近最优,需要小步慢走;有的还差得远,需要大步前进。自适应学习率算法的核心思想就是”因材施教”——给每个参数自动分配合适的学习率。

AdaGrad

AdaGrad(Adaptive Gradient,自适应梯度算法)为每个参数维护一个独立的累计平方梯度:

ri(τ)=ri(τ1)+(E(w)wi)2r_i^{(\tau)} = r_i^{(\tau-1)} + \left( \frac{\partial E(\mathbf{w})}{\partial w_i} \right)^2

对于第ii个参数wiw_i,维护一个rir_i值,它记录了该参数历史上所有梯度的平方和。

学习率调整为:

Δwi(τ)=Δwi(τ1)ηriτ+δ(E(w)wi)\Delta w_i^{(\tau)} =\Delta w_i^{(\tau-1)} - \frac{\eta}{\sqrt{r_i^\tau} + \delta}(\frac{\partial E(\mathbf{w})}{\partial w_i})

其中 δ\delta 是小常数,防止除零。

  • 对于经常更新(梯度较大)的参数:rir_i值增长快,学习率ηri\frac{\eta}{\sqrt{r_i}}下降快,更新步长变小
  • 对于很少更新(梯度较小)的参数:rir_i值增长慢,学习率保持相对较大,更新步长较大

缺点rir_i 持续累积,导致学习率单调下降,后期训练几乎停滞。


RMSProp

RMSProp(Root Mean Square Propagation,均方根传播算法)改进了 AdaGrad,使用指数加权移动平均(Exponential Moving Average,近期数据权重更大、远期数据逐渐”遗忘”的平均方法)计算梯度平方:

r(τ)=βr(τ1)+(1β)(E(w)w)2\mathbf{r}^{(\tau)} = \beta \mathbf{r}^{(\tau-1)} + (1 - \beta) (\frac{\partial E(\mathbf{w})}{\partial \mathbf{w}})^2

其中 β\beta(衰减率,decay rate,取值 0~1,通常取 0.9)控制”遗忘”速度——β\beta 越大,越依赖历史梯度;β\beta 越小,越看重当前梯度。

更新公式:

w(τ)=w(τ1)ηrτ+δ(E(w)w)2\mathbf{w}^{(\tau)} =\mathbf{w}^{(\tau-1)} - \frac{\eta}{\sqrt{\mathbf{r}^\tau} + \delta} (\frac{\partial E(\mathbf{w})}{\partial \mathbf{w}})^2
  • 如果某个参数一直变化很大(梯度大)→ r 值大 → 学习率变小 → 更新步长变小
  • 如果某个参数很少变化(梯度小)→ r 值小 → 学习率较大 → 更新步长较大 能“忘记”早期梯度,避免学习率过早衰减。一直记住之前所有走过的路,越走越小心,步伐越来越小

Adam

直觉Adam(Adaptive Moment Estimation,自适应矩估计)就像一个”聪明的登山者”——它既记住了之前走的方向(动量/一阶矩),又观察了脚下地形的起伏程度(自适应学习率/二阶矩),根据路况自动调整步幅。它是目前最常用的优化器,几乎没有之一。

结合动量与 RMSProp,其中 β1\beta_1β2\beta_2 分别是一阶矩和二阶矩的衰减率(通常取 β1=0.9\beta_1 = 0.9β2=0.999\beta_2 = 0.999):

一阶矩(动量 - 记住梯度的方向趋势):s(τ)=β1s(τ1)+(1β1)E(w)w\mathbf{s}^{(\tau)} = \beta_1 \mathbf{s}^{(\tau-1)} + (1 - \beta_1) \frac{\partial E(\mathbf{w})}{\partial \mathbf{w}}

二阶矩 - 记住梯度的大小变化:r(τ)=β2r(τ1)+(1β2)(E(w)w)2\mathbf{r}^{(\tau)} = \beta_2 \mathbf{r}^{(\tau-1)} + (1 - \beta_2)(\frac{\partial E(\mathbf{w})}{\partial \mathbf{w}})^2

偏差校正:刚开始时,因为初始化为0,所以前几次的估计不太准,需要校正:

s^(τ)=s(τ)1β1τr^(τ)=r(τ)1β2τ\hat{\mathbf{s}}^{(\tau)} = \frac{\mathbf{s}^{(\tau)}}{1-\beta_1^\tau} \quad \hat{\mathbf{r}}^{(\tau)} = \frac{\mathbf{r}^{(\tau)}}{1-\beta_2^\tau}

最终更新公式:

w(τ)=w(τ1)ηs^(τ)r^(τ)+δ\mathbf{w}^{(\tau)} = \mathbf{w}^{(\tau-1)} - \eta \frac{\hat{\mathbf{s}}^{(\tau)}}{\sqrt{\hat{\mathbf{r}}^{(\tau)}} + \delta}
  • s^(τ)\hat{\mathbf{s}}^{(\tau)}:告诉我们往哪个方向走(动量)
  • r^(τ)\sqrt{\hat{\mathbf{r}}^{(\tau)}}:告诉我们每个参数应该用多大的步长(自适应学习率)

归一化技术

直觉:想象一条流水线,每个工位(层)的零件(数据)尺寸差异很大——有的巨大有的微小,工人很难处理。批归一化(Batch Normalization,对每个小批量的数据进行标准化处理)就像在每个工位前加了一个”标准化机器”,把零件尺寸统一到合理范围内,这样工人(网络)就能高效工作了。

批归一化

对每个 mini-batch 的每个特征进行归一化(减均值、除标准差),再通过可学习参数 γ,β\gamma, \beta(缩放和平移参数,让网络自己决定最佳的数据范围)进行缩放和平移。

优点:

  • 减少内部协变量偏移(Internal Covariate Shift,网络各层输入分布随训练不断变化的现象)。
  • 允许更大学习率,加速收敛。
  • 有一定正则化效果。

层归一化

层归一化(Layer Normalization)对单个样本在所有特征上进行归一化,不依赖 batch,适用于 RNN(循环神经网络)和 Transformer(一种基于注意力机制的架构)。

归一化

左侧为批归一化,右侧为层归一化。

习题1

训练网络的时候发现 loss 前 100 轮嗖嗖降,之后就不动了。怎么回事?

原因挺多的,常见的几个:

  • 学习率太大,在谷底来回蹦跶就是不下去;或者太小,走得太慢以为不动了
  • 模型容量不够,已经”尽力了”——再怎么训也就这水平
  • 已经过拟合了:训练集 loss 低但验证集 loss 高,说明模型在”背答案”而不是”学规律”
  • 数据本身有噪声或者标签有问题,模型学不下去了

如果把全批量换成小批量(batch size=32),损失曲线看起来会有什么不同?

曲线会变得”毛躁”一些——因为每次更新只看了 32 个样本,梯度估计有噪声。但这个噪声其实有好处:不容易卡在局部极小值里,而且每步计算快很多,总体上反而可能更快收敛。


第7章小结

一句话版本:梯度下降就是”下山”——沿着最陡的方向走;SGD是”抽样估计”——每次只看几个点来决定方向;动量是”球滚下坡”——借惯性冲过小坑;Adam是”聪明登山者”——自动调整步幅;归一化是”标准化流水线”——让数据保持合理范围。

知识地图

梯度下降优化
├── 基础:误差曲面 → 梯度指向上坡 → 反方向下坡
├── 数据策略
│ ├── 批梯度下降:用全部数据(慢但准)
│ ├── SGD:用单个样本(快但噪声大)
│ └── 小批量:折中方案(实践中最常用)
├── 解决震荡 → 动量(惯性加速)
├── 解决学习率选择 → 自适应算法
│ ├── AdaGrad:累计梯度平方(会衰减到零)
│ ├── RMSProp:指数移动平均(能"遗忘")
│ └── Adam:动量+自适应(默认首选)
├── 归一化技术
│ ├── 批归一化:跨样本标准化
│ └── 层归一化:单样本内标准化
└── 参数初始化 → He初始化、对称性破坏

Chapter 8 反向传播

梯度的计算

直觉先行:想象一个工厂流水线,最终产品出了质量问题。你需要追溯责任——是哪个环节的工人(参数)导致了问题?反向传播(Backpropagation,一种高效计算神经网络中每个参数对误差贡献大小的算法)就是从最终误差出发,沿着网络反向逐层追溯,算出每个参数”该负多少责任”。本质上,它是链式法则(Chain Rule,复合函数求导法则)的系统化应用。

神经网络的训练通常涉及最小化一个误差函数 E(w)E(\mathbf{w}),其中 w\mathbf{w} 代表网络的所有权重和偏置参数。最常用的方法是基于梯度的优化算法(如梯度下降),因此高效准确地计算梯度 wE\nabla_{\mathbf{w}} E 至关重要。

前向传播与反向传播

反向传播算法的核心思想是利用一个局部消息传递(Local Message Passing,每个节点只需与相邻节点交换信息)方案,将误差信息从网络的输出端反向传递回输入端。

  1. 前向传播(Forward Propagation,数据从输入层逐层流向输出层的过程):

    • 输入数据 xn\mathbf{x}_n 通过网络,逐层计算每个单元的激活值 aja_j(神经元接收到的加权输入总和)和输出值 zjz_j(经过激活函数处理后的最终输出)。
    • 对于第 jj 个单元,其激活 aja_j 是其所有输入 ziz_i 的加权和:aj=iwjizia_j = \sum_i w_{ji} z_i
    • 然后应用激活函数 h()h(\cdot)(Activation Function,引入非线性变换的函数,如sigmoid、ReLU等)得到输出:zj=h(aj)z_j = h(a_j)
    • 最终得到网络的输出 y\mathbf{y},并计算误差函数 EE(通常针对单个数据点 nn,记为 EnE_n)。
  2. 反向传播(Backward Propagation,误差信息从输出层反向逐层传递的过程):

    • 从输出层开始,计算每个单元对误差的”敏感度”或”误差项” δj\delta_j(即误差对该单元激活值的偏导数,衡量该单元对最终误差的”责任”有多大)。
    • 对于输出单元 kkδk\delta_k 定义为误差函数 EnE_n 对该单元激活 aka_k偏导数(Partial Derivative,只改变一个变量、其他变量固定时的导数): δk=Enak\delta_k = \frac{\partial E_n}{\partial a_k} 例如,对于均方误差 En=12k(yktk)2E_n = \frac{1}{2} \sum_k (y_k - t_k)^2,有 δk=(yktk)h(ak)\delta_k = (y_k - t_k) h'(a_k)
    • 对于隐藏单元 jj,其误差项通过链式法则从后续层的误差项计算: δj=Enaj=kEnakakaj=kEnakakzjzjaj=kEnakwkjh(aj)=h(aj)kwkjδk\begin{align} \delta_j = \frac{\partial E_n}{\partial a_j} = \sum_k \frac{\partial E_n}{\partial a_k} \cdot \frac{\partial a_k}{\partial a_j}=\sum_k \frac{\partial E_n}{\partial a_k} \cdot \frac{\partial a_k}{\partial z_j} \cdot \frac{\partial z_j}{\partial a_j}\\ =\sum_k \frac{\partial E_n}{\partial a_k} \cdot w_{kj} \cdot h'(a_j) = h'(a_j) \sum_k w_{kj} \delta_k \end{align} 这个公式表明,隐藏单元的误差是其输出端所有连接权重与下游误差项乘积之和,再乘以其激活函数的导数。
      • kwkjδk\sum_k w_{kj} \delta_k:单元 jj 对最终误差的”贡献”等于它对所有下层单元的影响加权和
      • wkjw_{kj}:单元 jj 对单元 kk 的影响权重
      • δk\delta_k:单元 kk 对误差的敏感度
      • 乘积 wkjδkw_{kj} \delta_k:通过连接 jkj \rightarrow k 传递的误差
      • h(aj)h'(a_j):激活函数对误差传播的调节作用
      • 如果激活函数在该点变化平缓(导数小),则误差传播减弱;如果激活函数在该点变化剧烈(导数大),则误差传播增强
  3. 梯度计算

    • 一旦计算出所有单元的 δj\delta_j,就可以直接计算误差函数 EnE_n 对任意权重 wjiw_{ji} 的偏导数: Enwji=δjzi\frac{\partial E_n}{\partial w_{ji}} = \delta_j z_i 这个结果非常简洁:梯度等于目标权重输出端的误差项 δj\delta_j 乘以其输入端的激活值 ziz_i

反向传播算法可以总结为以下步骤(针对单个数据点 nn):

  1. 前向传播:计算所有单元的激活 aja_j 和输出 zjz_j
  2. 计算输出误差:对每个输出单元 kk,计算 δk=En/ak\delta_k = \partial E_n / \partial a_k
  3. 反向传播误差:按层从后向前,对每个隐藏单元 jj,计算 δj=h(aj)kwkjδk\delta_j = h'(a_j) \sum_k w_{kj} \delta_k
  4. 计算梯度:对每个权重 wjiw_{ji},计算 En/wji=δjzi\partial E_n / \partial w_{ji} = \delta_j z_i

对于批量或小批量训练,总误差 EE 的梯度是该批次中所有数据点梯度的和:

Ewji=nbatchEnwji\frac{\partial E}{\partial w_{ji}} = \sum_{n \in \text{batch}} \frac{\partial E_n}{\partial w_{ji}}

一个简单的例子

为了具体说明反向传播算法,考虑一个标准的两层前馈网络(一个隐藏层,一个输出层),并使用平方和误差函数

网络结构与符号:

  • 输入层:DD 个输入单元 xix_ii=0,1,...,D1i=0, 1, ..., D-1),其中 x0=1x_0 = 1 为偏置项。
  • 隐藏层:MM 个隐藏单元 zjz_jj=1,2,...,Mj=1, 2, ..., M)。
  • 输出层:KK 个输出单元 yky_kk=1,2,...,Kk=1, 2, ..., K)。

使用上标 (1)(1)(2)(2) 区分两层的权重:

  • wji(1)w_{ji}^{(1)}:从输入单元 ii 到隐藏单元 jj 的权重。(上标 1 = 第1层,下标 ji = 从 i 到 j)
  • wkj(2)w_{kj}^{(2)}:从隐藏单元 jj 到输出单元 kk 的权重。(上标 2 = 第2层,下标 kj = 从 j 到 k)

读符号的窍门:下标总是”从哪来→到哪去”,上标是”第几层”。比如 wkj(2)w_{kj}^{(2)} 就是”第2层里,从 j 到 k 的权重”。

前向传播计算

对于一个训练样本 nn

  1. 计算隐藏层的加权输入: aj=i=0D1wji(1)xi(j=1,...,M)a_j = \sum_{i=0}^{D-1} w_{ji}^{(1)} x_i \quad (j=1,...,M)
  2. 计算隐藏层的激活输出: 使用双曲正切(tanh)作为激活函数: zj=tanh(aj)z_j = \tanh(a_j) 其导数有简洁形式:zj=1zj2z_j' = 1 - z_j^2
  3. 计算输出层的加权输入: ak=j=0Mwkj(2)zj(k=1,...,K)a_k = \sum_{j=0}^{M} w_{kj}^{(2)} z_j \quad (k=1,...,K) (注意:z0=1z_0 = 1 是隐藏层的偏置)
  4. 计算输出层的激活输出: 使用线性激活函数(即恒等函数): yk=aky_k = a_k 其导数为 1。
  5. 计算误差: 使用平方和误差: En=12k=1K(yktk)2E_n = \frac{1}{2} \sum_{k=1}^K (y_k - t_k)^2

反向传播计算(计算梯度)

  1. 计算输出层的误差项 δk\delta_k: 因为输出层激活函数是线性的,h(ak)=1h'(a_k) = 1δk=(yktk)1=yktk公式来源见上\delta_k = (y_k - t_k) \cdot 1 = y_k - t_k \quad \text{公式来源见上}
  2. 计算隐藏层的误差项 δj\delta_j: 根据反向传播公式: δj=h(aj)kwkj(2)δk\delta_j = h'(a_j) \sum_k w_{kj}^{(2)} \delta_k 代入 h(aj)=1tanh2(aj)=1zj2h'(a_j) = 1 - \tanh^2(a_j) = 1 - z_j^2δj=(1zj2)k=1Kwkj(2)δk\delta_j = (1 - z_j^2) \sum_{k=1}^K w_{kj}^{(2)} \delta_k
  3. 计算权重梯度:
  • 第二层权重 wkj(2)w_{kj}^{(2)} 的梯度

    Enwkj(2)=δkzj\frac{\partial E_n}{\partial w_{kj}^{(2)}} = \delta_k \cdot z_j
  • 第一层权重 wji(1)w_{ji}^{(1)} 的梯度

    Enwji(1)=δjxi\frac{\partial E_n}{\partial w_{ji}^{(1)}} = \delta_j \cdot x_i
  • 复杂度:

    • 一次前向传播的计算量大致为 O(W)O(W),其中 WW 是网络中权重的总数。
    • 一次反向传播的计算量也大致为 O(W)O(W)
    • 因此,计算所有 WW 个梯度的总代价是 O(W)O(W)

因此,反向传播提供了一种计算上可行的方法来训练大型神经网络。


雅可比矩阵

点击展开:雅可比矩阵与数值微分验证(进阶内容)

雅可比矩阵(Jacobian Matrix,描述网络输出相对于输入的变化率的矩阵)适用于需要分析输入变化如何影响输出的场景。考虑一个有 DD 个输入 xix_iKK 个输出 yky_k 的神经网络。

雅可比矩阵 J\mathbf{J} 是一个 K×DK \times D 的矩阵,其第 kk 行、第 ii 列的元素是:

Jki=ykxiJ_{ki} = \frac{\partial y_k}{\partial x_i}

也就是kk 个输出对第 ii 个输入的偏导数

物理意义:雅可比矩阵告诉我们,当输入发生一个微小变化时,网络的输出会如何变化。它衡量了网络的”灵敏度”或”稳定性”。


计算雅可比矩阵同样可以利用类似反向传播的高效算法。

  1. 前向传播:
  • 应用输入向量 x\mathbf{x},进行标准的前向传播,计算出所有隐藏层和输出层的激活值 aja_jzjz_j
  1. 对于雅可比矩阵的每一行 kk(对应一个输出 yky_k):
  • 初始化:将输出层第 kk 个单元的”误差项”设为 1,其余输出单元设为 0。这对应于 δk(out)=yk/ak\delta_k^{(out)} = \partial y_k / \partial a_k
    • 如果输出层是线性激活,δk(out)=1\delta_k^{(out)} = 1
    • 如果是 Sigmoid,δk(out)=yk(1yk)\delta_k^{(out)} = y_k(1-y_k)
  • 反向传播:使用与标准反向传播相同的递归公式: δj=h(aj)kwkjδk\delta_j = h'(a_j) \sum_k w_{kj} \delta_k 将这个”误差”从输出层反向传播回所有隐藏层单元,直到输入层。
  • 当反向传播到输入层时,对于第 ii 个输入 xix_i,其对应的”梯度”就是雅可比矩阵的第 kk 行、第 ii 列元素: ykxi=δi(input)1=δi(input)\frac{\partial y_k}{\partial x_i} = \delta_i^{\text{(input)}} \cdot 1 = \delta_i^{\text{(input)}} (因为输入层没有激活函数,xix_i 就是其”加权输入”)。

计算完整的 K×DK \times D 雅可比矩阵,需要进行 KK 次独立的”反向传播”过程(每次针对一个输出 yky_k ),每次的计算量约为 O(W)O(W)


数值微分验证

为了验证雅可比矩阵计算的正确性,可以使用中心差分法(Central Difference Method,一种用两侧函数值近似导数的数值方法):

ykxiyk(x+ϵei)yk(xϵei)2ϵ\frac{\partial y_k}{\partial x_i} \approx \frac{y_k(\mathbf{x} + \epsilon \mathbf{e}_i) - y_k(\mathbf{x} - \epsilon \mathbf{e}_i)}{2\epsilon}

其中 ei\mathbf{e}_i 是第 ii 个分量为 1 的单位向量。

计算整个雅可比矩阵需要 2D2D 次前向传播,总计算量为 O(DW)O(DW)。当 DD 很大时,这比使用反向传播的 O(KW)O(KW) 代价更高(尤其当 KDK \ll D 时,反向传播更高效)。


黑塞矩阵

点击展开:黑塞矩阵与黑塞矩阵-向量积(进阶内容)

黑塞矩阵(Hessian Matrix,误差函数关于所有权重的二阶导数组成的方阵)描述的是误差函数关于网络权重 的二阶导数。将所有的权重和偏置参数看作一个大的向量 w=(w1,w2,...,wW)T\mathbf{w} = (w_1, w_2, ..., w_W)^T,其中 WW 是总参数数量。

黑塞矩阵 H\mathbf{H} 是一个 W×WW \times W 的方阵,其第 ii 行、第 jj 列的元素是:

Hij=2EwiwjH_{ij} = \frac{\partial^2 E}{\partial w_i \partial w_j}

也就是误差函数对两个权重 wiw_iwjw_j 的二阶偏导数

物理意义:黑塞矩阵描述了误差函数曲面的局部曲率。它告诉我们梯度 E\nabla E 在权重空间中是如何变化的。正定的黑塞矩阵意味着该点是一个局部极小值。


直接计算和存储一个 W×WW \times W 的黑塞矩阵的代价是巨大的。

  • 存储空间:需要 O(W2)O(W^2) 的内存。对于一个有百万参数 (W=106W=10^6) 的网络,存储一个 101210^{12} 量级的矩阵是不现实的。
  • 计算时间:朴素方法需要 O(W2)O(W^2) 次操作。

然而,通过扩展反向传播算法,可以设计出计算效率为 O(W2)O(W^2) 的算法,这比数值微分(需要 O(W3)O(W^3))要高效得多。


黑塞矩阵-向量积

在实际应用中,我们通常不需要显式地构造整个黑塞矩阵 H\mathbf{H},而是需要计算它与某个向量 v\mathbf{v} 的乘积 Hv\mathbf{Hv}。(在很多优化算法中(如牛顿法的变种),我们需要的是黑塞矩阵与向量的乘积,而不是黑塞矩阵本身。)

这可以通过两次反向传播(或称为”前向-反向”模式)高效计算,计算量仅为 O(W)O(W),与一次梯度计算相当。

  1. 前向模式:给定方向向量 v\mathbf{v},计算前向模式下的导数 ziwv\frac{\partial z_i}{\partial \mathbf{w}} \cdot \mathbf{v}
  2. 反向模式:使用标准反向传播计算梯度 g=E(w)\mathbf{g} = \nabla E(\mathbf{w}) ,然后再次应用反向传播计算 Hv=2E(w)v\mathbf{Hv} = \nabla^2 E(\mathbf{w}) \cdot \mathbf{v}

自动微分法

反向传播是自动微分(Automatic Differentiation,一种精确计算计算机程序中任何可微函数梯度的技术,比符号微分和数值微分更强大、更高效)的一个特例。它比符号微分(推导公式)和数值微分(近似计算)更强大、更高效。

核心思想

自动微分的关键思想是将函数的计算过程分解为一系列基本的、可微的初等运算(如加、减、乘、除、指数、对数、三角函数等)。它通过跟踪这些基本运算的执行过程(通常表示为一个 计算图(Computation Graph,用节点和边表示计算步骤及其依赖关系的有向图)或计算追踪),并应用链式法则来自动构建计算梯度的代码。

自动微分有两种主要模式:(书中P213有两个例子,更好理解)

  1. 前向模式

    • 在计算函数值的同时,计算其对某个输入变量的导数。
    • 它为每个中间变量 ziz_i(称为“原变量”)引入一个额外的“切线”变量 z˙i\dot{z}_i,代表该变量对某个输入的导数。
    • 在前向传播过程中,同时计算 (zi,z˙i)(z_i, \dot{z}_i) 的元组。
    • 对于有 DD 个输入的函数,计算完整的梯度需要 DD 次前向模式计算。
  2. 逆模式

    • 反向传播所使用的模式。
    • 首先进行一次前向传播,计算所有中间变量的值 ziz_i 并将其存储。
    • 然后进行一次反向传播,为每个中间变量 ziz_i 引入一个“伴随”变量 zˉi\bar{z}_i,代表最终输出对 ziz_i 的偏导数。
    • 从输出开始,利用存储的中间值,根据链式法则反向计算每个 zˉi\bar{z}_i
    • 对于有 KK 个输出和 DD 个输入的函数,计算从所有输出到所有输入的雅可比矩阵,逆模式通常比前向模式更高效,尤其是在 K<<DK << D 时(这正是神经网络的情况,KK 是标量误差,DD 是海量参数)。

与反向传播的关系

反向传播就是逆模式自动微分应用于神经网络误差函数的具体实现。它高效地计算了标量误差 EE 相对于所有网络参数 w\mathbf{w} 的梯度 wE\nabla_{\mathbf{w}} E

现代深度学习框架(如 PyTorch, TensorFlow)的核心就是逆模式自动微分引擎。用户只需编写前向传播的代码(定义网络和损失函数),框架就能自动计算梯度,无需手动推导复杂的偏导数公式。

习题2

一个极简网络:输入 xx,隐藏层 h=ReLU(w1x+b1)h = \text{ReLU}(w_1 x + b_1),输出 y=w2h+b2y = w_2 h + b_2,损失 E=12(yt)2E = \frac{1}{2}(y - t)^2。用链式法则算一下 Ew1\frac{\partial E}{\partial w_1}

链式法则就是”一环扣一环”地乘起来:

Ew1=(yt)误差对输出w2输出对隐藏x隐藏对w1\frac{\partial E}{\partial w_1} = \underbrace{(y - t)}_{\text{误差对输出}} \cdot \underbrace{w_2}_{\text{输出对隐藏}} \cdot \underbrace{x}_{\text{隐藏对}w_1}

注意 ReLU 那里:当 w1x+b1>0w_1 x + b_1 > 0 时导数是 1,否则是 0。所以如果某个神经元”没被激活”(输入是负的),梯度就直接断了——w1w_1 收不到任何更新信号。

如果隐藏层扩到 100 个神经元,反向传播的计算量大概是前向传播的多少倍?

差不多是 1 倍。前向传播算一遍大概 200 次乘法(每个神经元 1 次权重乘法 + 输出层 100 次),反向传播也是差不多 200 次。所以反向传播的额外开销很小——这也是它能被广泛使用的原因:算梯度几乎”免费”。


第8章小结

一句话版本:反向传播 = 链式法则的系统应用。从输出误差出发,逐层往回”追溯责任”,算出每个参数的梯度,计算量和一次前向传播差不多。

知识地图

反向传播
├── 前向传播:数据 → 逐层计算激活 → 输出 → 算误差
├── 反向传播:误差 → 逐层算误差项δ → 得到梯度
│ ├── 输出层:δ = (预测-真实) × 激活函数导数
│ └── 隐藏层:δ = 激活函数导数 × 下游δ的加权和
├── 梯度公式:∂E/∂wⱼᵢ = δⱼ × zᵢ(简洁!)
├── 复杂度:O(W),和前向传播一样
└── 扩展应用
├── 雅可比矩阵:输出对输入的灵敏度
├── 黑塞矩阵:误差曲面的曲率
└── 自动微分:框架自动帮你算梯度

Chapter 9 正则化

直觉先行:还记得第1篇中那个用高次多项式拟合数据的例子吗?(见第一章 - 正则化项)多项式次数太高,曲线就疯狂扭动去穿过每个训练点——这就是过拟合(Overfitting,模型在训练数据上表现很好但在新数据上表现很差的现象)。正则化(Regularization,通过约束模型复杂度来防止过拟合的一系列技术)就像给模型套上”紧箍咒”——不让它太自由地乱扭,从而学到更平滑、更泛化的规律。

如何通过引入归纳偏置(Inductive Bias,学习算法对某种假设的偏好)来提升模型在有限训练数据下的泛化能力

在前面(第一章 - 正则化项)我们看到了正则化用于解决多项式曲线拟合中的过拟合问题。其核心思想是: 在损失函数中加入一个惩罚项,以限制模型参数的大小

正则化误差函数的形式为:

E~(w)=E(w)+λΩ(w)\tilde{E}(\mathbf{w}) = E(\mathbf{w}) + \lambda \cdot \Omega(\mathbf{w})

其中:

  • E(w)E(\mathbf{w}) 是原始误差函数(如均方误差)
  • w\mathbf{w} 是模型参数向量
  • Ω(w)\Omega(\mathbf{w})正则化项(惩罚模型复杂度的部分,如 12wTw\frac{1}{2} \mathbf{w}^T\mathbf{w}
  • λ\lambda正则化超参数(Regularization Hyperparameter,控制正则化强度的”旋钮”——越大惩罚越重,模型越简单)

正则化本质上是在偏差-方差权衡(Bias-Variance Tradeoff,模型复杂度越高偏差越低但方差越高,反之亦然)中引入一定偏差,以显著降低模型的方差,从而提升泛化性能。


归纳偏置

大多数机器学习任务是逆问题(Inverse Problem,从有限结果反推原因的问题):我们只有有限的样本数据,却要推断出整个数据分布。由于存在无限多种可能的分布都能生成这些数据,因此必须引入 偏好来选择一个特定的解。这种偏好称为归纳偏置先验知识(Prior Knowledge,在看到数据之前就有的假设)。

例如:

  • 假设输入的小变化导致输出的小变化 → 鼓励模型学习平滑函数
  • 图像识别中物体位置不影响类别 → 引入平移不变性

没有归纳偏置,就无法从数据中学习。学习本质上是利用先验知识缩小假设空间。

“没有免费的午餐”定理

在所有可能的问题上,所有学习算法的平均性能是相同的。如果某个算法在某些问题上表现更好,必然在其他问题上表现更差。

  • 深度神经网络之所以强大,是因为它们内置了适合现实世界问题的归纳偏置(如平滑性、局部性)
  • 我们追求的“通用学习算法”,实际上是寻找适用于广泛实际场景的归纳偏置
  • 对特定任务,加入更强的领域相关偏置,效果会更好

对称性与不变性

许多任务要求模型输出对输入的某些变换保持不变。例如:

  • 平移不变性:图像中物体位置改变,分类结果不变
  • 尺度不变性:物体大小改变,分类结果不变

仅靠数据学习这些不变性非常困难,因为微小的平移可能导致像素值剧烈变化,且变换组合呈指数增长。

实现不变性的四种方法:

  1. 预处理:提取对变换不变的特征(如SIFT)
  2. 正则化误差函数:惩罚输出随输入变换的变化(如切线传播)
  3. 数据增强:在训练时加入变换后的样本(如翻转、旋转图像)
  4. 网络结构设计:将不变性嵌入网络结构(如卷积神经网络)

数据增强示例

数据增强示例


上述归纳偏置的引入方式将在后续章节中具体体现:正则化项体现参数偏好,网络结构设计体现函数形式偏好,数据增强体现变换不变性偏好。

权重衰减

广义权重衰减

简单二次正则化的一般形式:

Ω(w)=λ2wjq\Omega(\mathbf{w}) = \frac{ \lambda }{2}\sum |w_j|^q

不同q值的正则化函数等值线

不同q值的正则化函数等值线

使用 q=1q=1 的广义正则化称为 L1 正则化(也叫 Lasso,对权重的绝对值求和作为惩罚项):

Ω(w)=λwj\Omega(\mathbf{w}) = \lambda \sum |w_j|

其特点是:能产生稀疏解(Sparse Solution,即很多权重被精确推到零),实现自动特征选择(不重要的特征对应的权重直接变成零,相当于被”淘汰”了)。


基本形式

最常见的正则化项是权重平方和L2 正则化,也叫 Ridge 或权重衰减,对权重的平方求和作为惩罚项):

Ω(w)=12wTw\Omega(\mathbf{w}) = \frac{1}{2} \mathbf{w}^T\mathbf{w}

对应的正则化误差函数为:

E~(w)=E(w)+λ2wTw\tilde{E}(\mathbf{w}) = E(\mathbf{w}) + \frac{\lambda}{2} \mathbf{w}^T\mathbf{w}

在梯度下降中,其梯度为:

E~(w)=E(w)+λw\nabla \tilde{E}(\mathbf{w}) = \nabla E(\mathbf{w}) + \lambda \mathbf{w}

这相当于每次更新后,权重会“衰减”一点(乘以 (1ηλ)(1 - \eta\lambda)),故称“权重衰减”。

正则化会“抑制”对误差影响小的参数,使其趋近于零。真正起作用的参数数量称为有效参数数量。随着 λ\lambda 增大,有效参数数量减少。


一致性正则化器

标准权重衰减对所有权重一视同仁,但当输入或输出进行线性变换(如归一化)时,最优权重也会相应变换。标准正则化会打破这种一致性,导致不同数据预处理方式下得到不同性能的模型。

分层正则化

对不同层的权重使用不同的正则化系数,并排除偏置项b:

Ω(w)=λ12wW1w2+λ22wW2w2\Omega(\mathbf{w}) = \frac{\lambda_1}{2} \sum_{w \in W_1} w^2 + \frac{\lambda_2}{2} \sum_{w \in W_2} w^2

其中 W1,W2W_1, W_2 分别表示第一层和第二层的权重。

分层正则化

分层正则化

a1w,a1b,a2w,a2ba_1^w, a_1^b, a_2^w, a_2^b分别代表第一层偏置、权重,第二层偏置、权重


学习曲线

学习曲线(Learning Curve,训练过程中训练集和验证集误差随迭代次数变化的图表)是诊断训练状态的重要工具:

  • 观察模型的训练进度;
  • 判断是否发生过拟合;
  • 控制模型的有效复杂度。

在典型的训练过程中,训练误差通常随着迭代次数增加而单调下降。然而,验证集(Validation Set,不参与训练、专门用来检查模型泛化能力的数据集)的误差可能先下降,然后上升,这表明模型开始过拟合训练数据。

早停法

早停法(Early Stopping,当验证集误差不再下降时就停止训练的技术)是一种控制模型有效复杂度的重要技术,尤其在深度学习中广泛应用。其基本思想是:

在验证集误差达到最小值时停止训练,而不是等到训练误差完全收敛。

  • 当训练刚开始时,模型复杂度较低(例如权重接近初始值,如零)。
  • 随着训练进行,模型逐渐拟合训练数据,权重不断更新,模型的“有效复杂度”逐步增加。
  • 如果继续训练,模型会过度拟合训练数据,导致验证误差上升。

因此,早停相当于限制了模型的有效参数数量或有效复杂度,从而防止过拟合。

对于二次误差函数,早停与 L2 正则化(即权重衰减)有相似的效果:

  • 假设权重从原点开始,沿着负梯度方向更新。
  • 由于 Hessian 矩阵的特征值差异较大,权重路径会先沿着曲率较小的方向快速下降,再慢慢逼近全局最小值。
  • 如果在某个中间点停止,得到的权重向量 ŵ 与使用 L2 正则化得到的结果类似。

早停法与L2

早停法与L2

ww^* 表示对应于未正则化误差函数最小值的最大似然解。如果权重向量从原点开始,并根据局部负梯度方向移动,那么权重向量将沿着图中所示的路径前进。通过提前停止训练后,就可以找到一个权重向量w^\hat{w} 更接近原点。与L2在损失函数中添加 λ2wTw\frac{\lambda}{2} \mathbf{w}^T\mathbf{w} 项,使最优解偏向于原点功能类似

数学上可以证明,早停中的 τη(迭代次数 × 学习率)起到了类似于正则化系数 λ 的倒数的作用。

双重下降

双重下降(Double Descent,一种现代发现的现象:测试误差先降、再升、再降的非单调行为)打破了传统的偏差-方差权衡认知:

  • 训练误差随复杂度增加单调下降;
  • 测试误差先下降,再上升(经典过拟合区域),然后再次下降

当模型复杂度足够大,能够完全拟合训练数据(即训练误差为零)时,测试误差反而继续下降,且模型表现更好。

ResNet18 双重下降

ResNet18 双重下降

  • 插值阈值:模型能够完美拟合训练数据所需的最小复杂度。
  • 当模型复杂度超过该阈值后,进入“插值区域”,此时虽然训练误差为零,但测试误差可能继续下降。

在“临界复杂度”区域(即测试误差峰值附近),增加训练数据量反而可能导致测试误差上升。因为更多数据会将“插值阈值”向右推,使模型暂时处于更易过拟合的区域。

Transformer 增加训练数据量反而导致测试误差上升

Transformer 增加训练数据量反而导致测试误差上升


意义:

  1. 不要过早停止训练:传统早停法可能错过后期的性能提升
  2. 长时间训练可能是有益的:现代大模型训练数周甚至数月是有道理的
  3. 监控验证误差的长期变化:观察是否出现双重下降现象

参数共享

参数共享(Parameter Sharing,强制网络中多个位置使用同一组权重的技术)是一种硬约束,它将网络中的一组权重强制设为相同值。这些共享的参数作为一个整体从数据中学习。

  • 优点:显著减少模型的自由度(即有效参数数量),从而降低过拟合风险。
  • 缺点:只能用于特定问题,且需要预先知道哪些参数应被共享。

典型应用:卷积神经网络(CNN)中的卷积核。同一个卷积核在整个输入图像上滑动,其权重在所有位置共享,体现了“平移不变性”的先验知识。

软参数共享

与硬共享不同,软共享通过正则化项鼓励一组权重趋向相似值,而不是强制相等。这种方法更加灵活,且共享的“分组”也可以在训练中自动学习。

实现方式:

  • 使用高斯混合模型 作为权重的先验分布: p(w)=i(j=1KπjN(wiμj,σj2))p(w) = \prod_i \left( \sum_{j=1}^K \pi_j \mathcal{N}(w_i | \mu_j, \sigma_j^2) \right) 其中 KK 是高斯成分数量,μj,σj,πj\mu_j, \sigma_j, \pi_j 是可学习参数。
  • 对应的正则化项为负对数先验: Ω(w)=iln(j=1KπjN(wiμj,σj2))\Omega(w) = -\sum_i \ln \left( \sum_{j=1}^K \pi_j \mathcal{N}(w_i | \mu_j, \sigma_j^2) \right)
  • 总误差函数为: E(w)=E~(w)+λΩ(w)E(w) = \tilde{E}(w) + \lambda \Omega(w)

训练机制:

  • 引入后验概率 γj(wi)\gamma_j(w_i):表示权重 wiw_i 属于第 jj 个高斯成分的概率(通过贝叶斯定理计算)。
  • 梯度更新时,每个权重 wiw_i 会被拉向其所属高斯的均值 μj\mu_j,拉力大小由 γj(wi)\gamma_j(w_i) 决定。
  • 同时,μj,σj,πj\mu_j, \sigma_j, \pi_j 也会根据所有权重的后验概率进行更新。

优化方法

  • 使用EM算法交替优化:
    • E步:计算后验概率 γj(wi)=πjN(wiμj,σj2)k=1KπkN(wiμk,σk2)\gamma_j(w_i) = \frac{\pi_j \mathcal{N}(w_i | \mu_j, \sigma_j^2)}{\sum_{k=1}^K \pi_k \mathcal{N}(w_i | \mu_k, \sigma_k^2)}
    • M步:更新参数 μj,σj,πj\mu_j, \sigma_j, \pi_j

软共享的好处:无需预先指定分组;允许权重形成多个“簇”;更具灵活性和适应性。


残差连接

与参数共享类似,残差连接(Residual Connection,也叫跳跃连接/Skip Connection,让信息跳过中间层直接传递到更深层的结构)也可以看作一种结构化的参数共享形式,通过恒等映射实现跨层参数的”共享”。更多关于残差网络的深入讨论,可以参考第六篇

随着网络层数增加,训练变得越来越困难,即使使用了批归一化和合适的初始化,仍可能出现:

  • 梯度消失/爆炸:深层网络中梯度难以有效传播。
  • 梯度破碎:深度网络的梯度对输入极其敏感,变得“嘈杂”且不平滑,破坏了梯度下降的稳定性。

理论上更深的网络应该至少不差于浅层网络,但实际上更深的网络性能反而下降

例子:学数学

  • 传统方式:直接从一年级学到博士数学太难了,中间环节容易丢失信息,可能学到后面忘了前面的基础
  • 残差方式:在每个阶段都保留基础知识,博士数学 = 基础知识 + 新学内容,基础知识始终存在(通过捷径连接)因此网络只需要学习”增量”部分,这样即使新学内容为0,也不会丢失基础

残差块

标准层:z=F(x)z = F(x)

输入 x → 层1 → 层2 → … → 层L → 输出 z

残差层:z=F(x)+xz = F(x) + x;其中 F(x)F(x) 是一个非线性变换(如若干卷积+BN+ReLU),是网络学习的部分。(让网络学习从 x 到 (z-x) 的映射,即学习”残差”)

关键思想:网络不再直接学习输出 zz,而是学习“残差” F(x)=zxF(x) = z - x


优势

  1. 恒等映射容易实现:
  • 如果最优解接近恒等变换(zxz \approx x),只需将 F(x)F(x) 的权重训练到接近零即可。
  • 而在普通网络中,实现恒等映射需要精确调整大量参数。
  1. 梯度传播更稳定:
  • 残差连接提供了一条“捷径”,使得梯度可以直接回传,缓解了梯度消失问题。
  1. 误差面更平滑:
  • 实验可视化显示,残差连接使损失函数曲面更光滑,优化路径更稳定。
  1. 隐含的集成效应:
  • 将残差网络展开,可发现其等价于多个路径(不同深度)的并行组合。
  • 这使得网络同时具备浅层网络的稳定性和深层网络的表达能力。

实现

  • 维度匹配:当输入 xx 与输出 F(x)F(x) 维度不同时,可通过一个可学习的线性变换 WW 调整跳跃路径: z=F(x)+Wxz = F(x) + Wx
  • 连接位置:通常在 ReLU 激活前加残差连接(即先加再激活)

残差网络的两种实现

残差网络的两种实现,组合视为一个残差块


模型平均

在机器学习中,当我们有多个模型来解决同一个问题时,与其选择一个”最佳”模型,不如将这些模型的预测结果进行平均,通常可以获得更好的泛化性能。这种组合模型的方法也被称为委员会方法集成方法(Ensemble Method,将多个模型的预测结果组合以获得更好性能的技术)。


对于输出为概率分布的模型,集成模型的预测是各个模型预测的平均值:

p(yx)=(1/L)Σl=1Lpl(yx)p(y|x) = (1/L) * Σ_{l=1}^{L} p_l(y|x)
  • pl(yx)p_l(y|x) 是第ll个模型的输出概率;
  • LL 是模型总数。

这种平均操作有助于降低预测中的方差,从而提升整体性能。

偏差-方差分解的角度来看,单个模型的预测误差可以分解为偏差和方差两部分。

总误差=偏差2+方差+噪声\text{总误差} = \text{偏差}^2 + \text{方差} + \text{噪声}

当我们对多个模型的预测取平均时,如果这些模型的误差是不相关的,那么它们的方差部分会相互抵消,从而降低总体误差。

想象你在练习投飞镖:

  • 单个模型:你投了10次,都偏离靶心但偏离方式相似 → 高偏差,低方差
  • 集成模型:10个人各自投10次,每个人都有自己的偏向(偏差相似)但每个人的随机误差不同(方差不相关)。取每个人平均落点,再对这10个平均点取平均的结果更接近靶心中心

实际中我们只有一个数据集,因此需要人为引入模型之间的差异。常用方法包括:

  1. 自主聚合:
  • 从原始数据集 X={x1,...,xN}X = \{x₁, ..., x_N\} 中有放回地随机采样,生成多个大小为 NN 的新数据集(称为 bootstrap 数据集)。
  • 每个 bootstrap 数据集用于训练一个模型。
  • 最终预测是所有模型预测的平均。
  1. 使用不同结构的模型(如不同层数、不同激活函数等),然后进行平均。

考虑一个回归问题,有 M 个训练好的模型 y1(x),...,yM(x)y_1(x), ..., y_M(x),集成预测为:

yCOM(x)=(1/M)Σm=1Mym(x)y_{COM}(x) = (1/M) * Σ_{m=1}^{M} y_m(x)

设真实函数为 h(x),每个模型的输出可表示为:

ym(x)=h(x)+εm(x)y_m(x) = h(x) + ε_m(x)

其中 εm(x)ε_m(x) 是第 mm 个模型的误差。

个体模型平均误差:

EAV=(1/M)Σm=1MEx[εm(x)2]E_{AV} = (1/M) * Σ_{m=1}^{M} E_x[ε_m(x)²]

集成模型的期望误差:

ECOM=Ex[((1/M)Σm=1Mεm(x))2]E_{COM} = E_x[ ( (1/M) * Σ_{m=1}^{M} ε_m(x) )² ]

假设误差均值为零且互不相关

若满足:

  • Ex[εm(x)]=0E_x[ε_m(x)] = 0
  • Ex[εm(x)εl(x)]=0E_x[ε_m(x)ε_l(x)] = 0 (当mlm ≠ l

则可得:

ECOM=(1/M)EAVE_{COM} = (1/M) * E_{AV}

可以证明:集成误差不会超过个体模型的平均误差,即:ECOMEAVE_{COM} ≤ E_{AV},所以集成至少不会变差。


与自主聚合不同,提升是一种序列式集成方法:

  • 基分类器逐个训练;
  • 每个新分类器训练时,会更关注之前分类器分错的样本(通过增加这些样本的权重);
  • 最终预测采用加权投票方式组合所有基分类器的结果。

提升的优势在于,即使每个基分类器只是略优于随机猜测,组合后仍可能取得非常好的性能。

Dropout

直觉:想象一个团队里,每天随机让一些人”休假”(不上班)。这样每个人都不能偷懒指望别人帮自己干活,每个人都得学会独立完成任务。Dropout(训练时随机”关闭”一部分神经元的技术)就是这样——每次训练随机让一些神经元”休假”,迫使每个神经元都学到有用的特征,而不是依赖某几个”明星”神经元。

Dropout 是一种非常有效的正则化技术,可以看作是在训练过程中隐式地对指数级数量的子网络进行近似模型平均

  • 在每次训练迭代中,随机“丢弃”(即置为0)一部分神经元(包括输入和隐藏层,但不包括输出层);
  • 每次输入数据时,都生成一个新的“掩码”(mask),决定哪些神经元被保留(通常隐藏层保留概率 ρ=0.5,输入层 ρ=0.8);
  • 训练时只在当前“剪枝后”的网络上进行前向和反向传播。

Dropout 示意图

Dropout 示意图(随机忽略)

作用:

  1. 防止共适应:
  • 每个神经元不能依赖其他特定神经元的存在;
  • 必须在多种上下文中都能做出有用贡献;
  • 减少了对训练数据噪声的过拟合。
  1. 隐式模型平均:
  • 一个有 M 个非输出节点的网络,理论上可以生成2M2^M个不同的子网络;
  • Dropout 在训练中隐式地平均了这些子网络的预测。

由于无法在测试时对所有 2M2^M 个子网络进行精确平均(计算不可行),有两种近似方法:

  1. Monte Carlo Dropout
  • 保留 dropout;
  • 对同一个输入多次前向传播(每次使用不同的 dropout mask);
  • 平均多次输出作为最终预测。p(yx)(1/T)Σt=1Tp(yx,Rt)p(y|x) ≈ (1/T) * Σ_{t=1}^{T} p(y|x, R_t)其中 RtR_t 是第 t 次采样的掩码。
  • 其中 TT 通常取10-100次采样即可获得稳定结果。
  1. 权重缩放法(常用)
  • 测试时不使用 dropout
  • 将训练好的权重乘以保留概率 ρ;
  • 这样可以保证测试时神经元的期望输入与训练时一致。
习题3

你训了个 5 层网络,训练集 99% 准确率,验证集只有 75%。怎么办?

典型的过拟合——模型把训练集”背”下来了。试试这几招:

  • Dropout(p=0.5):随机砍掉一半神经元,强迫剩下的不能太依赖队友
  • L2 权重衰减:不让权重太大
  • 早停:验证集 loss 不降了就停手,别死磕
  • 数据增强:翻转、旋转、裁剪,变着法子扩充训练集

测试的时候,Dropout 有”权重缩放”和”蒙特卡洛”两种用法。有啥区别?

权重缩放:测试时关掉 Dropout,权重乘以保留概率。快,一次前向传播搞定,但输出是固定的。

蒙特卡洛:测试时 Dropout 开着,同一个输入跑好多遍取平均。慢,但能告诉你”模型有多不确定”——如果你想知道模型对自己答案有多大信心,用这个。


第9章小结

一句话版本:正则化 = 给模型套”紧箍咒”,防止它太自由地过拟合。L2权重衰减让它别太大,早停让它别学太久,Dropout让神经元别太依赖队友,集成让多个模型取长补短。

知识地图

正则化(防止过拟合)
├── 为什么需要?→ 归纳偏置(先验知识缩小假设空间)
├── 权重衰减
│ ├── L2(平方和):权重整体缩小,最常用
│ ├── L1(绝对值):产生稀疏解,自动选特征
│ └── 分层:不同层不同强度
├── 训练控制
│ ├── 早停:验证误差不再降就停
│ └── 双重下降:过插值阈值后误差反而再降
├── 结构约束
│ ├── 参数共享(硬共享/软共享)
│ └── 残差连接(捷径传梯度)
└── 模型平均
├── 集成方法:多模型取平均
└── Dropout:训练时随机关闭神经元

跨篇关联:本篇的正则化技术(L1/L2权重衰减)呼应了第一篇中多项式拟合的惩罚项;残差连接的更多细节见第六篇


感谢您的阅读!如果可以,给俺点些关注吧~

深度学习笔记-4:梯度下降、反向传播与正则化

周一 9月 01 2025
13672 · 50 分钟
封面
示例歌曲
示例艺术家
封面
示例歌曲
示例艺术家
0:00 / 0:00