首页 > 其他分享 >《深度学习》卷积神经网络 使用最优模型、调整学习率 用法解析及案例实现

《深度学习》卷积神经网络 使用最优模型、调整学习率 用法解析及案例实现

时间:2024-09-25 11:22:39浏览次数:10  
标签:卷积 self torch 学习 神经网络 lr model 模型

目录

一、使用最优模型

1、什么是最优模型

2、如实使用最优模型

1)读取参数方法

2)调用完整模型方法

3)实例

完整代码:

打印结果:

二、调整学习率

1、什么是调整学习率

2、目的

3、调整学习率的方法

1)有序调整

2)自适应调整

参数解析

3)自定义调整

4、案例使用


一、使用最优模型

1、什么是最优模型

        在深度学习中,最优模型指的是在给定的任务上具有最好性能的模型。最优模型通常通过最小化损失函数来确定,该损失函数能够衡量模型在训练数据上的预测结果与真实结果之间的差异。

        最优模型具有较低的训练误差和有效的泛化能力,能够在未见过的测试数据上表现良好。为了找到最优模型,通常会使用优化算法,如梯度下降算法,来更新模型的参数,直到找到损失函数的最小值。最优模型的选择通常基于多个因素,如训练数据的质量和数量,模型的复杂性和计算资源的限制。

2、如实使用最优模型

        上节课我们已经通过寻找最优模型得到了当前训练的最优参数的模型,然后将这个模型保存在pt、pth、t7文件中,如下所示:

1)读取参数方法
model = CNN().to(device)
model.load_state_dict(torch.load("best.path"))   # 调用仅包含权重参数和偏置的模型
2)调用完整模型方法
#  2、读取完整模型的方法,无需提前创建model
# model = CNN().to(device)  # 将模型传入GPU,device为前面判断的
model = torch.load('best.pt')   # 调用前面保存的完整模型
3)实例

        依旧是上节课的数据,如下所示,代码只需小改一下即可

        完整代码:
import numpy as np
from torch.utils.data import Dataset,DataLoader
import torch
import torch.nn as nn
from PIL import Image
from torchvision import transforms


device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu"


from torch import nn
class CNN(nn.Module):
    def __init__(self):
        super(CNN,self).__init__()
        self.conv1=nn.Sequential(nn.Conv2d(in_channels=3,
                                        out_channels=16,
                                        kernel_size=5,
                                        stride=1,
                                        padding=2)
                                ,nn.ReLU()
                                ,nn.MaxPool2d(kernel_size=2)
                                )
        self.conv2=nn.Sequential(
            nn.Conv2d(16,32,5,1,2),
            nn.ReLU(),
            nn.Conv2d(32, 32, 5, 1, 2),
            nn.ReLU(),
            nn.MaxPool2d(2)
        )

        self.conv3=nn.Sequential(
            nn.Conv2d(32,64,5,1,2),
            nn.ReLU())

        self.out = nn.Linear(64*64*64,20)

    def forward(self,x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        x = x.view(x.size(0),-1)
        output = self.out(x)
        # output = torch.sigmoid(x)
        return output

# model = CNN().to(device)

# 提取模型的两种方法
#  1、读取参数的方法
# model = CNN().to(device)
# model.load_state_dict(torch.load("best.path"))   # 调用仅包含权重参数和偏置的模型
#  2、读取完整模型的方法,无需提前创建model
# model = CNN().to(device)  # 将模型传入GPU,device为前面判断的
model = torch.load('best.pt')   # 调用前面保存的完整模型

model.eval()   # 固定模型参数和数据,防止后面被修改
# 数据增强
data_transforms={
    'train':transforms.Compose([
        transforms.Resize([256,256]),
        transforms.RandomRotation(45),#随机旋转,-45到45度
        # transforms.CenterCrop(256),#从中心裁剪240*240
        transforms.RandomHorizontalFlip(p=0.5),#随机水平翻转
        transforms.RandomVerticalFlip(p=0.5),#随机垂直翻转
        transforms.ColorJitter(brightness=0.2,contrast=0.1,saturation=0.1,hue=0.1),
        transforms.RandomGrayscale(p=0.1),#转换为灰度图

        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])
    ]),
    'valid':transforms.Compose([
        transforms.Resize([256,256]),
        transforms.ToTensor(),
        transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])
    ])
}

# 取出数据
class food_dataset(Dataset):   # food_dataset是自己创建的类名称,可以改变你需要的名称
    def __init__(self,file_path,transform=None):
        self.file_path=file_path
        self.imgs=[]
        self.labels=[]
        self.transform=transform
        with open(self.file_path) as f:
            samples=[x.strip().split(' ') for x in f.readlines()]
            for sample in samples:
                self.imgs.append(sample[0])
                self.labels.append(sample[1:])

    def __len__(self):
        return len(self.imgs)

    def __getitem__(self, idx):
        image=Image.open(self.imgs[idx])
        if self.transform:
            image=self.transform(image)

        label=self.labels[idx]
        label=torch.from_numpy(np.array(label,dtype=np.float64))
        return image,label

