【Week-P4】CNN猴痘病识别

文章目录

  • 一、环境配置
  • 二、准备数据
  • 三、搭建网络结构
  • 四、开始训练
  • 五、查看训练结果
  • 六、总结
    • 2.3 ⭐`torch.utils.data.DataLoader()`参数详解
    • 6.1 `print()`常用的三种输出格式
    • 6.2 修改网络结构,观察训练结果
      • 6.2.1 增加pool2、conv6、bn6,test_accuracy=82.5%
      • 6.2.2 去掉pool2,保留conv6、bn6,增加conv7、bn7,test_accuracy=84.4%
      • 6.2.3 继续增加conv8、bn8、conv9、bn9,test_accuracy=87.2%
      • 6.2.4 继续增加conv10、bn10、conv11、bn11,test_accuracy=82.1%

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊 | 接辅导、项目定制
    在这里插入图片描述
  • 本周的代码相对于上周增加指定图片预测与保存并加载模型这个两个模块,在学习这个两知识点后,时间有余的同学请自由探索更佳的模型结构以提升模型是识别准确率,模型的搭建是深度学习程度的重点。

一、环境配置

import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasetsimport os,PIL,pathlibimport sys
from datetime import datetime
print("---------------------1.配置环境------------------")
print("Start time: ", datetime.today())
print("Pytorch version: " + torch.__version__)
print("Python version: " + sys.version)device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device

在这里插入图片描述

二、准备数据

2.1 打印classeNames列表,显示每个文件所属的类别名称
2.2 打印归一化后的类别名称,01
2.3 划分数据集,划分为训练集&测试集,torch.utils.data.DataLoader()参数详解
2.4 检查数据集的shape

  • 第一步:使用pathlib.Path()函数将字符串类型的文件夹路径转换为pathlib.Path对象
  • 第二步:使用glob()方法获取data_dir路径下的所有文件路径,并以列表形式存储在data_paths中。
  • 第三步:通过split()函数对data_paths中的每个文件路径执行分割操作,获得各个文件所属的类别名称,并存储在classNames
  • 第四步:打印classNames列表,显示每个文件所属的类别名称。
import os,PIL,random,pathlib
print("------------2.1 打印classeNames列表,显示每个文件所属的类别名称------------")
total_datadir= './4-data/'
data_dir = pathlib.Path(total_datadir)data_paths = list(total_datadir.glob('*'))
classNames = [str(path).split("\\")[1] for path in data_paths]
print("classNames: ", classNames)print("------------2.2 打印归一化后的类别名称,0或1------------")
# 关于transforms.Compose的更多介绍可以参考:https://blog.csdn.net/qq_38251616/article/details/124878863
train_transforms = transforms.Compose([transforms.Resize([224, 224]),  # 将输入图片resize成统一尺寸transforms.ToTensor(),          # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间transforms.Normalize(           # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
])total_data = datasets.ImageFolder(total_datadir,transform=train_transforms)
print("total_data: ", total_data)
print("total_data.class_to_idx: ", total_data.class_to_idx)print("------------2.3 划分数据集,划分为训练集&测试集------------")
train_size = int(0.8 * len(total_data))
test_size  = len(total_data) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])
print( f"train_dataset: {train_dataset}, test_dataset: {test_dataset}")
print( f"train_size: {train_size}, test_size: {test_size}")print("------------2.4 检查数据集的shape------------")
batch_size = 32
train_dl = torch.utils.data.DataLoader(train_dataset,batch_size=batch_size,shuffle=True,num_workers=1)
test_dl = torch.utils.data.DataLoader(test_dataset,batch_size=batch_size,shuffle=True,num_workers=1)
for X, y in test_dl:print("Shape of X [N, C, H, W]: ", X.shape)print("Shape of y: ", y.shape, y.dtype)break

在这里插入图片描述

三、搭建网络结构

