学习率衰减策略
等间隔学习率衰减(Step Decay) 是一种常用的学习率调整策略。它的核心思想是:在训练过程中,每隔固定的训练轮数(epoch),将学习率乘以一个衰减系数 γ \gamma γ,从而逐步降低学习率。
1. 等间隔学习率衰减的数学原理
1.1 数学公式
等间隔学习率衰减的公式为:
η t = η 0 ⋅ γ ⌊ t / s ⌋ \eta_t = \eta_0 \cdot \gamma^{\lfloor t / s \rfloor} ηt=η0⋅γ⌊t/s⌋
其中:
- η t \eta_t ηt 是第 t t t 轮(epoch)的学习率。
- η 0 \eta_0 η0 是初始学习率。
- γ \gamma γ 是衰减系数(通常取值在 [ 0.1 , 0.5 ] [0.1, 0.5] [0.1,0.5] 之间)。
- s s s 是衰减步长(每隔 s s s 轮衰减一次)。
- ⌊ t / s ⌋ \lfloor t / s \rfloor ⌊t/s⌋ 表示对 t / s t / s t/s 取整。
1.2 公式解析
-
初始学习率 η 0 \eta_0 η0:
- 训练开始时,学习率为 η 0 \eta_0 η0。
- 例如, η 0 = 0.1 \eta_0 = 0.1 η0=0.1。
-
衰减步长 s s s:
- 每隔 s s s 轮,学习率会衰减一次。
- 例如, s = 30 s = 30 s=30 表示每 30 轮衰减一次。
-
衰减系数 γ \gamma γ:
- 每次衰减时,学习率会乘以 γ \gamma γ。
- 例如, γ = 0.1 \gamma = 0.1 γ=0.1 表示学习率衰减为原来的 10%。
-
取整函数 ⌊ t / s ⌋ \lfloor t / s \rfloor ⌊t/s⌋:
- 表示当前训练轮数 t t t 除以衰减步长 s s s 后取整。
- 例如, t = 35 t = 35 t=35, s = 30 s = 30 s=30,则 ⌊ 35 / 30 ⌋ = 1 \lfloor 35 / 30 \rfloor = 1 ⌊35/30⌋=1。
1.3 示例
假设:
- 初始学习率 η 0 = 0.1 \eta_0 = 0.1 η0=0.1。
- 衰减步长 s = 30 s = 30 s=30。
- 衰减系数 γ = 0.1 \gamma = 0.1 γ=0.1。
则学习率的变化如下:
- 第 0-29 轮: η t = 0.1 \eta_t = 0.1 ηt=0.1。
- 第 30-59 轮: η t = 0.1 ⋅ 0.1 = 0.01 \eta_t = 0.1 \cdot 0.1 = 0.01 ηt=0.1⋅0.1=0.01。
- 第 60-89 轮: η t = 0.1 ⋅ 0. 1 2 = 0.001 \eta_t = 0.1 \cdot 0.1^2 = 0.001 ηt=0.1⋅0.12=0.001。
- 以此类推。
2. 等间隔学习率衰减的作用机制
2.1 训练初期的学习率
在训练初期,学习率较大,可以帮助模型快速收敛。较大的学习率能够:
- 加快参数更新的速度。
- 帮助模型跳出局部最优解。
2.2 训练中后期的学习率
在训练中后期,学习率逐渐减小,可以帮助模型精细调整参数。较小的学习率能够:
- 避免在最优解附近震荡。
- 提高模型的收敛精度。
2.3 衰减步长 s s s 的选择
衰减步长 s s s 的选择非常重要:
- 如果 s s s 过小,学习率会频繁衰减,可能导致训练过早停滞。
- 如果 s s s 过大,学习率衰减过慢,可能导致训练后期震荡。
通常, s s s 的选择需要根据具体任务和数据集进行调整。
3. PyTorch 中的实现
在 PyTorch 中,等间隔学习率衰减可以通过 torch.optim.lr_scheduler.StepLR
实现。
3.1 代码示例
以下是一个使用等间隔学习率衰减的完整代码示例:
import torch
import torch.nn as nn
import torch.optim as optim
# 定义一个简单的线性模型
model = nn.Linear(10, 1)
# 定义损失函数
criterion = nn.MSELoss()
# 定义优化器
optimizer = optim.SGD(model.parameters(), lr=0.1)
# 定义等间隔学习率衰减策略
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
# 训练过程
for epoch in range(100):
# 模拟训练步骤
inputs = torch.randn(32, 10) # 32 个样本,每个样本 10 维
targets = torch.randn(32, 1) # 32 个目标值
# 前向传播
outputs = model(inputs)
loss = criterion(outputs, targets)
# 反向传播
optimizer.zero_grad() # 清空梯度
loss.backward() # 计算梯度
# 更新参数
optimizer.step() # 更新参数
# 更新学习率
scheduler.step()
# 打印当前学习率
if (epoch + 1) % 10 == 0:
print(f"Epoch [{epoch+1}/100], Learning Rate: {scheduler.get_last_lr()[0]:.6f}, Loss: {loss.item():.4f}")
3.2 代码解析
-
定义模型和优化器:
- 使用
nn.Linear
定义一个简单的线性模型。 - 使用
optim.SGD
定义优化器,初始学习率为 0.1。
- 使用
-
定义学习率衰减策略:
- 使用
optim.lr_scheduler.StepLR
定义等间隔学习率衰减策略。 step_size=30
表示每隔 30 轮衰减一次。gamma=0.1
表示每次衰减为原来的 10%。
- 使用
-
训练过程:
- 在每个 epoch 中,执行前向传播、反向传播和参数更新。
- 调用
scheduler.step()
更新学习率。
-
打印学习率:
- 使用
scheduler.get_last_lr()
获取当前学习率。
- 使用
4. 总结
- 等间隔学习率衰减:每隔固定的训练轮数,将学习率乘以一个衰减系数。
- 数学公式:
η t = η 0 ⋅ γ ⌊ t / s ⌋ \eta_t = \eta_0 \cdot \gamma^{\lfloor t / s \rfloor} ηt=η0⋅γ⌊t/s⌋ - 作用机制:
- 训练初期:较大的学习率加快收敛。
- 训练中后期:较小的学习率提高精度。
- PyTorch 实现:使用
torch.optim.lr_scheduler.StepLR
。