自定义的卷积神经网络模型CNN,对图片进行分类并使用图片进行测试模型-适合入门,从模型到训练再到测试,开源项目

自定义的卷积神经网络模型CNN,对图片进行分类并使用图片进行测试模型-适合入门,从模型到训练再到测试:开源项目
开源项目完整代码及基础教程:
https://mbd.pub/o/bread/ZZWclp5x

在这里插入图片描述
CNN模型:
在这里插入图片描述

1.导入必要的库和模块:

torch:PyTorch深度学习框架。

torchvision:PyTorch的计算机视觉库,用于处理图像数据。

transforms:包含数据预处理的模块。

nn:PyTorch的神经网络模块。

F:PyTorch的函数模块,包括各种激活函数等。

optim:优化算法模块。

2.数据预处理:

transforms.Compose:将一系列数据预处理步骤组合在一起。

transforms.ToTensor():将图像数据转换为张量。

transforms.Normalize:对图像数据进行归一化处理,以均值0.5和标准差0.5。

定义批处理大小:

batch_size:每个训练批次包含的图像数量。

加载训练集:

trainset:使用CIFAR-10数据集,设置训练标志为True。

torch.utils.data.DataLoader:创建用于加载训练数据的数据加载器,指定批处理大小和其他参数。

加载测试集:

testset:使用CIFAR-10数据集,设置训练标志为False。

torch.utils.data.DataLoader:创建用于加载测试数据的数据加载器,指定批处理大小和其他参数。

定义CNN模型:

My_CNN:自定义的卷积神经网络模型,包括卷积层、池化层和全连接层。

创建CNN模型、损失函数和优化器:

model:创建My_CNN模型的实例。

nn.CrossEntropyLoss():定义用于多分类问题的交叉熵损失函数。

optim.SGD:使用随机梯度下降优化器,指定学习率和动量。

训练模型:

epochs:指定训练轮数。

循环中的嵌套循环:迭代训练数据批次,进行前向传播、反向传播和参数优化。

保存模型:

model_path:指定模型保存的路径。

torch.save:保存训练后的模型。

在测试集上评估模型性能:

计算模型在测试集上的准确率。

计算每个类别的准确率。

具体代码来说:

transform = transforms.Compose(

[transforms.ToTensor(),

 transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

解释:

transforms.Compose:这是一个用于组合多个数据预处理步骤的函数。它允许你按顺序应用多个转换,以便将原始数据转换为最终的形式。

transforms.ToTensor():这是一个数据预处理步骤,将图像数据转换为张量(tensor)的格式。在深度学习中,张量是常用的数据表示方式,因此需要将图像数据从常见的图像格式(如JPEG或PNG)转换为张量。

transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)):这是另一个数据预处理步骤,用于对图像进行归一化处理。归一化的目的是将图像的像素值缩放到一个特定的范围,以便神经网络更容易学习。在这里,均值和标准差都被设置为0.5,这将使图像像素值在-1到1之间。

batch_size = 4

 trainset = torchvision.datasets.CIFAR10(root='./data', train=True,

                                        download=True, transform=transform)

 trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,

                                          shuffle=True, num_workers=0)

 testset = torchvision.datasets.CIFAR10(root='./data', train=False,

                                       download=True, transform=transform)

 testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size,

                                         shuffle=False, num_workers=0)

解释:

batch_size = 4:定义了每个训练和测试批次中包含的图像数量。在深度学习中,通常将数据分成小批次进行训练,以便更有效地使用计算资源。

trainset 和 testset 的定义:这两行代码加载了CIFAR-10数据集的训练集和测试集,并进行了如下操作:

torchvision.datasets.CIFAR10:使用CIFAR-10数据集,它包括一组包含10个不同类别的图像数据,适用于图像分类任务。

root=‘./data’:指定数据集的存储目录,可以根据需要更改。

train=True 和 train=False:这两个参数分别用于加载训练集和测试集。

download=True:如果数据集尚未下载,会自动下载。

transform=transform:指定了前面定义的数据预处理管道,将在加载数据时应用。

trainloader 和 testloader 的定义:这两行代码创建了数据加载器,将数据集划分为批次以进行训练和测试。

torch.utils.data.DataLoader:这是PyTorch提供的用于加载数据的工具,可以自动处理数据的分批和洗牌等任务。