# 取出图片数据后对其进行打包
test_data = food_dataset(file_path='./testda.txt',transform = data_transforms['valid'])
test_dataloader = DataLoader(test_data,batch_size=1,shuffle=True)

#
result=[]  # 保存的预测结果
labels=[]  # 真实结果
def test_true(dataloader,model):
    with torch.no_grad():  # 上下文管理器,关闭梯度运算
        for x,y in dataloader:   # 遍历打包好的图片及其标签
            x,y = x.to(device),y.to(device)  # 将其传入GPU
            pred = model.forward(x)   # 前向传播
            result.append(pred.argmax(1).item())   # 将预测值的结果转换成python变量然后增加到列表
            labels.append(y.item())  # 同时将真实值的标签转变成python标量然后存入labels列表

test_true(test_dataloader,model)   # 导入数据和模型
print('预测值:\t',result)
print('真实值:\t',labels)
打印结果:

二、调整学习率

1、什么是调整学习率

        学习率是优化算法中一个重要的超参数,用于控制模型参数在每次更新时的调整幅度。学习率决定了模型在参数空间中搜索的步长大小。调整学习率是指在训练过程中根据需要改变学习率的值。

        常用的学习率有0.1、0.01以及0.001等,学习率越大则权重更新越快。一般来说,我们希望在训练初期学习率大一些,使得网络收敛迅速,在训练后期学习率小一些,使得网络更好的收敛到最优解。

2、目的

        调整学习率的目的是为了能够更好地优化模型,避免训练过程中出现的一些问题,如梯度爆炸梯度消失、训练过程陷入局部极小值

3、调整学习率的方法

        PyTorch学习率调整策略通过torch.optim.lr_sheduler接口实现,下图可发现不同方法调整学习率所对应的横轴epoch值与纵轴学习率的关系

        1)有序调整

                等间隔调整step、多间隔调整MultiStep、指数衰减Exponential、余弦退火CosineAnnealing

"""等间隔调整"""
torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1)
# optimizer: 神经网络训练中使用的优化器,
# 如optimizer = torch.optim.Adam(model.parameters(),lr=0.001)
# step_size(int): 学习率下降间隔数,单位是epoch,而不是iteration.
# gamma(float):学习率调整倍数,默认为0.1
# 每训练step_size个epoch,学习率调整为lr=lr*gamma.

"""多间隔调整调整"""
torch.optim.lr_shceduler.MultiStepLR(optimizer, milestones, gamma=0.1)
# milestone(list): 一个列表参数,表示多个学习率需要调整的epoch值,
# 如milestones=[10, 30, 80],即10轮时将gamma乘以学习率lr,30轮时、80轮时、、

"""指数衰减"""
torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma)
# gamma(float):学习率调整倍数的底数,指数为epoch,初始值我lr, 倍数为γepoch,每一轮都调整

"""余弦退火"""
torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0)
# Tmax(int):学习率下降到最小值时的epoch数,即当epoch=T_max时,学习率下降到余弦函数最小值,# 当epoch>T_max时,学习率将增大;
# etamin: 学习率调整的最小值,即epoch=Tmax时,lrmin=etamin, 默认为0.


        2)自适应调整

                依训练状况伺机而变,通过检测某个指标的变化情况(如loss、accuracy),当该指标不怎么变化时,就是调整学习率的时机。

"""根据指标调整学习率"""
torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1,patience=10,verbose=False, threshold=0.0001, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08)
参数解析
  • optimizer:是优化器,例如SGD、Adam等。
  • mode:用于指示评估指标的变化方向。"min"表示评估指标越小越好,"max"表示评估指标越大越好。
  • factor:学习率缩放因子,每次调整学习率时,将学习率乘以factor。
  • patience:在模型没有显著改善时,经过多少个epoch才进行调整。
  • verbose:是否打印每次学习率调整的信息。
  • threshold:评估指标的变化阈值,控制何时进行学习率调整。
  • threshold_mode:用于指示threshold是"rel"相对于最好的评估指标还是"abs"绝对值。
  • cooldown:在学习率调整之后,经过多少个epoch才恢复正常操作。
  • min_lr:学习率的下限,不会再低于该值。
  • eps:一个很小的值,用于避免除以零错误。

        3)自定义调整

                通过自定义关于epoch的lambda函数调整学习率lambdaLR

torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda)
# lr_lambda(function or list): 自定义计算学习率调整倍数的函数,通常时epoch的函数,当有多个参数组时,设为list.

4、案例使用

        只需将上节课中训练模型的代码拿过来更改最后一小部分即可,首先在创建交叉熵损失函数下再创建一个更改学习率的接口,然后在进行每轮的训练时插入这个接口即可。

loss_fn = nn.CrossEntropyLoss()    # 创建交叉熵损失雨数对象
optimizer = torch.optim.Adam(model.parameters(),lr=0.001)   #创建一个优化器,一开始lr可以大一些
scheduler = torch.optim.lr_scheduler.StepLR(optimizer,step_size=5,gamma=0.5)  # 调整学习率
"""optimizer是一个PyTorch优化器对象
step_size表示学习率调整的步长
gamma表示学习率的衰减因子,即每次调整后将当前学习率乘以gamma
"""

