深度学习中常见的学习率调整策略
一、简介
在深度学习中,学习率是一个关键的超参数,它决定了模型在每次迭代中更新参数的步长。选择合适的学习率对于模型的收敛速度和最终性能至关重要。为了提高模型的训练效果,常常需要动态调整学习率。
二、常见策略
这里,我们介绍一些常用的学习率调度器。
1. StepLR
StepLR调度器在每隔固定的epoch数后,将学习率按一定的比例缩小。适用于需要在训练过程中定期降低学习率的场景。
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR
# 创建优化器
optimizer = optim.SGD(model.parameters(), lr=0.1)
# 创建StepLR调度器,每隔30个epoch将学习率缩小为原来的0.1倍
scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
# 在训练循环中使用调度器
for epoch in range(num_epochs):
train(...)
scheduler.step()
2. MultiStepLR
MultiStepLR调度器在指定的epoch数时,将学习率按一定的比例缩小。适用于需要在训练过程中在特定的epoch数降低学习率的场景。
import torch.optim as optim
from torch.optim.lr_scheduler import MultiStepLR
# 创建优化器
optimizer = optim.SGD(model.parameters(), lr=0.1)
# 创建MultiStepLR调度器,在第30和80个epoch时将学习率缩小为原来的0.1倍
scheduler = MultiStepLR(optimizer, milestones=[30, 80], gamma=0.1)
# 在训练循环中使用调度器
for epoch in range(num_epochs):
train(...)
scheduler.step()
3. ExponentialLR
ExponentialLR调度器在每个epoch后,将学习率按指数规律缩小。适用于需要在训练过程中逐步减小学习率的场景。
import torch.optim as optim
from torch.optim.lr_scheduler import ExponentialLR
# 创建优化器
optimizer = optim.SGD(model.parameters(), lr=0.1)
# 创建ExponentialLR调度器,每个epoch将学习率缩小为原来的0.95倍
scheduler = ExponentialLR(optimizer, gamma=0.95)
# 在训练循环中使用调度器
for epoch in range(num_epochs):
train(...)
scheduler.step()
4. CosineAnnealingLR
CosineAnnealingLR调度器使用余弦退火策略,在一个周期内将学习率从初始值逐渐减小到最小值。适用于需要在训练过程中周期性调整学习率的场景。
import torch.optim as optim
from torch.optim.lr_scheduler import CosineAnnealingLR
# 创建优化器
optimizer = optim.SGD(model.parameters(), lr=0.1)
# 创建CosineAnnealingLR调度器,周期为T_max个epoch,学习率的最小值0.01(默认最小值为0)
# last_epoch是一个整数,表示上一个epoch的索引。默认值为 -1,表示从头开始。如果需要从某个特定epoch开始调整学习率,可以设置这个参数
scheduler = CosineAnnealingLR(optimizer, T_max=50, eta_min=0.01, last_epoch=-1)
# 在训练循环中使用调度器
for epoch in range(num_epochs):
train(...)
scheduler.step()
5. CosineAnnealingWarmRestarts
CosineAnnealingWarmRestarts调度器结合了余弦退火和热启动策略,在每个周期内将学习率从初始值逐渐减小到最小值,然后重新开始。适用于需要在训练过程中多次调整学习率的场景。
import torch.optim as optim
from torch.optim.lr_scheduler import CosineAnnealingWarmRestarts
# 创建优化器
optimizer = optim.SGD(model.parameters(), lr=0.1)
# 创建CosineAnnealingWarmRestarts调度器,初始周期为T_0个epoch
# T_0为初始的周期长度(以epoch为单位),在第一个周期内,学习率将从初始值逐渐减小到最小值。
# T_mult是一个整数,表示每次重启时周期长度的倍增因子。默认值为1,表示每次重启时周期长度保持不变。如果设置为2,则每次重启时周期长度将翻倍。
# eta_min表示学习率的最小值。默认值为0。
# last_epoch表示上一个epoch的索引,默认值为-1。
scheduler = CosineAnnealingWarmRestarts(optimizer, T_0=10, T_mult=2)
# 在训练循环中使用调度器
for epoch in range(num_epochs):
train(...)
scheduler.step(epoch)
6. OneCycleLR
OneCycleLR调度器在一个周期内先增加学习率到最大值,然后再逐渐减小到最小值。适用于需要在训练过程中快速找到最佳学习率的场景。
import torch.optim as optim
from torch.optim.lr_scheduler import OneCycleLR
num_epochs = 10
# 创建优化器
optimizer = optim.SGD(model.parameters(), lr=0.1)
# 创建OneCycleLR调度器,设置最大学习率和总步数
# div_factor是一个浮点数,表示初始学习率与最大学习率的比值,默认值为25,即初始学习率为max_lr/25。
# final_div_factor是一个浮点数,表示最终学习率与初始学习率的比值,默认值为1e4,即最终学习率为initial_lr/1e4。
scheduler = OneCycleLR(optimizer, max_lr=0.1, steps_per_epoch=len(dataloader), epochs=num_epochs, div_factor=25, final_div_factor=1e4)
# 在训练循环中使用调度器
for epoch in range(num_epochs):
for batch in dataloader:
train(...)
scheduler.step()
7. LambdaLR
LambdaLR调度器允许用户自定义学习率的调整策略,通过传入一个函数来定义学习率的变化规律。适用于需要灵活调整学习率的场景。
import torch.optim as optim
from torch.optim.lr_scheduler import LambdaLR
# 创建优化器
optimizer = optim.SGD(model.parameters(), lr=0.1)
# 定义自定义的学习率调整函数
lambda_lr = lambda epoch: 0.95 ** epoch
# 创建LambdaLR调度器
scheduler = LambdaLR(optimizer, lr_lambda=lambda_lr)
# 在训练循环中使用调度器
for epoch in range(num_epochs):
train(...)
scheduler.step()
8、Cyclical Learning Rate (CLR)
学习率在一个周期内循环变化,可以帮助模型跳出局部最优解。常见的CLR方法包括三角形策略(Triangular Policy)和余弦退火策略(Cosine Annealing)。
from torch.optim.lr_scheduler import CyclicLR
# 创建优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 创建学习率调度器
# 在前step_size_up次迭代中,学习率从base_lr 线性增加到max_lr
# 在接下来的step_size_up次迭代中,学习率从max_lr 线性减小回base_lr
scheduler = CyclicLR(optimizer, base_lr=0.001, max_lr=0.01, step_size_up=2000, mode='triangular')
# 在训练循环中使用调度器
for epoch in range(num_epochs):
for batch in dataloader:
train(...)
scheduler.step()
9、ReduceLROnPlateau
当监控的指标在若干个epoch内没有改善时,降低学习率。常用于训练过程中验证集损失不再下降的情况。
import torch.optim as optim
# 创建优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 创建学习率调度器
# 当监控的指标在指定的patience个epoch内没有改善时,学习率将乘以factor
# mode是监控指标的模式,可以是'min'或'max':
# 'min':当监控的指标不再减小时(即指标值不再变小),降低学习率。
# 'max':当监控的指标不再增大时(即指标值不再变大),降低学习率。
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10, verbose=True)
# 在训练循环中使用调度器
for epoch in range(num_epochs):
train(...)
val_loss = validate(...)
scheduler.step(val_loss)
三、总结
一般情况下,我们最开始建模使用的学习率是固定不变的,这也是最基础的情况。当我们发现在这种情况下模型的损失跌宕起伏,甚至不收敛时,则可以考虑使用学习率调度器帮助我们找到最佳的学习率。