《深度学习》卷积神经网络CNN 实现手写数字识别

目录

一、卷积神经网络CNN

1、什么是CNN

2、核心

3、构造

二、案例实现

1、下载训练集、测试集

代码实现如下:

2、展示部分图片

运行结果:

3、图片打包

运行结果:

4、判断当前使用的CPU还是GPU

5、定义卷积神经网络

运行结果:

6、训练、测试模型

运行结果:


以下代码类似于前面所说的神经网络实现手写数字识别,可参考下列博客。

《深度学习》PyTorch 手写数字识别 案例解析及实现 <下>icon-default.png?t=O83Ahttps://blog.csdn.net/qq_64603703/article/details/142282105?fromshare=blogdetail&sharetype=blogdetail&sharerId=142282105&sharerefer=PC&sharesource=qq_64603703&sharefrom=from_link

一、卷积神经网络CNN

1、什么是CNN

        卷积神经网络是一种深度学习模型,主要应用于图像和视频处理任务。它的设计灵感来源于生物视觉系统的工作原理。

2、核心

        核心是卷积层,这是一种通过在输入数据上应用滤波器(也称为卷积核)来提取特征的操作。卷积层的输出是一系列的特征图每个特征图表示一种特定的图像特征,例如边缘、纹理等。这种特征提取的方式可以捕捉到图像中的局部模式,并且在不同位置共享参数,从而提高了模型的效率和泛化能力。

3、构造

        CNN还包括池化层,用于减小特征图的尺寸降低计算复杂度,增加模型的平移不变性。

        卷积神经网络还可以包含多个卷积层和池化层的堆叠,以及全连接层(Fully Connected Layer)用于进行分类或回归等任务。

二、案例实现

1、下载训练集、测试集

        通过现有的库调用其用法直接去下载现成的手写数字的数据集,这些手写数字集共有70000张图片,这些图片都有其对应的标签,大小为28*28,灰度图,数字居中,直接使用即可。

        将这70000张图片,60000张当做训练集,10000张当做测试集。

代码实现如下:
import torch
print(torch.__version__)"""MNIST包含70,000张手写数字图像:60,000张用于训练,10,000张用于测试。
图像是灰度的,28x28像素的,并且居中的,以减少预处理和加快运行。"""from torch import nn  # 导入神经网络模块
from torch.utils.data import DataLoader  # 数据包管理工具,打包数据,
from torchvision import datasets   # 封装了很多与图像相关的模型,数据集
from torchvision.transforms import ToTensor   # 数据转换,张量,将其他类型的数据转换为tensor张量,numpy arrgy,"""下载训练数据集,图片+标签"""
training_data = datasets.MNIST(   # 跳转到函数的内部源代码,pycharm 按下ctrl +鼠标点击root='data',   # 表述下载的数据存放的根目录train=True,   # 表示下载的是训练数据集,如果要下载测试集,更改为False即可download=True,   # 表示如果根目录有该数据,则不再下载,如果没有则下载transform=ToTensor()   # 张量,图片是不能直接传入神经网络模型# 表示制定一个数据转换操作,将下载的图片转换为pytorch张量,因为pytorch只能处理张量tensor类型的数据
)test_data = datasets.MNIST(root='data',train=False,download=True,transform=ToTensor()  # Tensor是在深度学习中提出并广泛应用的数据类型,它与深度学习框架(如 PyTorch、TensorFlo
)  # NumPy 数组只能在CPU上运行。Tensor可以在GPU上运行,这在深度学习应用中可以显著提高计算速度。print(len(training_data))
print(len(test_data))

        实现结果就是当前代码的目录多出了一个data文件,里面存放的就是下载好的手写数字的图片,打印内容为下载的图片个数。

2、展示部分图片

        取出9张图片,将其展示在画布上

