基于BP神经网络的手写数字识别-ANN报告
中 国 地 质 大 学
研究生课程论文封面
课程名称 人工神经网络
教师姓名 **
研究生姓名 **
研究生学号 1202221791
研究生专业 电子信息
所在院系 自动化学院
类别: 硕士
日期: 2021年 12 月1 日
目录
BP神经网络及手写数字识别简介 3
1.1 BP神经网络简介 3
1.2 数字识别简介 3
第二章 对神经网络的训练和优化 4
2.1 数据预处理 4
2.2 神经网络的训练 4
2.3 训练后的分析 5
2.4 改进优化神经网络 7
2.5 改进后神经网络的训练分析 7
2.5.1 隐含层单元数为10时的分析 8
2.5.2 隐含层单元数为15时的分析 9
2.5.3 隐含层单元数为20时的分析 11
2.5.4 隐含层单元数为25时的分析 12
2.5.5 综合分析 14
2.6 增加样本数后训练结果 14
第三章 总结分析 15
参考文献 16
附录 17
基于BP神经网络的手写数字识别
摘要:本文为基于BP神经网络的手写数字识别,介绍了BP神经网络的基本原理和手写数字识别的实现方法,提出了对手写数字图片数据以及目标数据的处理方法,利用Matlab中的神经网络工具箱对数据进行训练和测试,对于原本识别方法进行改进使得识别率增大,根据经验公式以及多次计算得到较优的隐含层单元数。
关键词:BP神经网络,数字识别,Matlab
BP神经网络及手写数字识别简介
1.1 BP神经网络简介
BP(Back Propagation)神经网络[1-3]是一种多层神经网络,其结构包括三层或三层,每层由多个神经元构成,左、右两层神经元均有完整的联系,左、右两层神经元之间没有任何联系,此网络被称作多层神经网络[4]。BP神经网络是按照有指导的学习方法来进行的,在网络中输入一对学习模式,神经元的激活值会从输入层通过各个隐藏层传递到输出层,每个神经元都会输出与输入模式相对应的网络响应 [5,6]。接着,按照减小期望输出和实际输出误差的原则,由输出层经过各个隐含层,再返回输入层(由右至左)对各个连接权进行逐级校正。由于该方法是从输出到输入的分层校正,故称之为“反差错扩散”[7,8]。通过对错误反向传播的不断改进,网络对输入方式的反应准确率也会越来越高
1.2 数字识别简介
本次对手写数字的识别主要使用Matlab中的神经网络工具箱,将手写数字图片转换为20×20个像素,作为400个输入,得到10个输出,每个数字用其中一个输出表示,再通过处理得到识别的数字。手写数字的数据从MNIST[9,10]得到,使用readMNIST函数读取其中的图片及标签数据,然后利用这些数据对神经网络进行训练和测试。
第二章 对神经网络的训练和优化
得到图片和标签数据后,需要对神经网络进行训练,对神经网络训练前需要将得到的数据进行预处理,训练之后再进行一些处理得到对应的数字,再针对不足进行优化处理。
2.1 数据预处理
从MNIST网站得到的数据为“.idx3-ubyte”格式的图片数据和“.idx1-ubyte”格式的标签数据,不能直接使用,需要将其转化为可用于计算的图片矩阵数据和标签向量数据,本次主要使用从MathWorks网站中找到的专门用于读取这两种格式的“readMNIST”函数,这里取出训练集中的3000个图像和标签数据并从测试集中取100组数据用于最后的测试。转换之后还需对图像矩阵进行处理,得到的图片数据为20×20×3000的三位矩阵,而标签数据为3000×1的矩阵,在训练的时候,给定的输入和输出应为二维矩阵,因此需要将图片数据转换为3000×400的二维矩阵形式,转换程序如下:
[imgs, labels] = readMNIST('train-images.idx3-ubyte', 'train-labels.idx1-ubyte', 3000, 0);
imgs2 = zeros(3000,400);
for i = 1:3000
for j = 1:20
for k = 1:20
imgs2(i,20*(j - 1) + k) = imgs(j,k,i);
end
end
end
2.2 神经网络的训练
将数据进行预处理后可以对神经网络进行训练,首先需要选择隐藏结点数量。以下 3 种途径可用于选择最佳隐含层单元数时的参考公式[1]
1)
,其中k为样本数,n1为隐含层单元数,n为输入单元数,i为[0,n]之间的常数。
2)
,其中n1为隐含层单元数,n为输入单元数,a为[0,n]之间的常数。
3)
,其中n1为隐含层单元数,n为输入单元数。
可以从这几种算法中算出的最小值和最大值之间进行多次训练,得到误差最小的隐含层单元数。[2]得到的n1的范围大概为10到30,选取10,15,20,25这几种隐含层数量对数据进行训练。
2.3 训练后的分析
首先将隐含层单元数选为10,样本数为3000,使用Levenberg-Marquardt方法进行训练,得到的误差及相关度如下:

图2.1 隐含层单元数为10时的误差直方图

图2.2 隐含层单元数为10时相关度拟合图
如图2.1所示,误差大于0.5的数据占很大一部分,而误差大于0.5就会影响最终对数字的识别,因此识别率非常低。

图2.3 手写数字5图片

图2.4 对数字5识别的代码
如图2.3为需要识别的图片,图2.4为执行数字识别的代码,最后的结果为1.8928,如果将该结果四舍五入的结果作为最终识别的数字,误差较大,因此需要对该网络进行改进。
2.4 改进优化神经网络
在2.3节中使用的方法误差较大,识别率非常低,因此需要用其他的方式进行改善。考虑到识别的数字是离散的,而上述方法得到的是离散的输出,因此考虑将输出的数量改为10,对应0到9,将标签中的数字改为一个包含10个元素的向量,例如数字为5,则第6个向量的值设为1,其他的设为0,通过这种方式进行训练,在识别时取输出向量中的最大值,对应的下标减1就是识别到的数字。

图2.5 改进后识别数字5的程序
如图2.5为对图2.3中数字的识别,得到的一组数据类似于相似度,相似度越高为该数字的可能性最大,如图2.5,该数字为5的可能性最大,其次可能是3,最后识别为5,结果准确。
2.5 改进后神经网络的训练分析
对于改进后的神经网络,测试不同隐含层单元数时的识别正确率,从而得到相对较优的隐含层单元数。测试方式为从MNIST中的测试数据中取100个数字图像和对应的标签,测试经过神经网络后得到的数字于目标数字是否一致,最后得到识别正确率。识别函数如下:
function [y] = accuracy(x,labels)
sum = size(labels);
right_num = 0;
for i = 1:sum
[Y] = net3_20(x(i,:));
n = get_num(Y);
if n == labels(i)
right_num = right_num + 1;
end
end
y = right_num;
end
2.5.1 隐含层单元数为10时的分析
隐含层单元数为10时,训练后的误差及相关度如图2.6和图2.7

图2.6 隐含层单元数为10时的误差直方图

图2.7 隐含层单元数为10时的相关度曲线
隐含层数量为10时,最后测得的识别正确率为81%。
2.5.2 隐含层单元数为15时的分析
隐含层单元数为15时,训练后的误差及相关度如图2.8和图2.9

图2.8 隐含层单元数为15时的误差直方图

图2.9 隐含层单元数为15时的相关度曲线
隐含层数量为15时,最后测得的识别正确率为87%。
2.5.3 隐含层单元数为20时的分析
隐含层单元数为20时,训练后的误差及相关度如图2.10和图2.11

图2.10 隐含层单元数为20时的误差直方图

图2.11 隐含层单元数为20时的相关度曲线
隐含层数量为20时,最后测得的识别正确率为89%。
2.5.4 隐含层单元数为25时的分析
隐含层单元数为25时,训练后的误差及相关度如图2.12和图2.13

图2.12 隐含层单元数为25时的误差直方图

图2.13 隐含层单元数为25时的相关度曲线
隐含层数量为25时,最后测得的识别正确率为79%。
2.5.5 综合分析
对几种隐含层单元数训练后的结果进行分析,发现隐含层数量为15到20时训练后识别率较高,且误差较低,相关度较高,因此隐含层单元数可以大致选在这个范围内。
2.6 增加样本数后训练结果
选取隐含层单元数为20,将样本数由3000增加至10000时,理论上会提高最后的识别率,如图2.14和图2.15为隐含层数量为20,样本数为10000时的误差直方图和相关度曲线。

图2.14 样本数增加为10000后误差直方图