batch_size=batch_size:指定了每个批次的大小,即每次加载多少图像数据。

shuffle=True 和 shuffle=False:shuffle参数指定是否在每个epoch(训练轮次)之前对数据进行洗牌,以增加数据的随机性。通常在训练时进行洗牌,而在测试时不进行洗牌。

num_workers=0:这个参数指定用于数据加载的线程数。在此代码中,设置为0表示不使用多线程加载数据。如果有多个CPU核心可用,可以将其设置为大于0的值以加速数据加载。

class My_CNN(nn.Module):

def __init__(self):

    super().__init__()

省略部分代码

def forward(self, x):

省略部分代码

    return x

model = My_CNN()

criterion = nn.CrossEntropyLoss()

optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

解释:

这部分代码定义了一个卷积神经网络(CNN)模型,并创建了用于训练该模型的损失函数和优化器。让我们逐步解释每一部分:

class My_CNN(nn.Module)::这是一个自定义的CNN模型类的定义。这个类继承自nn.Module,这是PyTorch中构建神经网络模型的基本方式。

def init(self)::这是构造函数,用于初始化CNN模型的各个层。

super().init():调用父类nn.Module的构造函数以确保正确初始化模型。

self.conv1 和 self.conv2:这是两个卷积层的定义,分别具有不同数量的输入和输出通道以及卷积核的大小。

self.pool:这是最大池化层的定义,用于减小特征图的空间尺寸。

self.fc1、self.fc2 和 self.fc3:这是三个全连接层(也称为线性层),用于将卷积层的输出转换为最终的分类结果。

def forward(self, x)::这是前向传播函数,定义了模型的前向传播过程。

在前向传播中,输入x经过卷积层、激活函数(F.relu)、池化层以及全连接层,最终输出分类结果。

torch.flatten(x, 1):这一步将卷积层的输出扁平化,以便将其输入到全连接层。

返回值是模型的输出,表示对输入数据的分类预测。

model = My_CNN():创建了My_CNN类的一个实例,即CNN模型。

criterion = nn.CrossEntropyLoss():定义了损失函数,这里使用的是交叉熵损失函数。它用于衡量模型的预测与实际标签之间的差距,是一个用于监督学习任务的常见损失函数。

optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9):定义了优化器,这里使用的是随机梯度下降(SGD)。优化器负责更新模型的参数,以减小损失函数的值。学习率(lr)和动量(momentum)是优化算法的超参数,影响了参数更新的速度和方向。

epochs=5

for epoch in range(epochs): # loop over the dataset multiple times

running_loss = 0.0

for i, data in enumerate(trainloader, 0):

    # get the inputs; data is a list of [inputs, labels]

    inputs, labels = data



    # zero the parameter gradients

    optimizer.zero_grad()

    # forward + backward + optimize

    outputs = model(inputs)

    loss = criterion(outputs, labels)

    loss.backward()

    optimizer.step()

    # print statistics

    running_loss += loss.item()

    if i % 2000 == 1999:    # print every 2000 mini-batches

        print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 2000:.3f}')

        running_loss = 0.0

print('Finished Training')

name_path = './cnn_model_model.pth'

torch.save(model,name_path)

解释:

epochs=5:定义了训练的轮次(epochs),也就是模型将遍历整个训练数据集的次数。

for epoch in range(epochs)::这是一个循环,遍历每个训练轮次。

running_loss = 0.0:用于追踪每个训练轮次的累积损失。

for i, data in enumerate(trainloader, 0)::这个嵌套循环遍历训练数据集的小批次。

i 表示当前批次的索引。

data 包含了当前批次的输入数据和标签。

optimizer.zero_grad():在每个批次开始时,将优化器的梯度清零,以便准备计算新的梯度。

outputs = model(inputs):进行前向传播,将输入数据传递给模型,得到模型的输出。

loss = criterion(outputs, labels):计算损失,衡量模型的预测与实际标签之间的差距。使用了前面定义的交叉熵损失函数。

loss.backward():进行反向传播,计算模型参数相对于损失的梯度。

optimizer.step():根据计算得到的梯度,更新模型的参数,以减小损失函数的值。

running_loss += loss.item():累积当前批次的损失值,用于后续打印统计信息。

