PyTorch实战5:运动鞋识别之动态学习率

本次实战主要学习内容:

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

一、设置动态学习率

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.92
    lr = start_lr * (0.92 ** (epoch // 2))
    # 遍历优化器中的所有参数组,并将学习率设置为新的值
    for param_group in optimizer.param_groups:
        param_group['lr'] = lr

# 初始学习率设为1e-4
learn_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 optim
from 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 optim
import 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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王者与CV

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值