《深度学习》PyTorch 手写数字识别 案例解析及实现 <下>

目录

一、回顾神经网络框架

1、单层神经网络

2、多层神经网络

二、手写数字识别

1、续接上节课代码,如下所示

2、建立神经网络模型

输出结果:

3、设置训练集

4、设置测试集

5、创建损失函数、优化器

参数解析:

1)params

2)lr

3)loss

6、开始训练

运行结果:

三、总结

1、关键步骤

2、训练过程中

3、训练完成后


一、回顾神经网络框架

1、单层神经网络

        图示为单层神经完了的基本构造,首先,有信号想传入输入层,然后这些信号会在传播途中发生衰减或者增强,假如想传入的信号为x,那么经过衰减或增强后的值则为wx,这个w叫权重,此时便有了传入信号,有很多传入信号,那么神经元就会对这些信号进行处理,把这些信号的加权值求和,再将这个求和的值映射到非线性激活函数上来引入非线性特征,最后得到输出结果。

2、多层神经网络

        相比于上述的单层神经网络,单层神经网络就相当于上图中的绿色的第一列,即多个信号传入后只进行加权映射处理一次即输出结果,而多层神经网络即有多列神经元,传入信号经过第一列神经元处理后得到的值将其再次当做信号进行衰减或增强传入下一层神经元对其进行处理,至于多少层需要经过多次训练去决定,没有固定的值。

二、手写数字识别

1、续接上节课代码,如下所示

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))"""展示手写数字图片,把训练数据集中的前59000张图片展示一下"""# # tensor -》numpy  矩阵类型的数据,矩阵是特殊的张量,张量可以包含任意维度的数据
# 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()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  # 跳出并终止循环,表示只遍历一个包的数据情况"""判断当前设备是否支持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,才可以进行训练。

2、建立神经网络模型

class NeuralNetwork(nn.Module):  # 通过调用类的形式来使用神经网络,神经网络的模型def __init__(self):super().__init__()   # 继承的父类初始化self.flatten = nn.Flatten()   # 将输入的多维数据展开成一维数据,创建一个展开对象flattenself.hidden1 = nn.Linear(28*28,128)  # 创建一个全连接层,其上包含权重的值,第1个参数表示有多少个神经元传入进来,第2个参数表示有多少个数据传出去,这里表示上述多层神经网络的第一列神经元self.hidden2 = nn.Linear(128, 256)  # 再次创建一个全连接层,将第一层输出个数转变成这一层的输入信号数,然后在设定输出层个数为256self.hidden3 = nn.Linear(256,128)  # 继承上一层的输出信号个数,将其当做这一层的输入为256层,设定输出为128层self.hidden4 = nn.Linear(128,64)   # 输入128层,输出64层self.out = nn.Linear(64, 10)   # 设定输出层,输出必需和标签的类别相同,输入必须是上一层的神经元个数def forward(self,x):   # 设定前向传播函数,你得告诉它,数据的流向。是神经网络层连接起来,函数名称不能改。当你调用forward函数的时候,传入进来的图像数据x = self.flatten(x)  # 传入信号x图像,首先进行展开x = self.hidden1(x)  # 将其当做输入层x = torch.sigmoid(x)   # 使用sigmoid激活函数得到结果,torch使用的relu函数 relu,tanhx = self.hidden2(x)    # 再次对上一层的结果进行加权x = torch.sigmoid(x)x = self.hidden3(x)x = torch.sigmoid(x)x = self.hidden4(x)x = torch.sigmoid(x)x = self.out(x)  # 输出结果return x  # 将输出结果返回出去model = NeuralNetwork().to(device)   # 把刚刚创建的模型传入到gpu
print(model)   # 打印模型的构造

        此处的神经网络层数可以自己设置,如果想多设置几层或者少设置基层,只需改变self.hidden的个数以及前向传播函数中激活函数的个数。

        输出结果:

3、设置训练集

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    # 每遍历一个包增加一次,以达到显示出来遍历的包的个数

4、设置测试集

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}")

5、创建损失函数、优化器

loss_fn = nn.CrossEntropyLoss()  # 创建交叉熵损失函数对象,因为手写字识别中一共有10个数字,输出会有10个结果
optimizer = torch.optim.Adam(model.parameters(),lr=0.0045)  # 创建一个优化器,SGD为随机梯度下降算法,学习率或者叫步长为0.0045
参数解析:
        1)params

                表示要训练的参数,一般我们传入的都是model.parameters()

        2)lr

                learning_rate学习率,也就是步长

        3)loss

                表示模型训练后的输出结果与样本标签的差距。如果差距越小,就表示模型训练越好,越逼近于真实的型。

