PyTorch实战4:猴痘病识别

news/2024/11/9 10:15:22/
  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍦 参考文章:365天深度学习训练营-第P4周:猴痘病识别
  • 🍖 原作者:K同学啊|接辅导、项目定制

目录

    • 一、搭建CNN网络结构
      • 1、原文网络结构
        • 1.1、网络结构赘述
        • 1.2、前向传播实现
        • 1.3、原型网络结构
      • 2、调整网络结构
        • 2.1、提升精度方案
        • 2.2、网络结构调整
      • 3、结果成效与对比
        • 3.1、原模型结果可视化
        • 3.2、调整后结果可视化
    • 二、保存并加载模型

本次实战主要学习内容:

  • 调整网络结构使测试集accuracy到达88%
  • 训练过程中保存效果最好的模型参数

一、搭建CNN网络结构

  1. 读取并加载本地数据以及数据增强可移步至PyTorch实战3:天气识别进行学习
  2. 卷积层、全连接层、池化层以及批量归一化层的详解可移步至PyTorch实战2:彩色图片识别(CIFAR10)

1、原文网络结构

1.1、网络结构赘述

代码定义了一个名为Network_bn的类,继承自nn.Module。

该类实现了一个卷积神经网络(CNN),包含了多个卷积层和池化层。

在类的初始化函数中,首先调用父类nn.Module的构造函数以进行初始化操作。

然后依次创建了六个神经网络层:

  • 两个卷积层、两个Batch Normalization层、一个最大池化层和一个全连接层。
  • 其中Conv2d函数用于创建二维卷积层,
  • BatchNorm2d函数用于创建二维批量归一化层,
  • MaxPool2d函数用于创建最大池化层,
  • Linear函数用于创建全连接层。

网络结构详解:

  • self.conv1是输入为3通道,输出为12通道,卷积核大小为5x5的卷积层;
  • self.bn1是12通道的Batch Normalization层;
  • self.conv2是输入为12通道,输出为12通道,卷积核大小为5x5的卷积层;
  • self.bn2是12通道的Batch Normalization层;
  • self.pool是2x2最大池化层;
  • self.conv4是输入为12通道,输出为24通道,卷积核大小为5x5的卷积层;
  • self.bn4是24通道的Batch Normalization层;
  • self.conv5是输入为24通道,输出为24通道,卷积核大小为5x5的卷积层;
  • self.bn5是24通道的Batch Normalization层;
  • self.fc1是全连接层,输入大小为24x50x50,输出大小为类别数(len(classNames))。

具体实现了以下结构:

  1. 三层卷积层和两个池化层,用于提取特征
  2. 五个批次归一化(Batch Normalization)层,用于加速训练过程
  3. 一个全连接层,用于输出分类结果

1.2、前向传播实现

接下来是forward函数,该函数定义了数据的前向传递流程。

  • 首先将输入x通过第一个卷积层conv1进行卷积,然后将卷积结果输入到第一个Batch Normalization层bn1中进行归一化处理,并通过激活函数F.relu进行非线性变换。
  • 接着将处理结果输入到第二个卷积层conv2中进行卷积,再将卷积结果输入到第二个Batch Normalization层bn2中进行归一化处理,并通过激活函数F.relu进行非线性变换。
  • 然后通过最大池化层pool进行下采样,缩小特征图的尺寸。然后将处理结果输入到第四个卷积层conv4中进行卷积,再将卷积结果输入到第四个Batch Normalization层bn4中进行归一化处理,并通过激活函数F.relu进行非线性变换。
  • 接着将处理结果输入到第五个卷积层conv5中进行卷积,再将卷积结果输入到第五个Batch Normalization层bn5中进行归一化处理,并通过激活函数F.relu进行非线性变换。
  • 最后通过最大池化层pool进行下采样,缩小特征图的尺寸。然后通过view函数将特征图展成一维向量,输入到全连接层fc1中进行分类。

具体来说,

  • x = F.relu(self.bn1(self.conv1(x)))表示先通过卷积层和Batch Normalization层提取特征,再进行ReLU激活;
  • x = F.relu(self.bn2(self.conv2(x)))同理;
  • x = self.pool(x)表示进行2x2最大池化操作;
  • x = F.relu(self.bn4(self.conv4(x)))同理;
  • x = F.relu(self.bn5(self.conv5(x)))同理;
  • x = self.pool(x)同理;
  • x = x.view(-1, 245050)将特征张量展平为一维向量;
  • x = self.fc1(x)表示通过全连接层得到分类结果。

1.3、原型网络结构

