LRScheduler

class paddle.optimizer.lr. LRScheduler ( learning_rate=0.1, last_epoch=- 1, verbose=False ) [源代码]

学习率策略的基类。定义了所有学习率调整策略的公共接口。

目前在 paddle 中基于该基类,已经实现了 14 种策略,分别为:

  • NoamDecay:诺姆衰减,相关算法请参考 《Attention Is All You Need》 。请参考 NoamDecay

  • ExponentialDecay:指数衰减,即每次将当前学习率乘以给定的衰减率得到下一个学习率。请参考 ExponentialDecay

  • NaturalExpDecay:自然指数衰减,即每次将当前学习率乘以给定的衰减率的自然指数得到下一个学习率。请参考 NaturalExpDecay

  • InverseTimeDecay:逆时间衰减,即得到的学习率与当前衰减次数成反比。请参考 InverseTimeDecay

  • PolynomialDecay:多项式衰减,即得到的学习率为初始学习率和给定最终学习之间由多项式计算权重定比分点的插值。请参考 cn_api_paddle_optimizer_lr_PolynomialDecay

  • PiecewiseDecay:分段衰减,即由给定 step 数分段呈阶梯状衰减,每段内学习率相同。请参考 PiecewiseDecay

  • CosineAnnealingDecay:余弦式衰减,即学习率随 step 数变化呈余弦函数周期变化。请参考 CosineAnnealingDecay

  • LinearWarmup:学习率随 step 数线性增加到指定学习率。请参考 LinearWarmup

  • StepDecay:学习率每隔固定间隔的 step 数进行衰减,需要指定 step 的间隔数。请参考 StepDecay

  • MultiStepDecay:学习率在特定的 step 数时进行衰减,需要指定衰减时的节点位置。请参考 MultiStepDecay

  • LambdaDecay:学习率根据自定义的 lambda 函数进行衰减。请参考 LambdaDecay

  • ReduceOnPlateau:学习率根据当前监控指标(一般为 loss)来进行自适应调整,当 loss 趋于稳定时衰减学习率。请参考 ReduceOnPlateau

  • MultiplicativeDecay:每次将当前学习率乘以 lambda 函数得到下一个学习率。请参考 MultiplicativeDecay

  • OneCycleLR: One Cycle 衰减,学习率上升至最大,再下降至最小。请参考 OneCycleLR

  • CyclicLR: Cyclic 学习率衰减,其将学习率变化的过程视为一个又一个循环,学习率根据固定的频率在最小和最大学习率之间不停变化。请参考 CyclicLR

你可以继承该基类实现任意的学习率策略,导出基类的方法为 form paddle.optimizer.lr import LRScheduler , 必须要重写该基类的 get_lr() 函数,否则会抛出 NotImplementedError 异常。

参数

  • learning_rate (float,可选) - 初始学习率,数据类型为 Python float。

  • last_epoch (int,可选) - 上一轮的轮数,重启训练时设置为上一轮的 epoch 数。默认值为 -1,则为初始学习率。

  • verbose (bool,可选) - 如果是 True,则在每一轮更新时在标准输出 stdout 输出一条信息。默认值为 False

返回

用于调整学习率的实例对象。

代码示例

这里提供了重载基类 LRScheduler 并实现 StepLR 的示例,你可以根据你的需求来实现任意子类。

import paddle
from paddle.optimizer.lr import LRScheduler

class StepDecay(LRScheduler):
    def __init__(self,
                learning_rate,
                step_size,
                gamma=0.1,
                last_epoch=-1,
                verbose=False):
        if not isinstance(step_size, int):
            raise TypeError(
                "The type of 'step_size' must be 'int', but received %s." %
                type(step_size))
        if gamma >= 1.0:
            raise ValueError('gamma should be < 1.0.')

        self.step_size = step_size
        self.gamma = gamma
        super(StepDecay, self).__init__(learning_rate, last_epoch, verbose)

    def get_lr(self):
        i = self.last_epoch // self.step_size
        return self.base_lr * (self.gamma**i)

方法

step(epoch=None)

step 函数需要在优化器的 optimizer.step() 函数之后调用,调用之后将会根据 epoch 数来更新学习率,更新之后的学习率将会在优化器下一轮更新参数时使用。

参数

  • epoch (int,可选)- 指定具体的 epoch 数。默认值 None,此时将会从-1 自动累加 epoch 数。

返回

无。

代码示例

请参考 基类 LRScheduler 的任意子类实现,这里以 StepLR 为例进行了示例:

import paddle
import numpy as np

x = np.random.uniform(-1, 1, [10, 10]).astype("float32")
linear = paddle.nn.Linear(10, 10)
scheduler = paddle.optimizer.lr.StepDecay(learning_rate=0.5, step_size=5, gamma=0.8, verbose=True)
sgd = paddle.optimizer.SGD(learning_rate=scheduler, parameters=linear.parameters())
for epoch in range(20):
    for batch_id in range(2):
        x = paddle.to_tensor(x)
        out = linear(x)
        loss = paddle.mean(out)
        loss.backward()
        sgd.step()
        sgd.clear_gradients()
        scheduler.step()    # If you update learning rate each step
  # scheduler.step()        # If you update learning rate each epoch

get_lr()

如果一个子类继承了 基类 LRScheduler,则用户必须重写方法 get_lr(),否则,将会抛出 NotImplementedError 异常,

上述给出了实现 StepLR 的一个简单示例。

_state_keys()

该函数通过定义字典 self.keys 来设置 optimizer.state_dict() 时的存储对象,默认情况下:self.keys=['last_epoch', 'last_lr'],其中 last_epoch 是当前的 epoch 数,last_lr 是当前的学习率值。

如果需要改变默认的行为,用户需要重写该方法,来重新定义字典 self.keys,一般无需重新设置。