文章目录
- 0.前言
- 1.学习率的概念
- 2.学习率的作用
- 3.学习率调度策略
- 3.1. StepLR
- 3.2. MultiStepLR
- 3.3.ExponentialLR
- 3.4. CosineAnnealingLR
- 3.5. ReduceLROnPlateau
- 3.6.LambdaLR
- 3.7. CyclicLR
- 3.8. OneCycleLR
- 4.使用方法
- 5.总结
0.前言
在深度神经网络训练中,学习率(Learning Rate)是一个重要的超参数,它决定了优化算法在每次更新模型参数时的步长大小。学习率对模型的训练过程和最终性能具有深远的影响。
本文主要介绍学习率的基本概念,以及在使用PyTorch训练神经网络模型时常用的学习率调度策略。
1.学习率的概念
学习率是控制每次迭代更新中梯度下降步幅大小的参数。在反向传播过程中,模型通过计算损失函数的梯度来更新参数,而学习率决定了沿梯度方向迈出多大的一步。
数学上,学习率通常用符号 η \eta η表示,更新公式为: θ = θ − η ⋅ ∇ J ( θ ) \theta = \theta - \eta \cdot \nabla J(\theta) θ=θ−η⋅∇J(θ)其中:
- θ \theta θ是模型参数。
- ∇ J ( θ ) \nabla J(\theta) ∇J(θ)是损失函数 J J J相对于参数 θ \theta θ的梯度。
2.学习率的作用
- 收敛速度:
- 大学习率:能够加快收敛速度,但可能导致错过最优点(overshooting)或震荡。
- 小学习率:增加了到达最优点的机会,但可能导致收敛过慢并增加训练时间。
- 优化效果:
- 适当的学习率有助于更快地达到模型的全局最优解或其附近,从而提升模型的性能。
- 稳定性:
- 学习率过大可能导致训练不稳定,模型发散。
- 学习率过小可能使训练停滞,容易陷入局部最优。
3.学习率调度策略
在PyTorch中,torch.optim.lr_scheduler._LRScheduler
是所有学习率调度器的基类。学习率调度器用于在训练过程中动态调整优化器的学习率,以改善模型的训练效果。
3.1. StepLR
逐步衰减学习率
StepLR(Step Learning Rate)是一种用于调节神经网络训练过程中学习率的策略。通过在训练过程中逐步降低学习率,StepLR有助于提高模型的稳定性和最终的收敛效果。
原理
StepLR策略的核心思想是在训练的过程中,每隔一段固定的时期(epoch),将学习率减少一个恒定的比例。这个过程形成了一个阶梯状的变化曲线,故称为“Step”(阶梯)学习率。
参数
- 初始学习率(initial learning rate):开始训练时的学习率。
- 步长(step size):每隔多少个epoch降低一次学习率。
- 下降因子(gamma):每次降低学习率的比例,通常小于1。例如,gamma=0.1意味着每次学习率变为原来的10%。
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
# step_size: 每经过多少个epoch调整一次学习率。
# gamma: 学习率调整的比例。新学习率 = 旧学习率 * gamma。
优势
- 简单明了:StepLR调度策略简单易用,仅需少量参数配置。
- 稳定收敛:在训练后期降低学习率可以帮助模型更接近全局最优并提升精度。
适用场景
StepLR特别适合于在模型训练后期希望降低步长进行精细调整的场景。不过,由于它是一个非常简单的调度策略,不适用于所有任务,尤其是在一些更复杂的训练需求下,可能需要更自适应的学习率调度策略(例如基于性能监控的ReduceLROnPlateau策略)。
3.2. MultiStepLR
在预定义的时间点逐步衰减学习率
MultiStepLR是一种学习率调度策略,它是StepLR的推广版本,用于在神经网络训练过程中更灵活地调整学习率。MultiStepLR允许用户在指定的多个epochs上调整学习率,而不是像StepLR那样每隔固定步长调整一次。这在需要对不同训练阶段采取不同学习率时尤其有用。
原理
MultiStepLR的原理与StepLR类似,都是通过在训练过程中降低学习率来帮助模型更稳定地收敛。不同之处在于,MultiStepLR允许用户指定多个epoch,当训练达到这些指定的epochs时,学习率将按照定义的因子进行缩减。
参数
- 初始学习率(initial learning rate):训练开始时的学习率。
- 里程碑(milestones):一个列表,包含了在训练过程中学习率要降低的epoch编号。例如,[30, 80]表示在第30和第80个epoch时降低学习率。
- 下降因子(gamma):学习率减少的比例,通常小于1,例如0.1表示每次减少到原来的10%。
scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[30, 80], gamma=0.1)
# milestones: 一个列表,包含在这些epoch时调整学习率。
# gamma: 学习率调整的比例。
优势
- 灵活性:MultiStepLR允许在不同时期改变学习率,使得用户可以根据具体的训练需求更加灵活地调整学习率。
- 稳定性:通过在需要的时期降低学习率,帮助模型在较小的学习率下进行更精细的权重更新,提高模型的泛化能力。
适用场景
MultiStepLR适合于复杂的训练任务,在这些任务中,简单的StepLR无法满足需求时,通过MultiStepLR可以更有效地控制学习率的变化,尤其是在训练分阶段进行以及每个阶段收敛速度不同的情况下。
3.3.ExponentialLR
按照指数方式衰减学习率
ExponentialLR是一种学习率调度策略,用于在训练过程中以指数递减的方式调整学习率。它通过在每一个epoch或每一个batch后按固定的指数因子缩减学习率,帮助模型以更平滑、渐进的方式逼近最优解。
原理
ExponentialLR递减学习率的基本公式是: new_lr = initial_lr × ( gamma ) epoch \text{new\_lr} = \text{initial\_lr} \times (\text{gamma})^{\text{epoch}} new_lr=initial_lr×(gamma)epoch
其中,gamma是一个小于1的常数,表示每个epoch学习率的缩减因子。
参数
- 初始学习率(initial learning rate):训练开始时设定的学习率。
- 下降因子(gamma):指数递减因子,通常在0到1之间(例如0.9),控制学习率递减的速度。
scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.95)
# gamma: 每个epoch学习率乘以的衰减因子。
优势
- 平滑性:通过指数方式平滑地减少学习率,避免了学习率骤降可能引发的不稳定性,从而可以更好地帮助模型收敛。
- 简单性与通用性:ExponentialLR只需设置一个简单的缩减因子gamma,适用于许多不同类型的任务和模型。
适用场景
ExponentialLR特别适用于那些训练过程中损失函数下降较为平缓、需要精细调整学习速率以达到最佳训练效果的任务。它也适用于一些预算有限的情形,因为它总是以一个稳定的速率调整学习率,使得训练过程中的性能波动可以控制在较小范围内。
3.4. CosineAnnealingLR
使用余弦退火法调整学习率
CosineAnnealingLR是一种用于动态调整学习率的调度策略,通过余弦退火(Cosine Annealing)方式来调整学习率。在训练过程中,学习率会以余弦曲线的方式逐渐减小,接近训练结束时再慢慢回到一个较高的学习率。这种非线性的调整方式有助于在训练的不同阶段更好地探索参数空间,从而找到更好的全局最优解。
原理
CosineAnnealingLR策略基于余弦函数,学习率的变化可以表示为: new_lr = min_lr + 1 2 ( max_lr − min_lr ) ( 1 + cos ( T c u r r T m a x π ) ) \text{new\_lr} = \text{min\_lr} + \frac{1}{2} (\text{max\_lr} - \text{min\_lr}) (1 + \cos(\frac{T_{curr}}{T_{max}} \pi)) new_lr=min_lr+21(max_lr−min_lr)(1+cos(TmaxTcurrπ))
其中:
- new_lr \text{new\_lr} new_lr 是当前的学习率。
- min_lr \text{min\_lr} min_lr是学习率的最小值。
- max_lr \text{max\_lr} max_lr是学习率的最大值,即初始学习率。
- T c u r r T_{curr} Tcurr是当前epoch的数目。
- T m a x T_{max} Tmax 是总的epoch数目,即周期长度。
这种策略会让学习率呈现一个类似余弦函数的波动曲线,在每个周期内从最大值逐渐减小到最小值,然后周期结束时再回升。
参数
- 初始学习率(initial learning rate):训练初始的学习率。
- 最小学习率(min_lr):余弦变化中学习率的最低值。
- 周期长度(T_max):一个周期内epoch的数目,通常等于训练的总epoch数。
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=50, eta_min=0)
# T_max: 余弦周期的最大步数。
# eta_min: 学习率的最低值。
优势
- 全局最优搜索:通过周期性地调节学习率,有助于跳出局部最优,寻找更优参数。
- 灵活适用性:适用于各种训练任务,尤其是那些需要在训练后期更加精细调整的情况。
- 避免手动配置:通过公式和参数化,减少了手动调整学习率的复杂性。
适用场景
CosineAnnealingLR适合用于深度神经网络中的很多场景,特别是在使用大规模数据集训练时,它在后期能够有效提高模型的泛化能力,避免出现过拟合现象。此策略尤其在图像分类、自然语言处理等任务中表现优异。
3.5. ReduceLROnPlateau
在验证指标停止提升时调整学习率
ReduceLROnPlateau是一种自适应的学习率调度策略,用于在训练过程中动态调整学习率。与固定策略不同,它根据模型性能的变化(通常是验证集上的损失或者准确率)来调整学习率。如果发现模型性能在若干个epoch后不再提高或停止改善,那么就会减少学习率。
原理
ReduceLROnPlateau的核心思想是通过监控模型在验证集上的表现指标(比如损失或准确率),判断是否需要降低学习率以继续优化模型。当检测到性能指标在一段时间内没有改善时,策略会自动降低学习率。
参数
- 监控指标(monitor):通常是验证损失或准确率,通过它来判断模型是否在进步。
- 模式(mode):
- ‘min’:若监控指标不变或上升,降低学习率(通常用在监控损失)。
- ‘max’:若监控指标不变或下降,降低学习率(通常用在监控准确率)。
- 因子(factor):每次降低学习率的倍率,通常小于1(例如0.1,表示学习率降为原来的10%)。
- 耐心度(patience):允许指标不改善的epoch数量。在这段时间内如果指标没有提升,则减少学习率。
- 最小学习率(min_lr):学习率可以降低到的最小值。
- 冷却时间(cooldown):每次降低学习率后,等待多少个epoch后才重新开始监控指标。
- 阈值(threshold):用于判断性能是否真的停止改善的小变化量,防止由于浮动而频繁调整学习率。
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10)
# mode: 'min' 或 'max',用于决定是否监控指标最小值或最大值。
# factor: 学习率调整的比例。
# patience: 在调整学习率之前,等待的epoch数量。
优势
- 自适应:根据模型的实际表现来调整学习率,能够更精确和合理地调节优化步长。
- 适应长时间训练:在长时间训练过程中,可以有效地在必要时减少学习率,以突破性能瓶颈。
- 避免手动调整:减少了人为尝试调整学习率的次数,使得模型训练更为自动化。
适用场景
ReduceLROnPlateau适用于那些训练早期进展较快,但在后期可能陷入停滞或存在收敛瓶颈的任务。尤其在深度学习中常用于处理大规模模型和训练数据集,以确保模型能在多个epoch内可持续地改善性能,是一种非常有效的学习率管理策略。
3.6.LambdaLR
通过自定义的lambda函数调整学习率
LambdaLR是一种灵活的学习率调度策略,允许用户通过自定义函数来调整学习率。与其他预定义调度策略不同,LambdaLR可以根据用户需求实现任意复杂或简单的学习率变化规则,为学习率调度提供了极大的灵活性。
原理
LambdaLR通过用户定义的“lambda函数”来确定学习率的调整方式。具体来说,这个调度器会在每个epoch结束时应用一个函数,该函数根据epoch数返回一个学习率乘以初始学习率的比例因子。
公式如下: new_lr = base_lr × λ ( epoch ) \text{new\_lr} = \text{base\_lr} \times \lambda(\text{epoch}) new_lr=base_lr×λ(epoch)其中, λ ( epoch ) \lambda(\text{epoch}) λ(epoch)是用户定义的函数, base_lr \text{base\_lr} base_lr是初始学习率。
参数
- optimizer:要进行学习率调度的优化器。
- lr_lambda:一个或多个计算乘子因子的lambda函数,可以是一个函数或函数列表(如果使用不同的参数组,每组需要一个函数)。
lambda1 = lambda epoch: 0.95 ** epoch
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda1)
# lr_lambda: 一个函数或函数列表,用于计算新的学习率。
优势
- 高度灵活:通过自定义lambda函数,用户可以精确控制学习率的变化模式,适合各种特殊需求。
- 便于实验:适合想要实验不同学习率调度策略的研究者,能够快速测试不同的函数形式。
- 支持多组参数:如果不同参数组有不同的学习率变化需求,lr_lambda可以是一个列表,其中每个lambda函数对应一个参数组。
适用场景
- 在调整学习率方面有特殊需求的复杂模型。
- 想要探索和实验不同学习率变化策略的科研任务。
- 多阶段训练过程中,需要根据不同阶段采用不同学习率变化规则的任务。
3.7. CyclicLR
使用周期学习率策略
CyclicLR是一种学习率调度策略,它在每个训练周期内循环调整学习率,通常在多次上升和下降之间波动。这种策略的设计初衷是为了在训练过程中,能够在局部最优陷阱之外进行探索,帮助模型更好地找到全局最优。
原理
CyclicLR基于周期性变化的概念调整学习率。在每个周期内,学习率从一个初始值(最小学习率)线性或者指数地增加到一个设定的最大值,然后再返回到初始值。这种波动提供了一个机制,让模型在参数空间中更灵活地探索,有助于增加模型的泛化能力。
参数
- base_lr:初始或最小学习率,周期开始时的学习率。
- max_lr:周期中的最大学习率。
- step_size_up:学习率从base_lr增加到max_lr的epoch/iterations数量。
- step_size_down:学习率从max_lr返回到base_lr的epoch/iterations数量。通常,如果不设置,与step_size_up相同。
- mode:决定学习率如何增加和减少的机制,主要有:
- ‘triangular’:线性增长和线性下降。
- ‘triangular2’:类似于三角形,但振幅逐步减小到一半。
- ‘exp_range’:用指数函数减小振幅。
scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.001, max_lr=0.01, step_size_up=2000)
# base_lr: 周期中的最低学习率。
# max_lr: 周期中的最高学习率。
# step_size_up: 上升部分的步数。
优势
- 提升模型泛化能力:通过在参数空间的不同区域进行探索,可能改善模型的泛化能力。
- 自动化调整:不需要手动调整学习率,从而简化了学习率调参过程。
- 适应多种任务:可以方便地调整 base_lr 和 max_lr 以适应不同任务需求。
CyclicLR 在深度学习领域常用于需要快速训练但有可能陷入局部最优的复杂模型,如图像分类、自然语言处理等任务。通过周而复始地调整学习率,该策略能够帮助模型在保持训练稳定性的同时提高性能。
3.8. OneCycleLR
在一个循环期间调整学习率到峰值,然后衰减回来
OneCycleLR 是一种先进的学习率调度策略,旨在通过在单个训练周期内动态调整学习率和动量来加速深度学习模型的训练。这种技术被发现在各种任务中提高模型的收敛速度和最终表现。
原理
OneCycleLR 的原理基于以下几个步骤:
- 学习率和动量的双向调整:学习率:从一个较低的起始值逐渐增加到一个最大值,然后再减小到一个比起始值低的最终值。动量:通常情况下,动量从一个较高值逐渐减小到较低值,然后再逐渐增加回一个中间值。
- 单个周期(One Cycle):整个调整过程在训练的单个周期内完成,即训练的全过程。OneCycleLR 不要求多个周期的重复训练。
- 提高模型鲁棒性:通过此类双向调整策略,使得模型更充分地探索参数空间,减少过拟合风险并提高泛化性能。
参数
- max_lr:学习率的最大值,在周期中的峰值。
- total_steps 或 epochs 和 steps_per_epoch:指定整个训练周期的步数或epoch数。
- pct_start:学习率增长阶段所占周期的比例,通常在0到1之间,比如0.3表示前30%用于增加学习率。
- anneal_strategy:退火策略,可以是 ‘cos’(余弦退火)或 ‘linear’(线性退火)。
- base_momentum 和 max_momentum:动量在整个周期内变化的范围。
- div_factor:初始学习率是 max_lr 除以 div_factor 的比值。
- final_div_factor:最终学习率是 max_lr 除以 final_div_factor 的比值。
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.01, total_steps=100)
# max_lr: 学习率的峰值。
# total_steps: 总的训练步骤数。
优势
- 加速训练:由于在训练初期快速提高学习率,可以更快地进行模型参数调整,达到快速收敛。
- 提升模型性能:有效的学习率调整策略能够提供更好的优化路径,提高最终模型的表现。
- 减少手工调参需求:通过系统性的学习率安排,减少对多次调试不同学习率曲线的需求。
OneCycleLR 在实践中已被证明是有效的,特别在图像分类和自然语言处理任务中表现显著。这种策略通过调优学习率和动量,为模型训练带来卓越的性能提升。
4.使用方法
通常在训练循环中,每个epoch后调用学习率调度器的step方法。
import torch
import torch.optim as optim# 定义模型和优化器
model = ... # 假设该模型已经定义
optimizer = optim.SGD(model.parameters(), lr=0.1)# 创建学习率调度器
scheduler = ...# 在训练循环中调整学习率
for epoch in range(num_epochs):for batch in train_loader:train(...) # 进行训练步骤optimizer.step()scheduler.step() # 更新学习率
5.总结
由于学习率对训练效果至关重要,选择合适的学习率是至关重要的任务。 三种常用方法:
初始尝试:通常从较小的学习率开始,并观察收敛率和模型效果。当变化减缓或者不稳定时,可以适当调整。
可视化学习曲线:通过图示的方式观察训练和验证损失随时间的变化情况以调整学习率。
学习率调度器:在库(如 PyTorch 或 TensorFlow)中使用预定义的调度器,帮助自动优化学习率变化。