深度学习笔记 03:深度网络训练与优化器
光能训练模型还不够,能“稳定的”训练模型才NB。
梯度消失与梯度爆炸
深层网络里,gradient 要从 loss 一层层传回前面层。
如果每一层的梯度因子都小于 1,多层相乘后会越来越小,这就是 vanishing gradients。
如果每一层的梯度因子都大于 1,多层相乘后会越来越大,这就是 exploding gradients。
一个粗略例子:
\[ 0.5^{20} \approx 9.5 \times 10^{-7} \]
如果反向传播里连续乘很多个 0.5,前面层几乎收不到有效梯度。
反过来:
\[ 1.5^{20} \approx 3325 \]
如果连续乘很多个大于 1 的因子,梯度可能爆炸,训练变得不稳定。
这也是为什么 deep network 不是简单“多堆几层”就行。层数变深后,梯度能不能稳定传过去本身就是问题。
参数初始化(initialization)
初始化的目标不是找一个好模型,而是给训练一个合适起点。
如果权重太小,信号逐层传递后可能越来越弱;如果权重太大,activation 和 gradient 可能变得不稳定。
常见初始化包括 Xavier initialization 和 He initialization。
- Xavier initialization 适合 tanh / sigmoid 这类 activation,核心想法是让每层输入输出的方差保持相对稳定。
- He initialization 更适合 ReLU,因为 ReLU 会把一部分负值截断为 0。
直觉上,初始化是在控制每一层信号的尺度。尺度合适,forward 和 backward 都更容易稳定。
归一化(normalization)
Normalization 的作用是让中间表示的分布更稳定。
Batch Normalization 通常对 batch 维度做归一化:
\[ \hat{x} = \frac{x-\mu_B}{\sqrt{\sigma_B^2+\epsilon}} \]
其中,\(\mu_B\) 和 \(\sigma_B^2\) 是当前 batch 的均值和方差。
BatchNorm 在 CNN 里很常见。它能让训练更稳定,也允许使用更大的 learning rate。
Layer Normalization 则通常对单个样本内部的 hidden dimension 做归一化。Transformer 里更常用 LayerNorm,因为序列任务里 batch 统计不一定稳定,而且不同 token 长度和并行方式会让 BatchNorm 不方便。
可以这样粗略理解:
| 方法 | 主要归一化维度 | 常见场景 |
|---|---|---|
| BatchNorm | batch 维度 | CNN |
| LayerNorm | feature / hidden 维度 | Transformer、RNN |
随机失活(dropout):训练时故意丢掉一部分连接
Dropout 是一种正则化方法。训练时随机把一部分 hidden units 置为 0:
1 | |
它的直觉是:不要让模型过度依赖某几个 neuron,而是让不同子网络都能工作。
测试时通常不再随机丢弃,而是使用完整网络,并对激活值做相应缩放。
Dropout 在早期深度网络里很常见。现在大模型里也会用 dropout,但很多大规模预训练模型会把 dropout 设得比较小,甚至某些设置下不用。
学习率(learning rate)和 scheduler
Learning rate 控制每次参数更新的步长。
如果太小,训练慢;如果太大,loss 可能震荡甚至发散。
深度学习里常见 scheduler:
- warmup:训练初期逐渐增大学习率
- step decay:训练到某些 epoch 后降低学习率
- cosine decay:按余弦曲线逐渐降低学习率
优化器 Optimizer
SGD:最基础的随机梯度下降
Stochastic Gradient Descent 使用 mini-batch gradient 更新参数:
\[ \theta_{t+1} = \theta_t - \eta g_t \]
其中,\(\eta\) 是 learning rate,\(g_t\) 是当前 mini-batch 上的 gradient。
SGD 的优点是简单、泛化表现常常不错。缺点是更新方向受当前 batch 影响,可能噪声较大,收敛也可能比较慢。
比如 loss surface 像一个狭长山谷,SGD 可能在山谷两侧来回震荡,同时沿着谷底方向前进很慢。
动量法(momentum):加入历史方向
Momentum 的思路:不要只看当前 gradient,也看过去一段时间的更新方向。
常见形式:
\[ v_t = \beta v_{t-1} + g_t \]
\[ \theta_{t+1} = \theta_t - \eta v_t \]
其中,\(v_t\) 是 velocity,\(\beta\) 控制保留多少历史方向。
直觉上,如果多个 step 的 gradient 方向一致,Momentum 会加速;如果某个方向来回震荡,正负更新会互相抵消。
这很像推一个球下山。SGD 每一步都只看当前坡度,Momentum 让球带一点惯性。
RMSProp:给每个参数自适应学习率
RMSProp 关注的是每个参数最近 gradient 的平方平均。
\[ s_t = \rho s_{t-1} + (1-\rho)g_t^2 \]
\[ \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{s_t}+\epsilon}g_t \]
如果某个参数的 gradient 一直很大,\(s_t\) 会变大,于是它的有效学习率会变小。
如果某个参数的 gradient 一直很小,\(s_t\) 小,有效学习率相对更大。
RMSProp 的直觉是:不同参数不一定应该用同一个步长。频繁大幅变化的方向要走得谨慎,变化小的方向可以走得相对积极。
Adam:动量法(momentum)+ RMSProp
Adam 可以看作把 Momentum 和 RMSProp 结合起来。
它维护一阶矩估计:
\[ m_t = \beta_1 m_{t-1} + (1-\beta_1)g_t \]
也维护二阶矩估计:
\[ v_t = \beta_2 v_{t-1} + (1-\beta_2)g_t^2 \]
然后做 bias correction:
\[ \hat{m}_t = \frac{m_t}{1-\beta_1^t} \]
\[ \hat{v}_t = \frac{v_t}{1-\beta_2^t} \]
最后更新:
\[ \theta_{t+1} = \theta_t - \eta \frac{\hat{m}_t}{\sqrt{\hat{v}_t}+\epsilon} \]
Adam 的直觉:
- \(m_t\) 像 Momentum,记录梯度方向的滑动平均
- \(v_t\) 像 RMSProp,记录梯度平方的滑动平均
- 分母让每个参数有自适应步长
Adam 的默认参数经常是:
1 | |
Adam 的优点是上手快、收敛稳定、对 learning rate 没有 SGD 那么敏感。
AdamW:把 weight decay 解耦出来
先看Adam 里常见的 L2 regularization。如果把 L2 penalty 加到 loss 里:
\[ L'(\theta)=L(\theta)+\frac{\lambda}{2}\|\theta\|^2 \]
那么梯度会变成:
\[ g'_t = g_t + \lambda \theta_t \]
在 SGD 里,这和 weight decay 基本等价:
\[ \theta_{t+1} = \theta_t - \eta(g_t + \lambda\theta_t) \]
可以整理成:
\[ \theta_{t+1} = (1-\eta\lambda)\theta_t - \eta g_t \]
也就是每步先把权重衰减一点,再按 gradient 更新。
但在 Adam 里,情况不一样。Adam 会用二阶矩 \(\sqrt{\hat{v}_t}\) 对梯度做自适应缩放。如果把 \(\lambda\theta_t\) 混进 gradient,它也会被 Adam 的自适应项缩放。
这样 weight decay 就不再是“统一把权重变小”,而是和每个参数的梯度历史纠缠在一起。
AdamW 的做法是把 weight decay 从 gradient update 里解耦出来:
\[ \theta_{t+1} = \theta_t - \eta \frac{\hat{m}_t}{\sqrt{\hat{v}_t}+\epsilon} - \eta\lambda\theta_t \]
也可以理解成:
- Adam update: use gradient statistics to update parameters
- Weight decay: separately shrink weights
AdamW 的核心变化:weight decay 不再被 Adam 的自适应梯度缩放影响。
Adam 和 AdamW 的区别
一句话:
Adam 里的 L2 regularization 是把 weight decay 混进 gradient;AdamW 是把 weight decay 作为单独的参数衰减步骤。
在 Adam 里:
1 | |
在 AdamW 里:
1 | |
在训练 Transformer / LLM 时,AdamW 比 Adam 更常见。它让 weight decay 的作用更接近正则化直觉。
优化器对比
| 优化器 | 核心想法 | 优点 | 常见问题 |
|---|---|---|---|
| SGD | 当前 mini-batch gradient | 简单,泛化常不错 | 收敛慢,对 lr 敏感 |
| Momentum | 加入历史方向 | 减少震荡,加速一致方向 | 多一个 momentum 参数 |
| RMSProp | 自适应缩放每个参数 | 处理不同尺度梯度 | 只看二阶信息 |
| Adam | Momentum + RMSProp | 稳定、好用、收敛快 | weight decay 处理不理想 |
| AdamW | Adam + decoupled weight decay | 现代深度学习常用 | 仍然需要调 lr 和 decay |
实际训练里,优化器不是越复杂越好。SGD 在一些视觉任务里仍然很强,AdamW 在 Transformer 训练里非常常见。