龙空技术网

基于pytorch实现全连接神经网络模型进行手写数字识别项目实战

龙涎 49

前言:

此时咱们对“神经网络训练结果图怎么看的”大致比较关注,看官们都需要学习一些“神经网络训练结果图怎么看的”的相关文章。那么小编也在网络上搜集了一些对于“神经网络训练结果图怎么看的””的相关知识,希望各位老铁们能喜欢,大家一起来学习一下吧!

预设条件

中级IDE使用经验(Jetbrain Pycharm优先)了解Python运行环境及其命令使用对Python编程语言有很好的理解基本了解Pandas(处理数据框架)、Numpy、Scikit Learn和Matplot库一些统计学知识,对分析数据是有帮助的

运行环境

以下运行软件的版本号是经过验证的可成功运行的版本号,以供参考。

编号

软件名称

版本号

1

Python

3.9.19

2

conda

22.9.0

3

pip

23.3.1

4

numpy

1.26.4

5

pandas

2.2.1

6

matplotlib

3.8.4

7

scikit-learn

1.4.2

8

scipy

1.13.0

9

seaborn

0.13.2

10

statsmodels

0.14.2

11

torch

2.4.1

12

torchaudio

2.4.1

13

torchvision

0.19.1

项目背景

全连接层(Fully Connected Layer),也被称为密集层(Dense Layer)或线性层(Linear Layer),是神经网络中最基本也是最重要的层之一。它在各种神经网络模型中扮演着关键角色,广泛应用于图像分类、文本处理、回归分析等各类任务。

本文在基于全连接神经网络模型的基础上,实现MNIST手写数字识别的项目,通过学习这个项目来深入理解全连接神经网络的知识,以为后续神经网络的学习打好基础。

全连接神经网络

基本概念

在全连接层中,每一个输入节点与输出节点之间都存在连接。假设有一个输入向量 和一个输出向量 ,全连接层的计算过程可以表示为:

其中:

W 是权重矩阵,包含了所有连接的权重。b 是偏置向量,通常用于调整输出的线性变换。

权重矩阵 W

权重矩阵 W 的维度为,其中是输入特征的数量,是输出特征的数量。每个元素 表示输入特征 对输出特征 的影响程度。在训练过程中,权重矩阵 是通过反向传播算法进行更新的,目标是最小化损失函数,使得模型的预测结果尽可能接近真实值。

偏置向量 b

偏置向量 的维度为 。每个元素 用于调整输出特征 的线性变换,确保模型具有更好的拟合能力。偏置项的引入可以帮助模型更好地适应数据的分布,尤其是在输入特征为零时,偏置项可以提供非零的输出。

全连接层通过线性变换和非线性激活函数,对输入特征进行变换和抽象,提取更高层次、更有代表性的特征。

示例

以下是一个简单的示例,展示了如何在PyTorch中使用 nn.Linear 来创建和使用全连接层。

输出结果:

结果解析:

权重矩阵 W

初始化的结果是:tensor([[-0.2548, 0.1562, 0.2072, -0.0799],

[ 0.1870, -0.0911, 0.4415, -0.1840]], requires_grad=True)

权重矩阵 W 的形状是 2 × 4 ,表示有两个输出特征(每个输出特征对应一行),四个输入特征(每个输入特征对应一列)。

偏置向量

初始化的结果是:tensor([-0.3627, 0.4926], requires_grad=True)

偏置向量 的形状是 2 × 1,表示每个输出特征有一个偏置。

输入向量

初始化结果如下:tensor([[-0.0169, 1.0620, 0.1655, -0.5485]])

输入向量 的形状是 1 × 4,表示一个样本(批大小为1),包含四个特征。

输出向量

初始化结果如下:tensor([[-0.1144, 0.5667]], grad_fn=<AddmmBackward0>)

输出向量 的形状是 1 × 2,表示一个样本(批大小为1),包含两个输出特征。

计算过程解析

全连接层的计算过程可以表示为:

让我们逐步计算:

矩阵乘法 Wx

首先将权重矩阵 W 与输入向量 x 相乘。

计算:

计算结果:

加上偏置向量

加上偏置项:

这与输出向量 的结果完全一致:

tensor([[-0.1144, 0.5667]], grad_fn=<AddmmBackward0>)

ReLU激活函数

基本概念

ReLU是一种常用的激活函数,全称为修正线性单元(Rectified Linear Unit)。它的主要作用是将输入值限制在一个非负的范围内,即当输入值小于0时,输出值为0;当输入值大于等于0时,输出值等于输入值本身。

ReLU函数的表达式为:f(x) = max(0, x)。

ReLU函数的优点是计算简单,梯度不会消失,适用于处理非线性问题。同时,ReLU函数的导数也很容易计算,这使得它在深度学习中得到了广泛的应用。

使用样例

下面是关于ReLU激活函数的一个简单的使用样例,读懂这段样例可有助于理解ReLU函数。

执行结果

代码分析

首先定义一个10 x 5 的全连接层:linear_layer = nn.Linear(10, 5)然后创建一个输入张量:input_tensor = torch.randn(1, 10)通过全连接层将输入张量计算得到输出张量:output_tensor = linear_layer(input_tensor)最后对输出张量应用ReLU激活函数:relu_output_tensor = torch.relu(output_tensor)

数据获取

MNIST数据集简介

MNIST数据集来自美国国家标准与技术研究所(National Institute of Standards and Technology, NIST)。MNIST训练集(Training Set)由来自250个不同人手写的数字构成,其中50%是高中学生,50%来自人口普查局(the Census Bureau)的工作人员。MNIST测试集(Test Set)也是同样比例的手写数字数据,但保证了测试集和训练集的作者集不相交。

MNIST数据集一共有7万张图片,其中6万张是训练集,1万张是测试集。每张图片是28 × 28的0 − 9的手写数字图片组成。每个图片是黑底白字的形式,黑底用0表示,白字用0-1之间的浮点数表示,越接近1,颜色越白。

如下图所示:

图像映射成向量

我们之前学习的案例中,输入x都是一个向量,在MNIST数据集中,我们需要输入的是一个图像,怎么才能输入到模型中进行训练呢?一种方法是我们可以把图像映射成一个向量,再输入到模型中进行训练。

如图所示是MNIST数据集中一个方格的图像,它是由28 x 28 = 784个像素组成,其中越深的地方数值越接近0,越亮的地方数值越接近1。

因此可以将此图像按照对应的像素和数值映射成一个28 x 28的一个矩阵,如下图所示:

将28 × 28维的图片矩阵拉直,转化为1 × 784维的向量:

[ 0 , 0 , 0 , 0.345 , 0.728 , 0.310 , 0.402 , 0 , 0 , 0 , ⋯   , 0 , 0 , 0 ]

图片的标签以一维数组的one-hot编码形式给出:

[ 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 ]

每个元素表示图片对应的数字出现的概率,显然该向量标签表示的是数字5。

MNIST数据集下载地址是,它包含了4 个部分:

训练数据集:train-images-idx3-ubyte.gz (9.45 MB,包含60,000个样本)。训练数据集标签:train-labels-idx1-ubyte.gz(28.2 KB,包含60,000个标签)。测试数据集:t10k-images-idx3-ubyte.gz(1.57 MB ,包含10,000个样本)。测试数据集标签:t10k-labels-idx1-ubyte.gz(4.43 KB,包含10,000个样本的标签)。

数据预处理

查看数据

使用pytorch工具的DataLoader ()方法可以加载数据,数据加载成功后可以查看具体数据,也可以可视化后查看。

关键代码:

代码执行结果:

上图显示出测试集样本标签的具体数据。

上图显示了测试集样本特征数据的形态,即1000条样例,每个样例为28 x 28像素的灰度值(即没有RGB通道)。

除了查看具体数据之外,还可以更直观的观察数据,通过以下代码实现数据的可视化。

