深度学习:神经网络--手写数字识别

devtools/2024/10/18 10:28:24/

目录

一、datasets

1.datasets简介

2.主要特点

二、MNIST

三、使用神经网络实现手写数字识别

1.创建数据加载器

2.判断是否使用GPU

3.创建神经网络

4.创建训练集模型

5.创建测试集模型

6.创建损失函数和优化器并训练


一、datasets

1.datasets简介

        datasets是一个广泛使用的库,尤其在机器学习和自然语言处理领域,用于方便地加载和处理各种数据集。它提供了标准化的接口,使得数据集的访问、处理和分割变得更加简单。

 

2.主要特点

  1. 丰富的数据集库

    提供了数百个公开数据集,涵盖不同领域,如文本、图像、音频等。
  2. 简化数据加载

    只需几行代码即可加载数据集,支持多种格式(如 CSV、JSON、文本文件等)。
  3. 高效的数据处理

    提供数据预处理功能,如分词、编码、数据增强等,方便进行数据清洗和转换。
  4. 数据集分割

    支持轻松地将数据集分为训练集、验证集和测试集。
  5. 自定义数据集

    用户可以自定义数据集,方便地与现有数据集结合使用。
  6. 深度学习框架的兼容性

    可以与 PyTorch、TensorFlow 等深度学习框架无缝集成,便于模型训练。

 

二、MNIST

  • MNIST 是一个经典的手写数字识别数据集,广泛用于机器学习和计算机视觉领域的研究和教学。
  • 它包含 70,000 张 28x28 像素的灰度图像,分为 60,000 张训练样本和 10,000 张测试样本,每张图像对应一个 0 到 9 的数字标签。

代码实现:

import torch
from torch import nn  # 导入神经网络模块
from torch.utils.data import DataLoader  # 数据包管理工具,打包数据
from torchvision import datasets  # 封装了很多与图像相关的模型,数据集
from torchvision.transforms import ToTensor  # 数据转换,张量,将其他类型的数据转换为tensor张量'''下载训练数据集(包含训练图片和标签)'''
train_data = datasets.MNIST(root='data', train=True, download=True, transform=ToTensor()  # 张量,图片是不能直接传入神经网络模型
)  # 对于pytorch库能够识别的数据一般是tensor张量.'''下载测试数据集(包含训练图片和标签)'''
test_data = datasets.MNIST(root='data', train=False, download=True, transform=ToTensor()
)  # NumPy 数组只能在CPU上运行.Tensor可以在GPU上运行,这在深度学习应用中可以显著提高计算速度.
print(len(train_data))'''展示手写数字图片'''
import matplotlib.pyplot as pltfigure = plt.figure()
for i in range(9):img, label = train_data[i + 100]figure.add_subplot(3, 3, i + 1)plt.title(label)plt.axis('off')plt.imshow(img.squeeze(), cmap='gray')a = img.squeeze()
plt.show()

输出:

 

三、使用神经网络实现手写数字识别

1.创建数据加载器

  • 对数据进行打包
  • 通过打包数据,可以提高工作效率,简化数据管理流程,并提升模型的训练和推理性能。
'''
创建数据DataLoader(数据加载器)batch_size:将数据集分成多份,每一份为batch_size个数据.优点:可以减少内存的使用,提高训练速度.
'''
train_dataloader = DataLoader(train_data, batch_size=64)  # 64张图片为一个包
test_dataloader = DataLoader(test_data, batch_size=64)
for x, y in test_dataloader:print(f"shape of x [N ,C,H,W]:{x.shape}")print(f"shape of y :{y.shape} {y.dtype}")break

输出:

  • 第一行输出表示一个包64张一个通道的图片,每张图片像素大小为28*28
  • 第二行输出表示包的大小为64,数据类型为torch里的int64
shape of x [N ,C,H,W]:torch.Size([64, 1, 28, 28])
shape of y :torch.Size([64]) torch.int64

 

2.判断是否使用GPU

