0
点赞
收藏
分享

微信扫一扫

深度学习之pytorch常见的学习率绘制

探头的新芽 2024-11-18 阅读 9

文章目录


https://blog.csdn.net/coldasice342/article/details/143435848

0. Scope

在深度学习中,学习率(Learning Rate, LR)是一个非常重要的超参数,它决定了模型权重更新的步长。选择合适的学习率对于训练过程至关重要,因为它不仅影响模型收敛的速度,还会影响最终模型的性能。然而,固定的学习率可能无法在整个训练过程中都保持最优,因此,学习率衰减(Learning Rate Decay, 或称 Learning Rate Schedule)策略应运而生,通过调整学习率来优化训练过程。

在PyTorch中,可以通过torch.optim.lr_scheduler模块提供的多个学习率调度器(Learning Rate Scheduler)来实现学习率的动态调整。这些调度器可以帮助优化训练过程,提高模型的性能。以下是PyTorch中一些常用的学习率调度器及其简要说明。

1. StepLR

每隔一定数量的epoch后,将学习率乘以一个固定的衰减因子。

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

参数:
step_size:经过多少个epoch后进行一次学习率衰减。
gamma:学习率的衰减因子,默认为0.1。
示例:

import torch
from torchvision import models
import matplotlib.pyplot as plt
import numpy as np

# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
net = models.resnet18(pretrained=False)

max_epoch = 50  # 一共50 epoch
iters = 20      # 每个epoch 有 20 个 bach
optimizer = torch.optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.9)

lr = []
for epoch in range(max_epoch):
    for batch in range(iters):
        optimizer.zero_grad()
        optimizer.step()

    scheduler.step()  # 更新learning rate
    # current_lr = scheduler.get_last_lr()[0]  #  注意:获取当前学习率不能使用get_lr()
    current_lr = optimizer.param_groups[0]['lr']
    lr.append(current_lr)
    print(f"End of Epoch {epoch + 1}: Current Learning Rate: {current_lr:.6f}")

plt.figure(figsize=(10, 8))
plt.plot(range(1, max_epoch + 1), lr, marker='o')
plt.xlabel('Epochs')
plt.ylabel('Learning Rate')
plt.title('Learning Rate Schedule')
plt.grid(True)
plt.show()

在这里插入图片描述

2. MultiStepLR

类似于 StepLR,但允许在不同 epoch 设置不同的学习率衰减点,提供更精细的控制。在指定的epoch列表处,将学习率乘以一个固定的衰减因子。

scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[10, 30], gamma=0.1)

参数:
milestones:一个列表,表示在哪些epoch处进行学习率衰减。
gamma:学习率的衰减因子,默认为0.1。
示例:
在这里插入图片描述

3. ExponentialLR

每个 epoch 将学习率按固定的指数衰减因子 gamma 进行调整。相比于 StepLR,它的衰减更平滑,适合需要持续减小学习率的任务。

scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.95)

参数:
gamma:每个epoch结束时学习率的乘法因子。
示例:
在这里插入图片描述

4. CosineAnnealingLR

CosineAnnealingLR 利用余弦函数的特点,使学习率在训练过程中按照一个周期性变化的余弦曲线来衰减,即学习率从大到小再到大反复变化。通常用于长时间训练任务,能在训练后期有效避免学习率过快下降。
在这里插入图片描述

torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0, last_epoch=- 1, verbose=False)

参数:
T_max:一个周期的最大epoch数。
eta_min:学习率的最小值,默认为0。

示例:

import torch
from torchvision import models
import matplotlib.pyplot as plt
import numpy as np

net = models.resnet18(pretrained=False)
max_epoch = 50  # 一共50 epoch
iters = 200     # 每个epoch 有 200 个 bach
update_mode = 'epoch'
if update_mode == 'epoch':
    optimizer = torch.optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
    scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer=optimizer, T_max=max_epoch)  # * iters

    lr = []
    for epoch in range(max_epoch):
        for batch in range(iters):
            optimizer.step()

            lr.append(scheduler.get_lr()[0])
        scheduler.step()  # 注意 每个epoch 结束, 更新learning rate
