优化器的核心作用是:根据梯度决定模型参数怎么更新 。
不同优化器的区别主要体现在:更新步长是否自适应、是否使用动量、是否容易调参、收敛速度和泛化能力。
一、最常见的优化器
1. SGD
SGD,全称 Stochastic Gradient Descent,随机梯度下降。
它的更新逻辑很直接:
text
参数 = 参数 - 学习率 × 梯度
优点:
text
简单
稳定
泛化能力通常不错
理论基础清晰
缺点:
text
收敛较慢
对学习率敏感
容易在复杂损失面上震荡
需要较多调参经验
适合场景:
text
图像分类
CNN
训练时间充足
追求最终泛化性能
不过实际使用时,很少直接用纯 SGD,通常会加 Momentum。
二、SGD + Momentum
Momentum 可以理解为给参数更新加了"惯性"。
普通 SGD 每一步只看当前梯度,而 Momentum 会参考之前的更新方向。
直观理解:
text
如果连续几步都往同一方向下降,就加速
如果梯度来回震荡,就抵消一部分震荡
优点:
text
比普通 SGD 收敛快
可以减少震荡
泛化能力较好
缺点:
text
仍然比较依赖学习率
通常需要学习率调度
前期调参成本较高
常见配置:
text
optimizer = SGD
learning_rate = 0.1 或 0.01
momentum = 0.9
weight_decay = 1e-4
适合场景:
text
CNN
ResNet
大规模视觉任务
追求较好的最终泛化效果
如果你在训练图像分类模型,SGD + Momentum 仍然是一个很经典、可靠的选择。
三、Adam
Adam 可以看作是:
text
Momentum + 自适应学习率
它不仅记录梯度的一阶动量,也记录梯度平方的二阶动量。
简单理解:
text
一阶动量:大致表示梯度方向
二阶动量:大致表示每个参数梯度变化的尺度
Adam 会给不同参数分配不同的更新步长。
优点:
text
收敛快
对学习率不那么敏感
默认参数通常好用
适合快速建立 baseline
缺点:
text
有时泛化能力不如 SGD
在某些任务上可能验证集效果略差
如果配合 L2 正则方式不当,可能不如 AdamW
常见配置:
text
optimizer = Adam
learning_rate = 1e-3
betas = (0.9, 0.999)
eps = 1e-8
适合场景:
text
快速实验
小数据集
非视觉任务
RNN / LSTM
普通 MLP
训练不太稳定的任务
如果你不知道从哪个优化器开始,Adam 通常是很好的起点。
四、AdamW
AdamW 是 Adam 的改进版本,核心区别是:更合理地处理 weight decay。
在 Adam 中,L2 正则和自适应学习率耦合在一起,可能导致正则效果不稳定。
AdamW 把 weight decay 从梯度更新中解耦出来。
可以简单理解为:
text
Adam:梯度更新和权重衰减混在一起
AdamW:先按 Adam 更新,再单独做权重衰减
优点:
text
通常比 Adam 泛化更好
适合 Transformer
适合大模型
weight decay 更容易调
缺点:
text
仍然需要调学习率和 weight decay
在部分传统 CNN 任务上未必明显优于 SGD
常见配置:
text
optimizer = AdamW
learning_rate = 3e-4 或 1e-4
weight_decay = 1e-2 或 1e-4
betas = (0.9, 0.999)
适合场景:
text
Transformer
BERT
GPT
ViT
现代深度学习模型
NLP
多模态模型
现在很多深度学习项目中,AdamW 是默认首选优化器。
五、RMSProp
RMSProp 也是一种自适应学习率优化器。
它会根据历史梯度平方的均值调整每个参数的学习率。
优点:
text
适合非平稳目标
对 RNN 曾经很常用
比普通 SGD 更稳定
缺点:
text
现在很多场景被 Adam / AdamW 替代
最终效果不一定最好
常见配置:
text
optimizer = RMSProp
learning_rate = 1e-3
alpha = 0.99
适合场景:
text
RNN
强化学习
某些 loss 波动较大的任务
六、Adagrad
Adagrad 会让频繁更新的参数学习率变小,让不常更新的参数学习率相对较大。
优点:
text
适合稀疏特征
对 NLP 中稀疏输入有帮助
缺点:
text
学习率会不断变小
训练后期可能几乎不再更新
适合场景:
text
稀疏特征
传统 NLP
推荐系统中的稀疏 embedding
但现在在深度学习中,Adagrad 使用频率不如 AdamW。
七、优化器之间的核心区别
| 优化器 | 是否自适应学习率 | 是否有动量 | 收敛速度 | 调参难度 | 泛化能力 |
|---|---|---|---|---|---|
| SGD | 否 | 否 | 慢 | 高 | 较好 |
| SGD + Momentum | 否 | 是 | 中等 | 较高 | 好 |
| RMSProp | 是 | 否/弱 | 较快 | 中等 | 中等 |
| Adagrad | 是 | 否 | 前期快 | 中等 | 任务相关 |
| Adam | 是 | 是 | 快 | 低 | 中等到较好 |
| AdamW | 是 | 是 | 快 | 中等 | 较好 |
简单来说:
text
SGD:慢但稳,泛化好
Momentum:让 SGD 更快更稳
Adam:好上手,收敛快
AdamW:现代深度学习最常用,尤其适合 Transformer
RMSProp:适合某些非稳定任务
Adagrad:适合稀疏特征
八、实际应该怎么选?
情况 1:不知道选什么
优先选:
text
AdamW
推荐初始配置:
text
learning_rate = 3e-4
weight_decay = 1e-4 或 1e-2
betas = (0.9, 0.999)
这是现在很多任务的安全起点。
情况 2:训练 CNN 图像分类模型
可以选:
text
SGD + Momentum
推荐配置:
text
learning_rate = 0.1 或 0.01
momentum = 0.9
weight_decay = 1e-4
scheduler = cosine decay 或 step decay
如果想快速跑 baseline,也可以先用 AdamW,然后再尝试 SGD + Momentum 看最终验证集是否更好。
情况 3:训练 Transformer / BERT / GPT / ViT
优先选:
text
AdamW
推荐配置:
text
learning_rate = 1e-5 到 5e-4
weight_decay = 1e-2
warmup_ratio = 0.03 到 0.1
scheduler = linear decay 或 cosine decay
Transformer 对学习率比较敏感,通常还要配合 warmup。
情况 4:小数据集
可以选:
text
AdamW
但要注意过拟合,所以更重要的是调:
text
weight_decay
dropout
data augmentation
early stopping
小数据集不一定适合很大的学习率。
情况 5:数据很稀疏
例如推荐系统、文本 bag-of-words、稀疏 embedding。
可以考虑:
text
AdamW
Adagrad
SparseAdam
如果是 embedding 很大的推荐系统,Adagrad 或稀疏优化器有时会有优势。
情况 6:训练不稳定、loss 震荡
优先尝试:
text
降低学习率
换 AdamW
加 gradient clipping
使用 warmup
训练不稳定时,不一定是优化器问题,学习率过大更常见。
九、优化器和学习率的关系
优化器不能脱离学习率单独看。
一般学习率范围:
| 优化器 | 常见学习率 |
|---|---|
| SGD + Momentum | 1e-2 到 1e-1 |
| Adam | 1e-4 到 1e-3 |
| AdamW | 1e-5 到 1e-3 |
| RMSProp | 1e-4 到 1e-3 |
注意:
text
同一个学习率在不同优化器中含义不一样
例如:
text
SGD 用 0.1 可能正常
Adam 用 0.1 通常会炸
所以换优化器时,学习率也必须重新调。
十、优化器选择的实用流程
可以按这个顺序来:
text
1. 先用 AdamW 建 baseline
2. 调学习率,确认 loss 能稳定下降
3. 调 weight decay
4. 如果是视觉 CNN,尝试 SGD + Momentum 对比最终效果
5. 如果是 Transformer,继续用 AdamW,并加入 warmup 和 scheduler
6. 如果 loss 不稳定,优先降学习率和加 gradient clipping
7. 如果验证集效果差,再考虑换优化器
十一、推荐默认配置
通用 baseline
python
optimizer = torch.optim.AdamW(
model.parameters(),
lr=3e-4,
weight_decay=1e-4
)
Transformer 微调
python
optimizer = torch.optim.AdamW(
model.parameters(),
lr=2e-5,
weight_decay=1e-2
)
CNN 图像分类
python
optimizer = torch.optim.SGD(
model.parameters(),
lr=0.1,
momentum=0.9,
weight_decay=1e-4
)
训练不稳定时
python
optimizer = torch.optim.AdamW(
model.parameters(),
lr=1e-4,
weight_decay=1e-4
)
并配合:
python
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
十二、容易踩的坑
1. 只换优化器,不调学习率
这是最常见错误。
例如从 SGD 换到 Adam 后,还用 0.1 的学习率,大概率训练崩掉。
2. Adam 不等于一定比 SGD 好
Adam 通常收敛更快,但有些任务上 SGD + Momentum 的最终泛化可能更好。
3. 忽略学习率调度器
优化器本身很重要,但学习率调度同样重要。
常用组合:
text
SGD + Momentum + Cosine decay
AdamW + Warmup + Cosine decay
AdamW + Warmup + Linear decay
4. weight decay 不是越大越好
weight decay 太大会欠拟合,太小可能过拟合。
常见搜索范围:
text
0, 1e-5, 1e-4, 1e-3, 1e-2
5. 对 bias 和 LayerNorm 使用 weight decay
在 Transformer 中,通常不对这些参数做 weight decay:
text
bias
LayerNorm.weight
LayerNorm.bias
BatchNorm 参数
因为这些参数做衰减可能影响训练稳定性。
十三、一句话总结
想快速稳定出结果,用 AdamW;训练 CNN 且追求最终泛化,可以试 SGD + Momentum;训练 Transformer 基本优先 AdamW;优化器选完后,学习率、weight decay 和 scheduler 往往比优化器名字本身更重要。