6、开始训练

epochs = 25  # 设置训练的轮数为25轮,因为模型中设置了权重值的更新,所以重复训练会更新模型的权值
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)   # 导入测试集进行测试

        将上述所有代码连贯起来运行。

        运行结果:

        至此训练结束,用户可手动更改模型激活函数、学习率、模型训练轮数等等,以找到最优结果。

        祝你成功!!

三、总结

1、关键步骤

        使用PyTorch进行手写数字识别可以分为几个关键步骤。首先,需要准备手写数字数据集,通常使用MNIST数据集。然后,需要定义神经网络模型,可以使用PyTorch提供的各种层和激活函数来构建模型架构。接下来,需要定义损失函数,通常使用交叉熵损失函数来计算预测结果与真实标签之间的差异。

2、训练过程中

        在训练过程中,使用优化算法(如随机梯度下降)来更新模型的权重和偏置,使其逐渐接近最优解。训练过程中会使用训练集的数据进行反向传播,并根据损失函数的结果来调整模型参数。可以设置训练的轮数和批次大小,以更好地优化模型。

3、训练完成后

        在训练完成后,可以使用测试集或新的手写数字图像来评估模型的性能。通过将图像输入已训练好的模型,可以获得预测结果,并与真实标签进行比较。可以计算准确率等指标来评估模型的性能。

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

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

相关文章

ArcGIS10.2/10.6安装包下载与安装(附详细安装步骤)

相信从事地理专业的小伙伴来说,应该对今天的标题不会陌生。Arcgis是一款很常用的地理信息系统软件,主要用于地理数据的采集、管理、分析和展示。目前比较常见的版本有ArcGIS 10.2和ArcGIS 10.6。 不可否认,Arcgis具有强大的地图制作、空间分…

DataGrip在Windows和MacOS平台上的快捷键

0. 背景信息 No.说明1测试DataGrip版本号 : 2024.2.2 1. Windows下快捷键 2. MacOS下快捷键

CentOS Stream 9部署Redis

1、安装Redis sudo dnf install redis 2、启动Redis服务 sudo systemctl start redis 3、设置Redis开机自启 sudo systemctl enable redis 4、打开Redis配置文件: sudo vi /etc/redis/redis.conf 在配置文件中找到并修改以下两行,确保密码验证功能已启…

Docker 容器技术:颠覆传统,重塑软件世界的新势力

一、Docker简介 什么是docker Docker 是一种开源的容器化平台,它可以让开发者将应用程序及其所有的依赖项打包成一个标准化的容器,从而实现快速部署、可移植性和一致性。 从功能角度来看,Docker 主要有以下几个重要特点: 轻量…

数据结构——串的模式匹配算法(BF算法和KMP算法)

算法目的: 确定主串中所含子串(模式串)第一次出现的位置(定位) 算法应用: 搜索引擎、拼写检查、语言翻译、数据压缩 算法种类: BF算法(Brute-Force,又称古典的…

web基础—dvwa靶场(七)SQL Injection

SQL Injection(SQL注入) SQL Injection(SQL注入),是指攻击者通过注入恶意的SQL命令,破坏SQL查询语句的结构,从而达到执行恶意SQL语句的目的。SQL注入漏洞的危害是巨大的,常常会导致…

『功能项目』QFrameWorkBug关联Slot(插槽)【67】

我们打开上一篇66QFrameWorkBug拖拽功能的项目, 本章要做的事情是关联插槽Slot 修改脚本:UISlot.cs 修改脚本:UGUICanvas.cs 此时关联Slot已经完成 接下来的文章内容: 1.QFrameWork扔到地上UGUI 2.位置存储功能 3.点击名称寻…

VMware ESXi 8.0U3b macOS Unlocker OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版)

VMware ESXi 8.0U3b macOS Unlocker & OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版) 发布 ESXi 8.0U3 集成驱动版,在个人电脑上运行企业级工作负载 请访问原文链接:https://sysin.org/blog/vmware-esxi-8-u3-sysin/,查看最新版…

10.3拉普拉斯金字塔

实验原理 拉普拉斯金字塔(Laplacian Pyramid)是一种图像表示方法,常被用于图像处理和计算机视觉领域。它是基于高斯金字塔的一种变换形式,主要用于图像融合、图像金字塔的构建等场景。下面简要介绍拉普拉斯金字塔的基本原理。 高…

