pytorch学习率设置——optimizer.param_groups、对不同层设置学习率、动态调整学习率。

news2024/11/16 1:25:52

文章目录

  • 前言
    • 1、关于optimizer.param_groups
    • 2、设置学习率
    • 3、optim 提供的优化器


前言

我的需求:我需要在yolov7中更改其中一层的学习率,但yolov7的学习率是随着eporch的变化动态变化的。


1、关于optimizer.param_groups

“param_groups” 是 Pytorch 中优化器 Optimizer 的一个属性,它是一个列表,其中的每个元素都是一个字典,表示优化的参数组。每个字典都包含了一组参数的各种信息,如当前的学习率、动量等。这个属性可以用来获取优化器中当前管理的参数组的信息,也可以用来修改优化器的参数设置。
param_groups中的一些参数介绍:
[‘param’,‘lr’,‘momentum’,‘dampening’,‘weight_decay’,‘nesterov’]
params(iterable)—待优化参数w、b 或者定义了参数组的dict
lr(float,可选)—学习率
momentum(float,可选,默认0)—动量因子
weight_decay(float,可选,默认0)—权重衰减
dampening (float, 可选) – 动量的抑制因子(默认:0)
nesterov (bool, 可选) – 使用Nesterov动量(默认:False)

2、设置学习率

查看优化器完整参数:

print(optimizer.state_dict()["param_groups"])

查看学习率:

print("Lr:{}".format(optimizer.state_dict()['param_groups'][0]['lr']))

以下是我测试的网络模型:

class resnet18(torch.nn.Module):
    def __init__(self):
        super(resnet18, self).__init__()
        self.block1 = torch.nn.Sequential(
            torch.nn.Conv2d(1, 10, 5),
            torch.nn.MaxPool2d(2),
            torch.nn.ReLU(True),
            torch.nn.BatchNorm2d(10),
        )
        self.block2 = torch.nn.Sequential(
            torch.nn.Conv2d(10, 20, 5),
            torch.nn.MaxPool2d(2),
            torch.nn.ReLU(True),
            torch.nn.BatchNorm2d(20),
        )
        self.fc = torch.nn.Sequential(
            torch.nn.Flatten(),
            torch.nn.Linear(320, 10)
        )
    def forward(self, x):
        x = self.block1(x)
        x = self.block2(x)
        x = self.fc(x)
        return x
    
model = resnet18()

设置优化器、学习率:

optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.5)

对网络的不同块设置学习率:

optimizer = torch.optim.SGD([
        {"params":model.block1.parameters()},
        {"params":model.block2.parameters(),"lr":0.08},
        {"params":model.fc.parameters(),"lr":0.09},],
        lr=0.1, #默认参数
    )

对网络的不同层设置学习率:

# 提取指定层对象
special_layers = torch.nn.ModuleList([model.block1[0], model.block2[3]])
# 获取指定层参数id
special_layers_params = list(map(id, special_layers.parameters()))
# 获取非指定层的参数id
base_params = filter(lambda p: id(p) not in special_layers_params, model.parameters())

optimizer = torch.optim.SGD([
    {'params': base_params},
    {'params': special_layers.parameters(), 'lr': 0.1}], lr=0.11)

动态调整学习率:

动态调整学习率 模型学习率必须为以全局的(也就是模型的学习率只能有一个比如全局设为0.5)

