深度学习Day06 学习率衰减策略
学习率衰减策略(Learning Rate Scheduler)
在深度学习训练过程中,学习率(Learning Rate)是一个至关重要的超参数。
它决定了模型参数每次更新的步幅:
学习率太大:可能跳过最优点,训练不稳定甚至发散
学习率太小:收敛速度慢,训练时间过长
因此,我们通常不会让学习率始终保持不变,而是采用一种更有效的方法:
学习率衰减(Learning Rate Decay)策略
一、为什么需要学习率衰减?
训练初期:
-
模型距离最优解较远
-
需要较大的学习率快速下降
训练后期:
-
模型接近最优解
-
需要较小学习率精细调整
所以学习率衰减的核心思想是:
先快后慢,逐步减小学习率,提高收敛效果
二、PyTorch 中的学习率调度器
PyTorch 提供了 torch.optim.lr_scheduler 模块,用于动态调整学习率。
典型的调度器结构为:
optimizer = torch.optim.SGD([w], lr=0.1, momentum=0.9)
scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.95)
训练过程中,每个 epoch 调用:
scheduler.step()
即可更新学习率。
三、常见学习率衰减策略
3.1 StepLR:等间隔衰减策略
思想
每隔固定 epoch,将学习率乘以一个衰减系数:
$$ lr = lr \times \gamma $$
PyTorch 实现
scheduler = torch.optim.lr_scheduler.StepLR(
optimizer,
step_size=50,
gamma=0.5
)
step_size=50:每 50 个 epoch 衰减一次
gamma=0.5:学习率减半
StepLR 优缺点
优点
简单易用
适合规律训练任务
缺点
衰减时刻固定,不够灵活
学习率变化如下所示:

3.2 MultiStepLR:指定节点衰减策略
思想
以StepLR为基础,在指定的 epoch 节点进行衰减:
比如:
第 50 轮衰减一次
第 125 轮再衰减
第 160 轮再次衰减
Pytorch 实现
milestones = [50, 125, 160]
scheduler = torch.optim.lr_scheduler.MultiStepLR(
optimizer,
milestones=milestones,
gamma=0.5
)
优点
更灵活
可根据训练曲线手动调整节点
学习率变化如下图所示:

3.3 ExponentialLR:指数衰减策略
思想
每一轮训练都按指数形式衰减:
$$ lr = lr \times \gamma $$
Pytorch 实现
scheduler = torch.optim.lr_scheduler.ExponentialLR(
optimizer,
gamma=0.95
)
每个 epoch 学习率都会变成:
$$l_r = l_r \times 0.95$$
优点
平滑衰减
适合长期训练任务
缺点
衰减过快可能导致后期学习率过小
学习率变化如下图所示:

3.4 CosineAnnealingLR:余弦退火学习率策略
在训练大模型(如 Transformer、BERT、ViT)时,指数衰减或 Step 衰减有时会显得过于生硬。
因此,实践中非常常用一种更加平滑的策略:
余弦退火学习率衰减(Cosine Annealing)
思想
余弦退火的学习率变化类似一个余弦曲线:
前期下降较慢
中期下降较快
后期下降趋于平缓
学习率的变化公式为:
$$ lr_t = lr_{min} + \frac{1}{2}(lr_{max} - lr_{min})(1 + \cos(\frac{t}{T}\pi)) $$
其中:
$lr_{max}$:初始学习率
$lr_{min}$:最低学习率
$T$:总衰减周期
$t$:当前 epoch
PyTorch 实现
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer,
T_max=200,
eta_min=1e-5
)
T_max=200:余弦周期长度(一般设为总 epoch)
eta_min=1e-5:学习率的最小值
优点
✅ 学习率变化更加平滑
✅ 后期训练更稳定
✅ 大模型训练效果更好
学习率变化曲线如下:

3.5 Warmup:学习率预热策略
很多人会发现一个问题:
模型训练刚开始时,如果学习率过大,loss 会剧烈震荡甚至直接发散。
为了解决这个问题,引入 Warmup 策略。
Warmup 的核心思想是:
训练初期不直接使用大学习率,而是从一个很小的学习率开始逐步升高。
比如:
第 0 epoch:lr = 0.0001
第 1 epoch:lr = 0.001
第 5 epoch:lr = 0.01
之后再进入正常衰减阶段
这种策略特别适合:
大 batch 训练
Transformer 网络
训练不稳定的深层模型
Warmup 的学习率变化
最常见的 Warmup 是线性增长:
$$ lr_t = lr_{max} \cdot \frac{t}{T_{warmup}} $$
其中:
$T_{warmup}$:预热轮数
$lr_{max}$:目标学习率
示例:
from torch.optim.lr_scheduler import LambdaLR
warmup_epochs = 5
def warmup_lambda(epoch):
if epoch < warmup_epochs:
return (epoch + 1) / warmup_epochs
return 1
scheduler = LambdaLR(optimizer, lr_lambda=warmup_lambda)
它实现的是 Warmup 学习率预热:
训练刚开始的前
warmup_epochs=5个 epoch,让学习率从小到大逐步变大;
第 5 个 epoch 之后,学习率保持不变(乘数固定为 1)。
举个具体的例子,假如优化器的学习率设置为0.1:
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
那么$lr_{max}$=0.1
Warmup阶段 5 个 epoch 的倍率分别是:
| epoch | warmup_lambda(epoch) | 实际 lr = 0.1 * 倍率 |
|---|---|---|
| 0 | (0+1)/5 = 0.2 | 0.02 |
| 1 | 0.4 | 0.04 |
| 2 | 0.6 | 0.06 |
| 3 | 0.8 | 0.08 |
| 4 | 1.0 | 0.10 |
| 5 | 1 | 0.10 |
| 6 | 1 | 0.10 |
画出来的图:

3.6 Warmup + CosineAnnealing
实际工程中最常用组合:
Warmup + CosineAnnealing
假设流程:
前 5 个 epoch Warmup
后续使用余弦退火衰减
# 训练的总轮次
epochs = 200
# Warmup + CosineAnnealing(最佳实践)
warmup_epochs = 5
warmup_scheduler = torch.optim.lr_scheduler.LambdaLR(
optimizer,
lr_lambda=lambda epoch: (epoch + 1) / warmup_epochs
)
cosine_scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer,
T_max=epochs - warmup_epochs
)
scheduler = torch.optim.lr_scheduler.SequentialLR(
optimizer,
schedulers=[warmup_scheduler, cosine_scheduler],
milestones=[warmup_epochs]
)
学习率变化如图所示:

四、总结:学习率衰减策略全景对比
| 策略 | 特点 | 常用场景 |
|---|---|---|
| StepLR | 固定间隔衰减 | 简单任务 baseline |
| MultiStepLR | 指定节点衰减 | 人工控制训练节奏 |
| ExponentialLR | 指数平滑下降 | 长期训练任务 |
| CosineAnnealingLR ⭐ | 平滑退火下降 | 大模型训练首选 |
| Warmup ⭐ | 初期逐步升高 | Transformer 必备 |
| Warmup + Cosine ⭐⭐⭐ | 最佳组合方案 | 工业级训练标准配置 |
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)