else:
    optimizer = torch.optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
    # 调整了四分之一周期的长度 max_epoch * iters
    scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer=optimizer, T_max=max_epoch * iters)  
    lr = []
    for epoch in range(max_epoch):
        for batch in range(iters):
            optimizer.step()

            lr.append(scheduler.get_lr()[0])
            scheduler.step()  # 注意 每个batch 结束, 更新learning rate

plt.figure(figsize=(10, 8))
plt.plot(np.arange(len(lr)), lr)
plt.xlabel('Iterations')
plt.ylabel('Learning Rate')
plt.title('Learning Rate Schedule')
plt.grid(True)
plt.show()

每个epoch更新一次
在这里插入图片描述
每个iteration更新一次
在这里插入图片描述

5. ReduceLROnPlateau

ReduceLROnPlateau 是基于验证集表现来调整学习率的一种方法。当模型的验证集指标(如损失)在一段时间内没有改善时,学习率会自动减小。

scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10)

和其他学习率更新不一样,ReduceLROnPlateau学习率更新时需要传入对应的参,例如:scheduler.step(ac) ,ac可以是loss或验证集的准确率之类的
参数:
mode:‘min’表示当监测指标不再下降时减少学习率,‘max’表示当监测指标不再上升时减少学习率。
factor:学习率的衰减因子,默认为0.1。
patience:在没有观察到性能提升的epoch数之后减少学习率。
示例:

import torch
from torchvision import models
import matplotlib.pyplot as plt
import numpy as np

# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
net = models.resnet18(pretrained=False)

max_epoch = 50  # 一共50 epoch
iters = 20      # 每个epoch 有 20 个 bach
optimizer = torch.optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=2)

lr = []
for epoch in range(max_epoch):
    for batch in range(iters):
        optimizer.zero_grad()
        optimizer.step()
    ac = 1
    if epoch > 20:
        ac = 10
    else:
        ac = ac - 0.1*epoch
    scheduler.step(ac)  # 更新learning rate
    # current_lr = scheduler.get_last_lr()[0]  #  注意:获取当前学习率不能使用get_lr()
    current_lr = optimizer.param_groups[0]['lr']
    lr.append(current_lr)
    print(f"End of Epoch {epoch + 1}: Current Learning Rate: {current_lr:.6f}")

plt.figure(figsize=(10, 8))
plt.plot(range(1, max_epoch + 1), lr, marker='o')
plt.xlabel('Epochs')
plt.ylabel('Learning Rate')
plt.title('Learning Rate Schedule')
plt.grid(True)
plt.show()

在这里插入图片描述

6. CyclicLR

学习率在一个范围内循环变化。

scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.01, max_lr=0.1, step_size_up=20, step_size_down=None,mode="triangular")

参数:
base_lr:学习率的下限。
max_lr:学习率的上限。
step_size_up:从base_lr到max_lr的步数。
step_size_down:从max_lr到base_lr的步数,如果为None,则默认与step_size_up相同。
示例:

CyclicLR - triangular

import torch
from torchvision import models
import matplotlib.pyplot as plt
import numpy as np

# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
net = models.resnet18(pretrained=False)

max_epoch = 50  # 一共50 epoch
iters = 20      # 每个epoch 有 20 个 bach
optimizer = torch.optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.01, max_lr=0.1, step_size_up=2, step_size_down=None)

lr = []
for epoch in range(max_epoch):
    for batch in range(iters):
        optimizer.zero_grad()
        optimizer.step()

    scheduler.step()  # 更新learning rate
    # current_lr = scheduler.get_last_lr()[0]  #  注意:获取当前学习率不能使用get_lr()
    current_lr = optimizer.param_groups[0]['lr']
    lr.append(current_lr)
    print(f"End of Epoch {epoch + 1}: Current Learning Rate: {current_lr:.6f}")

plt.figure(figsize=(10, 8))
plt.plot(range(1, max_epoch + 1), lr, marker='o')
plt.xlabel('Epochs')
plt.ylabel('Learning Rate')
plt.title('Learning Rate Schedule')
plt.grid(True)
plt.show()

