BP神经网络识别手写数字项目解析及代码

2023-11-17

这两天在学习人工神经网络,用传统神经网络结构做了一个识别手写数字的小项目作为练手。点滴收获与思考,想跟大家分享一下,欢迎指教,共同进步。

平常说的BP神经网络指传统的人工神经网络,相比于卷积神经网络(CNN)来说要简单些。
人工神经网络具有复杂模式和进行联想、推理记忆的功能, 它是解决某些传统方法所无法解决的问题的有力工具。目前, 它日益受到重视, 同时其他学科的发展, 为其提供了更大的机会。1986 年, Romelhart 和Mcclelland提出了误差反向传播算法(Error Back Propagation Algorithm) ,简称BP 算法,由于多层前馈网络的训练经常采用误差反向传播算法, 人们也把多层前馈网络称为BP 网络。

为了便于阅读,下面说一下全文的逻辑顺序:
1,通俗说下神经网络的结构和工作原理,简单好理解,推荐观看
2,逆向传播算法的数学推导,如果觉得太复杂可以暂时跳过
3,matlab代码和图像库

(1) 大白话讲解传统神经网络

首先,我们看一下神经网络的基本单元——单个的神经元:

图中圆形表示一个神经元,我们知道,一个神经元接收相邻的神经元传来的刺激,神经元对这些刺激以不同的权重进行积累,到一定的时候产生自己的刺激将其传递给一些与它相邻的神经元。这样工作的无数个神经元便构成了人脑对外界的感知。而人脑对世界的学习的机制就是通过调节这些相邻连接的神经元刺激的权重。
在图中,周围神经元传过来的刺激表示为Y,权重表示为W,圆形表示的神经元得到的刺激是所有刺激按照权重累加起来,即

同时这个神经元作为网络的一份子,也像其他神经元一样需要向外传播刺激信号,但是不是直接把s传播,而是传播一个f(s)出去,为什么呢?其实无关大局,我们后面分析。其中f(s)学名称为“激活函数”,常用的函数如下:

好了,理解到这里如果没什么问题的话,恭喜你你已经入门了,现在我们把这一个个的基本单元连接起来,就构成我们最终的神经网络了。传统的神经网络结构如下图所示:

是不是觉得很乱?不着急我们一点一点看,由整体到细微来解剖它。首先整体上,它的结构分为三部分,输入层,隐藏层和输出层,一般输入层和输出层各一个,隐藏层若干个,图中画出了一个。细微处,连接结构上,后一层的每个神经元都由前一层的所有神经元连接进来。
手写数字识别实验使用的是三层的神经网络结构,即只有一个隐藏层,下面以此说明。
下面说明一下各层的表示和各层的关系:
输入层:X=(x1,x2,x3…xn)
隐藏层:Y=(y1,y2,y3…ym)
输出层:O=(o1,o2,o3…or)

两个权重:
输入层到隐藏层的权重:V=(V1,V2,V3…Vm),Vj是一个列向量,表示输入层所有神经元通过Vj加权,得到隐藏层的第j个神经元
隐藏层到输出层的权重:W=(W1,W2,W3…Wr),Wk是一个列向量,表示隐藏层的所有神经元通过Wk加权,得到输出层的第k个神经元

根据我们上面说到的单个神经元的刺激传入和刺激传出,相信到这里很多人应该已经得出下面的各层之间的关系了:


到这里,神经网络的工作过程就清楚一些了。实例说明一下,假设输入是一张图像, 16x16大小,转换为一个二维的灰度值矩阵,再把每一行拼接在上一行的末尾,拼接成一个1x256的行向量,作为输入层的输入,即X,接下来按照公式2就可以计算出隐藏层,然后根据公式1又可以计算出输出层,输出层的输出就得到了。在这个手写数字识别的项目中,我使用的图片输入正是16x16,所以输入层有256个神经元,隐藏层的神经元我取了64个,最后的输出层神经元我取的是10个,为什么是10个呢?因为数字0到9一共10个,期望上是,比如输入一张写着数字1的图像,在输出端得到的输出是{1 0 0 0 0 0 0 0 0 0},输入的图像为2时,输出{ 0 1 0 0 0 0 0 0 0 0},以此类推,实际上输出的未必就是刚好1和刚好0,经过调参和训练,基本是输出0.9多和正负的0.0多,不过也足够了,仅仅用判断最大值所在位置的方式就可以识别到图像上的数字。