'''判断当前设备是否支持GPU mps是苹果m系列芯片GPU'''
device = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_avaibale() else 'cpu'
print(f"using {device} device")

输出:

using cuda device

 

3.创建神经网络

'''创建神经网络类'''class NeuralNetwork(nn.Module):def __init__(self):super().__init__()  # 继承的父类初始化self.flatten = nn.Flatten()  # 展开,创建一个展开对象flattenself.hidden1 = nn.Linear(28 * 28, 512)  # 第1个参数:有多少个神经元传入进来,第2个参数:有多少个数据传出去 前一层神经元的个数,当前本层神经元个数self.hidden2 = nn.Linear(512, 256)  # 第二个隐藏层self.hidden3 = nn.Linear(256, 128)  # 第三个隐藏层self.hidden4 = nn.Linear(128, 64)  # 第四个隐藏层self.out = nn.Linear(64, 10)  # 输出必须和标签的类别相同,输入必须是上一层的神经元个数def forward(self, x):  # 前向传播,你得告诉它,数据的流向.是神经网络层连接起来,函数名称不能改.当你调用forward函数的时候,传入进来的图像数据x = self.flatten(x)  # 图像进行展开x = self.hidden1(x)x = torch.relu(x)  # 激活函数,relu,tanh,sigmod  relu没有梯度消失问题,且计算消耗大大降低x = self.hidden2(x)x = torch.relu(x)x = self.hidden3(x)x = torch.relu(x)x = self.hidden4(x)x = torch.relu(x)x = self.out(x)return xmodel = NeuralNetwork().to(device)  # 把刚刚创建的模型传入到GPU
print(model)

输出:

  • 输出的就是神经网络的模型
  • 输入层--隐藏层1--隐藏层2--隐藏层3--隐藏层4--输出层
  • 每一层的输入神经元,输出神经元,偏置项
NeuralNetwork((flatten): Flatten(start_dim=1, end_dim=-1)(hidden1): Linear(in_features=784, out_features=512, bias=True)(hidden2): Linear(in_features=512, out_features=256, bias=True)(hidden3): Linear(in_features=256, out_features=128, bias=True)(hidden4): Linear(in_features=128, out_features=64, bias=True)(out): Linear(in_features=64, out_features=10, bias=True)
)

 

4.创建训练集模型

def train(dataloader, model, loss_fn, optimizer):model.train()  # 告诉模型,我要开始训练,模型中w进行随机化操作,已经更新w.在训练过程中,w会被修改的# pytorch提供2种方式来切换训练和测试的模式,分别是:model.train()和 model.eval().# 一般用法是: 在训练开始之前写上model.trian(),在测试时写上model.eval().batch_size_num = 1for x, y in dataloader:x, y = x.to(device), y.to(device)  # 把训练数据集和标签传入CPU或GPUpred = model.forward(x)  # 向前传播loss = loss_fn(pred, y)  # 通过交叉熵损失函数计算损失值lossoptimizer.zero_grad()  # 梯度值清零loss.backward()  # 反向传播计算得到每个参数的梯度值woptimizer.step()  # 根据梯度更新网络w参数loss_value = loss.item()  # 从tensor数据中提取数据出来,tensor获取损失值if batch_size_num % 200 == 0:print(f"loss:{loss_value:>7f} [number:{batch_size_num}]")batch_size_num += 1

 

5.创建测试集模型

def test(dataloader, model, loss_fn):size = len(dataloader.dataset)num_batches = len(dataloader)model.eval()  # 测试,w就不能再更新。test_loss, correct = 0, 0with torch.no_grad():  # 一个上下文管理器,关闭梯度计算。当你确认不会调用Tensor.backward()的时候。这可以减少计算所占用的消耗for x, y in dataloader:x, y = x.to(device), y.to(device)pred = model.forward(x)test_loss += loss_fn(pred, y).item()  # test loss是会自动累加每一个批次的损失值correct += (pred.argmax(1) == y).type(torch.float).sum().item()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}")

 

6.创建损失函数和优化器并训练

