第P4周:猴痘病识别

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

一、前期准备

1.设置GPU 

''' 设置GPU '''
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("Using {} device".format(device))

没有GPU则使用CPU 

 

2.导入数据、数据预处理

import os,PIL,random,pathlib
data_dir = r'D:\P4'
data_dir = pathlib.Path(data_dir)data_paths = list(data_dir.glob('*'))
class_names = [path.name for path in data_paths]
print(class_names)

 

 

import pathlib
import torchvision.transforms as transforms
from torchvision import datasets
total_datadir = r'D:\P4'train_transforms = transforms.Compose([transforms.Resize([224, 224]),transforms.ToTensor(),transforms.Normalize(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)

定义数据预处理操作 train_transforms

  • transforms.Resize([224, 224]):将输入图像的尺寸调整为 224x224 像素,这通常是训练深度学习模型所使用的常见图像尺寸。
  • transforms.ToTensor():将图像数据转换为PyTorch张量,并将像素值归一化到范围 [0, 1]。
  • transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]):对图像进行标准化处理,将像素值标准化为标准正态分布(高斯分布),这有助于模型更快地收敛。

使用 datasets.ImageFolder 加载图像数据集:

  • total_datadir 是包含图像数据集的目录路径。
  • transform=train_transforms 指定了要应用的数据预处理操作。

 3.标签映射

在DatasetFolder中,class_to_idx是一个字典,将类别名映射到类别标签(从0开始),其中类别名是文件夹的名称,类别标签是与之相关联的数字。

为什么要做标签映射呢?

  • 将类别名映射到类别标签是因为在训练深度学习模型时,通常使用类别标签来表示每个样本的类别。
  • 在训练模型时,输入数据被转换为张量,并且每个张量的标签是一个数字,表示与之相关联的类别。
  • 类别标签使得模型可以根据真实标签和预测标签之间的误差来更新模型权重,从而使模型学习到如何将输入数据映射到正确的输出标签。

 

print(total_data.class_to_idx)

二、划分数据集

import torch
from torch.utils.data import DataLoader# total_data 包含了数据集,我们可以从 total_data 中划分出训练集和测试集
# 例如,可以按照一定的比例划分数据集,或者根据需要自定义训练集和测试集# 划分数据集示例:
# 假设数据集总共有100个样本,可以将前80个样本用于训练,后20个用于测试
train_size = int(0.8 * len(total_data))
test_size = len(total_data) - train_sizetrain_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])batch_size = 32train_dl = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=1)
test_dl = DataLoader(test_dataset, batch_size=batch_size, shuffle=True, num_workers=1)

三、 构建 CNN 网络

import torch
import torch.nn as nn
import torch.nn.functional as Fclass Network(nn.Module):def __init__(self):super(Network, self).__init__()self.conv1 = nn.Conv2d(3, 6, 5)self.conv2 = nn.Conv2d(6, 16, 5)self.fc1 = nn.Linear(16 * 53 * 53, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 2)self.dropout = nn.Dropout(0.5)  # Adding dropout with a probability of 0.5def forward(self, x):x = F.max_pool2d(F.relu(self.conv1(x)), 2)x = F.max_pool2d(F.relu(self.conv2(x)), 2)x = x.view(-1, 16 * 53 * 53)x = F.relu(self.fc1(x))x = self.dropout(x)  # Applying dropout after the first fully connected layerx = F.relu(self.fc2(x))x = self.dropout(x)  # Applying dropout after the second fully connected layerx = self.fc3(x)x = F.log_softmax(x, dim=1)return xmodel = Network()
print(model)

四、训练模型

1. 设置超参数 

# 定义损失函数和优化器
loss_fn = nn.CrossEntropyLoss()
leaining_rate = 0.001
opt = torch.optim.Adam(model.parameters(),lr=leaining_rate)

2.编写训练函数