def adjust_learning_rate(optimizer, epoch, start_lr):
    lr = start_lr * (0.9 ** (epoch // 1))    # 每1个eporch学习率改变为上一个eporch的 0.9倍
    for param_group in optimizer.param_groups:
        param_group['lr'] = lr

动态调整学习率 网络模型学习率可以有多个

start_lr = [0.11,0.1]  # 不同层的初始学习率
def adjust_learning_rate(optimizer, epoch, start_lr):
    for index, param_group in enumerate(optimizer.param_groups):
        lr = start_lr[index] * (0.9 ** (epoch // 1))    # 每1个eporch学习率改变为上一个eporch的 0.9倍
        param_group['lr'] = lr

以上两个函数需要放在eporch的for循环中进行迭代,每一个eporch调整一次。如下我放在了train函数里。
在这里插入图片描述
以上的总代码:
代码是以resnet18分类手写数字体识别mini数据集为例,分别对不同的层设置了学习率,带动态调整,每经过一个eporch,学习率调整为上一个eporch的0.9倍。

import torch
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision import transforms
import torch.nn.functional as F
import matplotlib.pyplot as plt
import numpy as np
import os  # 添加代码①
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"  # 添加代码②

batch_size = 256    #设置batch大小
transform = transforms.Compose([
    transforms.ToTensor(),                        #转换为张量
    transforms.Normalize((0.1307,), (0.3081,))    #设定标准化值
])
#训练集
train_dataset = datasets.MNIST(
    root='../data/mnist',
    train=True,
    transform=transform,
    download=True)
#测试集
test_dataset = datasets.MNIST(
    root='../data/mnist',
    train=False,
    transform=transform,
    download=True)
 
#训练集加载器
train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size,shuffle=True)
#测试集加载器
test_loader = DataLoader(dataset=test_dataset,batch_size=batch_size, shuffle=False)

class resnet18(torch.nn.Module):
    def __init__(self):
        super(resnet18, self).__init__()
        self.block1 = torch.nn.Sequential(
            torch.nn.Conv2d(1, 10, 5),
            torch.nn.MaxPool2d(2),
            torch.nn.ReLU(True),
            torch.nn.BatchNorm2d(10),
        )
        self.block2 = torch.nn.Sequential(
            torch.nn.Conv2d(10, 20, 5),
            torch.nn.MaxPool2d(2),
            torch.nn.ReLU(True),
            torch.nn.BatchNorm2d(20),
        )
        self.fc = torch.nn.Sequential(
            torch.nn.Flatten(),
            torch.nn.Linear(320, 10)
        )
    def forward(self, x):
        x = self.block1(x)
        x = self.block2(x)
        x = self.fc(x)
        return x
    
model = resnet18()

device=torch.device("cuda:0"if torch.cuda.is_available()else"cpu")#使用GPU进行计算
model.to(device)#把model模型放进去
#---------------------------------------------------------------------# 
# 构造损失函数和优化函数
# 损失
criterion = torch.nn.CrossEntropyLoss()
#---------------------------------------------------------------------# 

#---------------------------------------------------------------------#
# 运行时,以下几个optimizer留一个就好

# 设置学习率 全局学习率0.1
#optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.5)

# 分块设置学习率
# optimizer = torch.optim.SGD([
#         {"params":model.block1.parameters()},
#         {"params":model.block2.parameters(),"lr":0.08},
#         {"params":model.fc.parameters(),"lr":0.09},],
#         lr=0.1, #默认参数
#     )

# 对不同层设置学习率
special_layers = torch.nn.ModuleList([model.block1[0], model.block2[3]]) # 提取指定层对象
special_layers_params = list(map(id, special_layers.parameters())) # 获取指定层参数id
base_params = filter(lambda p: id(p) not in special_layers_params, model.parameters()) # 获取非指定层的参数id
optimizer = torch.optim.SGD([
    {'params': base_params},
    {'params': special_layers.parameters(), 'lr': 0.1}], lr=0.11)

#---------------------------------------------------------------------# 
# 动态调整学习率 模型学习率必须为以全局的(也就是模型的学习率只能有一个比如全局设为0.5# def adjust_learning_rate(optimizer, epoch, start_lr):
#     lr = start_lr * (0.9 ** (epoch // 1))    # 每1个eporch学习率改变为上一个eporch的 0.9倍
#     for param_group in optimizer.param_groups:
#         param_group['lr'] = lr

# 动态调整学习率 网络模型学习率可以有多个
start_lr = [0.11,0.1]  # 不同层的初始学习率
def adjust_learning_rate(optimizer, epoch, start_lr):
    for index, param_group in enumerate(optimizer.param_groups):
        lr = start_lr[index] * (0.9 ** (epoch // 1))    # 每1个eporch学习率改变为上一个eporch的 0.9倍
        param_group['lr'] = lr
#---------------------------------------------------------------------#
def train(epoch):
    
    adjust_learning_rate(optimizer, epoch, start_lr)  # 动态调整学习率
    print("Lr:{}".format(optimizer.state_dict()['param_groups'][0]['lr']))  # 查看学习率
    print("Lr:{}".format(optimizer.state_dict()['param_groups'][1]['lr']))
#     print("Lr:{}".format(optimizer.state_dict()['param_groups'][2]['lr']))
#     print(optimizer.state_dict()["param_groups"])  # 查看优化器完整参数

    running_loss = 0.0        #每一轮训练重新记录损失值
    for batch_idx, data in enumerate(train_loader, 0):    #提取训练集中每一个样本
        inputs, target = data        
        inputs, target = inputs.to(device), target.to(device)  # 这里的数据(原数据)也要迁移过去
        # outputs输出为0-9的概率  256*10
        outputs = model(inputs)              #代入模型
        loss = criterion(outputs, target)    #计算损失值
        loss.backward()                      #反向传播计算得到每个参数的梯度值
        optimizer.step()                     #梯度下降参数更新
        optimizer.zero_grad()                #将梯度归零
        running_loss += loss.item()          #损失值累加
    
        if batch_idx % 300 == 299:           #每300个样本输出一下结果
            print('[%d,%5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
            running_loss = 0.0          # (训练轮次,  该轮的样本次,  平均损失值)
    
    return running_loss
    
def test():
    correct = 0
    total = 0
    with torch.no_grad():            #执行计算,但不希望在反向传播中被记录
        for data in test_loader:     #提取测试集中每一个样本
            images, labels = data
            images, labels = images.to(device), labels.to(device)
            # outputs输出为0-9的概率  256*10
            outputs = model(images)  #带入模型
            # torch.max()这个函数返回的是两个值,第一个值是具体的value(我们用下划线_表示)
            # 第二个值是value所在的index(也就是predicted)
            _, pred = torch.max(outputs.data, dim=1)    #获得结果中的最大值
            total += labels.size(0)                     #测试数++
            correct += (pred == labels).sum().item()    #将预测结果pred与标签labels对比,相同则正确数++
        print('%d %%' % (100 * correct / total))    #输出正确率
        
if __name__ == '__main__':
    # 这两个数组主要是为了画图
    lossy = []        #定义存放纵轴数据(损失值)的列表
    epochx = []       #定义存放横轴数据(训练轮数)的列表
    
    for epoch in range(10):    #训练10轮
        epochx.append(epoch)   #将本轮轮次存入epochy列表
        lossy.append(train(epoch))  #执行训练,将返回值loss存入lossy列表  
        test()                 #每轮训练完都测试一下正确率
    path = "D:/code/text/model2.pth"
    #torch.save(model,path)
    torch.save(model.state_dict(),path)   # 保存模型
    model = torch.load("D:/code/text/model2.pth")  # 加载模型
 
    #可视化一下训练过程
    plt.plot(epochx, lossy)
    plt.grid()
    plt.show()

结果如下:学习率正常缩小。
在这里插入图片描述

3、optim 提供的优化器

例如:

torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch = -1)

这篇博客总结的很全:http://t.csdn.cn/wXU18


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/487641.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode1047. 删除字符串中的所有相邻重复项

1047. 删除字符串中的所有相邻重复项 给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。 在 S 上反复执行重复项删除操作,直到无法继续删除。 在完成所有重复项删除操作后返回最终的字符串。答案保证唯一…

RabbitMQ 工作队列模型(任务队列)

任务模型 概念 ​ 当消息处理比较耗时的时候,可能生产消息的速度大于消费的速度,长此以往,就会导致消息堆积,无法及时处理,此时可以使用任务模型,当多个消费者绑定一个队列,共同消费其中的消息…

认识JSP

什么是JSP? JSP(Java Server Pages)是一种类似于HTML的标记语言,用于创建动态Web页面。与HTML不同的是,JSP页面中可以嵌入Java代码,由Web服务器在动态页面中生成HTML代码,从而实现Web应用程序的前端交互效…

scratch求和 中国电子学会图形化编程 少儿编程 scratch编程等级考试四级真题和答案解析2023年3月

目录 scratch求和 一、题目要求 1、准备工作 2、功能实现 二、案例分析

node之Express

目录 Express简介 安装 创建基本的Web服务器 托管静态资源 以上述案例为基础访问静态资源的路径为:http://127.0.0.1:8080/xxx.html 托管多个静态资源目录 路由的概念 路由的匹配过程 模块化路由 模块化路由案例 中间件的概念 定义中间件函数例 全局生…

AI助阵,领先创新丨智能评价分析·数字员工,开启顶级消费者体验新篇章!

GPT-4作为人工智能时代发展道路上的里程碑,以其惊人的多模态大模型能力吸引了众多零售消费品牌的关注,利用AI技术解决客户复杂业务问题,成为推动行业提质增效的重要途径。实在智能是国内首个生成式AI标准编写单位,始终坚持AI赋能商…

各种常用字符编码详解【图文教程】,Unicode 是一个编码规范,并不是一个具体的编码

文章目录 常见编码的比较,各个编码中各字符占用(字节数):简体中文编码发展史,编码出现时间和涵盖范围UTF-8、unicode与GBK编码转化一问一答其他ASCII表 参考文档 常见编码的比较,各个编码中各字符占用(字节数): 编码英文中文(简体…

数说热点 | 跟着《长月烬明》起飞,今年各地文旅主打的就是一个听劝

近日,随着热播剧《长月烬明》的爆火,蚌埠、宣城、敦煌等多个与剧情梦幻联动的宝藏城市被带飞,各地热心网友也纷纷催促自家文旅局赶紧“蹭飞”,《长月烬明》以一己之力打造了影视文旅融合的新样板。 仙偶剧特效天花板,…

SpringCloud------代码demo(二)

SpringCloud------代码demo(二) 编码实操 以订单——支付微服务模块作为基础,开始逐渐扩充 微服务架构编码构建 1.约定 > 配置 > 编码 2.IDEA新建project工作空间 3.Rest微服务工程构建 总父工程 POM project module 首先创建maven项…

FPGA入门系列14--VGA

文章简介 本系列文章主要针对FPGA初学者编写,包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解,旨在更快速的提升初学者在FPGA开发方面的能力,每一个章节中都有针对性的代码…

06 - 3 事件驱动架构模式——EDA

何为EDA 事件驱动架构是一种异步分发事件的架构模式用于高扩展且低耦合的系统以事件为核心,一系列解耦的、单一功能的事件处理器 Notification 源系统发送消息通知其他系统状态改变接收方响应非必须发送 Event 逻辑与处理 Event 逻辑无依赖,独立变化解…

华为路由WS5200 四核版使用体验

文章目录 前言一、主界面和上网设置二、网络WIFI设置三、安全和系统总结 前言 其实我是看不上这种除了能上网,没任何用的东东的。除了上古时代用过类似的简单设备,已经十数年没再看一眼这种东西了,当然更不会去买这种东西,别误会…

vscode配置latex

reference:https://zhuanlan.zhihu.com/p/166523064 1 texlive卸载 找到texlive\2019\tlpkg\installer下的uninst.bat文件并点击运行。 删除环境变量 2 texlive安装 打开https://tug.org/texlive/acquire-iso.html点击下载iso文件 3 vscode 安装 4 latex插件…

Linux系统编程 多线程基础

文章目录 前言一、线程概念二、线程的创建三、线程的退出四、pthread_join函数总结 前言 本篇文章作为多线程的入门讲解将带大家先创建几个线程来感受一下什么是多线程,了解一下多线程到底有什么作用。 一、线程概念 线程(Thread)是程序执…

C++类与对象(二)——构造函数与析构函数

文章目录 一.类的默认6个成员函数二.构造函数1.引例2.构造函数的概念及特性 三.析构函数😋析构函数的特性 前言: 上篇文章初步认识了类以及类的相关知识,本篇将继续深入学习类与对象——类的默认6个成员函数: 一.类的默认6个成员函…

制造企业如何跨越大规模定制鸿沟?中国最大减速机企业的答案来了

导读:传统制造企业如何深度用云? 在中国制造向中国智造的转型中,长三角地区一直扮演着急先锋的角色。总部位于常州的江苏国茂减速机股份有限公司(简称国茂股份),就是中国制造上云转型的典型代表。 国茂股份成立于1993年&#xff0…

Microelectronic学习章节总结(2)-- data path和control unit设计

文章目录 part1. Data path设计1.1 logic unit1.2 shifter1.3 adder1.4 comparator1.5 multiplier1.6 divider1.7 register file part2. Control unit设计part3. CPU SoC上的其它部件 (TODO:理解总结)3.1 总线AMBA(parallel) 3.2 Memorymemor…

[C++基础]-类和对象(下)

前言 作者:小蜗牛向前冲 名言:我可以接受失败,但我不能接受放弃 如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。 目录 一、深入学…

推荐算法实战项目:AFM 原理以及案例实战(附完整 Python 代码)

本文要介绍的是由浙江大学联合新加坡国立大学提出的AFM模型。通过名字也可以看出,此模型又是基于FM模型的改进,其中A代表”Attention“,即AFM模型实际上是在FM模型中引入了注意力机制改进得来的。 之所以要在FM模型中引入注意力机制&#xf…

PC3-管理员操作

token无效可能,就是token过期了需要配置::: history 安装可以跳路由在ts文件中:因为在ts文件中还需要store,清空token // 安装可以跳路由在ts文件中npm i history 防止接口出现 token 无效,登…