print("------------3 搭建简单CNN网络------------")
import torch.nn.functional as Fclass Network_bn(nn.Module):def __init__(self):super(Network_bn, self).__init__()"""nn.Conv2d()函数:第一个参数(in_channels)是输入的channel数量第二个参数(out_channels)是输出的channel数量第三个参数(kernel_size)是卷积核大小第四个参数(stride)是步长,默认为1第五个参数(padding)是填充大小,默认为0"""self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=5, stride=1, padding=0)self.bn1 = nn.BatchNorm2d(12)self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=5, stride=1, padding=0)self.bn2 = nn.BatchNorm2d(12)self.pool = nn.MaxPool2d(2,2)self.conv4 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=5, stride=1, padding=0)self.bn4 = nn.BatchNorm2d(24)self.conv5 = nn.Conv2d(in_channels=24, out_channels=24, kernel_size=5, stride=1, padding=0)self.bn5 = nn.BatchNorm2d(24)self.fc1 = nn.Linear(24*50*50, len(classNames))def forward(self, x):x = F.relu(self.bn1(self.conv1(x)))      x = F.relu(self.bn2(self.conv2(x)))     x = self.pool(x)                        x = F.relu(self.bn4(self.conv4(x)))     x = F.relu(self.bn5(self.conv5(x)))  x = self.pool(x)                        x = x.view(-1, 24*50*50)x = self.fc1(x)return xdevice = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))model = Network_bn().to(device)
model

在这里插入图片描述

四、开始训练

4.1 设置超参数
4.2 编写训练函数
4.3 编写测试函数
4.4 开始正式训练,epochs==20

print("------------4.1 设置超参数------------")
loss_fn    = nn.CrossEntropyLoss() # 创建损失函数
learn_rate = 1e-4 # 学习率
opt        = torch.optim.SGD(model.parameters(),lr=learn_rate)print("------------4.2 编写训练函数------------")
# 训练循环
def train(dataloader, model, loss_fn, optimizer):size = len(dataloader.dataset)  # 训练集的大小,一共60000张图片num_batches = len(dataloader)   # 批次数目,1875(60000/32)train_loss, train_acc = 0, 0  # 初始化训练损失和正确率for X, y in dataloader:  # 获取图片及其标签X, y = X.to(device), y.to(device)# 计算预测误差pred = model(X)          # 网络输出loss = loss_fn(pred, y)  # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失# 反向传播optimizer.zero_grad()  # grad属性归零loss.backward()        # 反向传播optimizer.step()       # 每一步自动更新# 记录acc与losstrain_acc  += (pred.argmax(1) == y).type(torch.float).sum().item()train_loss += loss.item()train_acc  /= sizetrain_loss /= num_batchesreturn train_acc, train_lossprint("------------4.3 编写测试函数------------")
def test (dataloader, model, loss_fn):size        = len(dataloader.dataset)  # 测试集的大小,一共10000张图片num_batches = len(dataloader)          # 批次数目,313(10000/32=312.5,向上取整)test_loss, test_acc = 0, 0# 当不进行训练时,停止梯度更新,节省计算内存消耗with torch.no_grad():for imgs, target in dataloader:imgs, target = imgs.to(device), target.to(device)# 计算losstarget_pred = model(imgs)loss        = loss_fn(target_pred, target)test_loss += loss.item()test_acc  += (target_pred.argmax(1) == target).type(torch.float).sum().item()test_acc  /= sizetest_loss /= num_batchesreturn test_acc, test_lossprint("------------4.4 开始正式训练,epochs==20------------")
epochs     = 20
train_loss = []
train_acc  = []
test_loss  = []
test_acc   = []for epoch in range(epochs):model.train()epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)model.eval()epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)train_acc.append(epoch_train_acc)train_loss.append(epoch_train_loss)test_acc.append(epoch_test_acc)test_loss.append(epoch_test_loss)template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}')print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss))
print('Done')

在这里插入图片描述

五、查看训练结果

5.1 Loss与Accuracy图
5.2 指定图片进行预测
5.3 保存并加载模型

