在深度学习训练中,学习率调度器(Learning Rate Scheduler)是至关重要的超参数优化工具。其中,余弦退火(Cosine Annealing)因其平滑的衰减特性和优秀的性能表现,已成为最流行的调度策略之一。
CosineAnnealingLR 基础
余弦退火的学习率变化遵循余弦函数:
\(\eta_t=\eta_{min}+\frac12(\eta_{max}-\eta_{min})\Big(1+\cos\big(\frac{t}{T_{max}}\pi\big)\Big)\)
- \(\eta_t\):当前步学习率
- \(\eta_{max}\):优化器初始学习率
- \(\eta_{min}\):
eta_min,学习率下限 - t:当前 step(batch 迭代次数)
- \(T_{max}\):余弦周期长度
当 \(t=T_{max}\),\(\cos(\pi)=-1\),学习率 = \(\eta_{min}\)。
基本用法
python
import torch
import torch.optim as optim
from torch.optim.lr_scheduler import CosineAnnealingLR
# 定义优化器
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 创建余弦退火调度器
scheduler = CosineAnnealingLR(
optimizer,
T_max=100, # 周期长度
eta_min=1e-6 # 最小学习率
)
T_max 参数
T_max 控制学习率从最大值下降到最小值所需的步数。
整个训练全部迭代步数,一次完整余弦衰减,训练结束 lr 到达 eta_min。
通常设置为:
- T_max = total_iter = (样本数 // batch_size) × epochs
- T_max = epochs
| 配置 | 调用 scheduler.step () 时机 |
|---|---|
T_max = total_iterations |
每个 batch 内部执行一次(每 1 个 step 调用) |
T_max = epochs |
epoch 循环末尾调用,一个 epoch 只 step 一次 |
T_max = total_iterations(总迭代 step)
使用条件(两个必须同时满足)
scheduler.step() 写在内层 batch 循环,每跑完一个 batch 调用一次
python
for epoch in range(epochs):
for imgs, label in dataloader:
# 前向、loss、反向传播
optimizer.step()
scheduler.step() #每个batch调用
T_max = total_iterations = (num_samples // batch_size) * epochs
T_max = epochs(T_max 数值等于轮数)
调度器调用时机
python
# 正确配套写法
scheduler = CosineAnnealingLR(optimizer, T_max=epochs, eta_min=1e‑6)
for epoch in range(epochs):
for imgs, label in dataloader:
#训练,只更新optimizer,不调用scheduler.step()
optimizer.step()
scheduler.step() #❗每个epoch结束才调用一次
假设epoch=100,学习率初始值为0.0006,
当T_max = epochs,则学习率变化;

当T_max < epochs,则学习率变化;

当T_max > epochs,则学习率变化;下图学习率最小值停留在0.0003

eta_min 参数
eta_min:余弦退火的学习率最低下限。
eta_min=0:训练末尾学习率直接归零,参数不再更新;
eta_min=1e‑6(工程常用):保留极小学习率,允许参数微小更新,避免训练末期完全冻结。
不建议直接置 0,部分场景会出现收敛停滞。CV 任务(车道线、检测)推荐
eta_min=1e‑6 ~ 1e‑7。