loss_fn = nn.CrossEntropyLoss()  # 处理多分类 损失函数
optimizer = torch.optim.Adam(model.parameters(), lr=0.0012)  #
# params:要训练的参数,一般我们传入的都是model.parameters()
# lr:leqrning rate学习率,也就是步长epochs = 4  # 到底选择多少呢?
for t in range(epochs):print(f"Epoch {t + 1}\n--------------")train(train_dataloader, model, loss_fn, optimizer)
print("Done!")
test(test_dataloader, model, loss_fn)

输出:

  • 可以看到每一轮之后模型损失值都在变小,说明模型在进行优化
Epoch 1
--------------
loss:0.459520 [number:200]
loss:0.307480 [number:400]
loss:0.213908 [number:600]
loss:0.196316 [number:800]
Epoch 2
--------------
loss:0.175202 [number:200]
loss:0.251854 [number:400]
loss:0.085344 [number:600]
loss:0.091463 [number:800]
Epoch 3
--------------
loss:0.050711 [number:200]
loss:0.184462 [number:400]
loss:0.043357 [number:600]
loss:0.056628 [number:800]
Epoch 4
--------------
loss:0.022849 [number:200]
loss:0.125797 [number:400]
loss:0.019434 [number:600]
loss:0.023895 [number:800]
Done!
Test result: Accuracy: 96.58%, Avg loss: 0.14490024165602944

http://www.ppmy.cn/devtools/117457.html

相关文章

tensorflow-dataset 内网下载 指定目录

内网下载报错 解决办法是设置环境变量,指向你的代理服务器TFDS_HTTP_PROXYhttp://xxx、TFDS_HTTPS_PROXYhttp://xxx。 留意到,赋值的是你的代理服务器,且最好协议都使用http(即使TFDS_HTTPS_PROXY也要使用http协议连服务器)。如果不这么做&a…

Elasticsearch快速入门

文章目录 Elasticsearch快速入门核心概念倒排索引基本使用索引操作创建索引类型映射[了解]数据类型[了解] 查看索引删除索引 文档操作添加文档修改文档删除文档查询文档准备数据主键查询精确查询匹配查询 Elasticsearch快速入门 核心概念 Elasticsearch是面向文档的&#xff…

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

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

CentOS下安装Kibana(保姆级教程)

前言 Kibana是一个开源的数据分析和可视化平台,通常与Elasticsearch一起使用,用于展示和分析大规模数据集。以下是关于Kibana的一些主要特点和功能: 数据可视化: Kibana允许用户将数据转化为交互式、实时的图形和可视化展示&…

STM32单通道ADC连续采集

0.91寸OLED屏幕大小的音频频谱,炫酷! RTT——一种代替串口打印的调试神器 经典振荡器电路及原理分析(超值文章) 超级简单的画PCB封装技巧,从此告别繁琐计算 前面介绍了关于ADC单通道单次采样软件触发的方式《STM32…

图像面积计算一般方法及MATLAB实现

一、引言 在数字图像处理中,经常需要获取感兴趣区域的面积属性,下面给出图像处理的一般步骤。 1.读入的彩色图像 2.将彩色图像转化为灰度图像 3.灰度图像转化为二值图像 4.区域标记 5.对每个区域的面积进行计算和显示 二、程序代码 %面积计算 cle…

获取 Jupyter Notebook IPython kernel 在电脑中的目录位置

获取 Jupyter Notebook IPython kernel 在电脑中的目录位置 正文 正文 在 VS code 的 terminal 中或者 Windows 的命令行中使用如下代码即可。 ipython locate运行后得到如下结果: 如图所示,我们获取到了 ipython 的位置。 如果大家觉得有用&#xf…

YOLOv5白皮书-第Y2周:训练自己的数据集(云jupyter运行版 )

>- **🍨 本文为[🔗365天深度学习训练营](小团体~第八波) 中的学习记录博客** >- **🍖 原作者:[K同学啊](K同学啊-CSDN博客)** 目录 前言 一、.xml文件里保存的是什么 二、准备好自己的数据 三、创建split_tr…