if i % 2000 == 1999::每经过2000个小批次,打印一次统计信息。这是为了跟踪训练进度,查看损失是否在逐渐减小。

print(f’[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 2000:.3f}'):打印当前训练轮次和批次的损失值。

running_loss = 0.0:重置累积损失值,以便下一个统计周期。

print(‘Finished Training’):当所有轮次的训练完成后,打印 “Finished Training” 以指示训练结束。

name_path = ‘./cnn_model_model.pth’:指定模型的保存路径。

torch.save(model, name_path):将训练好的模型保存到指定路径。这样可以在之后的任务中加载和使用该模型,而不需要重新训练。

这段代码执行了模型的训练过程,循环遍历多个轮次,每轮次内遍历训练数据的小批次。在每个小批次中,进行前向传播、计算损失、反向传播以及参数更新。训练的目标是通过调整模型参数,减小损失函数的值,从而提高模型的性能。同时,每隔一定数量的小批次,打印训练统计信息以监视训练进度。最后,训练完成后,模型被保存到文件以备将来使用。

classes = ('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')

prepare to count predictions for each class

correct_pred = {classname: 0 for classname in classes}

total_pred = {classname: 0 for classname in classes}

again no gradients needed

with torch.no_grad():

for data in testloader:

    images, labels = data

    outputs = model(images)

    _, predictions = torch.max(outputs, 1)

    # collect the correct predictions for each class

    for label, prediction in zip(labels, predictions):

        if label == prediction:

            correct_pred[classes[label]] += 1

        total_pred[classes[label]] += 1

print accuracy for each class

for classname, correct_count in correct_pred.items():

accuracy = 100 * float(correct_count) / total_pred[classname]

print(f'Accuracy for class: {classname:5s} is {accuracy:.1f} %')

解释:

classes = (‘plane’, ‘car’, ‘bird’, ‘cat’,‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’):这是数据集中的类别标签,它们代表CIFAR-10数据集中的10个不同类别,分别是飞机、汽车、鸟类、猫、鹿、狗、青蛙、马、船和卡车。

correct_pred 和 total_pred:这两个字典用于跟踪每个类别的正确预测数量和总预测数量,初始化为零。

with torch.no_grad()::这个语句块指示在此之后的计算不需要梯度信息。这是因为在测试阶段,我们不需要计算梯度,只是进行前向传播和计算准确度。

for data in testloader::遍历测试数据集的小批次。

images, labels = data:将小批次数据分成图像和对应的标签。

outputs = model(images):使用训练好的模型对图像进行预测,得到模型的输出。

_, predictions = torch.max(outputs, 1):通过 torch.max 函数找到每个样本预测的类别,即具有最高预测分数的类别。

for label, prediction in zip(labels, predictions)::通过 zip 函数,将实际标签和预测标签一一对应起来,以便比较它们。

if label == prediction::比较实际标签和预测标签,如果它们相等,表示模型做出了正确的预测。

correct_pred[classes[label]] += 1:对应类别的正确预测数量加一。

total_pred[classes[label]] += 1:对应类别的总预测数量加一。

for classname, correct_count in correct_pred.items()::遍历每个类别和其正确预测数量。

accuracy = 100 * float(correct_count) / total_pred[classname]:计算每个类别的准确度,即正确预测数量除以总预测数量,以百分比表示。

print(f’Accuracy for class: {classname:5s} is {accuracy:.1f} %'):打印每个类别的准确度,格式化输出。

总结:这段代码的目标是计算并打印出每个类别的分类准确度,以便评估模型在不同类别上的性能。这是在测试阶段对模型性能进行评估的一种方式。

测试模型的代码:

import torch

from PIL import Image

from torch import nn

import torch

import torchvision

import torch.nn.functional as F

device = torch.device('cuda')

image_path=“plane.png”

image =Image.open(image_path)

print(image)

image=image.convert('RGB')

transform=torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),torchvision.transforms.ToTensor()])

image=transform(image)

print(image.shape)

class My_CNN(nn.Module):

def __init__(self):

    super().__init__()

 省略部分代码        return x

#加载模型

model = torch.load(“cnn_net_model.pth”,map_location=torch.device(‘cuda’))#加载完成网络模型,映射

print(model)#维数不够

image = torch.reshape(image,(1,3,32,32))#这一个很重要,要满足四个通道

