基于深度学习的手写数字识别Matlab实现

  • 1.网络设计
  • 2. 训练方法
  • 3.实验结果
  • 4.实验结果分析
  • 5.结论

1.网络设计

1.1 CNN(特征提取网络+分类网络)
随着深度学习的迅猛发展,其应用也越来越广泛,特别是在视觉识别、语音识别和自然语言处理等很多领域都表现出色。卷积神经网络(Convolutional Neural Network,CNN)作为深度学习中应用最广泛的网络模型之一,也得到了越来越多的关注和研究。事实上,CNN作为一项经典的机器学习算法,早在20世纪80年代就已被提出并展开一定的研究。但是,在当时硬件运算能力有限、缺乏有效训练数据等因素的影响下,人们难以训练不产生过拟合情形下的高性能深度卷积神经网络模型。所以,当时CNN的一个经典应用场景就是用于识别银行支票上的手写数字,并且已实际应用。伴随着计算机硬件和大数据技术的不断进步,人们也尝试开发不同的方法来解决深度CNN训练中所遇到的困难,特别是Kizhesky 等专家提出了一种经典的CNN架构,论证了深度结构在特征提取问题上的潜力,并在图像识别任务上取得了重大突破,热起了深度结构研究的浪潮。而卷积神经网络作为一种已经存在的、有一定应用案例的深度结构,也重新回到人们的视野中,得以进一步研究和应用。
而本次实验就是基于CNN实现的。
1.1.1基本架构
卷积神经网络基本架构包括特征抽取器和分类器。特征抽取器通常由若干个卷积层和池化层叠加构成,卷积和池化过程不断将特征图缩小,同时会导致特征图数量的增多。特征抽取器后面一般连接分类器,通常由一个多层感知机构成。特别地,在最后一个特征抽取器后面,将所有的特征图展开并排列成一个向量得到特征向量,并作为后层分类器的输入。
1.1.2卷积层
卷积运算的基本操作是将卷积核与图像的对应区域进行卷积得到一个值,通过在图像上不断移动卷积核和来计算卷积值,进而完成对整幅图像的卷积运算。在卷积神经网络中,卷积层不仅涉及一般的图像卷积,还涉及深度和步长的概念。深度对应于同一个区域的神经元个数,即有几个卷积核对同一块区域进行卷积运算;步长对应于卷积核移动多少个像素,即前后距离的远近程度。
本次实验卷积层采用的是20个99的滤波器进行滤波,激活函数为ReLU函数。
1.1.2.1局部感知
人对外界的认知一般可以归纳为从局部到全局的过程,而图像的像素空间联系也是局部间的相关性强,远距离的相关性弱。因此,卷积神经网络的每个神经元实际上只需关注图像局部的感知,对图像全局的感知可通过更高层综合局部信息来获得,这也说明了卷积神经网络部分连通的思想。类似于生物学中的视觉系统结构,视觉皮层的神经元用于局部接收信息,即这些神经元只响应某些特定区域的刺激,呈现出部分连通的特点。
1.1.2.2参数共享
局部感知过程假设每个神经元都对应100个参数,共106个神经元,则参数共有100×106个,依然是一个很大的数字。如果这106个神经元的100个参数相等,那么参数个数就减少为100,即每个神经元用同样的卷积核执行卷积操作,这将大大降低运算量。因不论隐层的神经元个数有多少,两层间的连接只要100个参数,这也说明了参数共享的意义。
1.1.2.3多核卷积
如果10×10维数的卷积核都相同,那么只能提取图像的一种特征,局限性很明显。可以考虑通过增加卷积核来提高特征类别,例如选择16个不同的卷积核用于学习16种特征。其中,应用卷积核到图像执行卷积操作,可得到图像的不同特征,统称为特征图(Feature Map),所以16个不同的卷积核就有16个特征图,可以视作图像的不同通道。此时,卷积层包含10×10×16=1600个参数。
1.1.3池化层
从理论上来看,经卷积层得到特征集合,可直接用于训练分类器(例如经典的Softmax分类器),但这往往会带来巨大计算量的问题。通过计算图像局部区域上的某特定特征的平均值或最大值等来计算概要统计特征。这些概要统计特征相对于经卷积层计算得到的特征图,不仅达到了降维目的,同时还会提高调练效率,这种特征聚合的操作叫作池化(Pooling),本次实验采用的是2
2的平均池化。
1.1.4 特征提取网络
使用reshape函数将特征提取网络的矩阵转换为2000*1的列向量,然后是两个隐层节点,这两个隐层节点含分别都含有95个神经元,中间采用的都是ReLU激活函数。最后是10个输出节点,实现单热编码输出,使用的是Softmax激活函数。