print("------------5.1 Loss与Accuracy图------------")
import matplotlib.pyplot as plt
#隐藏警告
import warnings
warnings.filterwarnings("ignore")               #忽略警告信息
plt.rcParams['font.sans-serif']    = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False      # 用来正常显示负号
plt.rcParams['figure.dpi']         = 100        #分辨率epochs_range = range(epochs)plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()print("------------5.2 指定图片进行预测------------")
from PIL import Image classes = list(total_data.class_to_idx)def predict_one_image(image_path, model, transform, classes):test_img = Image.open(image_path).convert('RGB')# plt.imshow(test_img)  # 展示预测的图片test_img = transform(test_img)img = test_img.to(device).unsqueeze(0)model.eval()output = model(img)_,pred = torch.max(output,1)pred_class = classes[pred]print(f'预测结果是:{pred_class}')# 预测训练集中的某张照片
predict_one_image(image_path='./4-data/Monkeypox/M01_01_00.jpg', model=model, transform=train_transforms, classes=classes)print("------------5.3 保存并加载模型------------")
# 模型保存
PATH = './model.pth'  # 保存的参数文件名
torch.save(model.state_dict(), PATH)# 将参数加载到model当中
model.load_state_dict(torch.load(PATH, map_location=device))

在这里插入图片描述

六、总结

2.3 ⭐torch.utils.data.DataLoader()参数详解

torch.utils.data.DataLoaderPyTorch 中用于加载和管理数据的一个实用工具类。它允许你以小批次的方式迭代你的数据集,这对于训练神经网络和其他机器学习任务非常有用。DataLoader 构造函数接受多个参数,下面是一些常用的参数及其解释:

  1. dataset(必需参数):这是你的数据集对象,通常是 torch.utils.data.Dataset 的子类,它包含了你的数据样本。
  2. batch_size(可选参数):指定每个小批次中包含的样本数。默认值为 1
  3. shuffle(可选参数):如果设置为 True,则在每个 epoch 开始时对数据进行洗牌,以随机打乱样本的顺序。这对于训练数据的随机性很重要,以避免模型学习到数据的顺序性。默认值为 False
  4. num_workers(可选参数):用于数据加载的子进程数量。通常,将其设置为大于 0 的值可以加>快数据加载速度,特别是当数据集很大时。默认值为 0,表示在主进程中加载数据
  5. pin_memory(可选参数):如果设置为 True,则数据加载到 GPU 时会将数据存储在 CUDA 的锁页内存中,这可以加速数据传输到 GPU。默认值为 False
  6. drop_last(可选参数):如果设置为 True,则在最后一个小批次可能包含样本数小于 batch_size 时,丢弃该小批次。这在某些情况下很有用,以确保所有小批次具有相同的大小。默认值为 False
  7. timeout(可选参数):如果设置为正整数,它定义了每个子进程在等待数据加载器传递数据时的超时时间(以秒为单位),这可以用于避免子进程卡住的情况。默认值为 0,表示没有超时限制
  8. worker_init_fn(可选参数):一个可选的函数,用于初始化每个子进程的状态。这对于设置每个子进程的随机种子或其他初始化操作很有用。

6.1 print()常用的三种输出格式

    1. 带格式输出,{0}是指输出的第0个元素,同理{1}为第1个元素,{2}为第2个… 可以不按顺序排列
      print( "Hello {0}, I'm {2}, I,m {1} year old".format("world", age, name) )
    1. 使用类型输出,指定输出类型
      print( "I am %s, today is %d year"%(name, year) )
    1. f字符串,{}中为元素,是.format的简化形式
      print( f"Today is {year}")  

6.2 修改网络结构,观察训练结果

6.2.1 增加pool2、conv6、bn6,test_accuracy=82.5%

在这里插入图片描述
训练结果如下:
在这里插入图片描述
在这里插入图片描述
训练结果表明:修改网络结构之后,test_accuracy反而从85.3%降低到82.5%,说明此次修改结构不能提升test_accuracy的值。

6.2.2 去掉pool2,保留conv6、bn6,增加conv7、bn7,test_accuracy=84.4%

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
训练结果表明:与6.2.1的修改方法相比,test_accuracy从82.5%提升到84.4%。