from matplotlib import pyplot as plt   # 导入绘图库
figure = plt.figure()   # 设置一个空白画布
for i in range(9):img,label = training_data[i+59000]   # 提取第59000张图片开始,共9张,返回图片及其对应的标签值figure.add_subplot(3,3,i+1)   # 在画布创建3行3列的小窗口,通过遍历的值i来确定每个画布展示的图片plt.title(label)   # 设置每个窗口的标题,设置标签为上述返回的标签值plt.axis('off')   # 取消画布中的坐标轴的图像plt.imshow(img.squeeze(),cmap='gray')   # plt.imshow()将NumPy数组data中的数据显示为图像,并在图形窗口中,a = img.squeeze()   # img.squeeze()从张量img中去掉维度为1的。如果该维度的大小不为1,则张量不会改变。
plt.show()
运行结果:

3、图片打包

        因为图片的数量太多,将其一张一张的放入GPU进行计算太耗费时间,而且还浪费资源,所以将64张图片打包成一份,将这一整个数据包传入GPU使其计算,这样大大增加了运行的效率。

train_dataloader = DataLoader(training_data,batch_size=64)  # 调用上述定义的DataLoader打包库,将训练集的图片和标签,64张图片为一个包,
test_dataloader = DataLoader(test_data,batch_size=64)   # 将测试集的图片和标签,每64张打包成一份
for x,y in test_dataloader:# x是表示打包好的每一个数据包,其形状为[64,1,28,28],64表示批次大小,1表示通道数为1,即灰度图,28表示图像的宽高像素值# y表示每个图片标签print(f"shape of x[N,C,H,W]:{x.shape}")   # 打印图片形状print(f"shape of y:{y.shape}{y.dtype}")   # 打印标签的形状和数据类型break  # 跳出并终止循环,表示只遍历一个包的数据情况
运行结果:

4、判断当前使用的CPU还是GPU

"""判断当前设备是否支持GPU,其中mps是苹果m系列芯片的GPU"""  # 返回cuda,mps,cpu, m1,m2集显CPU+GPU RTX3060
device = "cuda" if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else "cpu"
print(f"Using {device} device")  # 字符串的格式化。CUDA驱动软件的功能:pytorch能够去执行cuda的命令,cuda通过GPU指令集
# 神经网络的模型也需要传入到GPU,1个batchsize的数据集也需要传入到GPU,才可以进行训练。

5、定义卷积神经网络

"""定义神经网络"""
class CNN(nn.Module):   # 继承nn算法中的Moduledef __init__(self):   # 这里输入大小为(1,28,28)super(CNN,self).__init__()self.conv1 = nn.Sequential(   # 第一层卷积, 将多个层组合成一起。nn.Conv2d(    # 二维卷积成,2d一般用于图像,3d用于视频数据(多一个时间维度),1d一般用于结构化的序列数据in_channels=1,    # 输入图像通道个数,1表示灰度图(确定了卷积核 组中的个数),out_channels=16,   # 输出多少个特征图,也可表示卷积核的个数kernel_size=5,   # 卷积核大小,5*5stride=1,   # 卷积核移动的步长padding=2,   # 边缘填充层数),   # 输出的特征图为(16*28*28)nn.ReLU(),   # 设置激活层,引入非线性,增强表达能力,relu层,不会改变特征图的大小(16*28*28)nn.MaxPool2d(kernel_size=2),   # 池化层,大小为2*2,进行最大池化,压缩图像大小,输出结果为:(16*14*14))self.conv2 = nn.Sequential(   # 第二层卷积, 输入(16*14*14),定义两个二维卷积层,用于连续卷积nn.Conv2d(16,32,5,1,2),  # 输出(32*14*14)nn.ReLU(),   # relu层(32*14*14)nn.Conv2d(32,32,5,1,2),  # 输出(32*14*14)nn.ReLU(),    # (32,14,14)nn.MaxPool2d(2),   # 最大池化,输出(32*7*7))self.conv3 = nn.Sequential(   # 输入(32*7*7)nn.Conv2d(32, 64, 5, 1, 2),  # (64*7*7)nn.ReLU(),  # 输出(64*7*7))self.out = nn.Linear(64*7*7,10)   # 全连接层得到的结果def forward(self, x):   # 定义前向传播x = self.conv1(x)    # 对传入模型的图片数据进行第一层卷积处理x = self.conv2(x)x = self.conv3(x)   # 输出(64,64,7,7)x = x.view(x.size(0),-1)    # 重新调整张量的形状,即flatten操作,结果为:(batch_size,64*7*7)# x.size(0)表示获取第一个维度的大小,-1表示自动计算维度大小# x.view(x.size(0),-1)将张量x重新调整为两维张量,其中第一维的大小保持不变(即x.size(0)),而第二维的大小是自动计算的,以确保总元素数量与原始张量相同。output = self.out(x)return outputmodel = CNN().to(device)   # 将模型传入GPU
print(model)   # 打印模型的结构
运行结果:

6、训练、测试模型

def train(dataloader,model,loss_fn,optimizer):   # 导入参数,dataloader表示打包,数据加载器,model导入上述定义的神经网络模型,loss_fn表示损失值,optimizer表示优化器model.train()   # 模型设置为训练模式# 告诉模型,我要开始训练,模型中权重w进行随机化操作,已经更新w。在训练过程中,w会被修改的# #pytorch提供2种方式来切换训练和测试的模式,分别是:model.train()和 model.eval()。# 一般用法是:在训练开始之前写上model.train(),在测试时写上model.eval()。batch_size_num = 1for x,y in dataloader:    # 遍历打包的图片的每一个包中的每一张图片及其对应的标签,其中batch为每一个数据的编号x,y = x.to(device),y.to(device)   # 把训练数据集和标签传入cpu或GPUpred = model.forward(x)    # 模型进行前向传播,输入图片信息后得到预测结果,forward可以被省略,父类中已经对次功能进行了设置。自动初始化w权值loss = loss_fn(pred,y)     # 调用交叉熵损失函数计算损失值loss,输入参数为预测结果和真实结果,# Backpropaqation 进来一个batch的数据,计算一次梯度,更新一次网络optimizer.zero_grad()    # 梯度值清零,在反向传播之前先清除之前的梯度loss.backward()     # 反向传播,计算得到每个参数的梯度值woptimizer.step()    # 根据梯度更新权重w参数loss_value = loss.item()   # 从tensor数据中提取数据出来,tensor获取损失值if batch_size_num % 200 == 0:  # 判断遍历包的个数是否整除于200,用于将训练到的包的个数打印出来,整除200目的是节省资源print(f"loss:{loss_value:>7f}   [number: {batch_size_num}]")  # 打印损失值及其对应的值,损失值最大宽度为7,右对齐batch_size_num += 1    # 每遍历一个包增加一次,以达到显示出来遍历的包的个数def test(dataloader,model,loss_fn):  # 输入参数打包的图片、训练好的模型、以及损失值size = len(dataloader.dataset)   # 返回测试数据集的样本总数num_batches = len(dataloader)   # 返回当前dataloader配置下的批次数model.eval()    # 表示此为模型测试,w就不能再更新。test_loss,correct = 0, 0   # 设置总损失值初始化为0,正确预测结果初始化为0with torch.no_grad():    # 一个上下文管理器,关闭梯度计算。当你确认不会调用Tensor.backward()的时候。这可以减少计算for x,y in dataloader:   # 遍历测试集中的每个包的每个图片及其对应的标签x,y = x.to(device),y.to(device)   # 将其传入gpupred = model.forward(x)   # 图片数据进行前向传播test_loss += loss_fn(pred,y).item()    # test_loss是会自动累加每一个批次的损失值correct += (pred.argmax(1) == y).type(torch.float).sum().item()  # pred.argmax(1) == y用于判断预测结果最大值对用的标签是否与真实值相同,然后将判断结果的bool值转变为浮点数并求和a = (pred.argmax(1) == y)   # dim=1表示每一行中的最大值对应的索引号,dim=0表示每一列中的最大值对应的索引号b = (pred.argmax(1) == y).type(torch.float)test_loss /= num_batches    # 总损失值除以打包的批次数,返回测试的每一个包的损失值的均值,能来衡量模型测试的好坏。correct /= size   # 平均的正确率print(f"Test result: \n Accuracy:{(100 * correct)}%, Avg loss:{test_loss}")  # 打印测试集测试结果
loss_fn = nn.CrossEntropyLoss()  # 创建交叉熵损失函数对象,因为手写字识别中一共有10个数字,输出会有10个结果
optimizer = torch.optim.Adam(model.parameters(),lr=0.001)  # 创建一个优化器,SGD为随机梯度下降算法,学习率或者叫步长为0.0045epochs = 8  # 设置训练的轮数为8轮,因为模型中设置了权重值的更新,所以重复训练会更新模型的权值
for i in range(epochs):print(f"Epoch {i+1}\n--------------------")train(train_dataloader,model,loss_fn,optimizer)
print('Done!!')
test(test_dataloader,model,loss_fn)   # 导入测试集进行测试
运行结果:

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

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