2. 训练方法

Delata规则+BP算法+交叉熵代价函数+SGD(随机梯度下降算法)+动量算法
2.1程序实现
使用到的 MNIST包自行下载后,需要用到的函数
accuracy

function y = accuracy(W1,W2,W3,W4,X_Test,D_Test,epoch)
N=length(D_Test);
d_comp=zeros(1,N);
for  k=1:NX=X_Test(:,:,k);V1=Conv(X,W1);%自定义函数(不旋转,直接滤波)Y1=ReLU(V1);Y2=Pool(Y1);%自定义函数,2×2平均池化操作y1=reshape(Y2,[],1);v2=W2*y1;y2=ReLU(v2);v3=W3*y2;y3=ReLU(v3);v=W4*y3;y=Softmax(v);[~,i]=max(y);%找到y向量中的最大元素,i为其位置索引d_comp(k)=i;%保存CNN的计算值(识别出的数字)
end
[~,d_true]=max(D_Test);%将单热编码变回相应数字,存入d true(1xN维向量)
acc=sum(d_comp==d_true);%统计正确识别的总数
fprintf('第%d轮:',epoch);
fprintf('Accuracy is %f\n',acc/N);%输出正确率
end

Conv

    function y = Conv(x, W)%     对一幅图片的卷积%%     [wrow, wcol, numFilters] = size(W);%     [xrow, xcol, ~] = size(x);%     y = zeros(xrow - wrow + 1, xcol - wcol + 1, numFilters);%     for k = 1:numFilters%         y(:, :, k) = conv2(x, rot90(W(:, :, k),2), 'valid');%     end[xrow, xcol, xcha] = size(x);[wrow, wcol, wpage, numFilters] = size(W);if xcha>1&&(xcha==wpage)y = zeros(xrow - wrow + 1, xcol - wcol + 1, numFilters);W = W(:,:,end:-1:1,:);for i = 1:numFiltersfor j = 1:wpageW(:,:,j,i) = rot90(W(:,:,j,i),2);endy(:, :, i) = convn(x, W(:,:,:,i), 'valid');endelsey = zeros(xrow - wrow + 1, xcol - wcol + 1, wpage);for k = 1:wpagey(:, :, k) = conv2(x, rot90(W(:, :, k),2), 'valid');endendend

Dropout

function ym = Dropout(y, ratio)[m, n] = size(y);  ym     = zeros(m, n);num     = round(m*n*(1-ratio));idx     = randperm(m*n, num);ym(idx) = m*n / num;
end

Pool

function y = Pool(x)
%
% 2x2 mean pooling
%
%
y=(x(1:2:end,1:2:end,:)+x(2:2:end,1:2:end,:)+x(1:2:end,2:2:end,:)+x(2:2:end,2:2:end,:))/4;
end

ReLU

function y = ReLU(x)y = max(0, x);
endSoftmax
function y = Softmax(x)ex = exp(x);y  = ex / sum(ex);
end

test