关键代码:

代码执行结果:

简单全连接伸进网络模型

很多介绍利用全连接神经网络来训练MNIST数据集的文章多数是以实现为主,本文则通过一个一个实验笔记,来一步一步递进模型优化的过程,以及记录在训练过程中的疑惑与思考。

构建模型

本章首先构建一个简单的三层全连接神经网络模型,关键代码:

从代码中可以看到,所构建的三层全连接神经网络需要3个参数的传递,其中,输入的维度(in_dim),第一层网络的神经元个数(n_hidden_1),第二层网络神经元的个数(n_hidden_2),第三层网络(输出层)神经元个数。

前向传播forward的网络定义是未设定激活函数,数据仅仅是从输入层,流经第一层、第二层,最后通过输出层输出。这里仅仅是实现了一个线性处理。

训练模型

接下来我们针对这个简单的神经网络进行训练模型及测试,关键代码:

输出结果如下:

从结果分析来看,简单的三层全连接神经网络因为没有设置激活函数,从网络的输入层到输出层完全是线性的输出,数据未能进行变换,导致训练损失率非常大,维持在0.27,其训练精度也不高,未能超过92%。由此可知,未添加激活函数的全连接神经网络损失率较大精度不高,并不是最优的模型。

在简单三层全连接神经网络基础上添加激活函数,关键代码如下:

继续使用上文的模型训练代码,只需要修改一句关键代码,如下所示:

执行代码,输出结果如下:

可以看到,训练损失率下降了不少,降低到0.1,其训练精度也提高了不少,达到了96%。其实第一轮训练时,准确率也是很低的,但是随着第五轮训练时,准确率便已经超越了之前的简单网络模型,模型的优化速度很快。由此可知,同样的全连接模型在添加了激活函数之后,数据进行了非线性变换,可以有效的提高精度降低损失率,远超未使用激活函数的模型。

继续对上面模型进行优化,添加批处理化,关键代码:

执行结果如下:

对比上面添加激活函数的模型数据来看,准确率真是大大的提高了,已经超过98%了,而且损失率也下降很多,低于0.1,到达0.06了,可见加入批处理化后的模型性能提高不少。

预测数据

模型训练好之后,可以用来进行预测。首先我们先对单张图片进行显示,这个显示出来的图片就用来进行预测。

单张图片显示关键代码:

执行显示结果:

以下是预测代码:

预测出来的结果如下:

结果的第一行是待测试的数字标签,第二行是预测出来的数字,同时也会有数字图片的可视化界面显示出来,根据第一行和第二行的对比,可以看到预测的结果非常精准,全部预测正确。

扩展研究

加入激活函数和批处理化能力的全连接神经网络模型预测的性能非常好,能够满足我们的需求,举一反三一下,如果使用精确度不高的简单全连接神经网络模型,是否会出现很多预测错误的情况呢?下面我们着手实验一下。

修改代码,开启简单全连接网络模型,然后执行程序观察执行结果。

执行结果如下:

可视化的数字图片可供对比:

从结果可以看到,的确出现了5处预测错误的情况,这5处错误的地方,数字的写法的确很容易造成误判,但这么多的误判也是因为模型训练出来的精确度不高导致的误判,所以说如果模型未添加激活函数或者激活函数选择不对,导致的神经网络模型预测精度是不高的,这一点在以后的项目实施中一定要加以注意。

结论

本文主要介绍了通过使用全连接神经网络模型进行建模和预测的实战项目案例,希望能够帮助你学习和理解全连接神经网络的核心内容。如果你还想学习更多人工智能/机器学习/深度学习相关的知识,请继续阅读我编写的其他内容的文章。

本文涉及到的机器学习实战项目文件(附带数据+代码+文档)名称如下:

fcnn_mnist.py

机器学习项目实战10-基于pytorch实现全连接神经网络模型进行手写数字识别项目实战.pdf

标签: #神经网络训练结果图怎么看的