当前位置: 首页 > article >正文

学习率调整策略 | PyTorch 深度学习实战

前一篇文章,深度学习里面的而优化函数 Adam,SGD,动量法,AdaGrad 等 | PyTorch 深度学习实战

本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started

本篇文章内容来自于 强化学习必修课:引领人工智能新时代【梗直哥瞿炜】

PyTorch 学习率调整策略

  • 常见的学习率调节器
    • 学习率衰减
    • 指数衰减
    • 余弦学习率调节
    • 预热
  • 示例程序
    • 执行结果
      • 没有使用学习率自动调节时
      • 使用了学习率自动调节
      • 结论
  • 常见学习率调节器
  • Links

常见的学习率调节器

在这里插入图片描述

学习率衰减

在这里插入图片描述

指数衰减

在这里插入图片描述

余弦学习率调节

实现学习率循环降低或升高的效果

在这里插入图片描述

预热

在这里插入图片描述

示例程序

下面以指数衰减调节器(ExponentialLR)为例子,展示同样的数据条件下:不衰减学习率和衰减学习率两种情况下,损失函数loss的收敛情况。

import torch
torch.manual_seed(777)


'''
Learning rate scheduler
'''
import matplotlib.pyplot as plt
import numpy as np
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset # 构造数据集加载器
from torch.utils.data import random_split # 划分数据集

torch.manual_seed(777)# for reproducibility为了重复使用

############################
# 生成数据
############################

# 定义函数
def f(x,y):
    return x**2 + 2*y**2

# 定义初始值
num_samples = 1000 # 1000 个样本点
X = torch.rand(num_samples) # 均匀分布
Y = torch.rand(num_samples)
Z = f(X,Y) + 3 * torch.randn(num_samples)


# Concatenates a sequence of tensors along a new dimension.
# All tensors need to be of the same size.
# https://pytorch.org/docs/stable/generated/torch.stack.html
dataset = torch.stack([X,Y,Z], dim=1)
# print(dataset.shape) # torch.Size([1000, 3])

# split data, 按照 7:3 划分数据集
train_size = int(0.7 * len(dataset))
test_size = len(dataset) - train_size

train_dataset, test_dataset = random_split(dataset=dataset, lengths=[train_size, test_size])

# 将数据封装为数据加载器
# narrow 函数对数据进行切片操作,
# 
train_dataloader = DataLoader(TensorDataset(train_dataset.dataset.narrow(1,0,2), train_dataset.dataset.narrow(1,2,1)), batch_size=32, shuffle=False)
test_dataloader = DataLoader(TensorDataset(test_dataset.dataset.narrow(1,0,2), test_dataset.dataset.narrow(1,2,1)), batch_size=32, shuffle=False)

############################
# 模型定义
############################

# 定义一个简单的模型
class Model(nn.Module):

    def __init__(self):
        super().__init__()
        self.hidden = nn.Linear(2, 8)
        self.output = nn.Linear(8, 1)

    def forward(self, x):
        x = torch.relu(self.hidden(x))
        return self.output(x)


############################
# 模型训练
############################

# 超参数
num_epochs = 100
learning_rate = 0.1 # 学习率,调大一些更直观

# 定义损失函数
loss_fn = nn.MSELoss()

