pytorch08:学习率调整策略

目录

一、为什么要调整学习率?

学习率(learning rate):控制更新的步伐

一般在模型训练过程中,在开始训练的时候我们会设置学习率大一些,随着模型训练epoch的增加,学习率会逐渐设置小一些。

1.1 class _LRScheduler

学习率调整的父类函数

主要属性:

• optimizer:关联的优化器

• last_epoch:记录epoch数

• base_lrs:记录初始学习率
主要方法:

• step():更新下一个epoch的学习率,该操作必须放到epoch循环下面

• get_lr():虚函数,计算下一个epoch的学习率

二、pytorch的六种学习率调整策略

2.1 StepLR

功能:等间隔调整学习率

主要参数:

• step_size:调整间隔数

• gamma:调整系数

调整方式:lr = lr * gamma

代码实现:

python 复制代码
import torch
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt

torch.manual_seed(1)

LR = 0.1
iteration = 10
max_epoch = 200
# ------------------------------ fake data and optimizer  ------------------------------

weights = torch.randn((1), requires_grad=True)
target = torch.zeros((1))

optimizer = optim.SGD([weights], lr=LR, momentum=0.9)

# ------------------------------ 1 Step LR ------------------------------
# flag = 0
flag = 1
if flag:

    scheduler_lr = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.1)  # 设置学习率下降策略,50轮下降一次,每次下降10倍

    lr_list, epoch_list = list(), list()
    for epoch in range(max_epoch):

        lr_list.append(scheduler_lr.get_lr())
        epoch_list.append(epoch)

        for i in range(iteration):
            loss = torch.pow((weights - target), 2)
            loss.backward()

            optimizer.step()
            optimizer.zero_grad()

        scheduler_lr.step()  # 学习率更新策略

    plt.plot(epoch_list, lr_list, label="Step LR Scheduler")
    plt.xlabel("Epoch")
    plt.ylabel("Learning rate")
    plt.legend()
    plt.show()

输出结果:

因为我们设置每50个epoch降低一次学习率,所以在7774554

2.2 MultiStepLR

功能:按给定间隔调整学习率

主要参数:

• milestones:设定调整时刻数

• gamma:调整系数

调整方式:lr = lr * gamma

代码实现

python 复制代码
flag = 1
if flag:

    milestones = [50, 125, 160]  # 设置学习率下降的位置
    scheduler_lr = optim.lr_scheduler.MultiStepLR(optimizer, milestones=milestones, gamma=0.1)

    lr_list, epoch_list = list(), list()
    for epoch in range(max_epoch):

        lr_list.append(scheduler_lr.get_lr())
        epoch_list.append(epoch)

        for i in range(iteration):
            loss = torch.pow((weights - target), 2)
            loss.backward()

            optimizer.step()
            optimizer.zero_grad()

        scheduler_lr.step()

    plt.plot(epoch_list, lr_list, label="Multi Step LR Scheduler\nmilestones:{}".format(milestones))
    plt.xlabel("Epoch")
    plt.ylabel("Learning rate")
    plt.legend()
    plt.show()

输出结果

根据我们设置milestones = [50, 125, 160],发现学习率在这三个地方发生下降。

2.3 ExponentialLR

功能:按指数衰减调整学习率

主要参数:

• gamma:指数的底

调整方式:lr = lr * gamma^epoch;这里的gamma通常设置为接近1的数值,例如:0.95

代码实现

python 复制代码
flag = 1
if flag:

    gamma = 0.95
    scheduler_lr = optim.lr_scheduler.ExponentialLR(optimizer, gamma=gamma)

    lr_list, epoch_list = list(), list()
    for epoch in range(max_epoch):

        lr_list.append(scheduler_lr.get_lr())
        epoch_list.append(epoch)

        for i in range(iteration):
            loss = torch.pow((weights - target), 2)
            loss.backward()

            optimizer.step()
            optimizer.zero_grad()

        scheduler_lr.step()

    plt.plot(epoch_list, lr_list, label="Exponential LR Scheduler\ngamma:{}".format(gamma))
    plt.xlabel("Epoch")
    plt.ylabel("Learning rate")
    plt.legend()
    plt.show()

输出结果

可以发现学习率是呈指数下降的。

2.4 CosineAnnealingLR

功能:余弦周期调整学习率

主要参数:

• T_max:下降周期

• eta_min:学习率下限

调整方式:

代码实现

python 复制代码
flag = 1
if flag:
    t_max = 50
    scheduler_lr = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=t_max, eta_min=0.)
    lr_list, epoch_list = list(), list()
    for epoch in range(max_epoch):
        lr_list.append(scheduler_lr.get_lr())
        epoch_list.append(epoch)
        for i in range(iteration):
            loss = torch.pow((weights - target), 2)
            loss.backward()
            optimizer.step()
            optimizer.zero_grad()
        scheduler_lr.step()
    plt.plot(epoch_list, lr_list, label="CosineAnnealingLR Scheduler\nT_max:{}".format(t_max))
    plt.xlabel("Epoch")
    plt.ylabel("Learning rate")
    plt.legend()
    plt.show()