在这里插入图片描述
CyclicLR - triangular2

scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.01, max_lr=0.1, step_size_up=2, step_size_down=None,mode="triangular2")

在这里插入图片描述
CyclicLR - exp_range

scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.01,
                                              max_lr=0.1, step_size_up=5,
                                              mode="exp_range", gamma=0.85)

在这里插入图片描述
当step_size_up设置较大时:

scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.01,
                                              max_lr=0.1, step_size_up=20,
                                              mode="exp_range", gamma=0.85)

在这里插入图片描述

7. OneCycleLR

根据 “1cycle” 策略,先逐步增加学习率,然后在训练的后期快速减小学习率,这种方式能在训练初期提供更快的收敛速度,同时在后期细化模型。

scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.1, total_steps=None, epochs=100, steps_per_epoch=1)

参数:
max_lr:周期内的最高学习率。
total_steps:整个训练过程中的总步数。注意,如果这里是None,那么必须通过提供epochs和step_per_epoch的值来推断它。
epochs:训练的总轮数。
steps_per_epoch:每个epoch中的步数。
示例:
若每个epoch更新学习率:

import torch
from torchvision import models
import matplotlib.pyplot as plt
import numpy as np

# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
net = models.resnet18(pretrained=False)

max_epoch = 50  # 一共50 epoch
iters = 20      # 每个epoch 有 20 个 bach
optimizer = torch.optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.1, total_steps=None, epochs=max_epoch, steps_per_epoch=1)

lr = []
for epoch in range(max_epoch):
    for batch in range(iters):
        optimizer.zero_grad()
        optimizer.step()

    scheduler.step()  # 更新learning rate
    # current_lr = scheduler.get_last_lr()[0]  #  注意:获取当前学习率不能使用get_lr()
    current_lr = optimizer.param_groups[0]['lr']
    lr.append(current_lr)
    print(f"End of Epoch {epoch + 1}: Current Learning Rate: {current_lr:.6f}")

plt.figure(figsize=(10, 8))
plt.plot(range(1, max_epoch + 1), lr, marker='o')
plt.xlabel('Epochs')
plt.ylabel('Learning Rate')
plt.title('Learning Rate Schedule')
plt.grid(True)
plt.show()

在这里插入图片描述
若每个batch更新学习率:

import torch
from torchvision import models
import matplotlib.pyplot as plt
import numpy as np

# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
net = models.resnet18(pretrained=False)

max_epoch = 50  # 一共50 epoch
iters = 20      # 每个epoch 有 20 个 bach
optimizer = torch.optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.1, total_steps=None, epochs=max_epoch, steps_per_epoch=iters)

lr = []
for epoch in range(max_epoch):
    for batch in range(iters):
        optimizer.zero_grad()
        optimizer.step()
        scheduler.step()
        current_lr = optimizer.param_groups[0]['lr']
        lr.append(current_lr)
    # scheduler.step()  # 更新learning rate
    # current_lr = scheduler.get_last_lr()[0]  #  注意:获取当前学习率不能使用get_lr()
    # current_lr = optimizer.param_groups[0]['lr']
    # lr.append(current_lr)
    print(f"End of Epoch {epoch + 1}: Current Learning Rate: {current_lr:.6f}")

plt.figure(figsize=(10, 8))
plt.plot(range(1, max_epoch*iters + 1), lr, marker='o')
plt.xlabel('Epochs')
plt.ylabel('Learning Rate')
plt.title('Learning Rate Schedule')
plt.grid(True)
plt.show()

在这里插入图片描述

小结

本文绘制了pytorch中7种常见的学习率,其中没有最好的,只有适合的。无论使用何种学习率策略,主要还是得适合自己的模型训练,切勿邯郸学步。谨以此记,以备后续训练模型时选择合适的学习率。

参考文献

[1] 图解Pytorch学习率衰减策略(一)
[2] 深度学习】图解 9 种PyTorch中常用的学习率调整策略
[3] pytorch余弦退火学习率CosineAnnealingLR的使用

举报

相关推荐

0 条评论