6.2.3 继续增加conv8、bn8、conv9、bn9,test_accuracy=87.2%

在这里插入图片描述
训练情况如下:
在这里插入图片描述
在这里插入图片描述
训练结果表明:与6.2.2的修改方法相比,test_accuracy从84.4%提升到87.2%。

6.2.4 继续增加conv10、bn10、conv11、bn11,test_accuracy=82.1%

在这里插入图片描述
训练情况如下:
在这里插入图片描述
在这里插入图片描述
训练结果表明:与6.2.3的修改方法相比,test_accuracy从87.2%降低到82.1%。

综合上述4次修改,可以得出的结论是:适当增加conv、bn层可以有效提升test_accuracy,最好的效果是第三次修改,test_accuracy的值达到了87.2%。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

航天航空线束工艺3D虚拟展馆支持多人异地参观漫游

为了满足汽车线束企业员工工作需要,让新老员工了解到更先进、规范的线束工艺设计技术,华锐视点基于VR虚拟仿真、web3d开发和图形图像技术制作了一款汽车线束工艺设计VR虚拟仿真模拟展示系统。 汽车线束工艺设计VR虚拟仿真模拟展示系统共分为pc电脑端和VR…

时序分解 | Matlab实现CPO-VMD基于冠豪猪优化算法(CPO)优化VMD变分模态分解时间序列信号分解

时序分解 | Matlab实现CPO-VMD基于冠豪猪优化算法(CPO)优化VMD变分模态分解时间序列信号分解 目录 时序分解 | Matlab实现CPO-VMD基于冠豪猪优化算法(CPO)优化VMD变分模态分解时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 【原创】CPO-VMD【24年新算法…

Element+vue3.0 tabel合并单元格span-method

Elementvue3.0 tabel合并单元格 span-method :span-method"objectSpanMethod"详解: 在 objectSpanMethod 方法中,rowspan 和 colspan 的值通常用来定义单元格的行跨度和列跨度。 一般来说,rowspan 和 colspan 的值应该是大于等于…

zabbix监控windows主机

下载安装zabbix agent安装包 Zabbix官网下载地址: https://www.zabbix.com/cn/download_agents?version5.0LTS&release5.0.40&osWindows&os_versionAny&hardwareamd64&encryptionOpenSSL&packagingMSI&show_legacy0 这里使用zabbix agent2 安装 …

qml实现动态轮播图