至此,我们已经了解了整个网络的结构和正向工作的具体流程。可以说我们已经对神经网络理解了有50%了。为什么才50%呢?仔细想想相信你会发现,我们还不知道两个在网络中很重要的量,就是权重矩阵W和V。

如何求得W和V呢,这里要用到一种算法,就是误差反向传播算法(Error Back Propagation Algorithm) ,简称BP 算法。说的很晦涩,我们来翻译成人话。先来看看算法的工作过程,首先随机地初始化W和V的值,然后代入一些图片进行计算,得到一个输出,当然由于W和V参数不会刚好很完美,输出自然不会是像上文说的,刚好就是{1 0 0 0 0 0 0 0 0 0}这一类,所以存在误差,根据这个误差就可以反过来修正W和V的值,修正后的W和V可以使输出更加的靠近于理想的输出,这就是所谓的“误差反向传播”的意思,修正一次之后,再代入其他一些图片,输出离理想输出又靠近了一点,我们又继续计算误差,然后修正W和V的值,就这样经过很多次的迭代计算,最终多次修正得到了比较完美的W和V矩阵,它可以使得输出非常靠近于理想的输出,至此我们的工作完成度才是100%了。这种在输出端计算误差,根据误差来作调节的思想,学自动化的或者接触过飞思卡尔一类的智能车比赛的同学体会应该是比较深的,跟PID自控算法有很大相似性。

下面是数学推导,关于实际输出和理想输出之间的误差如何具体来调节W和V的值,调节多少的问题。上面说过了,暂时不理解的话可以先跳过推导,看最后的结论就好,自己最后跟着代码实践一遍,有了更深的体会,慢慢会理解的。

(2)逆向传播算法的数学推导

输出层的理想输出:d=(d1,d2,d3…dr),例如{1 0 0 0 0 0 0 0 0 0}和{0 1 0 0 0 0 0 0 0 0}等
假设实际输出和理想输出之间的差距是E,明显W是一个关于输入X,权重W和V,输出O的函数。要修正W,则需要知道具体的修正增量ΔW,离散情况下,表征微分增量,可以得到:



这样,改变η的大小即可改变每一次调节的幅度,η大的话调节更快,小则调节慢,但是过大容易导致振荡,这一点也跟PID中的比例系数P是一样的。一般η的大小需要经过多次尝试来找到合适值。

好了,到这里神经网络就讲解完毕,下面是一个较次要的内容,我们上面说了,通过不断迭代来调整权重W和V,那么如何衡量迭代是否可以停止了呢。一个自然的想法是判断每次的输出和理想输出是否足够接近,所以我们可以用算向量距离的方法,跟均方差是一个 道理,如下:

这样,主要s足够小,迭代就可以结束了。


(3)实践

下面是我试验用的MATLAB代码。

训练部分:recognize_handwriting_numbers_by_simple_NN_train.m

V=double(rand(256,64));
W=double(rand(64,10));
delta_V=double(rand(256,64));
delta_W=double(rand(64,10));

yita=0.2;%缩放系数,有的文章称学习率
yita1=0.05;%我自己加的参数,缩放激活函数的自变量防止输入过大进入函数的饱和区,可以去掉体会一下变化
train_number=9;%训练样本中,有多少个数字,一共9个,没有0
train_num=30;%训练样本中,每种数字多少张图,一共100张
x=double(zeros(1,256));%输入层
y=double(zeros(1,64));%中间层,也是隐藏层
output=double(zeros(1,10));%输出层
tar_output=double(zeros(1,10));%目标输出,即理想输出
delta=double(zeros(1,10));%一个中间变量,可以不管

%记录总的均方差便于画图
s_record=1:1000;
tic %计时
for train_control_num=1:1000   %训练次数控制,在调参的最后发现1000次其实有多了,大概400次完全够了
    s=0;
