一、优化器 (Optimizer)
优化器负责根据损失函数的梯度更新模型参数,以最小化损失值。所有优化器都继承自基类 torch.optim.Optimizer。
1. SGD (随机梯度下降)
最基础的优化算法,适用于各种场景。
核心参数:
torch.optim.SGD(
params, # 待优化的参数 (model.parameters())
lr=0.01, # 学习率 (默认0.01)
momentum=0, # 动量因子 (加速收敛,减少震荡)
dampening=0, # 动量抑制因子 (默认0)
weight_decay=0, # L2正则化系数 (权重衰减)
nesterov=False # 是否使用Nesterov动量
)
参数解释:
- 动量因子 (Momentum):模拟了物体运动的惯性特性,帮助优化器在正确方向加速,减少震荡:
v_t = β * v_{t-1} + (1 - β) * g_t
θ_t = θ_{t-1} - η * v_t
其中:
- v_t:当前动量
- β:动量因子 (0 < β < 1),典型取值:
- SGD:β = 0.9 (常用)
- Adam:β1 = 0.9 (一阶动量)
- g_t:当前梯度
- θ_t:更新后的参数
- η:学习率
- 权重衰减 (Weight Decay):权重衰减本质是L2正则化,在损失函数中添加参数范数惩罚项:
L_reg = L_orig + λ/2 * ||θ||^2
优化器更新时:
θ_t = θ_{t-1} - η * (g_t + λ * θ_{t-1})
使用场景:
- 基础训练任务
- 配合动量(momentum>0)可加速收敛
- 需要精细调优的场景
示例:
optimizer = torch.optim.SGD(
model.parameters(),
lr=0.1,
momentum=0.9,
weight_decay=1e-4
)
2. Adam (自适应矩估计)
结合了动量法和RMSProp的优点,是当前最常用的优化器。
核心参数:
torch.optim.Adam(
params,
lr=0.001, # 学习率 (默认0.001)
betas=(0.9, 0.999), # 一阶和二阶矩估计的指数衰减率
eps=1e-8, # 数值稳定常数 (防止除零)
weight_decay=0, # L2正则化
amsgrad=False # 是否使用AMSGrad变体
)
使用场景:
- 大多数深度学习任务的首选
- 对超参数相对不敏感
- 训练收敛速度快
示例:
optimizer = torch.optim.Adam(
model.parameters(),
lr=0.001,
betas=(0.9, 0.99),
weight_decay=1e-5
)
3. RMSprop
适用于非平稳目标,对循环神经网络效果较好。
核心参数:
torch.optim.RMSprop(
params,
lr=0.01, # 学习率
alpha=0.99, # 平滑常数
eps=1e-8, # 数值稳定常数
weight_decay=0, # L2正则化
momentum=0, # 动量因子
centered=False # 是否计算中心化的方差
)
使用场景:
- RNN/LSTM等序列模型
- 非平稳目标函数
- 当Adam效果不佳时可尝试
示例:
optimizer = torch.optim.RMSprop(
model.parameters(),
lr=0.01,
alpha=0.98
)
4. Adagrad (自适应梯度)
为每个参数分配不同的学习率,适合稀疏数据。
核心参数:
torch.optim.Adagrad(
params,
lr=0.01, # 初始学习率
lr_decay=0, # 学习率衰减系数
weight_decay=0, # L2正则化
initial_accumulator_value=0 # 累加器初始值
)
使用场景:
- 自然语言处理
- 推荐系统
- 稀疏特征数据
示例:
optimizer = torch.optim.Adagrad(
model.parameters(),
lr=0.01,
weight_decay=1e-4
)
5. AdamW (Adam + 权重衰减)
Adam的改进版本,正确处理权重衰减。
核心参数:
torch.optim.AdamW(
params,
lr=0.001,
betas=(0.9, 0.999),
eps=1e-8,
weight_decay=0.01, # 权重衰减系数 (比Adam更有效)
amsgrad=False
)
使用场景:
- 需要正则化的复杂模型
- 计算机视觉任务 (ViT, ConvNext等)
- 当标准Adam出现过拟合时
示例:
optimizer = torch.optim.AdamW(
model.parameters(),
lr=0.0001,
weight_decay=0.05
)
二、学习率调度器 (lr_scheduler)
动态调整学习率可以显著提高模型性能和收敛速度。所有调度器都通过 step() 方法更新学习率。
1. StepLR (步长衰减)
torch.optim.lr_scheduler.StepLR(
optimizer, # 绑定的优化器
step_size, # 衰减周期 (epoch数)
gamma=0.1, # 衰减系数
last_epoch=-1 # 上一个epoch索引
)
使用场景:
- 稳定收敛后降低学习率
- 简单训练策略
示例:
scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
for epoch in range(100):
train(...)
validate(...)
scheduler.step() # 每个epoch后更新
2. MultiStepLR (多步衰减)
torch.optim.lr_scheduler.MultiStepLR(
optimizer,
milestones, # 衰减点列表 [30, 80]
gamma=0.1,
last_epoch=-1
)
使用场景:
- 在特定epoch调整学习率
- 复杂训练计划
示例:
scheduler = MultiStepLR(optimizer, milestones=[30, 80], gamma=0.1)
3. ExponentialLR (指数衰减)
torch.optim.lr_scheduler.ExponentialLR(
optimizer,
gamma, # 指数衰减因子
last_epoch=-1
)
使用场景:
- 平滑连续的学习率衰减
- 需要缓慢调整学习率的任务
示例:
scheduler = ExponentialLR(optimizer, gamma=0.95) # 每个epoch衰减5%
4. ReduceLROnPlateau (基于指标衰减)
torch.optim.lr_scheduler.ReduceLROnPlateau(
optimizer,
mode='min', # 'min'或'max' (指标优化方向)
factor=0.1, # 衰减系数
patience=10, # 等待epoch数无改善
verbose=True, # 打印信息
threshold=1e-4, # 显著变化阈值
cooldown=0, # 衰减后等待epoch数
min_lr=0 # 学习率下限
)
使用场景:
- 验证指标停滞时自动降低学习率
- 避免手动调整学习率
示例:
scheduler = ReduceLROnPlateau(optimizer, 'max', patience=5) # 准确率最大
for epoch in range(100):
train(...)
val_acc = validate(...)
scheduler.step(val_acc) # 传入监控指标
5. CosineAnnealingLR (余弦退火)
torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer,
T_max, # 半周期长度 (epoch数)
eta_min=0 # 最小学习率
)
使用场景:
- 重启优化 (SimCLR, SWAV等)
- 跳出局部最优解
示例:
scheduler = CosineAnnealingLR(optimizer, T_max=50, eta_min=1e-6)
6. OneCycleLR (单周期策略)
torch.optim.lr_scheduler.OneCycleLR(
optimizer,
max_lr, # 峰值学习率
total_steps=None, # 总迭代次数
epochs=None, # 总epoch数
steps_per_epoch=None,# 每epoch迭代次数
pct_start=0.3, # 上升阶段比例
anneal_strategy='cos', # 'cos'或'linear'
cycle_momentum=True, # 是否调整动量
base_momentum=0.85, # 基础动量
max_momentum=0.95, # 最大动量
div_factor=25.0, # max_lr = initial_lr * div_factor
final_div_factor=1e4 # min_lr = initial_lr / final_div_factor
)
使用场景:
- 快速收敛
- 小批量数据训练
- 无需复杂调参
示例:
scheduler = OneCycleLR(
optimizer,
max_lr=0.01,
epochs=50,
steps_per_epoch=len(train_loader),
pct_start=0.25
)
for epoch in range(50):
for batch in train_loader:
optimizer.zero_grad()
loss = ...
loss.backward()
optimizer.step()
scheduler.step() # 每个batch后更新
三、优化器与调度器应用
典型训练循环
# 1. 初始化模型和优化器
model = MyModel()
optimizer = torch.optim.AdamW(model.parameters(), lr=0.001)
# 2. 创建学习率调度器
scheduler = torch.optim.lr_scheduler.OneCycleLR(
optimizer,
max_lr=0.01,
epochs=50,
steps_per_epoch=len(train_loader)
)
# 3. 训练循环
for epoch in range(50):
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
optimizer.zero_grad()
output = model(data)
loss = F.cross_entropy(output, target)
loss.backward()
# 梯度裁剪 (防止梯度爆炸)
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
optimizer.step()
scheduler.step() # 每个batch更新学习率
# 4. 验证和保存最佳模型
model.eval()
val_loss = validate(model, val_loader)
if val_loss < best_loss:
torch.save(model.state_dict(), 'best_model.pth')
best_loss = val_loss
优化器选择
| 场景 | 推荐优化器 | 说明 |
|---|---|---|
| 通用任务 | Adam/AdamW | 快速收敛,超参数鲁棒 |
| 计算机视觉 | SGD w/momentum | 配合学习率调度可获最佳结果 |
| NLP任务 | Adam/Adagrad | 适应稀疏特征 |
| 强化学习 | RMSprop | 经典DQN算法使用 |
| GAN训练 | Adam + SGD | 生成器和判别器使用不同优化器 |
| 大模型训练 | AdamW | 更好的权重衰减处理 |
调度器选择
| 需求 | 推荐调度器 | 特点 |
|---|---|---|
| 简单衰减 | StepLR/MultiStepLR | 手动控制衰减点 |
| 自动调整 | ReduceLROnPlateau | 根据验证指标自动调整 |
| 快速收敛 | OneCycleLR | 单周期策略,训练速度快 |
| 跳出局部最优 | CosineAnnealingLR | 周期性重启学习率 |
| 精细控制 | LambdaLR | 自定义衰减函数 |
| 热身阶段 | ChainedScheduler | 组合多个调度器 |
四、进阶技巧
-
参数组不同学习率:
optimizer = AdamW([ {'params': model.backbone.parameters(), 'lr': 1e-5}, {'params': model.head.parameters(), 'lr': 1e-3} ]) -
梯度裁剪:
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) -
监控学习率:
# 在训练循环中记录学习率 current_lr = optimizer.param_groups[0]['lr'] writer.add_scalar('lr', current_lr, global_step)
五、如何选择初始学习率
- 使用学习率范围测试:指数增加lr,观察损失变化
- 经验法则:
- SGD:0.01 ~ 0.1
- Adam:0.0001 ~ 0.001
- 大模型:1e-5 ~ 1e-4
- OneCycleLR:设置为最大学习率

1万+

被折叠的 条评论
为什么被折叠?



