今天刚好有空,来讲讲deep learning中学习率调节的常见技巧:余弦退火算法。
学习率调整
学习率是最影响性能的超参数之一,在我们的大多数的炼丹过程中,遇到 loss 变成 NaN 的情况大多数是由于学习率选择不当引起的(当然也有可能是loss实现过程有问题)。
过大的学习率容易造成loss NaN,太小的学习率会导致训练过程非常缓慢。所以在实际训练中,我们都会采用学习率调整的方法。调节的策略有很多,但都大致都遵从一个原则,即学习率在开始训练时很大,在训练过程中逐渐变小,在结束时达到一个最小值。
常见的方法,如:StepLR,设置好固定的训练节点,到达这个节点就将学习率下降一个固定值。LinearLR,以一个初始值和一个结束值做线性的下降。
Warm up
那么我们今天要介绍的是,余弦先退火算法CosineAnnealingLR。它的思路不同于以往的学习率调整策略。作者认为神经网络在刚开始训练时,并非如同理想的情况(见下图)一样,只需要确定一个方向即可。模型参数在初始化时,是非常不稳定的,因此在刚开始时需要选用小的学习率。

但是小的学习率会让训练过程非常缓慢,因此这里会采用以较低学习率逐渐增大至较高学习率的方式实现网络训练的“热身”阶段,称为 warm up stage。
CosineAnnealingLR
如果我们使得网络训练的 loss 最小,那么一直使用较高学习率是不合适的,因为它会使得权重的梯度一直来回震荡,很难使训练的损失值达到全局最低谷。所以学习率还是需要下降,可以通过余弦函数来降低学习率。余弦函数中随着x的增加余弦值首先缓慢下降,然后加速下降,再次缓慢下降。这种下降模式能和学习率配合,以一种十分有效的计算方式来产生很好的效果。
上述过程就称为余弦退火。

代码实现
pytorch实现
import torch.optim as optim
class CosineAnnealingWarmupRestarts(optim.lr_scheduler._LRScheduler):
"""
optimizer (Optimizer): Wrapped optimizer.
first_cycle_steps (int): First cycle step size.
cycle_mult(float): Cycle steps magnification. Default: -1.
max_lr(float): First cycle's max learning rate. Default: 0.1.
min_lr(float): Min learning rate. Default: 0.001.
warmup_steps(int): Linear warmup step size. Default: 0.
gamma(float): Decrease rate of max learning rate by cycle. Default: 1.
last_epoch (int): The index of last epoch. Default: -1.
"""
def __init__(self,
optimizer: torch.optim.Optimizer,
first_cycle_steps: int,
cycle_mult: float = 1.,
max_lr: float = 0.1,
min_lr: float = 0.001,
warmup_steps: int = 0,
gamma: float = 1.,
last_epoch: int = -1
):
assert warmup_steps < first_cycle_steps
self.first_cycle_steps = first_cycle_steps # first cycle step size
self

本文介绍了深度学习中学习率调整的重要性和常见问题,特别是学习率过大导致loss发散或过小导致训练缓慢。重点讲解了余弦退火算法(CosineAnnealingLR),它在训练初期采用小学习率进行warmup,随后通过余弦函数平滑降低学习率,以避免梯度震荡。此外,提供了PyTorch和TensorFlow的代码实现,帮助读者理解并应用该策略。
最低0.47元/天 解锁文章
952