%读图,输入网络
for number=1:train_number
ReadDir=['E:\Matlab\recognize_handwiting_numbers\train_lib\'];%读取样本的路径
for num=1:train_num  %控制多少张
photo_name=[num2str(number),num2str(num,'%05d'),'.png'];%图片名
photo_index=[ReadDir,photo_name];%路径加图片名得到总的图片索引
photo_matrix=imread(photo_index);%使用imread得到图像矩阵
photo_matrix=uint8(photo_matrix<=230);%二值化,黑色是1
tmp=photo_matrix';
tmp=tmp(:);%以上两步完成了图像二维矩阵转变为列向量,256维,作为输入
%计算输入层输入
x=double(tmp');%转化为行向量因为输入层X是行向量,并且化为浮点数
%得到隐层输入
y0=x*V;
%激活
y=1./(1+exp(-y0*yita1));
%得到输出层输入
output0=y*W;
output=1./(1+exp(-output0*yita1));
%计算预期输出
tar_output=double(zeros(1,10));
tar_output(number)=1.0;
%计算误差
%按照公式计算W和V的调整,为了避免使用for循环比较耗费时间,下面采用了直接矩阵乘法,更高效
delta=(tar_output-output).*output.*(1-output);
delta_W=yita*repmat(y',1,10).*repmat(delta,64,1);
tmp=sum((W.*repmat(delta,64,1))');
tmp=tmp.*y.*(1-y);
delta_V=yita*repmat(x',1,64).*repmat(tmp,256,1);
%计算均方差
s=s+sum((tar_output-output).*(tar_output-output))/10;
%更新权值
W=W+delta_W;
V=V+delta_V;
end
end
s=s/train_number/train_num  %不加分号,随时输出误差观看收敛情况
train_control_num           %不加分号,随时输出迭代次数观看运行状态
s_record(train_control_num)=s;%记录
end
toc %计时结束
plot(1:1000,s_record);


测试部分:recognize_handwriting_numbers_by_simple_NN_test.m


correct_num=0;%记录正确的数量
incorrect_num=0;%记录错误数量
test_number=9;%测试集中,一共多少数字,9个,没有0
test_num=100;%测试集中,每个数字多少个,最大100个
% load W;%%之前训练得到的W保存了,可以直接加载进来
% load V;
% load yita1;

%记录时间
tic %计时开始
for number=1:test_number
ReadDir=['E:\Matlab\recognize_handwiting_numbers\test_lib\'];
for num=1:test_num  %控制多少张
photo_name=[num2str(number),num2str(num,'%05d'),'.png'];
photo_index=[ReadDir,photo_name];
photo_matrix=imread(photo_index);
%大小改变
photo_matrix=imresize(photo_matrix,[16 16]);
%二值化
photo_matrix=uint8(photo_matrix<=230);%黑色是1
%行向量
tmp=photo_matrix';
tmp=tmp(:);
%计算输入层输入
x=double(tmp');
%得到隐层输入
y0=x*V;
%激活
y=1./(1+exp(-y0*yita1));
%得到输出层输入
o0=y*W;
o=1./(1+exp(-o0*yita1));
%最大的输出即是识别到的数字
[o,index]=sort(o);
if index(10)==number
    correct_num=correct_num+1
else
    incorrect_num=incorrect_num+1;
    %显示不成功的数字,显示会比较花时间
%     figure(incorrect_num)
%     imshow((1-photo_matrix)*255);
%     title(num2str(number));
end
end
end
correct_rate=correct_num/test_number/test_num
toc %计时结束



使用的库来自于http://www.ee.surrey.ac.uk/CVSSP/demos/chars74k/#download
使用其中的EnglishFnt.tgz库,从其中的数字选出前100张作为训练,再另外取100张作为测试。图片集有需要也可以邮件我发送。


运行结果:

最后调参得到比较好的结果,使用η=0.2,η1=0.05,在我电脑上,i5-3210M,4G内存,迭代1000次所需要的时间是468s,最终得到下面的曲线,横坐标是训练的迭代次数,纵坐标是均方差,可以看到,其实在350次迭代的时候已经取得了很小的均方差,考虑时间和性能的折中的话,迭代350次已经可以了。


最后训练结束,使用η=0.2,η1=0.05,用测试集测试,可以得到89.11%的准确率,继续调节参数,曾经可以得到90.56%的准确率,不过也难再上去,估计瓶颈了。

如果你跟着本文的步骤一步一步下来,最后还自己动手打一遍代码,应该会很好的理解了传统类型的神经网络,对接下来理解卷积神经网络应该会有些帮助。

我自己对神经网络的的一些理解,以识别图片手写数字为例,图片中黑色像素点和白色像素点之间的空间编排关系构成了我们看到的数字,如果我们能找到一个很厉害的方程组,方程的输入参数是一张图片,返回一个数字表示识别结果,那肯定是很理想的,但是可惜,很难找到的方程来映射图片像素点的空间排布和识别结果这样的一种关系。而神经网络刚好就完成了这样的映射功能,所有的关于像素点空间排布信息的解析都隐藏于矩阵W和V之中,所以W和V实际上代表了这样一种映射关系。而神经网络聪明的地方在于,当这样的映射关系未知时,我们设计了一套机理让它自己来寻找,这就是学习和训练的过程,而最后得到的W和V就是学习的结果,这个过程很像婴儿开始认东西的过程,一开始婴儿的认知体系是空白的,像刚随机初始化的W和V,我们给它看一本书,像给了网络一个输入,告诉他这个是“书”,像告诉网络,理想输出应该是“书”,他会开始尝试来理解,建立书这个物品到“书”这个字的映射关系,一开始他会犯错,看到相似的比如一张纸也会认为是书,但是在看到更多的书之后,并且我们告诉他这个是“书”之后,他又会不断修正这样一种映射关系,最后建立完整的对于书这样一种物品到“书”这个字的映射过程,初步的认知体系建立。现在可以说说上面的“激活函数”是干嘛用的了,可以想象,自然界的各种各样的映射关系显然是比较复杂的,关靠线性关系是无力描述的,而神经网络中用的是加权相加的运算,如果没有经过激活函数处理,后层的所有输入都可以由多层之前的信号经过线性运算来得到,一个现象模型显然表现力是远远不够的,所以我们在神经网络模型中加入了非线性的因素,就是激活函数。

最后,感谢看完这么长一篇文字,有不足之处,欢迎评论指正,共同进步。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BP神经网络识别手写数字项目解析及代码 的相关文章

  • java 使用hutool工具进行MD5加密

    引入依赖
  • C语言:猜数字游戏

    define CRT SECURE NO WARNINGS include
  • 有问题的代码

    1 把对象加到集合中
  • 老猿Python部分代码样例

    专栏 Python基础教程目录 专栏 使用PyQt开发图形界面Python应用 专栏 PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 PyQt编程实战 通过eventFilter监视QScrollArea的widget 的P
  • 使用redis做消息队列

    文章目录 前言 代码展示 前言 目前项目中有一项耗时操作 使用华为OBS做文件存储服务 有点类似minio 使用永中做在线预览 读取OBS中的office类文件 因为现在架构里并没有集成mq 所以使用redis做消息队列 代码展示 定时消费
  • OpenCV仪表数据识别(二):数字区域自动定位

    下载和配置Opencv在网上和书上有很多的讲解 这里不再赘述 此处附上Opencv的下载链接 想要对图片中的数字信息进行识别首先要对图片进行预处理 排除干扰的因素 只留下有价值的信息 这里需要两张图 一张为有数据的图片 一张为仪表关闭时没有
  • jsp 不能识别 el 表达式 的解决方法

    在以前使用EL表达式的时候 在JSP页面直接使用就可以了 但昨天我在做项目的时候在JSP页面上的EL表达式不能被识别 如 loginForm username 在页面上还是显示 loginForm username 后来我在JSP头上加上红
  • C++串口编程

    CSerialPort 类 头文件 SerialPort h ifndef SERIAL H define SERIAL H include
  • Transformer怎么入门?如何学习Transformer?

    Transformer比较好学 整个路线也非常简单 就三步 第一步 理论学习 理论学习部分首先要了解Attention机制 这里推荐李宏毅老师的机器学习 或者看他的PPT 讲的很清楚 国外的也有斯坦福的CS25 Transformers U
  • 某市出租车,起步价(2 公里以内)为 8 元,超过 2 公里的按照每公里 4.5 元计算。要求根据路程计算费用。

    public class Task 10101003 01 public static void main String args Scanner input new Scanner System in double sum 0 总费用 d
  • Scanner读取文件(按行读入)

    public class ScannerTest public static void main String args 其实 Scanner在使用结束之后 也是需要进行关闭的 调用close方法 try Scanner scanner n
  • 人工智能是怎么用在人脸识别上的?

    相信大家都有这样的生活经历 小区的门禁不知道从什么时候开始可以 刷脸 进入了 支付宝账号登录不知道从什么时候开始只需要扫脸了等等 这一切都是人脸识别技术在改变我们的生活 那么人脸识别技术究竟是什么 它是如何工作的呢 人工智能是怎么用在人脸识
  • 学人工智能以后从事什么工作?这6大就业方向前景广阔

    学AI以后从事什么工作 近些年来 科技的快速发展 使人工智能方面的人才炙手可热 根据此前UiPath发布的数据显示 我国AI岗位空缺数量最多 有12113个相关职位因为招聘不到人才而发生空缺 我国对于AI人才的渴求已经超过了人工智能大国美国
  • super.onCreate(savedInstanceState);

    super onCreate savedInstanceState 是调用父类的onCreate构造函数 savedInstanceState是保存当前Activity的状态信息 onCreate方法的参数是一个Bundle类型的参数 Bu
  • 使用statsvn统计svn中的代码量

    StatSVN介绍 StatSVN是一个Java写的开源代码统计程序 从statCVS移植而来 能够从Subversion版本库中取得信息 然后生成描述项目开发的各种表格和图表 比如 代码行数的时间线 针对每个开发者的代码行数 开发者的活跃
  • 如何写好Java程序呢

    如何写出更好的Java代码 05 22 2014 Java是最流行的编程语言之一 但似乎并没有人喜欢使用它 好吧 实际上Java是一门还不错的编程语言 由于最近Java 8发布了 我决定来编辑一个如何能更好地使用Java的列表 这里面包括一
  • Matplotlib绘制漂亮的饼状图

    python绘图系列文章目录 往期python绘图合集 python绘制简单的折线图 python读取excel中数据并绘制多子图多组图在一张画布上 python绘制带误差棒的柱状图 python绘制多子图并单独显示 python读取exc
  • android 使用 ImageLoader 显示文章和图片

    android 中使用Textview 显示文章及图片 1 下载 universal image loader 1 9 5 jar 添加到app项目中 2 在android 后台 的 onCreate 方法中初始化 ImageLoader
  • 机器视觉最火应用领域

    1 图像和视频识别 人工神经网络领域最重要的进展之一出自 ImageNet ImageNet收集了 1400 万标签图像并于2009年发布 ImageNet挑战赛要求参赛者设计一个能够跟人类一样对照片进行分类的算法 但一直没有出现获胜者 直
  • Java代码世界的神奇技巧与魔法艺术

    目录 前言 1 Java的独特优势 1 1 跨平台性 1 2 面向对象 1 3 强大的生态系统 2 Java的应用场景 2 1 企业级应用开发 2 2 移动应用开发

随机推荐

  • virtIO前后端notify机制详解

    本来这是在前端驱动后期分析的 但是这部分内容比较多 且分析了后端notify前端的机制 所以还是单独拿出一节分析比较好 还是拿网络驱动部分做案例 网络驱动部分有两个队列 忽略控制队列 接收队列和发送队列 每个队列都对应一个virtqueue
  • FFmpeg:UDP外网传输花屏严重问题完美解决

    1 前言 最近发现 UDP外网传输是 丢帧严重 我的环境是 视频流是济南移动 播放端是济南电信家庭宽带 由于视频流没有固定IP 所以我想了一个办法 让视频流网络穿透 直接点对点传输到我的播放端 但是发现我的播放端花屏严重 如下图 2 解决
  • 如何选择开源许可证?

    作者 阮一峰 日期 2011年5月 2日 如何为代码选择开源许可证 这是一个问题 世界上的开源许可证 大概有上百种 很少有人搞得清楚它们的区别 即使在最流行的六种 GPL BSD MIT Mozilla Apache和LGPL 之中做选择
  • R语言与金融数据分析 浙江工商学院 第一章:R简介 测试和作业

    本次作业数量为2题 作业互评时按每题50分 合计100分批改 统计成绩时系统会自动折算 要求在规定时间内完成并递交 采取同学互评的形式批改 请大家注意截止时间 按时完成 依照学术诚信条款 我保证此回答为本人原创 所有回答中引用的外部材料已经
  • 解决报错ImportError: IProgress not found. Please update jupyter and ipywidgets

    在终端 pip install ipywidgets 然后重启jupyter notebook即可
  • mysql 修改字符编码

    修改表的字符编码 查看 show create table ods goods alter table ods goods default character set utf8 修改字段的字符编码 alter table ods goods
  • 学MySQL的前置条件--会不断更新

    在MySQL软件中关于数据的操作无非就是CRUD C 插入数据记录操作 create R 查询数据记录操作 read U 更新数据记录操作 update D 删除数据操作记录 delete 所有的SQL语言中 学明白了CRUD加上实战几年
  • IDA+VirtulKD+VMware实现高速双机调试

    目录 前言 一 环境 二 配置步骤 1 配置VirtualKD 2 配置IDA 前言 我尝试只使用windbg作为调试器 但它界面不够友好 我又尝试使用IDA作为调试器 但是使用pipe传输速度太慢了 导致IDA卡的不行 单步特慢 前段时间
  • 在nginx中部署https服务,详细步骤

    目录 前言 一 https是什么 二 部署步骤 1 下载SSL证书 2 上传文件 3 解压文件 4 在nginx conf配置文件中 修改https服务 5 修改hosts文件 6 http跳转到https中 三 注意事项 前言 Web服务
  • 线程管理之Thread类相关方法简介

    CurrentThread 静态方法 currentThread 方法可返回代码段正在被那个线程调用的信息 简单案列 打印main 方法 正在被那个线程调用 package com zzg thread import com zzg obj
  • [工具使用]黑暗引擎FOFA

    黑暗引擎FOFA FOFA 点我进入 逻辑运算符 搜索子域名domain 搜索指定内容的host全部域名 body cert 搜索选定应用的网站 搜索指定开放端口的IP 搜索指定协议的IP 搜索IP或者网段的信息 搜索指定CSS JS网站
  • 物联网毕设选题 机器视觉口罩佩戴检测系统 - 单片机 stm32 嵌入式

    文章目录 0 前言 1 简介 2 主要器件 3 实现效果 4 设计原理 5 部分核心代码 6 最后 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到毕业答辩的要求 这两年不断有学弟学妹告诉
  • VSCode插件开发

    VSCode插件开发 文章目录 VSCode插件开发 创建项目 Extension ts Package json Contribution Points Activation Events 创建项目 npm g i yo generato
  • 【Linux旅行记】进度条小程序

    文章目录 一 预备知识 1 1回车换行 1 2缓冲区 二 倒计时 三 进度条 3 1普通版本源代码 3 2高级版本源代码 小结 博客主页 小智 x0 0x 欢迎关注 点赞 收藏 留言 系列专栏 Linux入门到精通 代码仓库 小智的代码仓库
  • word中目录右边页码对不齐解决方法

    这个目录对不齐原因未知 解决方法 1 在视图中打开标尺 2 选择对不齐的目录项 如果整个目录都有出现不对齐 选择整个目录 3 拖动标尺 进行对齐 4 被治愈了
  • GDB调试的基本使用、GDB调试多进程

    1 编译时加选项 g 生成具有调试信息的程序 gcc g test c o test 2 启动GDB 1 启动GDB gdb test 2 设置运行时参数 主函数中可接收运行时参数 set args 设置运行时参数 如set args 10
  • i.mx287学习笔记9-编译mplayer源码

    上面是我的微信和QQ群 欢迎新朋友的加入 1 下载资源 mplayer http www mplayerhq hu MPlayer releases 这个我编译没用到 但是我看很多帖子都要这个东西 不管他 也找个资源过来 编码库 http
  • C/C++打开目录、读取目录、获取目录下文件状态

    1 程序示例 lstat 或者 stat 需要包含的头文件 include
  • Composite:组合模式

    将对象组合成树形结构以表示 部分 整体 的层次结构 组合模式使得用户对单个对象和组合对象的使用具有一致性 处理树中的每个节点时 其实不用考虑他是叶子节点还是根节点 即模糊了简单元素和复杂元素的概念 客户端可以像处理简单元素一样来处理复杂元素
  • BP神经网络识别手写数字项目解析及代码

    这两天在学习人工神经网络 用传统神经网络结构做了一个识别手写数字的小项目作为练手 点滴收获与思考 想跟大家分享一下 欢迎指教 共同进步 平常说的BP神经网络指传统的人工神经网络 相比于卷积神经网络 CNN 来说要简单些 人工神经网络具有复杂