image=image.to(device)#做cuda变换,不然报错

model.eval()

with torch.no_grad():#节约内存性能

output=model(image)

#识别类别,数字最大的就是我们的结果

print(output)

解释:

导入必要的库和模块:

torch:PyTorch库,用于构建和运行深度学习模型。

PIL:Python Imaging Library,用于处理图像。

nn:PyTorch的神经网络模块。

F:PyTorch的函数模块。

device:将模型加载到GPU设备。

image_path:待分类的图像文件路径。

Image.open(image_path):使用PIL库打开图像文件。

图像的预处理:

image.convert(‘RGB’):将图像转换为RGB模式,以确保图像通道数为3。

transform:定义了一系列的图像预处理操作,包括将图像缩放到32x32像素大小并将其转换为PyTorch的Tensor数据类型。

image = transform(image):应用上述的预处理操作,将图像准备好以供模型处理。

定义神经网络模型:

My_CNN 类:这是一个自定义的卷积神经网络模型,包括两个卷积层,两个池化层,以及三个全连接层。这个模型与之前训练的CNN模型相似,用于图像分类任务。

加载预训练模型:

model = torch.load(“cnn_net_model.pth”, map_location=torch.device(‘cuda’)):加载之前训练并保存的CNN模型。map_location 参数指定了模型的加载位置,这里指定为CUDA/GPU。

调整输入图像的维度和数据类型:

image = torch.reshape(image, (1, 3, 32, 32)):将输入的图像数据调整为适合模型的维度(1个样本,3个通道,32x32像素大小)。

image = image.to(device):将图像数据移动到GPU设备,以便进行GPU上的推理。

模型推理和分类:

model.eval():将模型切换到推理模式,这意味着模型不再更新梯度。

with torch.no_grad()::在这个块中,不会计算或保存梯度信息,以提高性能和节省内存。

output = model(image):对输入的图像进行前向传播,得到模型的输出。

print(output):打印模型的输出,这是一个包含了不同类别的分数的张量。

测试结果:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与算法:使用数组模拟环形队列Java版

文章目录 如何使用数组模拟队列环形队列逻辑分析自己写的听课笔记实现代码部分方法说明 如何使用数组模拟队列 不知道如何使用数组模拟队列的可以看上一篇文章 使用数组模拟队列点击跳转 环形队列逻辑分析 自己写的听课笔记 实现代码 package com.haimeng.queue;import java…

uniapp-自定义表格,右边操作栏固定

uniapp-自定义表格,右边操作栏固定 在网上找了一些,没找到特别合适的,收集了一下其他人的思路,基本都是让左边可以滚动,右边定位,自己也尝试写了一下,有点样式上的小bug,还在尝试修…

多线程锁的升级原理是什么

在 Java 中,锁共有 4 种状态,级别从低到高依次为:无状态锁,偏向锁,轻量级锁和重量级锁状态,这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级。 多线程锁锁升级过程 如下图所示 多线程锁的升级过程…

在NISQ小型计算机上执行大型并行量子计算的可能性

简介 Steve White提出了密度矩阵重整化群(DMRG)的基本思想,即纠缠是一种有价值的资源,可以用来精确或近似地描述大量子系统。后来,这一思想被理解为优化矩阵积状态(MPS)的算法,支持…

Android开发笔记(三)—Activity篇

活动组件Activity 启动和结束生命周期启动模式信息传递Intent显式Intent隐式Intent 向下一个Activity发送数据向上一个Activity返回数据 附加信息利用资源文件配置字符串利用元数据传递配置信息给应用页面注册快捷方式 启动和结束 (1)从当前页面跳到新页…

[idea]关于idea开发乱码的配置

在JAVA开发中,一般统一设置为UTF-8的编码,包括但不限于开发工具、日志架构、虚拟机、文件编码等。常见配置如下: 1、IDEA工具 在idea64.exe.vmoptions、idea.exe.vmoptions中添加: -Dfile.encodingUTF-8 2、JAVA 运行在window…

python科研绘图:条形图

条形图(bar chart)是一种以条形或柱状排列数据的图形表示形式,可以显示各项目之间的比较。它通常用于展示不同类别的数据,例如在分类问题中的不同类别、不同产品或不同年份的销售数据等。 条形图中的每个条形代表一个类别或一个数…

