基于BP神经网络的数字识别基础系统(一)
随着《最强大脑》中的人机大战播放以及AlphaGo的围棋领域的攻克,深度学习开始进入了人们的视野,事实上神经网络作为深度学习的基础慢慢成为了人工智能以及模式识别的核心。其实神经网络的理论基础并不困难,甚至可以说是十分的简单。
这里,笔者通过一个数字识别基础系统来介绍神经网络中的BP神经网络,这里之所以说“基础”是因为这个系统只完成了核心部分:固定图片像素大小的单数字识别。而对于前期图像的处理以及感兴趣区域的分割并没有更多的介绍,若要完成一个完善的数字识别系统,那么前期的图像处理(包括去噪,二值化,图像分割)也需要进行实现。文章参考了人民邮电出版社出版的由张铮主编的《数字图像处理与机器视觉(第二版)》,很多地方书中都有详细的叙述,若对细节有什么不懂的地方可以查阅该书。
另外,笔者发现目前网上存在的很多类似的内容是基于C++等语言的,很少是基于java语言的(虽然由于语言的特性,这个情况是很正常的),于是笔者打算使用java来实现这个系统,这样,也方便了系统向移动端的移植。
由于笔者能力有限,难免出现错误或者并不完美的地方,也欢迎大家一起讨论学习。
在BP神经网络之前,笔者避不开的要介绍基础的神经网络。在这里笔者略去了神经网络的发展历史,直接介绍其实现以及理论基础。若对其发展历史有兴趣的读者可以直接去网上搜索一下,鉴于目前神经网络的火热程度,应该是一搜一大把(笑)。
首先我们拿人的神经作为切入的点,根据我们所了解的知识,人的大脑有无数个神经细胞相互联动工作,从而使得人们有了各种各样的识别能力以及思考的能力。神经网络架构的本质便是模仿人类的神经系统(当然,目前还无法做到像人的神经系统一样)。我们来看下面一张摘自http://image.so.com/v?ie=utf-8&src=hao_360so&q=神经系统&correct=神经系统&fromurl=http%3A%2F%2Fwww.taopic.com%2Ftuku%2F201304%2F343874.html&gsrc=1#ie=utf-8&src=hao_360so&q=%E7%A5%9E%E7%BB%8F%E7%B3%BB%E7%BB%9F&correct=%E7%A5%9E%E7%BB%8F%E7%B3%BB%E7%BB%9F&fromurl=http%3A%2F%2Fwww.taopic.com%2Ftuku%2F201304%2F343874.html&gsrc=1&lightboxindex=2&id=c727dd4e09abe72ed82c093ce677c835&multiple=0&itemindex=0&dataindex=2的图片。
我们发现,其实人的神经细胞之间互相连接,传递信息,这启发了我们做一个神经细胞的简单抽象,如下摘自http://image.so.com/v?q=神经网络&src=srp&correct=神经网络&fromurl=http%3A%2F%2Fbaike.cntronics.com%2Fabc%2F2039&gsrc=1#q=%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C&src=srp&correct=%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C&fromurl=http%3A%2F%2Fbaike.cntronics.com%2Fabc%2F2039&gsrc=1&lightboxindex=5&id=ce9cc854438b05a897e6bfa94eb9fa26&multiple=0&itemindex=0&dataindex=52图。
解释一下抽象图的含义:每个神经细胞与很多上级细胞相连,将上级细胞的输出作为自己的信号输入,然后通过一定的处理后输出信号给下一级细胞。当然这里所谓的一定的处理可以各有各的不同,目前普遍采用的是最为简单的线性处理
即如图的
那么现在的问题是如何确定系数w,从而使得输出与输入相对应呢?或者换一种更加具体的问法:如何能够做到给你一个数字“1”的图片(可能是各种形式,各种书写),你就能够知道它代表的字符是什么?如果不知道如何下手的话我们不妨再一次拿人的大脑来思考。即有了以下的思考过程:
刚出生的婴儿能够认识数字吗?——不能
婴儿如何认识数字的?——老师或家长交的
如何教?——不断拿出数字让婴儿识别并且告诉其正确与否,不断的反馈学习。
思考到这里,确定系数的方式便显得自然而然了:给出大量的样本以及其标签信息,然后不断的改变系数使得在样本空间内output(即输入的线性和)与标签输出在一定的误差范围内。这就是有监督的训练的过程。通过训练我们确定了w系数大小使得其在样本空间内能够给出一定误差内的正确结果。
如上,我们就知道了神经细胞相关的一些重要的信息。
现在回到我们人的大脑,正如我们开头所说的那样,人的大脑由无数个神经细胞相互连接,也就是说,一个功能较为强大的神经网络识别系统需要足够丰富的神经细胞。那么我们现在需要考虑神经系统的构建。
为了更加简单的管理以及更加清晰的逻辑,我们构建的方式就像封装一样,有细胞,层,系统。
神经细胞是构成的基本单位
层由多个神经细胞构成
系统由多个层连接而成
在上述并不十分详细(详细的还是要看看书)的描述中,我们已经了解了神经网络的组成方式。然而这里依然存在着两个十分重要的问题。
训练过程中,系数w如何改变的问题,即寻找一个比较好的改变方式,使得w能够更快的收敛到正确的系数。
使用这样的神经网络,只能拟合线性的求解方式,无法拟合非线性的求解方式(呃,笔者后面发现其实Sigmoid也算是线性拟合,具体请看笔者的《机器学习数学原理系列》)。
现在我们拿单个神经细胞的训练来考虑着两个问题。现在我们有n对样本<xd,yd>,其中xd为样本向量,而yi为目标输出。wi为对应的加权系数,这里先不考虑偏置项bias。因为偏置项bias可以简单的看做输入为1,加权系数为bias从而整合到样本中。即
首先我们先来看看第二个问题:拟合非线性的求解方式。
这里我们常用的可以使用Sigmoid函数来将输出结果映射后再输出。Sigmoid函数的映射关系式以及函数图摘自http://image.so.com/v?q=sigmoid&src=srp&correct=sigmoid&fromurl=http%3A%2F%2Fwww.myexception.cn%2Fother%2F1699185.html&gsrc=1#q=sigmoid&src=srp&correct=sigmoid&fromurl=http%3A%2F%2Fwww.myexception.cn%2Fother%2F1699185.html&gsrc=1&lightboxindex=4&id=b27d9648f7f749d6e367ea1a9bbe54f9&multiple=0&itemindex=0&dataindex=4
式子中的z便是我们的Output,f(z)为处理后的输出。
这里有两个好处:一是在多层网络中可以使系统能够进行非线性的映射,二是能够将解压缩在0到1这个区间内。
置于第一个问题的解决方式会在下一篇中来讨论。
下一篇博客链接:http://blog.csdn.net/z_x_1996/article/details/60779141
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z_x_1996/article/details/55670814
网友评论