# 训练函数
def train(dataloader, model, loss_fn, optimizer):size = len(dataloader.dataset)num_batches = len(dataloader)train_loss, train_acc = 0, 0for x, y in dataloader:x, y  = x.to(device), y.to(device)# Compute prediction errorpred = model(x) # 网络输出loss = loss_fn(pred, y) # 计算损失optimizer.zero_grad() # 梯度清零loss.backward() # 反向传播optimizer.step() # 更新参数train_acc += (pred.argmax(1) == y).type(torch.float).sum().item()train_loss += loss.item()train_acc /= sizetrain_loss /= num_batchesreturn train_acc, train_loss# 测试函数
def test(dataloader, model, loss_fn):size = len(dataloader.dataset)num_batches = len(dataloader)test_loss, test_acc = 0, 0with torch.no_grad():for x, y in dataloader:x, y  = x.to(device), y.to(device)pred = model(x)loss = loss_fn(pred, y)test_loss += loss_fn(pred, y).item()test_acc += (pred.argmax(1) == y).type(torch.float).sum().item()test_acc /= sizetest_loss /= num_batchesreturn test_acc, test_loss

3.正式训练

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')

 

代码在运行时出现下列问题可能是以下原因导致: 

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "D:\Python\lib\multiprocessing\spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "D:\Python\lib\multiprocessing\spawn.py", line 125, in _main
    prepare(preparation_data)
  File "D:\Python\lib\multiprocessing\spawn.py", line 236, in prepare
    _fixup_main_from_path(data['init_main_from_path'])
  File "D:\Python\lib\multiprocessing\spawn.py", line 287, in _fixup_main_from_path
    main_content = runpy.run_path(main_path,
  File "D:\Python\lib\runpy.py", line 289, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "D:\Python\lib\runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "D:\Python\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "c:\Users\刘鸿逸\Desktop\python\01.py", line 156, in <module>
    epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)
  File "c:\Users\刘鸿逸\Desktop\python\01.py", line 105, in train
    for X, y in dataloader:  # 获取图片及其标签
  File "D:\Python\lib\site-packages\torch\utils\data\dataloader.py", line 441, in __iter__
    return self._get_iterator()
  File "D:\Python\lib\site-packages\torch\utils\data\dataloader.py", line 388, in _get_iterator
    return _MultiProcessingDataLoaderIter(self)
  File "D:\Python\lib\site-packages\torch\utils\data\dataloader.py", line 1042, in __init__
    w.start()
  File "D:\Python\lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
  File "D:\Python\lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "D:\Python\lib\multiprocessing\context.py", line 336, in _Popen
    return Popen(process_obj)
  File "D:\Python\lib\multiprocessing\popen_spawn_win32.py", line 45, in __init__
    prep_data = spawn.get_preparation_data(process_obj._name)
  File "D:\Python\lib\multiprocessing\spawn.py", line 154, in get_preparation_data
    _check_not_importing_main()
  File "D:\Python\lib\multiprocessing\spawn.py", line 134, in _check_not_importing_main
    raise RuntimeError('''
RuntimeError:
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.

这个错误是由于在Windows操作系统上使用多进程时,未按照正确的方式设置了启动子进程的方法引起的。它提示需要在主模块中添加适当的if __name__ == '__main__':块以正确启动子进程。下面解释一下报错的含义以及如何解决它: 

  • 为了解决这个问题,应该确保在主模块中使用if __name__ == '__main__':块来包装主要的执行代码,这是一种在使用多进程时常见的做法。
  • 在主模块中包装代码后,子进程将只在主进程中执行,而不会在导入模块时执行。这可以防止上述报错。

修改后完整代码:

import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasets
import os
import PIL
import pathlib# Your code for data loading, model definition, training, and testing should go hereif __name__ == '__main__':device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print(device)import os,PIL,random,pathlibdata_dir = r'D:\P4'data_dir = pathlib.Path(data_dir)data_paths = list(data_dir.glob('*'))class_names = [path.name for path in data_paths]print(class_names)total_datadir = r'D:\P4'# 关于transforms.Compose的更多介绍可以参考:https://blog.csdn.net/qq_38251616/article/details/124878863train_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)train_size = int(0.8 * len(total_data))test_size  = len(total_data) - train_sizetrain_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])print(train_dataset, test_dataset)batch_size = 32train_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)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(class_names))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)print(model)loss_fn    = nn.CrossEntropyLoss() # 创建损失函数learn_rate = 1e-4 # 学习率opt        = torch.optim.SGD(model.parameters(),lr=learn_rate)# 训练循环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_lossdef 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_lossepochs     = 17train_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')

 

验证集正确率达到88%以上。

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

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

相关文章

系统架构设计师-嵌入式系统

目录 一、嵌入式系统概述 1、基本概念 2、嵌入式系统软件组成架构 二、嵌入式软件开发 三、嵌入式硬件 1、嵌入式微处理器 2、人工智能芯片 3、嵌入式微处理器体系结构 4、总线 四、嵌入式操作系统 1、嵌入式实时操作系统 2、操作系统内核架构 3、鸿蒙操作系统 五、嵌入式…

postman token 请求头添加

思路&#xff1a; 1、登录成功后将 得到的token设置为集合变量 2、在需要携带Authorization的请求头上使用该集合变量 关键代码 const responseData pm.response.json(); if(responseData.code 1) {// 获取tokenconst {data:{token}} responseData// 设置为集合变量pm.colle…

编译OpenWrt内核驱动

编译OpenWrt内核驱动可以参考OpenWrt内部其它驱动的编写例程&#xff0c;来修改成自己需要的驱动 一、OpenWrt源代码获取与编译 1.1、搭建环境 下载OpenWrt的官方源码&#xff1a; git clone https://github.com/openwrt/openwrt.git1.2、安装编译依赖项 sudo apt update -…

vue中如何给特殊字段设置插槽

大纲: <template><div><div><span>卡号</span><el-input type"text" v-model"cardNo" clearable placeholder"请输入卡号" /><el-button type"primary" plain icon"el-icon-search"…

我们如何在工作与生活中找到平衡点?

找到工作与生活中的平衡点是每个人都必须面对的问题。以下是一些建议&#xff0c;可以帮助你在工作和生活之间找到平衡&#xff1a; 制定时间表&#xff1a;确保你有足够的时间来处理工作和生活中的各种任务。为工作、学习和个人生活设定优先级&#xff0c;并确保时间分配合理…

ElasticSearch第三讲:ES详解 - Elastic Stack生态和场景方案

ElasticSearch第三讲&#xff1a;ES详解 - Elastic Stack生态和场景方案 本文是ElasticSearch第三讲&#xff0c;在了解ElaticSearch之后&#xff0c;我们还要了解Elastic背后的生态 即我们常说的ELK&#xff1b;与此同时&#xff0c;还会给你展示ElasticSearch的案例场景&…

浅谈限流式保护器在高校防火工作的应用

安科瑞 华楠 【摘要】摘要&#xff1a;为了预防火灾和减少火灾带来的危害&#xff0c;保护校园和师生生命财产安全&#xff0c; 建和谐安宁的校园环境&#xff0c;保障学校安全稳定发展&#xff0c;我们必须要时刻拧紧消防安全这弦&#xff0c;时刻注意这根高压线。随着近年来…

el-select下拉框定位问题

1.当el-select所在页面滚动时或者el-select上面区域高度发生变化时&#xff0c;定位存在偏差 2.解决办法&#xff1a; 1. el-select自带属性popper-append-to-body&#xff1a;true&#xff0c;可能会无效 2.设置ref,监听高度变化或者滚动时&#xff0c;手动执行刷新方法&…

应用在汽车新风系统中消毒杀菌的UVC灯珠

在病毒、细菌的传播可以说是一个让人敏感而恐惧的事情。而对于车内较小的空间&#xff0c;乘坐人员流动性大&#xff0c;更容易残留细菌病毒。车内缺少通风&#xff0c;残留的污垢垃圾也会滋生细菌&#xff0c;加快细菌的繁殖。所以对于车内消毒就自然不容忽视。 那么问题又来…

算法:贪心---跳一跳

1、题目&#xff1a; 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 2…

【SpringMvc 丨跨域】

Spring MVC 支持跨域处理&#xff08;CORS&#xff09;。 CORS 简介处理CORS 过滤器CrossOrigin注解java配置xml配置 主页传送门&#xff1a;&#x1f4c0; 传送 简介 跨域是指在浏览器的同源策略下&#xff0c;不能执行其他网站的脚本。它是由浏览器的安全限制造成的&#xf…

2023-9-12 完全背包问题

题目链接&#xff1a;完全背包问题 初版(时间复杂度拉满) #include <iostream> #include <algorithm>using namespace std;const int N 1010;int n, m; int v[N], w[N]; int f[N][N];int main() {cin >> n >> m;for(int i 1; i < n; i ) cin >…

欧洲汽车制造商押注电力合成燃料 | 2023中国可持续燃料峰会

欧洲几家汽车制造商表示&#xff0c;所谓的电力合成燃料(e-fuels&#xff0c;利用可再生电力合成的化石燃料&#xff0c;又称电子燃料)将在欧洲汽车行业的未来发挥关键作用&#xff0c;它们相信&#xff0c;布鲁塞尔方面在替代燃料问题上的让步&#xff0c;将使它们能够在未来1…

VoxWeekly|The Sandbox 生态周报|20230904

欢迎来到由 The Sandbox 发布的《VoxWeekly》。我们会在每周发布&#xff0c;对上一周 The Sandbox 生态系统所发生的事情进行总结。 如果你喜欢我们内容&#xff0c;欢迎与朋友和家人分享。请订阅我们的 Medium 、关注我们的 Twitter&#xff0c;并加入 Discord 社区&#xf…

Python - PyQt6、QDesigner、pyuic5-tool 安装使用

Python 开发可视化界面可以使用原生的 tkinter&#xff0c;但是原生框架使用起来颇为不方便&#xff0c;所以最流行的还是QT UI框架&#xff0c;QT是使用C语言开发&#xff0c;Python 想使用需要对其进行封装&#xff0c;所以就出现了PyQt框架&#xff0c;这个框架使用极其方便…

u盘制成系统盘之后如何让恢复普通盘

U盘装完pe后怎么还原成普通U盘 1.插入U盘&#xff0c;按WindowsR 输入diskpart 2.输入“list disk”回车&#xff0c;查看U盘代号&#xff0c;例如下图里我的U盘代号是磁盘1&#xff08;你的不一定是1&#xff0c;一定要分清楚&#xff09; 3.输入“select disk 2”选中U盘磁…

学习day59

昨天学了插槽&#xff0c;但是没有即笔记了 今天的是vuex 总体来说&#xff0c;vuex就是一个共享单车&#xff0c;每个人都可以使用他&#xff0c;也可也对他进行反馈。即把一个数据列为vuex&#xff0c;然后每个组件可以使用这个对象&#xff0c;也可也反过来反馈他 这一个设…

vim的使用介绍以及命令大全

懒羊羊感谢大家的关注和三连支持~ 目录 前言 一、vim的使用介绍 二、命令大全 1.命令模式 &#xff08;1&#xff09;复制&#xff08;配合粘贴命令p使用&#xff09; &#xff08;2&#xff09;剪切 &#xff08;3&#xff09;粘贴 &#xff08;4&#xff09;删除 …

centos安装flink,通过windows访问webui

1. 安装flink 1.1. flink的下载 通过flink官网下载flink安装包 https://flink.apache.org/ 下载安装包 1.2 flink在centos上的安装 将下载好的flink-1.17.1-bin-scala_2.12.tgz安装包放到centos目录下 解压文件&#xff1a; [rootlocalhost ~]# tar -zxvf flink-1.17.…

数据分享|WEKA信贷违约预测报告:用决策树、随机森林、支持向量机SVM、朴素贝叶斯、逻辑回归...

完整报告链接&#xff1a;http://tecdat.cn/?p28579 作者&#xff1a;Nuo Liu 数据变得越来越重要&#xff0c;其核心应用“预测”也成为互联网行业以及产业变革的重要力量。近年来网络 P2P借贷发展形势迅猛&#xff0c;一方面普通用户可以更加灵活、便快捷地获得中小额度的贷…