"""训练模型"""
train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)

epochs = 80
acc_s = [] 
loss_s = []

for t in range(epochs):
    print(f"Epoch {t+1}\n---------------------------")
    train(train_dataloader,model,loss_fn,optimizer)
    test(test_dataloader, model, loss_fn)
    scheduler.step()
print(bast_acc)

        前面部分的代码可以参考之前的博客,如下链接

《深度学习》CNN 数据增强、保存最优模型 实例详解icon-default.png?t=O83Ahttps://ahao1004.blog.csdn.net/article/details/142498728?fromshare=blogdetail&sharetype=blogdetail&sharerId=142498728&sharerefer=PC&sharesource=qq_64603703&sharefrom=from_link

标签:卷积,self,torch,学习,神经网络,lr,model,模型
From: https://blog.csdn.net/qq_64603703/article/details/142514756

相关文章

  • 【深度学习基础模型】径向基函数网络(Radial Basis Function Networks, RBFN)详细理解并
    【深度学习基础模型】径向基函数网络(RadialBasisFunctionNetworks,RBFN)【深度学习基础模型】径向基函数网络(RadialBasisFunctionNetworks,RBFN)文章目录【深度学习基础模型】径向基函数网络(RadialBasisFunctionNetworks,RBFN)1.算法原理介绍:径向基函数网络(R......
  • 【深度学习|地学应用】glacier——让我们一起看看深度学习在冰川研究中的应用是怎么样
    【深度学习|地学应用】glacier——让我们一起看看深度学习在冰川研究中的应用是怎么样的呢?【深度学习|地学应用】glacier——让我们一起看看深度学习在冰川研究中的应用是怎么样的呢?文章目录【深度学习|地学应用】glacier——让我们一起看看深度学习在冰川研究中的应......
  • 嵌入式小白学习Day02 Linux命令
    快捷键终端     CTRLALT T放大终端:Ctrl SHIFT +缩小终端:Ctrl -清屏   Ctrl  L结束当前进程:Ctrl c历史命令:↑ ↓命令pwd:查看当前路径ls:查看详细内容cd:切换路径cp:复制文件或文件夹mv:移动文件或文件夹rm:删除绝对路径:从根目录......
  • AI大模型知识点梳理:大模型是什么?大模型发展历程、底层原理、优点和不足、如何学习大模
    一、AI大模型是什么AI大模型是指具有巨大参数量的深度学习模型,通常包含数十亿甚至数万亿个参数。这些模型可以通过学习大量的数据来提高预测能力,从而在自然语言处理、计算机视觉、自主驾驶等领域取得重要突破。AI大模型的定义具体可以根据参数规模来分类。根据OpenAI的分类方法,可以......
  • 神经网络之卷积篇:详解为什么使用卷积?(Why convolutions?)
    详解为什么使用卷积?来分析一下卷积在神经网络中如此受用的原因,然后对如何整合这些卷积,如何通过一个标注过的训练集训练卷积神经网络做个简单概括。和只用全连接层相比,卷积层的两个主要优势在于参数共享和稀疏连接,举例说明一下。假设有一张32×32×3维度的图片,假设用了6个大小为......
  • PyTorch自定义学习率调度器实现指南
    在深度学习训练过程中,学习率调度器扮演着至关重要的角色。这主要是因为在训练的不同阶段,模型的学习动态会发生显著变化。在训练初期,损失函数通常呈现剧烈波动,梯度值较大且不稳定。此阶段的主要目标是在优化空间中快速接近某个局部最小值。然而,过高的学习率可能导致模型跳过潜在的......
  • 决策树算法在机器学习中的应用
    决策树算法在机器学习中的应用决策树(DecisionTree)算法是一种基本的分类与回归方法,它通过树状结构对数据进行建模,以解决分类和回归问题。决策树算法在机器学习中具有广泛的应用,其直观性、易于理解和实现的特点使其成为数据挖掘和数据分析中的常用工具。本文将详细探讨决策......
  • Linux信号学习三步走及知识脉络
    Linux信号学习三步走及知识脉络在Linux系统中,信号(Signal)是一个非常重要的概念,它作为一种异步通知机制,用于通知进程发生了某些事件。信号的本质是软件层次上对中断机制的一种模拟,是进程间通信机制中唯一的异步通信方式。学习Linux信号,可以通过以下三步走,并打通相关的知识脉......
  • 从零开始学机器学习——了解回归
    首先给大家介绍一个很好用的学习地址:https://cloudstudio.net/columns回归今天我们将深入探讨回归分析的概念。回归分析是统计学中一种重要的方法,通常分为线性回归和逻辑回归两种类型。它们分别用于不同的数据模型和分析需求。为了更直观地理解它们的作用,让我们先通过一个图表来......
  • golang学习笔记11-模块化与包管理【重要】
    注:本人已有C,C++,Python基础,只写本人认为的重点。在第六节(golang学习笔记6)中,我讲了如何自定义包,包其实有两种引用方式,一种是不用模块,还有种是用模块。不用模块的是旧版本的做法,因为在18年8月发布的1.11版本中,增加了模块管理的内容,到现在六年多了,所以旧版本的方法早过时了。......