图2.15 样本数增加为10000后相关度曲线
如图2.14和图2.15,当样本数增大后,误差会减少,相关度增大,最后测得正确率为93%,相对于样本数为3000时也有所增大。
第三章 总结分析
使用BP神经网络解决某些实际问题,首先要将问题数字化,如在本次对数字的识别中,首先要将图片数字化,即将每张图片变为二维矩阵,然后将矩阵变为一维向量,作为神经网络的输入,然后根据输入以及样本数选择隐含层单元数,对于输出有时也需要进行一定的变量,比如分类,输出为离散数据,使用单输出效果较差,在对数字的识别中就是对数字的分类,使用多输出效果会远远好于单输出。
通过本次课程,我对BP神经网络的原理以及图像识别有了初步的认识,能够自己查找资料实现一些简单的BP神经网络的运用,并且能对于结果的不足之处提出一些解决方法,这对我之后的学习工作也有很大的帮助,我也会在之后的学习中深入对这些知识的理解和运用,最后感谢老师在本次课程中对我们的帮助。
参考文献
[1]Hecht-Nielsen R. Theory of the backpropagation neural network[M]//Neural networks for perception. Academic Press, 1992: 65-93.
[2]Wright L G, Onodera T, Stein M M, et al. Deep physical neural networks trained with backpropagation[J]. Nature, 2022, 601(7894): 549-555.
[3]Alkronz E S, Moghayer K A, Meimeh M, et al. Prediction of whether mushroom is edible or poisonous using back-propagation neural network[J]. 2019.
[4]Shanmuganathan S. Artificial neural network modelling: An introduction[M]//Artificial neural network modelling. Springer, Cham, 2016: 1-14.
[5]Csáji B C. Approximation with artificial neural networks[J]. Faculty of Sciences, Etvs Lornd University, Hungary, 2001, 24(48): 7.
[6]Cui Y, Liu H, Wang Q, et al. Investigation on the ignition delay prediction model of multi-component surrogates based on back propagation (BP) neural network[J]. Combustion and Flame, 2022, 237: 111852.
[7]Jin Y, Zhang W, Li P. Hybrid macro/micro level backpropagation for training deep spiking neural networks[J]. Advances in neural information processing systems, 2018, 31.
[8]Vlachas P R, Pathak J, Hunt B R, et al. Backpropagation algorithms and reservoir computing in recurrent neural networks for the forecasting of complex spatiotemporal dynamics[J]. Neural Networks, 2020, 126: 191-217.
[9]Schott L, Rauber J, Bethge M, et al. Towards the first adversarially robust neural network model on MNIST[J]. arXiv preprint arXiv:1805.09190, 2018.
[10]Tabik S, Peralta D, Herrera-Poyatos A, et al. A snapshot of image pre-processing for convolutional neural networks: case study of MNIST[J]. 2017.
附录
[imgs, labels] = readMNIST('train-images.idx3-ubyte', 'train-labels.idx1-ubyte', 3000, 0);
imgs2 = zeros(3000,400);
for i = 1:3000
for j = 1:20
for k = 1:20
imgs2(i,20*(j - 1) + k) = imgs(j,k,i);
end
end
end
%%
m=1;
imshow(imgs(:,:,m))
[Y] = net2_20(imgs2(m,:))
get_num(Y)
%%
imshow(imgs(:,:,5))
%%
function [y] = accuracy(x,labels)
sum = size(labels);
right_num = 0;
for i = 1:sum
[Y] = net3_20(x(i,:));
n = get_num(Y);
if n == labels(i)
right_num = right_num + 1;
end
end
y = right_num;
end
function [y] = get_num(x)
max_num = 1;
max = 0;
for i = 1:10
if x(i) > max
max_num = i;
max = x(i);
end
end
y = max_num - 1;
end
function [y] = accuracy(x,labels)
sum = size(labels);
right_num = 0;
for i = 1:sum
[Y] = net2_25(x(i,:));
n = get_num(Y);
if n == labels(i)
right_num = right_num + 1;
end
end
y = right_num;
end
% readMNIST by Siddharth Hegde
%
% Description:
% Read digits and labels from raw MNIST data files
% File format as specified on http://yann.lecun.com/exdb/mnist/
% Note: The 4 pixel padding around the digits will be remove
% Pixel values will be normalised to the [0...1] range
%
% Usage:
% [imgs labels] = readMNIST(imgFile, labelFile, readDigits, offset)
%
% Parameters:
% imgFile = name of the image file
% labelFile = name of the label file
% readDigits = number of digits to be read
% offset = skips the first offset number of digits before reading starts
%
% Returns:
% imgs = 20 x 20 x readDigits sized matrix of digits
% labels = readDigits x 1 matrix containing labels for each digit
%
function [imgs, labels] = readMNIST(imgFile, labelFile, readDigits, offset)
% Read digits
fid = fopen(imgFile, 'r', 'b');
header = fread(fid, 1, 'int32');
if header ~= 2051
error('Invalid image file header');
end
count = fread(fid, 1, 'int32');
if count < readDigits+offset
error('Trying to read too many digits');
end
h = fread(fid, 1, 'int32');
w = fread(fid, 1, 'int32');
if offset > 0
fseek(fid, w*h*offset, 'cof');
end
imgs = zeros([h w readDigits]);
for i=1:readDigits
for y=1:h
imgs(y,:,i) = fread(fid, w, 'uint8');
end
end
fclose(fid);
% Read digit labels
fid = fopen(labelFile, 'r', 'b');
header = fread(fid, 1, 'int32');
if header ~= 2049
error('Invalid label file header');
end
count = fread(fid, 1, 'int32');
if count < readDigits+offset
error('Trying to read too many digits');
end
if offset > 0
fseek(fid, offset, 'cof');
end
labels = fread(fid, readDigits, 'uint8');
fclose(fid);
% Calc avg digit and count
imgs = trimDigits(imgs, 4);
imgs = normalizePixValue(imgs);
%[avg num stddev] = getDigitStats(imgs, labels);
end
function digits = trimDigits(digitsIn, border)
dSize = size(digitsIn);
digits = zeros([dSize(1)-(border*2) dSize(2)-(border*2) dSize(3)]);
for i=1:dSize(3)
digits(:,:,i) = digitsIn(border+1:dSize(1)-border, border+1:dSize(2)-border, i);
end
end
function digits = normalizePixValue(digits)
digits = double(digits);
for i=1:size(digits, 3)
digits(:,:,i) = digits(:,:,i)./255.0;
end
end
%
% [imgs, labels] = readMNIST('train-images.idx3-ubyte', 'train-labels.idx1-ubyte', 10000, 0);
%
% imgs2 = zeros(10000,400);
% for i = 1:10000
% for j = 1:20
% for k = 1:20
% imgs2(i,20*(j - 1) + k) = imgs(j,k,i);
% end
% end
% end
%
%
% labels2 = zeros(10000,10);
% for i = 1:10000
% for j = 1:10
% if labels(i) == j - 1
% labels2(i,j) = 1;
% else
% labels2(i,j) = 0;
% end
% end
% end
% [imgs_test, labels_test] = readMNIST('t10k-images.idx3-ubyte', 't10k-labels.idx1-ubyte', 100, 0);
% imgs_test2 = zeros(100,400);
% for i = 1:100
% for j = 1:20
% for k = 1:20
% imgs_test2(i,20*(j - 1) + k) = imgs_test(j,k,i);
% end
% end
% end
心得体会:
本次人工神经网络课程的学习让我学到了不少实用性的知识。并且也可以和我的研究方向相结合,也给了我一定在未来科研道路上的启发和思考。
我的研究课题主要是针对事件触发控制来展开一系列的研究,那么神经网络是否可以和事件触发控制结合在一起呢,在我之前查阅的一些文献中,也有不少学者研究了基于事件触发控制下的神经网络系统。因此,在我的科研方向中,我会在考虑网络攻击(通常是DoS攻击)和事件触发控制下的神经网络系统,设计相应的控制器,推导出使系统稳定的充分条件,使系统稳定。同时,也可以考虑基于事件触发控制下的自适应神经网络控制以及基于神经网络的离散系统事件触发控制的故障检测研究等,都是我可以研究的方向和学习的方向,并且应用到实际中。感谢对我们的科研道路上的启发和激励,我认为在今后的学习中需要更多的创新和思考,并且和自己的研究方向结合起来,才是做到了真正的运用。
评 语
对课程论文的评语: 本文为基于BP神经网络的手写数字识别,介绍了BP神经网络的基本原理和手写数字识别的实现方法,提出了对手写数字图片数据以及目标数据的处理方法。 利用Matlab中的神经网络工具箱对数据进行训练和测试,对于原本识别方法进行改进使得识别率增大,根据经验公式以及多次计算得到较优的隐含层单元数。 课程论文完成度较高,代码能实现相应的功能,对课程也有所启发! |
平时成绩: | 课程论文成绩: |
总 成 绩: | 评阅人签名: |
注:1、无评阅人签名成绩无效;
2、必须用钢笔或圆珠笔批阅,用铅笔阅卷无效;
3、如有平时成绩,必须在上面评分表中标出,并计算入总成绩。
版权声明:
1.大文斗范文网的资料来自互联网以及用户的投稿,用于非商业性学习目的免费阅览。
2.《基于BP神经网络的手写数字识别-ANN报告》一文的著作权归原作者所有,仅供学习参考,转载或引用时请保留版权信息。
3.如果本网所转载内容不慎侵犯了您的权益,请联系我们,我们将会及时删除。