# 通过两次训练,对比有无调节器的效果
for with_scheduler in [False, True]:

    # 定义训练和测试误差数组
    train_losses = []
    test_losses = []

    # 初始化模型
    model = Model()

    # 定义优化器
    optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate)

    # 定义学习率调节器
    scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=0.99)

    # 迭代训练
    for epoch in range(num_epochs):
        # 设定模型工作在训练模式
        model.train()
        train_loss = 0

        # 遍历训练集
        for inputs, targets in train_dataloader:
            # 预测、损失函数、反向传播
            optimizer.zero_grad()
            outputs = model(inputs)
            loss = loss_fn(outputs, targets)
            loss.backward()
            optimizer.step()
            
            # 记录 loss
            train_loss += loss.item()

        # 计算 loss 并记录到训练误差
        train_loss /= len(train_dataloader)
        train_losses.append(train_loss)

        # 在测试数据集上评估
        model.eval()
        test_loss = 0

        with torch.no_grad():
            # 遍历测试集
            for inputs, targets in test_dataloader:
                # 预测、损失函数
                outputs = model(inputs)
                loss = loss_fn(outputs, targets)
                # 记录 loss
                test_loss += loss.item()

            # 计算 loss 并记录到测试误差
            test_loss /= len(test_dataloader)
            test_losses.append(test_loss)

        
        # 是否更新学习率
        if with_scheduler:
            scheduler.step()

    # 绘制训练和测试误差曲线
    plt.figure(figsize= (8, 4))
    plt.plot(range(num_epochs), train_losses, label="Train")
    plt.plot(range(num_epochs), test_losses, label="Test")
    plt.title("{0} lr_scheduler".format("With " if with_scheduler else "Without"))
    plt.legend()
    # plt.ylim((1,2))
    plt.show()

执行结果

没有使用学习率自动调节时

在这里插入图片描述

使用了学习率自动调节

在这里插入图片描述

结论

使用了学习率自动调节,学习的速度更快,收敛速度更快。

常见学习率调节器

## 学习率衰减,例如每训练 100 次就将学习率降低为原来的一半
scheduler = torch.optim.lr_scheduler.StepLR(optimizer=optimizer, step_size=100, gamma=0.5)
## 指数衰减法,每次迭代将学习率乘上一个衰减率
scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer,gamma=0.99)
## 余弦学习率调节,optimizer 初始学习率为最大学习率,eta_min 是最小学习率,T_max 是最大的迭代次数
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer=optimizer, T_max=100, eta_min=0.00001)
## 自定义学习率,通过一个 lambda 函数自定义实现学习率调节器
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer=optimizer, lr_lambda=lambda epoch: 0.99 ** epoch)
## 预热
warmup_steps = 20
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer=optimizer, lr_lambda=lambda t: min(t/warmup_steps, 0.001))

Links

  • PyTorch学习率调整策略.ipynb
  • 6.2 动态调整学习率
  • 【学习率】torch.optim.lr_scheduler学习率10种调整方法整理
  • 11.11. 学习率调度器
  • Pytorch – 手动调整学习率以及使用torch.optim.lr_scheduler调整学习率

http://www.kler.cn/a/536901.html

相关文章:

  • 换电脑了如何快速导出vscode里的插件
  • 【数据结构】_栈的结构与实现
  • 详解python的单例模式
  • 98.2 AI量化开发:基于DeepSeek打造个人专属金融消息面-AI量化分析师(理论+全套Python代码)
  • Mac上搭建k8s环境——Minikube
  • Qt:Qt环境配置安装
  • IntelliJ IDEA新版本的底部version control(或git)里local change窗口显示配置修改详细教程
  • PHP填表统计预约打卡表单系统小程序
  • 配置GitHub和PicGo的详细步骤
  • 通过Python编写的中国象棋小游戏
  • mac 安装 dotnet 环境
  • 嵌入式硬件篇---OpenMV串口通信json字符串
  • Redis | 十大数据类型
  • Spring Boot:解决现代Java应用开发的难题
  • 关于阿里云 dataworks 运维中心下的任务运维的问题
  • 发布:大彩科技DN系列2.8寸高性价比串口屏发布!
  • TPC服务器与客户端的搭建
  • 【iOS自动化】Xcode配置WebDriverAgent
  • Java/Kotlin双语革命性ORM框架Jimmer(一)——介绍与简单使用
  • Android Studio 2024.2.2.13版本安装配置详细教程
  • leetcode 907. 子数组的最小值之和
  • MySql数据库SQL编写规范注意事项
  • 如何保证系统上线不出现bug?
  • 阿里云负载均衡:DDoS 攻击的坚固防线?
  • 单片机通讯中的时序图:初学者的入门指南
  • http cookie的作用学习