区块链与教育:颠覆传统,引领未来

区块链与教育:颠覆传统,引领未来 摘要:本文将探讨区块链技术在教育领域的应用及其潜在影响。通过介绍区块链技术的基本原理、教育领域的现状,以及区块链技术在教育中的实际应用案例,我们将展望一个去中心化、安全可信…

软件测试面试高频30道面试题

如果哪个测试经理在看我的文章,希望对面试者要微笑,不然面试结束,出门之后就一万个草泥马奔腾而过,其实面试者并不是希望你给他们什么,而是一种尊重,平等的谈话,不要高高在上感觉自己超牛逼一样…

【星海出品】VUE(一)

Windows安装nvm控制器 Windows里找都PowerShell。右击点击管理员运行。 1.安装choco Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString(https://chocolatey.org/install.ps1))2.安装NVM choco install nvm 3.查看可…

【HeidiSql_01】python在heidisql当中创建新表的注意事项

python在heidisql当中创建新表的注意事项 假设你已经在python当中弄好了所有的结果,并且保存在df_all这个dataframe当中,然后要将其导入数据库当中并创建一张新的表进行保存。 # 构建数据库连接,将merged_df写回数据库 from sqlalchemy import create_e…

中海达守护电力人员作业安全

近日,中海达为电网某换流站作业人员提供的160余套北斗高精度定位产品顺利完成交付。通过使用北斗高精度定位技术,帮助换流站实现了人员(车辆)位置实时定位、电子围栏实时预警、远程作业指导等应用效果,用高科技保障电网…

【Linux学习笔记】进程概念(上)

1. 冯诺依曼体系结构2. 操作系统的作用3. 进程 1. 冯诺依曼体系结构 如图,这是一个冯诺依曼体系结构简图 其中这里的存储器指的是内存! 用通俗的话来解释这个图,就是数据从输入设备进入,然后进入到存储器,CPU从存储器…

echarts 画散点图, x周,y周在指定位置标志一下

文章目录 echarts 画散点图, x周,y周在指定位置标志一下示例一例子二示例三 echarts 画散点图, x周,y周在指定位置标志一下 示例一 let scatterData {data: [[[-0.2, -0.6],[0.4, 0.3],[0.1, 0.4],[0.3, 0.5],[0.09, 0.1],[0.7,…

没有PDF密码,如何解密文件?

PDF文件有两种密码,一个打开密码、一个限制编辑密码,因为PDF文件设置了密码,那么打开、编辑PDF文件就会受到限制。想要解密,我们需要输入正确的密码,但是有时候我们可能会出现忘记密码的情况,或者网上下载P…

2023年最新版潮乎盲盒源码含搭建教程

后台开发语言:后端 Laravel 框架开发 前端开发框架:uniappvue 环境配置: php7.4 mysql5.6 nginx1.22 redis(建议宝塔面板或 lnmp) 源码获取请自行百度:一生相随博客 一生相随博客致力于分享全网优质资源&#x…

kotlin中集合操作符

集合操作符 1.总数操作符 any —— 判断集合中 是否有满足条件 的元素; all —— 判断集合中的元素 是否都满足条件; none —— 判断集合中是否 都不满足条件,是则返回true; count —— 查询集合中 满足条件 的 元素个数&#x…

机器学习-基本知识

 任务类型 ◼ 有监督学习(Supervised Learning) 每个训练样本x有人为标注的目标t,学习的目标是发现x到t的映射,如分类、回归。 ◼ 无监督学习(Unsupervised Learning) 学习样本没有人为标注,学习的目的是发现数据x本身的分布规律&#xf…

Hadoop PseudoDistributed Mode 伪分布式

Hadoop PseudoDistributed Mode 伪分布式加粗样式 hadoop101hadoop102hadoop103192.168.171.101192.168.171.102192.168.171.103namenodesecondary namenoderecource managerdatanodedatanodedatanodenodemanagernodemanagernodemanagerjob historyjob logjob logjob log 1. …

论文 辅助笔记:t2vec train.py

1 train 1.1 加载training和validation数据 def train(args):logging.basicConfig(filenameos.path.join(args.data, "training.log"), levellogging.INFO)设置了日志的基本配置。将日志信息保存到名为 "training.log" 的文件中日志的级别被设置为 INFO&…