一、效果展示 二、源码分享 DynamicCarousel.qmlimport QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick.ShapesItem {id:selfsignal clearError(string numberStr)PathView{id:pathViewanchors.fill: parentfocus: trueclip: truemodel:listModeldele…

[Docker] Mac M1系列芯片上完美运行Docker

docker pull qinchz/dm8-arm64 container_name: dm8ports:- "5236:5236"mem_limit: 1gmemswap_limit: 1gvolumes:- /data/dm8:/home/dmdba/data 数据库实例参数已修改,接近oracle使用习惯 #字符集 utf-8 CHARSET1 #VARCHAR 类型对象的长度以字符为单位 …

软件测试|Windows系统配置pytest+allure环境教程

前言 allure可以输出非常精美的测试报告,也可以和pytest进行完美结合,不仅可以渲染页面,还可以控制用例的执行。本文我们将介绍Windows系统中如何配置allure环境。 第一步:配置Java环境 因为allure的运行依赖于Java环境&#x…

WEB 3D技术 three.js 光照与阴影

本文 我们来说 灯光与阴影 之前 我们有接触到光照类的知识 但是阴影应该都是第一次接触 那么 我们先来看光 首先是 AmbientLight 环境光 你在官网中搜索 AmbientLight 官方是就写明了 环境光是不会产生阴影的 因为 它没有反向 然后是 DirectionalLight 平行光 它是可以投射阴…

OpenAI ChatGPT-4开发笔记2024-04:Chat之Tool之2:multiple functions

从程序员到ai Expert 1 定义参数和函数2 第一轮chatgpt3 第一轮结果和function定义全部加入prompt再喂给chatgpt4 大结局7 参考资料 上一篇解决了调用一个函数的问题。这一篇扩展为调用3个。n个自行脑补。 1 定义参数和函数 #1.设定目标 import json import openai#1.定义para…

Python 快速合并PDF表格转换输出CSV文件

单位的刷脸考勤机后台系统做得比较差,只能导出每个部门的出勤统计表pdf,格式如下: 近期领导要看所有部门的考勤数据,于是动手快速写了个合并pdf并输出csv文件的脚本。 安装模块 pypdf2,pdfplumber,前者用…

docker打包介绍

最近在做一个开源项目,遇到开发者问各种问题,发现都是系统和软件版本的差异引起的。于是了解了一下docker的使用,发现docker真是个好东东,基本解决了各种版本差异的问题,真正做到了一键部署使用。 先熟悉一下docker里…

使用Django框架自带的Form表单完成简单的用户登录注册

如果不知道怎么配置Django环境以及如何连接数据库请点击我的上一篇博客: 使用pycharm初始化Django框架并连接Sql Server 文章目录 1.Django默认生成的数据表2.用户登录2.1创建登录页面2.2视图处理登录请求2.3配置访问路径 3.用户注册3.1创建用户表单3.2创建注册模版…

Java中的网络编程

文章目录 网络基础知识IP 地址端口协议 Java 中网络编程InetAddress(静态类)UDP 通信原理UDP 发送数据步骤UDP 接收数据步骤UDP 发送接收案例 TCP 通信原理TCP 发送数据步骤TCP 接收数据步骤TCP 发送接收案例 网络基础知识 概述:在网络通信协…

限流式保护器在户外汽车充装的应用

摘 要:国家标准GB51348-2019中规定储备仓库、电动车充电等场所的末端回路应设置限流式电气防火保护器。电气防火限流式保护器可以有效克服传统断路器、空气开关和监控设备存在的短路电流大、切断短路电流时间长、短路时产生的电弧火花大,以及使用寿命短等…

鱼哥赠书活动第⑥期:《内网渗透实战攻略》看完这本书教你玩转内网渗透测试成为实战高手!!!!

鱼哥赠书活动第⑥期:《内网渗透实战攻略》 如何阅读本书:本书章节介绍:本书大致目录:适合阅读对象:赠书抽奖规则:往期赠书福利: 当今,网络系统面临着越来越严峻的安全挑战。在众多的安全挑战中&…

14:00面试,14:07就出来了,问的问题有点变态。。。

前言 刚从小厂出来,没想到在另一家公司我又寄了。 在这家公司上班,每天都要加班,但看在钱给的比较多的份上,也就不太计较了。但万万没想到一纸通知,所有人不准加班了,不仅加班费没有了,薪资还…

EndNote20 下载与安装详细教程

扫描文末二维码,关注微信公众号:ThsPool 后台回复 a004 ,免费领取 EndNote20下载安装包 EndNote是一款备受欢迎的文献管理软件,被数百万研究人员、学生和图书管理员广泛使用。它提供便捷的方式来扩展各种语言的参考书目&#xff0…

并发程序设计--D11D12进程间通信

概念:就是进程和进程之间交换信息。 常用通信方式 无名管道(pipe) 有名管道 (fifo) 信号(signal) 共享内存映射(mmap) 套接字(socket) 过时的IPC通信方式 System…

ChatGPT扩展系列之网易数帆ChatBI

在当今数字化快速发展的时代,数据已经成为业务经营与管理决策的核心驱要素。无论是跨国大企业还是新兴创业公司,正确、迅速地洞察数据已经变得至关重要。然而,传统的BI工具往往对用户有一定的技术门槛,需要熟练的操作技能和复杂的查询语句,这使得大部分的企业员工难以深入…

【Flutter 开发实战】Dart 基础篇:从了解背景开始

想要学会用 Flutter 开发 App,就不可避免的要学习另一门很有意思的编程语言 —— Dart。很多小伙伴可能在学习 Flutter 之前可能都没听说过这门编程语言,我也是一样,还以为 Dart 是为了 Flutter 而诞生的;然而,当我们去…