【优选算法之二分查找】No.5--- 经典二分查找算法

文章目录 前言一、二分查找模板:1.1 朴素二分查找模板1.2 查找区间左端点模板1.3 查找区间右端点模板 二、二分查找示例:2.1 ⼆分查找2.2 在排序数组中查找元素的第⼀个和最后⼀个位置2.3 搜索插⼊位置2.4 x 的平⽅根2.5 ⼭脉数组的峰顶索引2.6 寻找峰值…

实现人体模型可点击

简化需求:实现项目内嵌人体模型,实现点击不同部位弹出部位名称 一:优先3d, 方案:基于three.js,.gltf格式模型,vue3 缺点:合适且免费的3d模型找不到,因为项目对部位有要…

【记录】Excel|不允许的操作:合并或隐藏单元格出现的问题列表及解决方案

人话说在前:这篇的内容是2022年5月写的,当时碰到了要批量处理数据的情况,但是又不知道数据为啥一直报错报错报错,说不允许我操作,最终发现是因为存在隐藏的列或行,于是就很无语地写了博客,但内容…

Java笔试面试题AI答之单元测试JUnit(5)

文章目录 25. 简述什么是Junit 忽略测试(Ignore Test)?一、基本概念二、使用方法三、注意事项四、示例 26. 简述什么是Junit 超时测试(Timeout Test)?Junit 超时测试的主要特点包括:实现方式&am…

全国832个贫困县名单及精准扶贫脱贫数据(2016-2020.11)

自党的十八大以来,通过全党全国各族人民的共同努力,中国成功实现了现行标准下9899万农村贫困人口的全部脱贫,832个贫困县全部摘帽。 摘帽名单 2016年-2020.11全国832个贫困县名单及精准扶贫脱贫数据整理(大数据)https…

JavaEE:探索网络世界的魅力——玩转UDP编程

文章目录 UDPUDP的特点UDP协议端格式校验和前置知识校验和具体是如何工作的? UDP UDP的特点 UDP传输的过程类似于寄信. 无连接: 知道对端的IP和端口号就直接进行传输,不需要建立连接.不可靠: 没有确认机制,没有重传机制,如果因为网络故障导致该段无法到达对方,UDP协议也不会…

nodejs基于vue+express度假村旅游管理系统设计与实现7t82p

目录 功能介绍数据库设计具体实现截图技术栈技术论证解决的思路论文目录核心代码风格详细视频演示源码获取 功能介绍 实现了一个完整的农家乐系统,其中主要有用户表模块、关于我们模块、收藏表模块、公告信息模块、酒店预订模块、酒店信息模块、景区信息模块、景区…

基于YOLOv5的教室人数检测统计系统

基于YOLOv5的教室人数检测统计系统可以有效地用于监控教室内的学生数量,适用于多种应用场景,比如 自动考勤、安全监控或空间利用分析 以下是如何构建这样一个系统的概述,包括环境准备、数据集创建、模型训练以及如何处理不同类型的媒体输入…

音乐项目,总结

今天的写的思路都挺简单的但是比较繁琐&#xff0c;这个查找&#xff0c;传文件的话可以了&#xff0c;但是没有用分片传送&#xff0c;然后在写音乐播放的处理&#xff0c;<歌单&#xff0c;二级评论&#xff0c;歌曲歌词滚轮播放>三个还没有实现&#xff0c;时间挺紧张…

开源免费的NAS系统-TrueNAS CORE上创建CentOS7虚拟机

目录 文章目录 目录1、说明2、准备工作2.1、准备安装镜像2.1、创建用户2.2、开启 ssh 服务2.3、设置用户权限2.4、上传系统镜像2.5、 添加虚拟机 3、开始安装系统3.1、启动虚拟机3.2、选择语言3.3、配置网络3.4、设置 root 密码3.5、删除光驱3.6、重启虚拟机3.7、使用 ssh 连接…

【2024】前端学习笔记7-颜色-位置-字体设置

学习笔记 1.定义&#xff1a;css2.颜色&#xff1a;color3.字体相关属性&#xff1a;font3.1.字体大小&#xff1a;font-size3.2.字体风格&#xff1a;font - style3.3.字体粗细&#xff1a;font - weight3.4.字体族&#xff1a;font - family 4.位置&#xff1a;text-align 1.…