clc;clear all; close all;
tic;
load MNISTData
%初始化权值
alpha=0.01;
beta =0.01;
epoch=20;
W1=randn(9,9,20);
W2=(2*rand(95,2000)-1)/20 ;
W3=(2*rand(45,95)-1)/10;
W4=(2*rand(10,45)-1)/5;
mmt1 = zeros(size(W1));
mmt2 = zeros(size(W2));
mmt3 = zeros(size(W3));
mmt4 = zeros(size(W4));
for G=1:epoch[xrow, xcol, xcha] = size(X_Train);
for    I= 1:xcha%%卷积池化层V1= Conv(X_Train(:,:,I),W1);Y1=ReLU(V1);Y2=Pool(Y1);%%分类层y1=reshape(Y2,[],1);v2=W2*y1;y2=ReLU(v2);y2 = y2 .* Dropout(y2, 0.01);v3=W3*y2;y3=ReLU(v3);y3 = y3 .* Dropout(y3, 0.01);v=W4*y3;    y=Softmax(v);e=D_Train(:,I)-y;%%误差前向传播delta=e;%交叉熵+softmaxe3=W4'*delta;delta3=(v3>0).*e3;e2=W3'*delta3;delta2=(v2>0).*e2;e1=W2'*delta2;E2=reshape(e1,size(Y2));E1=zeros(size(Y1));E2_4=E2/4;E1(1:2:end,1:2:end,:)=E2_4;E1(1:2:end,2:2:end,:)=E2_4;E1(2:2:end,1:2:end,:)=E2_4;E1(2:2:end,2:2:end,:)=E2_4;delta1=(V1>0).*E1;%%更新权值[a,b,c]=size(W1);for t=1:cdW1(:,:,t)=alpha* conv2(X_Train(:,:,I),rot90(delta1(:,:,t),2),'valid');mmt1(:,:,t)= dW1 (:,:,t)+ beta*mmt1(:,:,t);W1(:,:,t)=W1(:,:,t)+mmt1(:,:,t);%         W1(:,:,t)=W1(:,:,t)+dW1(:,:,t);enddW4=alpha*delta*y3';mmt4 = dW4 + beta*mmt4;W4   = W4 + mmt4;%        W4   = W4 +dW4;dW3=alpha*delta3*y2';mmt3 = dW3 + beta*mmt3;W3   = W3 + mmt3;%        W3   = W3 +dW3;dW2=alpha*delta2*y1';mmt2 = dW2 + beta*mmt2;W2   = W2 + mmt2;%        W2   = W2 +dW2;
endtoc
%%统计正确率的代码:acc=accuracy(W1,W2,W3,W4,X_Test,D_Test,G);
end

2.2代码解释
2.2.1加载数据

clc; clear all; close all;
tic;
load MNISTData

2.2.2根据网络结构初始化学习速率,权值,循环次数等

alpha=0.01;
beta =0.01;
epoch=2
W1=randn(9,9,20);
W2=(2*rand(95,2000)-1)/20;
W3=(2*rand(45,95)-1)/10;
W4=(2*rand(10,45)-1)/5;mmt2 = zeros(size(W2));mmt3 = zeros(size(W3)); mmt4 = zeros(size(W4));
for G=1:epoch

2.2.3训练CNN网络

[xrow, xcol, xcha] = size(X_Train);
for    I= 1:xcha%%卷积池化层V1= Conv(X_Train(:,:,I),W1);Y1=ReLU(V1);Y2=Pool(Y1);%%分类层 + dropouty1=reshape(Y2,[],1);v2=W2*y1;y2=ReLU(v2);y2 = y2 .* Dropout(y2, 0.01);v3=W3*y2;y3=ReLU(v3);y3 = y3 .* Dropout(y3, 0.01);v=W4*y3;    y=Softmax(v);e=D_Train(:,I)-y;

BP算法+Delta规则+交叉熵代价函数
%误差前向传播(交叉熵+softmax)

 delta=e;e3=W4'*delta;delta3=(v3>0).*e3;e2=W3'*delta3;delta2=(v2>0).*e2;e1=W2'*delta2;E2=reshape(e1,size(Y2));E1=zeros(size(Y1));E2_4=E2/4;E1(1:2:end,1:2:end,:)=E2_4;E1(1:2:end,2:2:end,:)=E2_4;E1(2:2:end,1:2:end,:)=E2_4;E1(2:2:end,2:2:end,:)=E2_4;delta1=(V1>0).*E1;

