Pytorch动态调整学习率的方法详解及示例

PyTorch动态调整学习率

  在深度神经网络中,学习率是最重要的超参数之一。如何调整学习率是“炼丹玄学”中最重要的药方之一。作为当前最为流行的深度学习框架,PyTorch已经为我们封装好了一些在训练过程中动态调整学习率的方法,下面就让我们来看一下。

torch.optim.lr_scheduler

  在torch.optim.lr_scheduler上,基于当前epoch的数值,为我们封装了几种相应的动态学习率调整方法,该部分的官方手册传送门——optim.lr_scheduler官方文档需要注意的是学习率的调整需要应用在优化器参数更新之后,其应用的简要代码示例如下:

>>> optimizer = torch.optim.Adam(...) #选择一种优化器
>>> scheduler = torch.optim.lr_scheduler.... # 选择一种动态调整学习率的方法,可以是下面几种之一
>>> for epoch in range(100):
>>>     train(...)
>>>     validate(...)

>>>     optimizer.step()
>>>     scheduler.step() # 需要在优化器参数更新之后再动态调整学习率

  下面将介绍一下torch.optim.lr_scheduler中封装的各种动态调整学习率的方法。

torch.optim.lr_scheduler.LambdaLR

该类的参数说明
  这种动态调整方法的原理是:将每一个参数组的学习率调整为初始化学习率lr的给定函数倍,在fine-tune中十分有用,我们不仅可以为不同的层设定不同的学习率,还可以为其设定不同的学习率调整策略。它的官方形参说明如上,第一个形参optimizer是之前定义好的优化器的实例名(wrapped optimizer)。第二个形参lr_lambda可以是function或是function list一般是一个关于epoch数目的函数,从而计算出一个乘数因子,并根据该乘数因子调整初始学习率。第三个形参last_epoch默认为-1,它一般不用设置,为-1时的作用是将人为设置的学习率设定为调整学习率的基础值lr。这里需要注意的是,last_epoch默认为-1只能保证第一次调整学习率时,原始待调整的值为人工设定的初始学习率,而第二次调整学习率时,调整的基值就变成了第一次调整后的学习率。
  它的使用示例如下:

>>> # 假设优化器有两组参数
>>> lambda1 = lambda epoch: epoch // 30 # 第一组参数的调整方法
>>> lambda2 = lambda epoch: 0.95 ** epoch # 第二组参数的调整方法
>>> optimizer = torch.optim.Adam(...) #选择Adam优化器
>>> scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=[lambda1, lambda2]) # 选定调整方法
>>> for epoch in range(100):
>>>     train(...)
>>>     validate(...)

>>>     optimizer.step()
>>>     scheduler.step() # 需要在优化器参数更新之后再动态调整学习率,每次更新是根据epoch数量在两个函数上计算得到的乘数因子进行更新

torch.optim.lr_scheduler.StepLR

在这里插入图片描述
  这是比较常用的等间隔动态调整方法,该方法的原理为:每隔step_size个epoch就对每一参数组的学习率按gamma参数进行一次衰减。在它的形参中,第一个形参optimizer是之前定义好的优化器的实例名(wrapped optimizer);第二个形参step_size是学习率衰减的周期(隔多少个epoch衰减一次);第三个形参gamma是学习率衰减的乘法因子(Multiplicative factor),默认值为0.1;第四个形参last_epoch默认为-1,它一般不用设置,为-1时的作用是将人为设置的学习率设定为调整学习率的基础值lr。这里需要注意的是,last_epoch默认为-1只能保证第一次调整学习率时,原始待调整的值为人工设定的初始学习率,而第二次调整学习率时,调整的基值就变成了第一次调整后的学习率。
  该方法的使用示例如下:

>>> # 假定对于所有参数组的初始学习率为0.5,那么下列代码的学习率调整效果如下:
>>> # lr = 0.05     if epoch < 30
>>> # lr = 0.005    if 30 <= epoch < 60
>>> # lr = 0.0005   if 60 <= epoch < 90
>>> # ...
>>> scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
>>> for epoch in range(100):
>>>     train(...)
>>>     validate(...)
>>>     scheduler.step()

torch.optim.lr_scheduler.ExponetialLR

在这里插入图片描述
  这种方法是上面调整方法的简易版本,原理是每个epoch都对当前学习率根据gamma作一个动态调整,相当于做以gamma为底,epoch为幂次的指数运算。它的形参和上述方法中的作用一致,不再多言。

torch.optim.lr_scheduler.MultiStepLR

在这里插入图片描述
  这种方法也是基于等间隔调整方法的翻版,它的原理是当epoch的数目增加到一个里程碑(milestones)时对学习率基于gamma做一个动态调整这个方法适合后期调试使用,可以通过观察loss曲线,为训练过程的不同阶段设定不同的学习率。在它的形参中,第一个形参optimizer是之前定义好的优化器的实例名(wrapped optimizer);第二个形参milestones是一个关于epoch数值的list,表示在达到哪个epoch范围内开始变化,其变化原理如后例所示;第三个形参gamma是学习率衰减的乘法因子(Multiplicative factor),默认值为0.1;第四个形参last_epoch默认为-1,它一般不用设置,为-1时的作用是将人为设置的学习率设定为调整学习率的基础值lr。同样地,last_epoch默认为-1只能保证第一次调整学习率时,原始待调整的值为人工设定的初始学习率,而第二次调整学习率时,调整的基值就变成了第一次调整后的学习率。
  该方法的使用示例如下:

>>> # 假定优化器的初始学习率为0.05
>>> # lr = 0.05     if epoch < 30, 保存不变
>>> # lr = 0.005    if 30 <= epoch < 80, 衰减gamma倍
>>> # lr = 0.0005   if epoch >= 80, 再衰减gamma倍
>>> scheduler = MultiStepLR(optimizer, milestones=[30,80], gamma=0.1)
>>> for epoch in range(100):
>>>     train(...)
>>>     validate(...)
>>>     scheduler.step()

torch.optim.torch.optim.lr_scheduler.ReduceLROnPlateau

在这里插入图片描述
  与上述基于epoch数目调整学习率的方法不同,该方法是PyTorch提供的一种基于验证指标的调整方法它的原理是:当指标停止改善时,降低学习率。当模型的学习停滞时,训练过程通常会受益于将学习率降低2~10倍。该种调整方法读取一个度量指标,如果在“耐心”期间内没有发现它有所改善,那么就会降低学习率。下面将一一讲解它的形参:
(1)optimizer:和上述方法一致
(2)mode:可选str字符串数据,为minmax。当选择min时,代表当度量指标
停止下降
时,开始减小学习率;当选择max时,代表当度量指标停止上升时,开始减小学习率。
(3)factorfloat类型数据,学习率调整的乘法因子,默认值为0.1。
(4)patienceint类型数据,可容忍的度量指标没有提升的epoch数目,默认为10。举例说明,当其设置为10时,我们可以容忍10个epoch内没有提升,如果在第11个epoch依然没有提升,那么就开始降低学习率。
(5)verbosebool数据,如果设置为True,输出每一次更新的信息,默认为False
(6)thresholdfloat类型数据,衡量新的最佳阈值,仅关注重大变化,默认为0.0001。
(7)threshold_mode:可选str字符串数据,为relabs,默认为rel。在rel模式下,如果mode参数为max,则动态阈值(dynamic_threshold)为best*(1+threshold),如果mode参数为min,则动态阈值为best+threshold,如果mode参数为min,则动态阈值为best-threshold
(8)cooldownint类型数据,减少lr后恢复正常操作之前要等待的epoch数,默认为0。
(9)min_lrfloatlist类型数据,学习率的下界,默认为0。
(10)epsfloat类型数据,学习率的最小变化值。如果调整后的学习率和调整前的差距小于eps的话,那么就不做任何调整,默认为1e-8
  其使用案例为:

>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> scheduler = ReduceLROnPlateau(optimizer, 'min')
>>> for epoch in range(10):
>>>     train(...)
>>>     val_loss = validate(...) # 度量指标
>>>     # Note that step should be called after validate()
>>>     scheduler.step(val_loss) # 根据度量指标调整学习率

其他方法:

在这里插入图片描述
  这种方法基于论文训练神经网络的循环学习率,根据周期性学习率策略(CLR)确定每个参数组的学习率。 该策略以恒定的频率在两个边界之间循环学习率,两个边界之间的距离可以在每次迭代或每个周期的基础上进行缩放
  使用示例:

>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> scheduler = torch.optim.CyclicLR(optimizer)
>>> data_loader = torch.utils.data.DataLoader(...)
>>> for epoch in range(10):
>>>     for batch in data_loader:
>>>         train_batch(...)
>>>         scheduler.step()
  • 61
    点赞
  • 253
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
学习率是训练深度学习模型中一个重要的超参数,对模型的训练效果有极大的影响。PyTorch中提供了多种动态调整学习率方法,能够根据训练过程中的损失值、准确率或训练轮数等信息动态调整学习率,从而使得训练过程更加有效和高效。 在PyTorch中,可以通过定义一个学习率调度器(lr_scheduler)来实现动态调整学习率PyTorch中提供了以下几种学习率调整器: 1. StepLR(lr_scheduler.StepLR):在给定的一个step_size的间隔内,将学习率乘以gamma。当epoch_size被调整为n时,学习率按下面的公式来更新: ```python lr = lr * gamma ^ floor(epoch_size / step_size) ``` 这个调度器通常使用一个固定的step_size,每n个epoch就将学习率缩小一定比例。 2. MultiStepLR(lr_scheduler.MultiStepLR):在给定milestones列表中的epoch数后,将学习率乘以gamma。每个milestone后,gamma的乘数乘以上一个。 ```python if epoch in milestones: lr = lr * gamma ``` 这个调度器通常使用一个milestones列表,在每个milestone处将学习率乘以gamma。 3. ExponentialLR(lr_scheduler.ExponentialLR):获取指数衰减值gamma,然后每个epoch更新学习率。公式为 ```python lr = lr * gamma ** epoch ``` 该调度器通常将学习率按指数级衰减,gamma通常是在0.1-0.9之间,通常选择比较小的值。 4. CosineAnnealingLR(lr_scheduler.CosineAnnealingLR):将学习率按照一定的余弦函数来调整。公式为 ```python lr = eta_min + 0.5 * (lr_max - eta_min) * (1 + cos(T_cur / T_max * pi)) ``` 其中T_cur是当前epoch的个数,T_max是期望学习率到达点的epoch数量。 如果调度器以指定的warmup_epochs开始,那么lr_max将被限制到第warmup_epochs个epoch的学习率。 以上是PyTorch中几种常见的学习率调整方式,每种方式都有其优缺点。根据具体的模型和数据集,选择合适的学习率调整方式可以使得训练过程更加有效和高效。同时,也可以将不同的学习率调整方式进行组合,实现更加复杂的学习率调整策略。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值