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

PyTorch使用Tricks:学习率衰减 !!

文章目录

前言

1、指数衰减

2、固定步长衰减

3、多步长衰减

4、余弦退火衰减

5、自适应学习率衰减

6、自定义函数实现学习率调整:不同层不同的学习率


前言

在训练神经网络时,如果学习率过大,优化算法可能会在最优解附近震荡而无法收敛;如果学习率过小,优化算法的收敛速度可能会非常慢。因此,一种常见的策略是在训练初期使用较大的学习率来快速接近最优解,然后逐渐减小学习率,使得优化算法可以更精细地调整模型参数,从而找到更好的最优解。

通常学习率衰减有以下的措施:

  • 指数衰减:学习率按照指数的形式衰减,每次乘以一个固定的衰减系数,可以使用 torch.optim.lr_scheduler.ExponentialLR 类来实现,需要指定优化器和衰减系数。
  • 固定步长衰减:学习率每隔一定步数(或者epoch)就减少为原来的一定比例,可以使用 torch.optim.lr_scheduler.StepLR 类来实现,需要指定优化器、步长和衰减比例。
  • 多步长衰减:学习率在指定的区间内保持不变,在区间的右侧值进行一次衰减,可以使用 torch.optim.lr_scheduler.MultiStepLR 类来实现,需要指定优化器、区间列表和衰减比例。
  • 余弦退火衰减:学习率按照余弦函数的周期和最值进行变化,可以使用 torch.optim.lr_scheduler.CosineAnnealingLR 类来实现,需要指定优化器、周期和最小值。
  • 自适应学习率衰减:这种策略会根据模型的训练进度自动调整学习率,可以使用 torch.optim.lr_scheduler.ReduceLROnPlateau 类来实现。例如,如果模型的验证误差停止下降,那么就减小学习率;如果模型的训练误差上升,那么就增大学习率。
  • 自适应函数实现学习率调整:不同层不同的学习率。

1、指数衰减

指数衰减是一种常用的学习率调整策略,其主要思想是在每个训练周期(epoch)结束时,将当前学习率乘以一个固定的衰减系数(gamma),从而实现学习率的指数衰减。这种策略可以帮助模型在训练初期快速收敛,同时在训练后期通过降低学习率来提高模型的泛化能力。

在PyTorch中,可以使用 torch.optim.lr_scheduler.ExponentialLR 类来实现指数衰减。该类的构造函数需要两个参数:一个优化器对象和一个衰减系数。在每个训练周期结束时,需要调用ExponentialLR 对象的 step() 方法来更新学习率。

以下是一个使用 ExponentialLR代码示例:

import torch
from torch.optim import SGD
from torch.optim.lr_scheduler import ExponentialLR# 假设有一个模型参数
model_param = torch.nn.Parameter(torch.randn(2, 2, requires_grad=True))# 使用SGD优化器,初始学习率设置为0.1
optimizer = SGD([model_param], lr=0.1)# 创建ExponentialLR对象,衰减系数设置为0.9
scheduler = ExponentialLR(optimizer, gamma=0.9)# 在每个训练周期结束时,调用step()方法来更新学习率
for epoch in range(100):# 这里省略了模型的训练代码# ...# 更新学习率scheduler.step()

在这个例子中,初始的学习率是0.1,每个训练周期结束时,学习率会乘以0.9,因此学习率会按照指数的形式衰减。

2、固定步长衰减

固定步长衰减是一种学习率调整策略,它的原理是每隔一定的迭代次数(或者epoch),就将学习率乘以一个固定的比例,从而使学习率逐渐减小。这样做的目的是在训练初期使用较大的学习率,加快收敛速度,而在训练后期使用较小的学习率,提高模型精度。

PyTorch提供了 torch.optim.lr_scheduler.StepLR 类来实现固定步长衰减,它的参数有:

  • optimizer:要进行学习率衰减的优化器,例如 torch.optim.SGD torch.optim.Adam等。
  • step_size:每隔多少隔迭代次数(或者epoch)进行一次学习率衰减,必须是正整数。
  • gamma:学习率衰减的乘法因子,必须是0到1之间的数,表示每次衰减为原来的 gamma倍。
  • last_epoch:最后一个epoch的索引,用于恢复训练的状态,默认为-1,表示从头开始训练。
  • verbose:是否打印学习率更新的信息,默认为False。

下面是一个使用  torch.optim.lr_scheduler.StepLR 类的具体例子,假设有一个简单的线性模型,使用 torch.optim.SGD 作为优化器,初始学习率为0.1,每隔5个epoch就将学习率乘以0.8,训练100个epoch:

import torch
import matplotlib.pyplot as plt# 定义一个简单的线性模型
class Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.fc = torch.nn.Linear(1, 1)def forward(self, x):return self.fc(x)# 创建模型和优化器
model = Net()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)# 创建固定步长衰减的学习率调度器
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.8)# 记录学习率变化
lr_list = []# 模拟训练过程
for epoch in range(100):# 更新学习率scheduler.step()# 记录当前学习率lr_list.append(optimizer.param_groups[0]['lr'])# 绘制学习率曲线
plt.plot(range(100), lr_list, color='r')
plt.xlabel('Epoch')
plt.ylabel('Learning Rate')
plt.show()

学习率在每个5个epoch后都会下降为原来的0.8倍,直到最后接近0。

固定步长衰减指数衰减都是学习率衰减的策略,但它们在衰减的方式和速度上有所不同:

  • 固定步长衰减:在每隔固定的步数(或epoch)后,学习率会减少为原来的一定比例。这种策略的衰减速度是均匀的,不会随着训练的进行而改变。
  • 指数衰减:在每个训练周期(或epoch)结束时,学习率会乘以一个固定的衰减系数,从而实现学习率的指数衰减。这种策略的衰减速度是逐渐加快的,因为每次衰减都是基于当前的学习率进行的。

3、多步长衰减

多步长衰减是一种学习率调整策略,它在指定的训练周期(或epoch)达到预设的里程碑时,将学习率减少为原来的一定比例。这种策略可以在模型训练的关键阶段动态调整学习率。

在PyTorch中,可以使用 torch.optim.lr_scheduler.MultiStepLR 类来实现多步长衰减。以下是一个使用 MultiStepLR 的代码示例:

import torch
import torch.optim as optim
from torch.optim.lr_scheduler import MultiStepLR# 假设有一个简单的模型
model = torch.nn.Linear(10, 2)
optimizer = optim.SGD(model.parameters(), lr=0.1)# 创建 MultiStepLR 对象,设定在第 30 和 80 个 epoch 时学习率衰减为原来的 0.1 倍
scheduler = MultiStepLR(optimizer, milestones=[30, 80], gamma=0.1)# 在每个训练周期结束时,调用 step() 方法来更新学习率
for epoch in range(100):# 这里省略了模型的训练代码# ...# 更新学习率scheduler.step()

在这个例子中,初始的学习率是0.1,当训练到第30个epoch时,学习率会变为0.01(即0.1*0.1),当训练到第80个epoch时,学习率会再次衰减为0.001(即0.01*0.1)。

4、余弦退火衰减

余弦退火衰减是一种学习率调整策略,它按照余弦函数的周期和最值来调整学习率。在PyTorch中,可以使用 torch.optim.lr_scheduler.CosineAnnealingLR 类来实现余弦退火衰减。

以下是一个使用 CosineAnnealingLR 的代码示例:

import torch
import torch.nn as nn
from torch.optim.lr_scheduler import CosineAnnealingLR
import matplotlib.pyplot as plt# 假设有一个简单的模型
class SimpleModel(nn.Module):def __init__(self):super(SimpleModel, self).__init__()self.linear = nn.Linear(10, 2)model = SimpleModel()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)# 创建 CosineAnnealingLR 对象,周期设置为 10,最小学习率设置为 0.01
scheduler = CosineAnnealingLR(optimizer, T_max=10, eta_min=0.01)lr_list = []
# 在每个训练周期结束时,调用 step() 方法来更新学习率
for epoch in range(100):# 这里省略了模型的训练代码# ...# 更新学习率scheduler.step()lr_list.append(optimizer.param_groups[0]['lr'])# 绘制学习率变化曲线
plt.plot(range(100), lr_list)
plt.xlabel('Epoch')
plt.ylabel('Learning Rate')
plt.title("Learning rate schedule: CosineAnnealingLR")
plt.show()

在这个例子中,初始的学习率是0.1,学习率会按照余弦函数的形式在0.01到0.1之间变化,周期为10个epoch。

5、自适应学习率衰减

自适应学习率衰减是一种学习率调整策略,它会根据模型的训练进度自动调整学习率。例如,如果模型的验证误差停止下降,那么就减小学习率;如果模型的训练误差上升,那么就增大学习率。在PyTorch中,可以使用 torch.optim.lr_scheduler.ReduceLROnPlateau 类来实现自适应学习率衰减。

