• 本文为365天深度学习训练营 中的学习记录博客
  • 参考文章:365天深度学习训练营-第P5周:运动鞋识别
  • 原作者:K同学啊|接辅导、项目定制

目录

    • 一、设置动态学习率
        • 1、动态学习率的设置
        • 2、✨调用官方动态学习率接口
        • 3、正式训练动态学习率的使用
    • 二、动态学习率
        • 1. torch.optim.lr_scheduler.StepLR
        • 2. lr_scheduler.LambdaLR
        • 3. lr_scheduler.MultiStepLR
        • 4、调用官方接口示例

本次实战主要学习内容:

  • 了解如何设置动态学习率(重点)

一、设置动态学习率

1、动态学习率的设置

编写一段代码用来调整模型优化器中学习率的函数。它接受三个参数:优化器(optimizer)、当前的 epoch 数量(epoch)以及初始学习率(start_lr)。

将 lr 设置为 start_lr 乘以 0.92 的 epoch//2 次方,表示每两个 epoch 学习率都会降低到原来的 0.92 倍。

def adjust_learning_rate(optimizer, epoch, start_lr):# 每 2 个 epoch 将学习率衰减到原来的 0.92lr = start_lr * (0.92 ** (epoch // 2))# 遍历优化器中的所有参数组,并将学习率设置为新的值for param_group in optimizer.param_groups:param_group['lr'] = lr# 初始学习率设为1e-4learn_rate = 1e-4 # 使用 SGD 优化器,并传入初始学习率作为参数optimizer= torch.optim.SGD(model.parameters(), lr=learn_rate)

2、✨调用官方动态学习率接口

使用PyTorch中的学习率调度器来动态地调整模型训练时的学习率。

首先,定义了一个lambda函数lambda1,该函数将每个epoch(训练时对数据集遍历一次称为一个epoch)作为输入,返回一个新的学习率。在这里,新学习率是原学习率(learn_rate)的0.92的(epoch//2)次方。这意味着每过两个epoch,学习率将降低为原来的0.92倍。

接下来,创建了一个SGD优化器(Stochastic Gradient Descent,随机梯度下降),用于更新模型中的参数,并将初始学习率传递给它。

然后,使用LambdaLR类创建了一个学习率调度器对象scheduler。LambdaLR接受两个参数:优化器对象和一个lr_lambda函数。在这里,我们将之前定义的lambda函数传递给它,以便在每个epoch结束时调整学习率。

最后,可以通过optimizer.param_groups[0][‘lr’]来查看当前学习率的值。

与上面方法是等价的

# 调用官方动态学习率接口时使用lambda1 = lambda epoch: 0.92 ** (epoch // 2)optimizer = torch.optim.SGD(model.parameters(), lr=learn_rate)scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda1) #选定调整方法

3、正式训练动态学习率的使用

  • 使用自定义学习率时使用
 # 更新学习率 adjust_learning_rate(optimizer, epoch, learn_rate)
  • 调用官方动态学习率接口时使用
# 更新学习率scheduler.step() 

二、动态学习率

1. torch.optim.lr_scheduler.StepLR

torch.optim.lr_scheduler.StepLR,它可以根据给定的步长和衰减因子来动态地调整优化器的学习率。具体来说,每经过一个指定的步数后,学习率就会按照衰减因子进行乘法运算,从而使得学习率不断降低。

下面是StepLR的使用方法:

scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma, last_epoch=-1)

其中,参数含义如下:

  • optimizer(Optimizer): 是之前定义好的需要优化的优化器的实例名。
  • step_size(int): 是学习率衰减的周期,每经过每个epoch,做一次学习率decay;学习率调整的步长,即经过多少次迭代之后才对学习率进行调整,默认值为1。
  • gamma(float): 学习率衰减的乘法因子,学习率下降的倍数,即每次调整后学习率都会乘以这个倍数,默认值为0.1。
  • last_epoch: 上一次调整学习率发生的迭代次数,如果不指定则默认为-1,表示当前没有完成任何一次迭代。

等间隔动态调整方法,每经过step_size个epoch,做一次学习率decay,以gamma值为缩小倍数。

当调用StepLR.step()方法时,该调度器会将优化器的学习率进行更新。例如,假设我们想要每10个epoch将学习率降低为原来的0.1倍,那么代码如下:

scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)for epoch in range(100):train(...)test(...)# 调整学习率scheduler.step()

上述代码中,scheduler.step()会在每个epoch结束后被调用一次,从而对优化器的学习率进行更新。

需要注意的是,StepLR还有一个可选参数verbose,可以用来控制是否打印学习率的更新信息。当verbose=True时,每次调用StepLR.step()方法时都会打印出当前的学习率。

