李沐深度学习优化算法
在前面的学习中,我们已经接触了数据获取、数据预处理、模型构建、损失函数等内容。接下来要进入机器学习与深度学习中非常关键的一部分:优化算法(Optimization Algorithm)。
很多同学刚开始学的时候,会觉得“优化算法”就是换个优化器名字,比如SGD、Adam、RMSprop。但实际上,优化算法决定了模型参数如何更新,直接影响模型能不能学会、学得快不快、最后效果好不好。
这一篇,我们就系统讲清楚:
什么是优化算法
梯度下降到底在干什么
SGD、Mini-batch、Momentum、AdaGrad、RMSprop、Adam 的区别
学习率为什么这么重要
实战中该怎么选优化器
一、什么是优化算法
先说最核心的一句话:
机器学习训练模型的过程,本质上就是不断调整参数,让损失函数尽可能变小的过程。
比如我们训练一个分类模型,模型会输出预测结果,然后和真实标签进行比较,计算出一个损失值loss。
这个loss越小,说明模型预测得越接近真实情况。
那问题来了:
模型参数该怎么调,才能让 loss 变小?
这就需要优化算法。
所以,所谓优化算法,本质上就是:
按照某种规则更新模型参数,使损失函数不断减小。
二、优化问题的基本形式
在深度学习里,这个参数可能是:
线性回归中的权重和偏置
神经网络中的卷积核参数
全连接层中的权重矩阵
BatchNorm、注意力层等模块中的可学习参数
三、梯度下降:优化算法的起点
1. 什么是梯度
梯度可以简单理解成:
函数在某一点上增长最快的方向。
而我们想让损失函数减小,所以更新参数时,通常要朝着梯度的反方向走,也就是:
沿着损失下降最快的方向更新参数。
这就是梯度下降法的核心思想。
2. 梯度下降公式
这个公式的意思很简单:
先求当前参数下的梯度
再按学习率控制步长
沿着负梯度方向更新参数
3. 直观理解
可以把优化过程想象成:
一个人站在山上,想走到最低点。
这时候:
损失函数= 山的地形
参数更新= 走路
梯度= 当前最陡的上坡方向
负梯度方向= 下坡最快方向
学习率= 每一步迈多大
如果步子太小,下降很慢;
如果步子太大,可能直接跨过最低点,来回震荡,甚至越走越偏。
四、批量梯度下降、随机梯度下降、Mini-batch 梯度下降
1. 批量梯度下降(Batch Gradient Descent)
批量梯度下降的做法是:
每次都用整个训练集计算一次梯度,然后更新参数。
优点:
梯度方向比较稳定
理论上更新比较准确
缺点:
数据集大时,计算非常慢
每次更新代价高
不适合大规模深度学习训练
2. 随机梯度下降(Stochastic Gradient Descent, SGD)
随机梯度下降的做法是:
每次只取一个样本计算梯度,然后立刻更新参数。
优点:
更新速度快
每次计算开销小
缺点:
波动大,不稳定
容易震荡
收敛路径比较“抖”
3. 小批量梯度下降(Mini-batch Gradient Descent)
实际中最常用的是 Mini-batch 梯度下降:
每次取一小批样本,比如 32、64、128 个样本,计算平均梯度,再更新参数。
它综合了前两者的优点:
比单样本更稳定
比全量样本更高效
适合 GPU 并行计算
所以在深度学习中,我们平时说的训练,基本默认就是Mini-batch 梯度下降。
五、学习率:训练成败的关键参数
学习率是优化算法中最重要的超参数之一。
1. 学习率太小
如果学习率太小,会出现:
loss 下降特别慢
训练很多轮效果仍不好
模型迟迟学不会
就像下山时每一步都迈得特别小,虽然方向没错,但速度太慢。
2. 学习率太大
如果学习率太大,会出现:
loss 来回震荡
训练不稳定
甚至 loss 直接发散
这就像下山时每一步迈得太大,结果在山谷两边来回跳,根本到不了最低点。
3. 学习率的常见设置
常见初始学习率例如:
0.10.010.001
不同优化器适合的学习率不同:
SGD常常需要相对大一些的学习率Adam常常从1e-3开始RMSprop也常从1e-3左右开始
六、SGD:最基础的优化器
1. SGD 的思想
SGD 就是随机梯度下降。
在深度学习框架中,我们平时用的SGD,通常其实是基于 Mini-batch 的参数更新。
更新公式依旧是:
2. SGD 的优点
原理简单
内存占用较小
泛化能力有时较好
在很多视觉任务中仍然很强
3. SGD 的缺点
收敛速度可能较慢
容易在沟壑型区域震荡
对学习率比较敏感
七、Momentum:给 SGD 加上“惯性”
普通 SGD 有一个问题:
如果损失曲面的某些方向很陡、某些方向很平,参数更新就容易左右震荡,下降效率不高。
于是就有了Momentum(动量)。
1. 核心思想
Momentum 的思想很像物体运动中的惯性:
不只看当前梯度,还结合过去一段时间的更新方向。
这样可以让参数更新更平滑,也能在正确方向上加速前进。
2. 公式理解
3. 优点
减少震荡
加快收敛
在深度学习中很常用
所以很多时候我们看到的SGD实际上是:
SGD + Momentum
这也是计算机视觉任务中非常经典的组合。
八、AdaGrad:自适应学习率的开始
1. 核心思想
AdaGrad 的核心是:
不同参数使用不同学习率。
如果某个参数历史梯度较大,那么它之后的学习率就会变小;
如果某个参数历史梯度较小,那么它的学习率就相对大一些。
这对稀疏特征任务比较有帮助。
2. 优点
能自动调整不同参数的学习率
对稀疏数据比较友好
3. 缺点
AdaGrad 最大的问题是:
学习率会不断衰减,而且越到后面越小。
结果就是训练后期可能几乎走不动,更新特别慢。
九、RMSprop:解决 AdaGrad 后期学习率过小的问题
RMSprop 可以看作是对 AdaGrad 的改进。
1. 核心思想
AdaGrad 是把所有历史梯度都累加起来,时间长了数值越来越大,导致学习率越来越小。
RMSprop 则改成:
只关注最近一段时间梯度的平方均值。
也就是说,它不再无止境地累加,而是使用“滑动平均”的方式控制学习率。
2. 优点
收敛速度通常比 AdaGrad 更好
缓解学习率持续衰减的问题
在 RNN 等场景中曾经很常见
十、Adam:最常用的优化器之一
Adam 是目前最常见的优化器之一,全称是:
Adaptive Moment Estimation
它结合了:
Momentum 的一阶动量思想
RMSprop 的二阶动量思想
可以理解为:
既考虑梯度方向的惯性,又考虑梯度大小的自适应调整。
1. Adam 的优势
Adam 之所以常用,是因为它通常具备以下优点:
收敛快
对初始学习率不那么敏感
实现方便
大多数任务都能直接用
很多同学第一次训练神经网络时,往往都会先用 Adam,因为“比较稳,比较省事”。
2. Adam 的不足
虽然 Adam 很方便,但它也不是万能的。
在一些任务中,Adam 可能会出现:
后期泛化不如 SGD
收敛很快,但最终最好精度不一定最高
对某些数据集可能容易过快陷入次优解
这也是为什么在很多计算机视觉任务里,研究者最后仍然喜欢用:
SGD + Momentum
因为它训练虽然慢一点,但泛化性能往往更扎实。
十一、几种常见优化器对比
1. SGD
特点:
简单直接
训练稳定性一般
泛化能力较强
适用:
计算机视觉任务
追求最终精度时常用
2. SGD + Momentum
特点:
在 SGD 基础上加速
减少震荡
实战非常常用
适用:
CNN、目标检测、图像分类等任务
3. AdaGrad
特点:
自适应学习率
对稀疏特征友好
缺点:
后期学习率衰减过快
4. RMSprop
特点:
改善 AdaGrad 学习率过小问题
训练通常较稳
适用:
某些序列模型、非平稳目标问题
5. Adam
特点:
收敛快
调参相对轻松
上手最方便
适用:
初学者训练神经网络
大多数通用深度学习任务
十二、PyTorch 中如何使用优化器
下面给出一个最基础的 PyTorch 示例。
1. SGD 优化器
import torch import torch.nn as nn import torch.optim as optim model = nn.Linear(10, 2) optimizer = optim.SGD(model.parameters(), lr=0.01)2. SGD + Momentum
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)3. Adam
optimizer = optim.Adam(model.parameters(), lr=0.001)4. 典型训练流程
for epoch in range(epochs): for x, y in dataloader: pred = model(x) loss = criterion(pred, y) optimizer.zero_grad() # 梯度清零 loss.backward() # 反向传播,计算梯度 optimizer.step() # 更新参数这里面三句非常关键:
optimizer.zero_grad():清空上一次梯度loss.backward():根据 loss 反向传播计算梯度optimizer.step():根据优化算法更新参数
这三步构成了参数优化的核心流程。
十三、训练中常见问题分析
1. loss 不下降
可能原因:
学习率太大或太小
数据有问题
模型结构不合适
梯度传播异常
损失函数设置不合理
2. loss 震荡明显
可能原因:
学习率太大
batch size 太小
使用普通 SGD 且没有动量
数据噪声较大
3. 收敛很慢
可能原因:
学习率偏小
优化器选择不合适
特征表达能力不足
模型过于简单
4. 训练集效果很好,测试集很差
这通常不是优化器本身的问题,而更像是:
过拟合
数据量不足
数据增强不够
正则化不足
十四、实战中怎么选优化器
这是很多初学者最关心的问题。
我给出一个比较实用的建议:
情况1:你刚开始做项目,想先跑通
优先用:
Adam
原因:
收敛快
调参省心
容易先得到一个可用结果
情况2:你做的是图像分类、目标检测、语义分割
优先尝试:
SGD + Momentum
原因:
视觉任务里很经典
泛化能力通常更好
论文和工程里都很常见
情况3:你想快速验证模型结构有没有用
优先用:
Adam
先快速看趋势,再决定后续是否切到 SGD。
情况4:你想冲最终性能
建议:
先用 Adam 快速调通,再尝试 SGD + Momentum 做精调
这在项目实践中是很常见的思路。
十五、学习率调度器的重要性
在实际训练中,仅仅设置固定学习率还不够。
很多时候我们还会配合使用学习率调度器(Learning Rate Scheduler)。
意思就是:
训练前期学习率大一点,下降快;
训练后期学习率小一点,收敛更稳。
常见策略有:
StepLR:每隔若干轮下降一次
Cosine Annealing:余弦退火
ReduceLROnPlateau:当指标不提升时自动降低学习率
所以完整训练中,通常是:
优化器 + 学习率策略一起决定训练效果。
十六、优化算法学习小结
这一节我们重点学习了优化算法的基本思想。
可以把核心内容总结成下面几句话:
训练模型,本质上是在最小化损失函数。
梯度下降是最基本的优化思想。
学习率决定更新步长,是最关键的超参数之一。
Mini-batch 是深度学习训练的主流方式。
SGD、Momentum、AdaGrad、RMSprop、Adam 各有特点。
Adam 上手方便,SGD + Momentum 在很多视觉任务中效果更强。
十七、写在最后
优化算法并不是简单地“换个优化器试试”,它背后反映的是:
参数更新机制
收敛速度
训练稳定性
泛化能力
对于初学者来说,建议先把这条主线真正理解清楚:
前向传播得到预测 → 计算损失 → 反向传播求梯度 → 优化器更新参数
一旦你把这条链路理解透了,后面学更复杂的深度学习内容就会顺很多。
下一节,我们将进入本课程的收尾部分:课程总结和进阶学习。
到那时,我们会把整个机器学习学习路线完整串起来,帮助大家真正形成系统框架。
十八、课后思考题
为什么训练模型的本质是最小化损失函数?
批量梯度下降、随机梯度下降、Mini-batch 梯度下降有什么区别?
学习率过大和过小分别会带来什么问题?
Momentum 相比普通 SGD 的优势是什么?
为什么 Adam 通常收敛更快,而 SGD 在某些任务上泛化更好?
十九、本文小结
本文从优化问题出发,系统介绍了梯度下降、学习率、SGD、Momentum、AdaGrad、RMSprop、Adam 等常见优化算法,并结合 PyTorch 给出了基本使用方式。优化算法是训练神经网络的核心模块之一,理解它们的原理与差异,对后续学习深度学习训练技巧、模型调参和项目实践都非常重要。