import torch.nn.functional as Fclass Network_bn(nn.Module):def __init__(self):super(Network_bn, self).__init__()# 第1层卷积层:输入有3个channel,输出有12个channel,卷积核大小为5x5,步长为1,填充为0self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=5, stride=1, padding=0)# 第1个Batch Normalization层,有12个channel的输出self.bn1 = nn.BatchNorm2d(12)# 第2层卷积层:输入有12个channel,输出有12个channel,卷积核大小为5x5,步长为1,填充为0self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=5, stride=1, padding=0)# 第2个Batch Normalization层,有12个channel的输出self.bn2 = nn.BatchNorm2d(12)# 第1个池化层,窗口大小为2x2,步长为2self.pool = nn.MaxPool2d(2,2)# 第3层卷积层:输入有12个channel,输出有24个channel,卷积核大小为5x5,步长为1,填充为0self.conv4 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=5, stride=1, padding=0)# 第3个Batch Normalization层,有24个channel的输出self.bn4 = nn.BatchNorm2d(24)# 第4层卷积层:输入有24个channel,输出有24个channel,卷积核大小为5x5,步长为1,填充为0self.conv5 = nn.Conv2d(in_channels=24, out_channels=24, kernel_size=5, stride=1, padding=0)# 第4个Batch Normalization层,有24个channel的输出self.bn5 = nn.BatchNorm2d(24)# 全连接层:输入是24x50x50(24个24x24的feature map),输出是类别数self.fc1 = nn.Linear(24*50*50, len(classeNames))def forward(self, x):# 第1层卷积层+Batch Normalization层+ReLU激活函数x = F.relu(self.bn1(self.conv1(x)))      # 第2层卷积层+Batch Normalization层+ReLU激活函数x = F.relu(self.bn2(self.conv2(x)))     # 第1个池化层x = self.pool(x)                        # 第3层卷积层+Batch Normalization层+ReLU激活函数x = F.relu(self.bn4(self.conv4(x)))     # 第4层卷积层+Batch Normalization层+ReLU激活函数x = F.relu(self.bn5(self.conv5(x)))  # 第2个池化层x = self.pool(x)                        # 展开成一维张量x = x.view(-1, 24*50*50)# 全连接层x = self.fc1(x)return x
  • 模型打印:

在这里插入图片描述
其中,ReLU激活函数在卷积层中使用以增强模型的非线性特征。所有层之间都使用了Batch Normalization技术,可以有效地加速训练过程并提高模型的稳定性。

2、调整网络结构

2.1、提升精度方案

可以考虑尝试以下几个调整来提升网络精度:

  1. 增加卷积层的数量和大小:增加卷积层的数量和大小可以提高网络的感受野,从而更好地捕捉图像的特征。可以尝试增加一些卷积层和调整卷积核的大小。

  2. 调整池化层的大小:池化层可以减小数据的维度,但是过大的池化层会导致信息丢失。可以尝试使用更小的池化层或者不使用池化层。

  3. 使用更深的网络结构:可以尝试使用更深的网络结构,如ResNet、DenseNet等,这些网络结构能够更好地解决梯度消失问题,从而使得模型训练更加稳定。

  4. 数据扩充(data augmentation):可以通过对训练数据进行随机裁剪、旋转、翻转等操作来扩充数据集,从而提高模型的泛化能力。

  5. 使用预训练的模型进行微调:可以使用在大规模数据集上预训练的模型,在本任务上进行微调,能够更好地利用已有数据集的信息,提高模型的精度。

  6. 调整超参数:可以尝试调整学习率、批量大小、优化器等超参数来获得更好的结果。

  7. 使用更多的正则化技术:可以尝试使用 Dropout、L2 正则化等技术来减少过拟合。

  8. 增加数据集:可以尝试增加训练数据的数量,或者通过数据增强技术来生成更多的数据样本,以便网络可以更好地学习数据特征。

2.2、网络结构调整

调整后的模型包括若干个卷积层和池化层,并使用批归一化层进行正则化。在输入数据后,模型通过这些卷积和池化操作将其转换为特征向量,并使用全连接层对其进行分类。这个模型与原始的卷积神经网络不同之处在于:

  1. 添加了一个新的卷积层,用于提取更多的特征;
  2. 在模型中添加了一个批归一化层,可以加速训练并提高准确率;
  3. 修改了全连接层的输入大小,以适应新的卷积层。