2.2.5 动量算法+SGD更新权值

            [a,b,c]=size(W1);for t=1:cdW1(:,:,t)=alpha* conv2(X_Train(:,:,I),rot90(delta1(:,:,t),2),'valid');mmt1(:,:,t)= dW1 (:,:,t)+ beta*mmt1(:,:,t);W1(:,:,t)=W1(:,:,t)+mmt1(:,:,t);%         W1(:,:,t)=W1(:,:,t)+dW1(:,:,t);enddW4=alpha*delta*y3';mmt4 = dW4 + beta*mmt4;W4   = W4 + mmt4;%        W4   = W4 +dW4;dW3=alpha*delta3*y2';mmt3 = dW3 + beta*mmt3;W3   = W3 + mmt3;%        W3   = W3 +dW3;dW2=alpha*delta2*y1';mmt2 = dW2 + beta*mmt2;W2   = W2 + mmt2;%        W2   = W2 +dW2;
endtoc

2.2.6 评估训练效果
%%统计正确率的代码:

acc=accuracy(W1,W2,W3,W4,X_Test,D_Test);
end

3.实验结果



上图分别为四轮次和单轮的最佳运行效果,成功达到了要求。

4.实验结果分析

通过对网络结构,算法,权值的不断调整,获得了目前最好的结果(98%+正确率)。通过对训练后的权值和初始化的权值对比,不断调整其参数,尽量让初始化权值大小和训练后的结果差不多大,这样的训练效果最好。在SGD,小批量,批量中,根据运行的时间和精度不断比较,最终还是选择SGD算法最优。而动量算法对准确率提升不大,但是提升了稳定性,也提高了更新速度。在特征提取网络中,从一个隐层变成两个隐层,对实验结果精确率也有所帮助。而学习速率和动量算法的步进速率的选取,只能通过一次次实验寻找合适的值。一轮训练效果不够理想,所以进行了多轮训练。对于dropout,多轮次训练中可以有效解决过拟合问题。我也尝试了20001000100*10的分类层,虽然不符合设计要求,可是我发现节点更多,训练效果会更好一些。最高跑过10轮,可以达到98.9%的准确率。

5.结论

*卷积神经网络在图像、视频、语音和文本处理中取得了较多突破。在这一次的设计中,通过对代码的查找,修改,理解,自己从底层了解了卷积神经网络的一些概念,算法,优化方法。而且我认为只有如此才能理解其他编程软件的框架的由来,每一步在做什么。当然,也通过这次设计熟悉掌握了卷积神经网络在matlab上的代码操作。简单实现这次目标检测后,我也深刻认识到他还需要我更进一步的研究。
首先,由于CNN层数变得越来越深,人们对大规模的有效数据和高性能的计算能力也提出了越来越多的要求。同时,传统的人工搜集标签数据要求投入大量的人力和物力,这也导致了成本的提升,所以,无监督式的CNN学习方式越来越重要。
其次,为了提高CNN训练速度,一般采用某些异步的SGD算法,通过CPU和GPU集群可以得到一定的效果,但同时对硬件配置提出了一定的要求。因此,开发高效可扩展的训练算法依然有重要的实际价值。此外,深度模型在训练过程中往往需要在较长时间内占据较多的内存空间,对运行环境也带来了较大的压力。因此,在保证准确度的情况下,如何降低复杂性并快速训练得到模型,也是重要的研究方向。
再次,CNN应用于不同的任务要面临的关键问题是如何选择合适的训练参数,例如学习率、卷积核大小、卷积和池化层数等,这要求较多的技术积累和经验总结。这些训练参数存在内部相关性,也为参数调整带来较高的成本。因此,在CNN架构的选择上,依然值得我们去深入研究。