输出结果

2.5 ReduceLRonPlateau

功能:监控指标,当指标不再变化则调整,例如:可以监控我们的loss或者准确率,当其不发生变化的时候,调整学习率。

主要参数:

• mode:min/max 两种模式

min模式:当某一个值不下降的时候我们调整学习率,通常用于监控损失

max模型:当某一个值不上升的时候我们调整学习率,通常用于监控精确度

• factor:调整系数

• patience:"耐心",接受几次不变化

• cooldown:"冷却时间",停止监控一段时间

• verbose:是否打印日志

• min_lr:学习率下限

• eps:学习率衰减最小值

代码实现

python 复制代码
flag = 1
if flag:
    loss_value = 0.5
    accuray = 0.9
    factor = 0.1  # 学习率变换参数
    mode = "min"
    patience = 10  # 能接受多少轮不变化
    cooldown = 10  # 停止监控多少轮
    min_lr = 1e-4  # 设置学习率下限
    verbose = True  # 打印更新日志
    scheduler_lr = optim.lr_scheduler.ReduceLROnPlateau(optimizer, factor=factor, mode=mode, patience=patience,
                                                        cooldown=cooldown, min_lr=min_lr, verbose=verbose)
    for epoch in range(max_epoch):
        for i in range(iteration):
            # train(...)
            optimizer.step()
            optimizer.zero_grad()
        #if epoch == 5:
           # loss_value = 0.4
        scheduler_lr.step(loss_value) #监控的标量是否下降

输出结果

2.6 LambdaLR

功能:自定义调整策略

主要参数:

• lr_lambda:function or list

代码实现

python 复制代码
flag = 1
if flag:

    lr_init = 0.1

    weights_1 = torch.randn((6, 3, 5, 5))
    weights_2 = torch.ones((5, 5))

    optimizer = optim.SGD([
        {'params': [weights_1]},
        {'params': [weights_2]}], lr=lr_init)

    # 设置两种不同的学习率调整方法
    lambda1 = lambda epoch: 0.1 ** (epoch // 20)  # 每到20轮的时候学习率变为原来的0.1倍
    lambda2 = lambda epoch: 0.95 ** epoch  # 将学习率进行指数下降

    scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=[lambda1, lambda2])

    lr_list, epoch_list = list(), list()
    for epoch in range(max_epoch):
        for i in range(iteration):
            # train(...)

            optimizer.step()
            optimizer.zero_grad()

        scheduler.step()

        lr_list.append(scheduler.get_lr())
        epoch_list.append(epoch)

        print('epoch:{:5d}, lr:{}'.format(epoch, scheduler.get_lr()))

    plt.plot(epoch_list, [i[0] for i in lr_list], label="lambda 1")
    plt.plot(epoch_list, [i[1] for i in lr_list], label="lambda 2")
    plt.xlabel("Epoch")
    plt.ylabel("Learning Rate")
    plt.title("LambdaLR")
    plt.legend()
    plt.show()

输出结果

通过lambda方法定义了两种不同的学习率下降策略。

三、学习率调整小结

  1. 有序调整:Step、MultiStep、Exponential 和 CosineAnnealing
  2. 自适应调整:ReduceLROnPleateau
  3. 自定义调整:Lambda

四、学习率初始化

1、设置较小数:0.01、0.001、0.0001

2、搜索最大学习率: 参考该篇《Cyclical Learning Rates for Training Neural Networks

方法:我们可以设置学习率逐渐从小变大观察精确度的一个变化,下面这幅图,当学习率为0.055左右的时候模型精确度最高,当学习率大于0.055的时候精确度出现下降情况,所以在模型训练过程中我们可以设置学习率为0.055作为我们的初始学习率。

相关推荐
XMYX-029 分钟前
Python 操作 Elasticsearch 全指南:从连接到数据查询与处理
python·elasticsearch·jenkins
正义的彬彬侠34 分钟前
sklearn.datasets中make_classification函数
人工智能·python·机器学习·分类·sklearn
belldeep35 分钟前
python:用 sklearn 转换器处理数据
python·机器学习·sklearn
ctrey_35 分钟前
2024-11-13 学习人工智能的Day26 sklearn(2)
人工智能·学习·sklearn
安静的_显眼包O_o37 分钟前
from sklearn.preprocessing import Imputer.处理缺失数据的工具
人工智能·python·sklearn
安静的_显眼包O_o41 分钟前
from sklearn.feature_selection import VarianceThreshold.移除低方差的特征来减少数据集中的特征数量
人工智能·python·sklearn
_可乐无糖1 小时前
pytest中的断言
python·pytest
AI服务老曹1 小时前
不仅能够实现前后场的简单互动,而且能够实现人机结合,最终实现整个巡检流程的标准化的智慧园区开源了
大数据·人工智能·深度学习·物联网·开源
金蝶软件小李1 小时前
深度学习和图像处理
图像处理·深度学习·计算机视觉
Wils0nEdwards1 小时前
Leetcode 整数转罗马数字
linux·python·leetcode