用法示例:

optimizer = torch.optim.SGD(net.parameters(), lr=0.001 )scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)

2. lr_scheduler.LambdaLR

torch.optim.lr_scheduler.LambdaLR,它允许用户通过传递一个函数来自定义学习率衰减方式。该函数接受当前epoch作为输入,返回一个学习率因子,将其应用于初始学习率以获得每个epoch的新学习率。

下面是LambdaLR的构造函数:

torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1, verbose=False)

其中,参数说明如下:

  • optimizer(Optimizer):需要进行学习率调度的优化器对象。
  • lr_lambda(function):更新学习率的函数,它接受当前epoch作为输入,返回一个新的学习率因子。例如,如果我们想将学习率按照指数方式衰减,则可以这样定义lr_lambda函数:lambda epoch: 0.95 ** epoch
  • last_epoch:用于指定上一次调用step()方法时的epoch数,当last_epoch和当前epoch相同时,表明已经调用过step()方法了。

下面是一个例子,展示如何使用LambdaLR对优化器的学习率进行指数衰减:

import torch.optim as optimfrom torch.optim.lr_scheduler import LambdaLR# 定义优化器和学习率衰减函数model = ...# 模型定义optimizer = optim.SGD(model.parameters(), lr=0.1)lr_decay = LambdaLR(optimizer, lr_lambda=lambda epoch: 0.95 ** epoch)# 在每个epoch后调用step()方法for epoch in range(num_epochs):train(...)lr_decay.step()

在上面的例子中,学习率将按照指数方式衰减,每个epoch的学习率为前一个epoch学习率的0.95次方。在每个epoch结束时,需要调用lr_decay.step()方法来更新优化器的学习率。

LambdaLR还可以与其他学习率调度器结合使用,例如StepLR、MultiStepLR等,以实现更复杂的学习率调度策略。

根据自己定义的函数更新学习率。

用法示例:

lambda1 = lambda epoch: (0.92 ** (epoch // 2) # 第二组参数的调整方法optimizer = torch.optim.SGD(model.parameters(), lr=learn_rate)scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda1) #选定调整方法

3. lr_scheduler.MultiStepLR

torch.optim.lr_scheduler.MultiStepLR 是 PyTorch 中的一个学习率调整策略,它在训练过程中按照指定的里程碑(milestones)调整学习率。具体地,每当当前训练 epoch 数量等于里程碑中的某个值时,就将学习率乘以 gamma 的值。

下面是 MultiStepLR 的构造函数签名及参数说明:

torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=-1, verbose=False)
  • optimizer(Optimizer):是之前定义好的需要优化的优化器的实例名。
  • milestones(list):是一个关于epoch数值的list,表示在达到哪个epoch范围内开始变化,必须是升序排列;由递增整数构成的列表,表示要在哪些 epoch 时降低学习率。例如,如果设置为 [30, 80],则在第 30 和第 80 个 epoch 时学习率会被降低。
  • gamma:乘法因子,用于计算新的学习率。默认值为 0.1。
  • last_epoch:上一个 epoch 的索引。默认为 -1,表示初始学习率为初始 lr。
  • verbose:如果为 True,则会打印出有关调整学习率的详细信息。默认为 False

使用 MultiStepLR 可以很容易地实现学习率的衰减,例如:

import torch.optim as optimimport torch.optim.lr_scheduler as lr_scheduler# 构建优化器和 MultiStepLR 学习率衰减策略optimizer = optim.SGD(model.parameters(), lr=0.1, momentum=0.9)milestones = [30, 80]scheduler = lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1)for epoch in range(100):# 训练模型train(...)# 更新学习率scheduler.step()# 验证模型validate(...)

这里,使用 optim.SGD 构建了一个随机梯度下降优化器,并将其传递给 MultiStepLR。然后,定义了里程碑 [30, 80] 和乘法因子 0.1,并将它们传递给 MultiStepLR 的构造函数。在训练过程中,先进行模型训练,然后调用 scheduler.step() 方法更新学习率。因为设置了里程碑为 30 和 80,所以当 epoch 数量分别为 30 和 80 时,学习率会被乘以 0.1。

在特定的 epoch 中调整学习率

用法示例:

optimizer = torch.optim.SGD(net.parameters(), lr=0.001 )scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer,milestones=[2,6,15], #调整学习率的epoch数 gamma=0.1)

4、调用官方接口示例

model = [Parameter(torch.randn(2, 2, requires_grad=True))]optimizer = SGD(model, 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()

更多的官方动态学习率设置方式可参考:https://pytorch.org/docs/stable/optim.html