以下是一个使用 ReduceLROnPlateau 的代码示例:

import torch
import torch.nn as nn
from torch.optim.lr_scheduler import ReduceLROnPlateau# 假设有一个简单的模型
model = nn.Linear(10, 2)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)# 创建 ReduceLROnPlateau 对象,当验证误差在 10 个 epoch 内没有下降时,将学习率减小为原来的 0.1 倍
scheduler = ReduceLROnPlateau(optimizer, 'min', patience=10, factor=0.1)# 模拟训练过程
for epoch in range(100):# 这里省略了模型的训练代码# ...# 假设有一个验证误差val_loss = ...# 在每个训练周期结束时,调用 step() 方法来更新学习率scheduler.step(val_loss)

6、自定义函数实现学习率调整:不同层不同的学习率

可以通过为优化器提供一个参数组列表来实现对不同层使用不同的学习率。每个参数组是一个字典,其中包含一组参数和这组参数的学习率。

以下是一个具体的例子,假设有一个包含两个线性层的模型,想要对第一层使用学习率0.01,对第二层使用学习率0.001:

import torch
import torch.nn as nn
import torch.optim as optim# 定义一个包含两个线性层的模型
class SimpleModel(nn.Module):def __init__(self):super(SimpleModel, self).__init__()self.layer1 = nn.Linear(10, 2)self.layer2 = nn.Linear(2, 10)model = SimpleModel()# 创建一个参数组列表,每个参数组包含一组参数和这组参数的学习率
params = [{'params': model.layer1.parameters(), 'lr': 0.01},{'params': model.layer2.parameters(), 'lr': 0.001}]# 创建优化器
optimizer = optim.SGD(params)# 现在,当调用 optimizer.step() 时,第一层的参数会使用学习率 0.01 进行更新,第二层的参数会使用学习率 0.001 进行更新

在这个例子中,首先定义了一个包含两个线性层的模型。然后,创建一个参数组列表,每个参数组都包含一组参数和这组参数的学习率。最后创建了一个优化器SGD,将这个参数组列表传递给优化器。这样,当调用 optimizer.step() 时,第一层的参数会使用学习率0.01进行更新,第二层的参数会使用学习率0.001进行更新。

参考:深度图学习与大模型LLM

相关文章:

  • Leetcode 209.长度最小的子数组
  • 第2讲-Memory
  • 一文带你解决如何设置Redis临时密码和永久密码
  • C++内联函数的使用
  • 面试前端性能优化八股文十问十答第三期
  • Python+Requests+Pytest+YAML+Allure实现接口自动化
  • SpringBoot项目嵌入RabbitMQ
  • VSCODE include错误 找不到 stdio.h
  • leetcode-回溯法-矩阵中的路径
  • PostMan使用自带js库base64编码、sha256摘要、环境变量的使用
  • 主流开发语言和开发环境:探索编程世界的基础
  • Linux篇:指令
  • 程序媛的mac修炼手册-- 小白入门Java篇
  • 第八篇【传奇开心果系列】python的文本和语音相互转换库技术点案例示例:Google Text-to-Speech虚拟现实(VR)沉浸式体验经典案例
  • 2024 windows环境下安装RabbitMQ(亲测超详细)
  • [译] 怎样写一个基础的编译器
  • Akka系列(七):Actor持久化之Akka persistence
  • C++类的相互关联
  • canvas 绘制双线技巧
  • docker容器内的网络抓包
  • dva中组件的懒加载
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • javascript 总结(常用工具类的封装)
  • java正则表式的使用
  • js学习笔记
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • ng6--错误信息小结(持续更新)
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 将 Measurements 和 Units 应用到物理学
  • 精彩代码 vue.js
  • 前端面试总结(at, md)
  • 优化 Vue 项目编译文件大小
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • ​​​​​​​​​​​​​​Γ函数
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (1)(1.13) SiK无线电高级配置(六)
  • (安卓)跳转应用市场APP详情页的方式
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (第二周)效能测试
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (四)鸿鹄云架构一服务注册中心
  • .net 8 发布了,试下微软最近强推的MAUI
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET导入Excel数据
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • [BZOJ2208][Jsoi2010]连通数
  • [C++] 多线程编程-thread::yield()-sleep_for()
  • [C++]C++类基本语法
  • [ICCV2017]Neural Person Search Machines
  • [linux] 创建用户
  • [linux运维] 利用zabbix监控linux高危命令并发送告警(基于Zabbix 6)
  • [math]判断线段是否相交及夹角