class Network_bn(nn.Module):def __init__(self):super(Network_bn, self).__init__()self.features = nn.Sequential(nn.Conv2d(in_channels=3, out_channels=12, kernel_size=5, stride=1, padding=0),nn.BatchNorm2d(12),nn.ReLU(),nn.Conv2d(in_channels=12, out_channels=12, kernel_size=5, stride=1, padding=0),nn.BatchNorm2d(12),nn.ReLU(),nn.MaxPool2d(2, 2),nn.Conv2d(in_channels=12, out_channels=24, kernel_size=5, stride=1, padding=0),nn.BatchNorm2d(24),nn.ReLU(),nn.Conv2d(in_channels=24, out_channels=24, kernel_size=5, stride=1, padding=0),nn.BatchNorm2d(24),nn.ReLU(),nn.MaxPool2d(2, 2),nn.Conv2d(in_channels=24, out_channels=48, kernel_size=5, stride=1, padding=0), # 添加了一个新的卷积层nn.BatchNorm2d(48),nn.ReLU(),nn.MaxPool2d(2, 2))self.classifier = nn.Linear(48 * 23 * 23, len(classNames)) # 修改了全连接层的输入大小def forward(self, x):x = self.features(x)x = x.view(-1, 48 * 23 * 23)x = self.classifier(x)return x
  • 模型打印:

在这里插入图片描述

3、结果成效与对比

3.1、原模型结果可视化

在这里插入图片描述
在这里插入图片描述

3.2、调整后结果可视化

在这里插入图片描述
在这里插入图片描述

二、保存并加载模型

首先,将模型的参数保存到指定路径下的文件中。PATH 变量为保存的参数文件名,model.state_dict() 返回当前模型的参数字典,并使用 torch.save() 将其保存到 PATH 指定的文件中。

  • 定义一个文件路径PATH,用于保存模型参数
  • model.state_dict()函数返回一个字典对象,其中包含了模型中所有的可学习参数和缓存项
  • torch.save()函数将这个字典保存到指定的文件路径中
  • torch.load()函数将保存的参数加载回到模型中
  • model.load_state_dict()函数将加载的参数复制到模型中
# 定义保存参数的文件路径
PATH = './model.pth'# 保存模型参数到指定文件路径
torch.save(model.state_dict(), PATH)

接着,可以在需要使用这些参数的时候,通过 torch.load() 方法将之前保存的参数加载回来。其中,map_location 参数指定了模型应该加载到哪个设备上(例如CPU或GPU)。

model.load_state_dict(torch.load(PATH, map_location=device))  # 将参数加载到模型实例中

总体而言,这段代码的作用是实现了对训练好的神经网络模型进行持久化存储并在需要的时候重新加载模型参数。


http://www.ppmy.cn/news/82143.html

相关文章

python自动化(一)基础能力:9.yaml文件详解

一、什么是yaml文件 yaml 是专门用来写配置文件的语言——可以用例作为自动化框架的配置文件yaml文件其实也是一种配置文件类型,后缀名是.yaml或.yml都可以个人认为比yaml比json格式更方便 二、yaml语法规则 YAML 语言(发音 /ˈjməl/ )的设…

java版鸿鹄工程项目管理系统 Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统源代码

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展,企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,公司对内部工程管…

【每日一题Day217】LC2451差值数组不同的字符串 | 枚举+变量记录

差值数组不同的字符串【LC2451】 给你一个字符串数组 words &#xff0c;每一个字符串长度都相同&#xff0c;令所有字符串的长度都为 n 。 每个字符串 words[i] 可以被转化为一个长度为 n - 1 的 差值整数数组 difference[i] &#xff0c;其中对于 0 < j < n - 2 有 dif…

微签助力中融基金电子文件安全高效签章

中融基金重安全&#xff0c;炼丹炉里炼微签 这次讲一个微签在炼丹炉里炼出了火眼金睛的故事。 先看一个数字。 金融隐私泄露事件大约以每年35&#xff05;的数据在增长。 数字来自《中国银行保险报》与亚信网络安全产业技术研究院发布的《金融行业网络安全白皮书》。 大数据时…

Ubuntu TDengine集群搭建

我这里用三台服务器搭建集群 1、如果搭建集群的物理节点上之前安装过TDengine先卸载清空&#xff0c;直接执行以下4条命令 rmtaos rm -rf /var/lib/taos rm -rf /var/log/taos rm -rf /etc/taos2、确保集群中所有主机开放端口 6030-6043/tcp&#xff0c;6060/tcp&#xff0c;…

Java 远程连接 SQLite 数据库

Java 可以使用 JDBC API 来连接 SQLite 数据库。但是&#xff0c;SQLite 不支持远程连接&#xff0c;因为它是一种文件数据库&#xff0c;需要直接访问数据库文件。 如果您需要从远程位置访问 SQLite 数据库&#xff0c;可以将 SQLite 数据库文件放在共享文件夹中&#xff0c;…

高精度加法

给定两个正整数&#xff08;不含前导 0&#xff09;&#xff0c;计算它们的和。 输入格式 共两行&#xff0c;每行包含一个整数。 输出格式 共一行&#xff0c;包含所求的和。 数据范围 1≤整数长度≤100000 输入样例&#xff1a; 12 23 输出样例&#xff1a; 35 代码: #incl…

一些云原生开源安全工具介绍

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/130789465 一、Kubernetes安全监测工具kube-bench kube-bench是一个用Golang开发的、由Aqua Security发布的自动化Kubernetes基准测试工具&#xff0c;它运行CIS Kubernetes基准中的测试项目。这些测试…