基于深度学习的手写数字识别Matlab实现相关推荐

  1. 基于深度学习的手写数字识别、python实现

    基于深度学习的手写数字识别.python实现 一.what is 深度学习 二.加深层可以减少网络的参数数量 三.深度学习的手写数字识别 一.what is 深度学习 深度学习是加深了层的深度神经网络 ...

  2. 基于深度学习的手写数字识别算法Python实现

    摘 要 深度学习是传统机器学习下的一个分支,得益于近些年来计算机硬件计算能力质的飞跃,使得深度学习成为了当下热门之一.手写数字识别更是深度学习入门的经典案例,学习和理解其背后的原理对于深度学习的理解有 ...

  3. Python基于深度学习的手写数字识别

    Python基于深度学习的手写数字识别 1.代码的功能和运行方法 2. 网络设计 3.训练方法 4.实验结果分析 5.结论 1.代码的功能和运行方法 代码可以实现任意数字0-9的识别,只需要将图片载入 ...

  4. 03_深度学习实现手写数字识别(python)

    本次项目采用了多种模型进行测试,并尝试策略来提升模型的泛化能力,最终取得了99.67%的准确率,并采用pyqt5来制作可视化GUI界面进行呈现.具体代码已经开源. 代码详情见附录 1简介 早在1998 ...

  5. 【深度学习】手写数字识别Tensorflow2实验报告

    实验一:手写数字识别 一.实验目的 利用深度学习实现手写数字识别,当输入一张手写图片后,能够准确的识别出该图片中数字是几.输出内容是0.1.2.3.4.5.6.7.8.9的其中一个. 二.实验原理 ( ...

  6. Python实现深度学习MNIST手写数字识别(单文件,非框架,无需GPU,适合初学者)

    注: 本文根据阿卡蒂奥的Python深度学习博客文章代码进行调整,修复了少量问题,原文地址:https://blog.csdn.net/akadiao/article/details/78175737 ...

  7. 基于深度学习的手写数字实现及超简单的英文字母识别

    本文章大致分为5个板块,分别是MNIST数据库,深度学习神经网络的构建,图像预处理,图像识别,简单的英文字母识别展示. 1.MNIST数据库 总所周知,MNIST数据库是专门用于为手写数字识别系统提供 ...

  8. 深度学习数字仪表盘识别_深度学习之手写数字识别项目(Sequential方法amp;Class方法进阶版)...

    此项目使用LeNet模型针对手写数字进行分类.项目中我们分别采用了顺序式API和子类方法两种方式构建了LeNet模型训练mnist数据集,并编写了给图识物应用程序用于手写数字识别. 一.LeNet模型 ...

  9. 深度学习day04-MNIST手写数字识别与模型使用

    本文大概分为以下几个部分:手写数字识别原理(不强相关).具体代码实现(算上import和空行一共50行代码不到).训练出来的模型怎么使用. 目录 一.手写数字识别原理 二.具体代码实现 三.训练出来的 ...

最新文章

  1. HDU1045 Fire Net 递归回溯
  2. JavaScript实现CountingSort计数排序算法(附完整源码)
  3. boost::shared_ptr相关的测试程序
  4. 【Java】日期/事件字符串包含TZ
  5. maven依赖包下载地址
  6. SAP Spartacus checkout Shipping address的页面实现
  7. 或成为性能宠儿,荣耀8x Max 骁龙660版首销在即
  8. 标准日本语 05_003
  9. Android笔记 ANR Application Not Response
  10. PO、VO、BO、POJO、DAO、DTO都是什么对象
  11. 51中程序存储器和数据存储器
  12. UTC时区表(.Net)
  13. eclipse安装hadoop插件教程
  14. 江苏统考计算机英语作文,2017年高考江苏卷英语作文
  15. 什么是EISA分区,如何删除
  16. poj 百练 2807:两倍
  17. 使用python制作小鸟游戏
  18. 手把手Selenium安装使用及实战爬取前程无忧招聘网站(一)
  19. 服务器系统日志事件id41,系统不定时重启,事件ID41,任务类别63
  20. 关于电脑插耳机没有声音的解决办法

热门文章

  1. Mysql探索之索引详解,又能和面试官互扯了~,java分布式系统面试题
  2. textField使用合集(附字体设置合集)
  3. 3dmax 创建圆锥体1
  4. css照片缩放清晰显示问题
  5. 怎么让联想计算机升级,联想电脑怎么升级win11?联想电脑升级win11的几种方法...
  6. 回炉篇5—数据结构(4)之冒泡、选择、插入排序算法
  7. Windows10笔记本 闲置一段时间后黑屏无法唤醒,风扇全速运转的解决日志
  8. so链接及动态加载原理分析
  9. 人人憎恨的大数据杀熟你了解吗? 大数据杀熟”是否真的存在?
  10. 人工智能研究的内容:_更深入:人工智能研究的思想史