学习率调度:PyTorch训练过程动态调整策略

【免费下载链接】pytorch-deep-learning Materials for the Learn PyTorch for Deep Learning: Zero to Mastery course. 【免费下载链接】pytorch-deep-learning 项目地址: https://gitcode.com/GitHub_Trending/py/pytorch-deep-learning

引言:为什么学习率调度如此重要?

在深度学习模型训练过程中,学习率(Learning Rate)是最关键的超参数之一。它决定了模型参数在每次迭代中更新的步长大小。一个合适的学习率可以显著加速模型收敛,提高训练效率,而一个不恰当的学习率则可能导致训练过程发散或陷入局部最优解。

痛点场景:你是否遇到过以下情况?

  • 训练初期loss下降迅速,但后期几乎停滞不前?
  • 模型在验证集上的表现波动剧烈,难以稳定提升?
  • 尝试了各种学习率值,但始终无法找到最优设置?

这些问题往往可以通过智能的学习率调度策略来解决。本文将深入探讨PyTorch中的学习率调度机制,帮助你掌握动态调整学习率的艺术。

学习率调度基础概念

什么是学习率调度?

学习率调度(Learning Rate Scheduling)是指在训练过程中根据预定义的策略动态调整学习率的技术。与使用固定学习率相比,学习率调度能够:

  • 加速收敛:在训练初期使用较大学习率快速下降
  • 提高精度:在训练后期使用较小学习率精细调优
  • 避免震荡:防止在最优解附近来回震荡
  • 跳出局部最优:通过周期性调整帮助模型跳出局部最小值

学习率调度策略分类

mermaid

PyTorch内置学习率调度器详解

1. StepLR:阶梯式下降

StepLR是最简单的学习率调度器,每隔固定步数将学习率乘以一个衰减因子。

import torch
import torch.optim as optim
from torch.optim import lr_scheduler

# 创建模型和优化器
model = torch.nn.Linear(10, 1)
optimizer = optim.SGD(model.parameters(), lr=0.1)

# 创建StepLR调度器
scheduler = lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)

# 训练循环中的使用
for epoch in range(100):
    # 训练步骤...
    train(...)
    
    # 更新学习率
    scheduler.step()
    
    # 打印当前学习率
    print(f'Epoch {epoch}, Learning Rate: {scheduler.get_last_lr()}')

参数说明

  • step_size:学习率衰减的周期步数
  • gamma:学习率衰减的乘数因子

2. MultiStepLR:多阶段阶梯下降

MultiStepLR允许在多个特定的epoch点进行学习率调整。

# 创建MultiStepLR调度器
scheduler = lr_scheduler.MultiStepLR(
    optimizer, 
    milestones=[30, 80],  # 在第30和80个epoch调整学习率
    gamma=0.1
)

3. ExponentialLR:指数衰减

ExponentialLR在每个epoch都将学习率乘以gamma因子,实现指数衰减。

scheduler = lr_scheduler.ExponentialLR(optimizer, gamma=0.95)

4. ReduceLROnPlateau:基于性能调整

这是最实用的调度器之一,当验证指标停止改善时自动降低学习率。

scheduler = lr_scheduler.ReduceLROnPlateau(
    optimizer,
    mode='min',           # 监控指标的模式:min或max
    factor=0.1,           # 学习率衰减因子
    patience=10,          # 等待多少个epoch没有改善
    verbose=True,         # 打印调整信息
    threshold=0.0001,     # 改善的最小阈值
    cooldown=5            # 调整后的冷却期
)

# 训练循环中的使用
for epoch in range(100):
    # 训练步骤
    train_loss = train(...)
    
    # 验证步骤
    val_loss = validate(...)
    
    # 根据验证损失更新学习率
    scheduler.step(val_loss)

5. CosineAnnealingLR:余弦退火

CosineAnnealingLR使用余弦函数周期性地调整学习率,有助于跳出局部最优。

scheduler = lr_scheduler.CosineAnnealingLR(
    optimizer, 
    T_max=50,    # 半个周期的epoch数
    eta_min=0     # 最小学习率
)

高级调度策略组合

OneCycleLR策略

OneCycleLR是一种高效的调度策略,先升温再降温,在一个周期内完成学习率调整。

scheduler = lr_scheduler.OneCycleLR(
    optimizer,
    max_lr=0.1,              # 最大学习率
    steps_per_epoch=len(train_loader),
    epochs=100,
    pct_start=0.3,           # 升温阶段占比
    div_factor=25,           # 初始学习率 = max_lr/div_factor
    final_div_factor=1e4     # 最终学习率 = max_lr/final_div_factor
)

自定义调度策略

使用LambdaLR可以创建完全自定义的调度策略:

# 自定义学习率函数
def lambda_rule(epoch):
    if epoch < 50:
        return 1.0
    elif epoch < 100:
        return 0.5
    else:
        return 0.1

scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda_rule)

学习率调度实践指南

选择合适调度策略的决策流程

mermaid

超参数调优建议

调度器类型 关键参数 推荐值范围 调整建议
StepLR step_size 20-50 epochs 根据总epoch数调整,通常占总epoch数的1/3-1/2
MultiStepLR milestones [30, 60, 90] 在训练损失平台期设置里程碑点
ReduceLROnPlateau patience 5-15 epochs 根据验证集波动情况调整,波动大时增大patience
CosineAnnealingLR T_max 20-100 epochs 根据问题复杂度调整,复杂问题用较大T_max
OneCycleLR pct_start 0.3-0.5 升温阶段占比,数据量大时用较小值

监控与调试技巧

  1. 学习率曲线可视化
import matplotlib.pyplot as plt

learning_rates = []
for epoch in range(num_epochs):
    # ...训练步骤
    scheduler.step()
    learning_rates.append(scheduler.get_last_lr()[0])

plt.plot(learning_rates)
plt.xlabel('Epoch')
plt.ylabel('Learning Rate')
plt.title('Learning Rate Schedule')
plt.show()
  1. 多调度器组合使用
# 组合使用多个调度器
scheduler1 = lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
scheduler2 = lr_scheduler.ReduceLROnPlateau(optimizer, patience=5)

# 在训练循环中
for epoch in range(100):
    train(...)
    val_loss = validate(...)
    
    # 先使用StepLR
    scheduler1.step()
    
    # 再使用ReduceLROnPlateau
    scheduler2.step(val_loss)

实际案例:图像分类任务中的学习率调度

ResNet模型训练配置

import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
from torchvision import models

# 加载预训练模型
model = models.resnet50(pretrained=True)
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 10)  # 假设10分类任务

# 配置优化器和调度器
optimizer = optim.SGD(
    model.parameters(),
    lr=0.01,
    momentum=0.9,
    weight_decay=1e-4
)

# 使用CosineAnnealingLR调度器
scheduler = lr_scheduler.CosineAnnealingLR(
    optimizer,
    T_max=100,      # 假设训练100个epoch
    eta_min=1e-6    # 最小学习率
)

# 训练循环
for epoch in range(100):
    # 训练阶段
    model.train()
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
    
    # 更新学习率
    scheduler.step()
    
    # 验证阶段
    model.eval()
    with torch.no_grad():
        # ...验证代码

【免费下载链接】pytorch-deep-learning Materials for the Learn PyTorch for Deep Learning: Zero to Mastery course. 【免费下载链接】pytorch-deep-learning 项目地址: https://gitcode.com/GitHub_Trending/py/pytorch-deep-learning

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