相关文章

后端-对表格数据进行添加、删除和修改

一、添加 要求: 按下添加按钮出现一个板块输入添加的数据信息,点击板块的添加按钮,添加;点击取消,板块消失。 实现: 1.首先,设计页面输入框格式,表格首行 2.从数据库里调数据 3.添加…

LPDDR4芯片学习(二)——Functional Description

一、LPDDR4寻址表 以每个die容量为4GB为例: Memory density(per channel) 2Gb:每个通道大小为2Gb,一个die有两个通道Configuration 16Mb 16DQ 8 banks 2 channels :16Mb的寻址空间16位每个channels8个bank*每个die两channels。1…

Java基础(Arrays工具类)(asList()方法)(详细)

目录 一、Arrays工具类 (1)引言 (2)基本介绍 (3)主要功能(提供的方法) (I)排序(Arrays.sort()) (II)搜索(查找…

ECCV 2024 现场:参会者付高价、跨万里,却无法入场?

ECCV(European Conference on Computer Vision,欧洲计算机视觉国际会议)是计算机视觉领域的重要国际会议之一,与CVPR和ICCV并称为计算机视觉的三大顶级会议。 ECCV2024是该系列会议的第18届会议,2024年9月29日至10月4…

第3篇:常见的Webshell查杀工具----应急响应篇

当网站服务器被入侵时,我们需要一款Webshell检测工具,来帮助我们发现webshell,进一步排查系统可能存在的安全漏洞。 本文推荐了10款Webshll检测工具,用于网站入侵排查。当然,目前市场上的很多主机安全产品也都提供这种…

引入Scrum激发研发体系活力

引言 在当今快速变化的技术环境中,IT企业面临着持续的市场压力和竞争,传统的瀑布式开发模式已经难以满足现代企业的需要。瀑布模型过于僵化,缺乏灵活性,导致项目经常延期,成本增加,最终可能无法达到预期效果…

这款工具在手,前端开发轻松搞定!

这款工具在手,前端开发轻松搞定! 引言 在之前的一篇文章中,已经给大家分享了一款AI助手。尽管该助手能够生成前端代码,但遗憾的是缺少了实时预览的功能。而现在,这一缺憾已经被弥补——你只需要描述你的设计想法&…

递归算法介绍和【题解】——数楼梯

递归算法介绍和【题解】——数楼梯 1.递推算法介绍2.数楼梯题目描述输入格式输出格式输入输出样例输入 #1输出 #1 提示 1.思路解析2.AC代码 1.递推算法介绍 有些目标是宏大的,比如如果你想找到一个好工作,需要先把面试通过。要把面试通过,就需…

力扣(leetcode)每日一题 1014 最佳观光组合

题干 1014. 最佳观光组合 给你一个正整数数组 values&#xff0c;其中 values[i] 表示第 i 个观光景点的评分&#xff0c;并且两个景点 i 和 j 之间的 距离 为 j - i。 一对景点&#xff08;i < j&#xff09;组成的观光组合的得分为 values[i] values[j] i - j &#…

总结C/C++中内存区域划分

目录 1.C/C程序内存分配主要的几个区域&#xff1a; 2.内存分布图 1.C/C程序内存分配主要的几个区域&#xff1a; 1、栈区 2、堆区 3、数据段&#xff08;静态区&#xff09; 4.代码段 2.内存分布图 如图&#xff1a; static修饰静态变量成员——放在静态区 int globalVar 是…

uniapp在线打包的ios后调用摄像头失败的解决方法

uniapp在线打包的ios后调用摄像头失败的解决方法 解决方法&#xff1a; 由于未选中打包模块的配置 当你在测试时发现能够正常的开启摄像头&#xff0c;但是当你对其进行在线打包后&#xff0c;发现当你点击启用摄像头时&#xff0c;没有反应&#xff0c;或者是打开是黑屏状态…

《情书》你的名字,是最美的情书

《情书》你的名字&#xff0c;是最美的情书 岩井俊二&#xff0c;日本电影导演&#xff0c;作家及记录片导演。被誉为日本最有潜质的新近“映像作家”&#xff0c;也有中国影迷称他为“日本王家卫”。影像清新独特、感情细腻丰富。&#xff08;来自豆瓣&#xff09; 穆晓芳 译 …

网页WebRTC电话和软电话哪个好用?

关于WebRTC电话与软件电话哪个更好用&#xff0c;这实际上取决于多个因素&#xff0c;并没有一个绝对的答案。不过&#xff0c;我可以根据WebRTC技术的一些特点&#xff0c;以及与传统软件电话相比的优劣势&#xff0c;为你提供一个清晰的对比。 首先&#xff0c;让我们了解一下…

无监督算法目标识别-工业异常检测模型Padim+PatchCore的C++_libtorch实现

基于anomalib的python代码完美复现 示例&#xff1a; 使用无监督算法识别缺陷&#xff1a;图像复杂不能太高&#xff0c;尽量是简单背景的图片&#xff0c;如果太复杂了还是直接上有监督算法识别泛化能力强 代码实现详见&#xff1a;****Gitee

11.全面学习面向对象技术

面向对象开发 相关概念 对象&#xff1a;由数据及其操作所构成的封装体&#xff0c;是系统中用来描述客观事务的一个实体&#xff0c;是构成系统的一个基本单位。一个对象通常可以由对象名、属性和方法3个部分组成。类&#xff1a;现实世界中实体的形式化描述&#xff0c;类…

Chainlit集成LlamaIndex实现知识库高级检索(组合对象检索)

检索原理 对象组合索引的原理 是利用IndexNode索引节点&#xff0c;将两个不同类型的检索器作为节点对象&#xff0c;使用 SummaryIndex &#xff08;它可以用来构建一个包含多个索引节点的索引结构。这种索引通常用于从多个不同的数据源或索引方法中汇总信息&#xff0c;并能…

第18章 中断和异常的处理与抢占式多任务

第18章 中断和异常的处理与抢占式多任务 中断和异常 中断和异常概述 中断&#xff08;Interrupt&#xff09;&#xff1a; 硬件中断是由外围硬件设备发出的中断信号引发的&#xff0c;以请求处理器提供服务。软中断是由int n指令引发的中断处理&#xff0c;n是中断号或者叫…

【Python】数据可视化之分布图

分布图主要用来展示某些现象或数据在地理空间、时间或其他维度上的分布情况。它可以清晰地反映出数据的空间位置、数量、密度等特征&#xff0c;帮助人们更好地理解数据的内在规律和相互关系。 目录 单变量分布 变量关系组图 双变量关系 核密度估计 山脊分布图 单变量分布…

5.数据结构与算法-类C语言的有关操作

元素类型说明 数组定义 C语言的动态内存分配 C动态存储分配 C的参数传递 传值方式 传地址方式 形参变化影响实参 形参变化不影响实参 数组名做参数 引用类型做参数

高通AI应用程序开发3:网络模型(一)

1. 支持的网络模型 Qualcomm神经处理SDK支持下表所列的网络模型。 有关支持的运行时和单个图层类型的限制和约束的详细信息&#xff0c;请参阅 限制 。 GPU运行时中支持的所有层对两种GPU模式都有效&#xff1a;GPU_FLOAT32_16_HYBRID和GPU_FLAAT16。GPU_FLOAT32_16_HYBRID-…