深度学习学习率调整小结

深度学习学习率lr_scheduler调整小结

  • 简介
  • 代码
  • StepLR
  • MultiStepLR
  • ExponentialLR
  • OneCycleLR
  • CyclicLR
  • CosineAnnealingLR
  • CosineAnnealingWarmRestarts
  • LambdaLR
  • MultiplicativeLR

禁止以任何形式转载或抄袭!!

简介

learning rate schedules主要就是对分子部分进行调整,采用learning rate schedules的时候多用于SGD这类非自适应的算法之中。
深度学习学习率调整小结_第1张图片
PyTorch提供的学习率调整策略分为三大类:

  1. 有序调整:等间隔调整(Step),按需调整学习率(MultiStep),指数衰减调整(Exponential)和 余弦退火CosineAnnealing
  2. 自适应调整:自适应调整学习率 ReduceLROnPlateau
  3. 自定义调整:自定义调整学习率 LambdaLR

代码

在PyTorch 1.1.0之前,学习率调度程序应该在优化器更新之前调用;1.1.0以后改变了这种方式。如果在优化器更新(调用optimizer.step())之前使用学习率调度程序(调用scheduler.step()),这将跳过学习率调度程序的第一个值。In PyTorch 1.1.0 and later, you should call them in the opposite order: optimizer.step() before lr_scheduler.step().

model_param = [Parameter(torch.randn(2, 2, requires_grad=True))]
optimizer = SGD(model_param, 0.1)
scheduler = ExponentialLR(optimizer, gamma=0.9)

for epoch in range(20):
    for input, target in dataset:
        optimizer.zero_grad()
        output = model(input)
        loss = loss_fn(output, target)
        loss.backward()
        optimizer.step()
    scheduler.step()

注意,一般都是在优化器进行调整之后,才应用学习率调整策略对学习率进行调整。
大多数学习率调整程序,都是可以根据前一个调整策略所获得的学习率再次进行调整的。

model = [Parameter(torch.randn(2, 2, requires_grad=True))]
optimizer = SGD(model, 0.1)
scheduler1 = ExponentialLR(optimizer, gamma=0.9)
scheduler2 = MultiStepLR(optimizer, milestones=[30,80], gamma=0.1)


for epoch in range(20):
    for input, target in dataset:
        optimizer.zero_grad()
        output = model(input)
        loss = loss_fn(output, target)
        loss.backward()
        optimizer.step()
    scheduler1.step()
    scheduler2.step()

StepLR

等间隔调整

scheduler = lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)

深度学习学习率调整小结_第2张图片

MultiStepLR

按需调整学习率

scheduler = lr_scheduler.MultiStepLR(optimizer, milestones=[40,70], gamma=0.1)

深度学习学习率调整小结_第3张图片

ExponentialLR

指数衰减,用得少

scheduler =lr_scheduler.ExponentialLR(optimizer, gamma=0.9)

深度学习学习率调整小结_第4张图片

OneCycleLR

scheduler =lr_scheduler.OneCycleLR(optimizer,max_lr=0.9,total_steps=1000, verbose=True)

注意:之前的几个学习率优化器是放在每个epoch,每个epoch更新一次,这个方法是每个step更新一次,应该放在step的循环中。

  1. total_steps:总的batch数,这个参数设置后就不用设置epochs和steps_per_epoch,anneal_strategy 默认是"cos"方式,当然也可以选择"linear"
  2. 注意这里的max_lr和你优化器中的lr并不是同一个
  3. 低版本torch里面没有这个函数

深度学习学习率调整小结_第5张图片

CyclicLR

深度学习学习率调整小结_第6张图片
深度学习学习率调整小结_第7张图片
同样的,这里也是以每个step进行更新的。

scheduler = lr_scheduler.CyclicLR(optimizer, base_lr=0.01, max_lr=0.1,step_size_up=150,step_size_down=250,mode='triangular')

深度学习学习率调整小结_第8张图片
mode=‘triangular2’:
深度学习学习率调整小结_第9张图片

scheduler = lr_scheduler.CyclicLR(optimizer, base_lr=0.01, max_lr=0.1,step_size_up=150,step_size_down=250,mode='exp_range',gamma=0.997)

深度学习学习率调整小结_第10张图片

CosineAnnealingLR

与上一个函数所不同的是,这里使用余弦函数进行学习率的衰减,而且学习率是大学习率开始的。仍然是每个step更新。

T_max:Cosine是个周期函数,这里的T_max就是这个周期的一半,如果你将T_max设置为10,则学习率衰减的周期是20个epoch,其中前10个epoch从学习率的初值(也是最大值)下降到最低值,后10个epoch从学习率的最低值上升到最大值
eta_min:学习率衰减时的最小值,默认值为0
last_epoch:(上次训练)最后一个epoch的索引值,默认值为-1。如果你将其设置为20,那定义出来的scheduler的第一次step就会到第21个epoch对应的学习率。这里是为了resuming

optimizer = optim.SGD(params=model.parameters(), lr=0.05)
scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=200, eta_min=0.01, last_epoch=-1)

当然,这里你可以只选择用最前面的一段,从大到小的余弦衰减
深度学习学习率调整小结_第11张图片

CosineAnnealingWarmRestarts

T_0 – 设定初次在哪里WarmRestarts
T_mult – 每次Restarts后周期扩展系数 默认为: 1.
eta_min–最小学习率,默认为0

scheduler = lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_0=300, T_mult=1, eta_min=0)

深度学习学习率调整小结_第12张图片

scheduler = lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_0=200, T_mult=2, eta_min=0)

深度学习学习率调整小结_第13张图片

这一个是用于自适应调整的学习率衰减函数。
功能:监控指标,当指标不再变化则调整(很实用)
比如监控Loss不再下降、或者分类准确率acc不再上升就进行学习率的调整。
深度学习学习率调整小结_第14张图片

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)

LambdaLR

自定义调整策略
这里主要是通过lr_lambda (function or list) 参数来设定学习率调整策略:

lambda1 = lambda epoch: 0.95 ** epoch
scheduler = LambdaLR(optimizer, lr_lambda=lambda1)

或者有多个学习率需要调整

#Assuming optimizer has two groups.
lambda1 = lambda epoch: epoch // 30
lambda2 = lambda epoch: 0.95 ** epoch
scheduler = LambdaLR(optimizer, lr_lambda=[lambda1, lambda2])

我这里来定义一个复杂一点的函数,

def lr_lambda(current_step: int,num_warmup_steps=280,num_training_steps=1000):
     # 自定义函数
    '''
    num_warmup_steps (:obj:`int`):
        The number of steps for the warmup phase.
    num_training_steps (:obj:`int`):
        The total number of training steps.
     last_epoch (:obj:`int`, `optional`, defaults to -1):
        The index of the last epoch when resuming training.
    '''
    if current_step < num_warmup_steps:
        return float(current_step) / float(max(1, num_warmup_steps))
    return max(
        0.0, float(num_training_steps - current_step) / float(max(1, num_training_steps - num_warmup_steps))
    )
scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lr_lambda)

深度学习学习率调整小结_第15张图片

MultiplicativeLR

将每个参数组的学习速率乘以指定函数中给定的因子。跟LambdaLR差不多,用得很少,就不画图了。

lambdaa = lambda epoch : 0.5
scheduler = optim.lr_scheduler.MultiplicativeLR(optimizer, lambdaa)

上一篇:深度学习Optimizer优化器小结

你可能感兴趣的:(AI代码相关基础知识,一些方法和trick,深度学习,python,神经网络,人工智能)