神经网络 订阅
人工神经网络(Artificial Neural Networks,简写为ANNs)也简称为神经网络(NNs)或称作连接模型(Connection Model),它是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。 [1] 展开全文
人工神经网络(Artificial Neural Networks,简写为ANNs)也简称为神经网络(NNs)或称作连接模型(Connection Model),它是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。 [1]
信息
简    称
神经网络(NNs)
应用学科
通信
中文名
神经网络
外文名
neural networks
神经网络定义
生物神经网络主要是指人脑的神经网络,它是人工神经网络的技术原型。人脑是人类思维的物质基础,思维的功能定位在大脑皮层,后者含有大约10^11个神经元,每个神经元又通过神经突触与大约103个其它神经元相连,形成一个高度复杂高度灵活的动态网络。作为一门学科,生物神经网络主要研究人脑神经网络的结构、功能及其工作机制,意在探索人脑思维和智能活动的规律。人工神经网络是生物神经网络在某种简化意义下的技术复现,作为一门学科,它的主要任务是根据生物神经网络的原理和实际应用的需要建造实用的人工神经网络模型,设计相应的学习算法,模拟人脑的某种智能活动,然后在技术上实现出来用以解决实际问题。因此,生物神经网络主要研究智能的机理;人工神经网络主要研究智能机理的实现,两者相辅相成。 [2] 
收起全文
精华内容
参与话题
问答
  • 卷积神经网络

    万次阅读 多人点赞 2014-11-29 16:20:41
    自今年七月份以来,一直在实验室负责卷积神经网络(Convolutional Neural Network,CNN),期间配置和使用过theano和cuda-convnet、cuda-convnet2。为了增进CNN的理解和使用,特写此博文,以其与人交流,互有增益。...

    卷积神经网络

    转载请注明:http://blog.csdn.net/stdcoutzyx/article/details/41596663

    自今年七月份以来,一直在实验室负责卷积神经网络(Convolutional Neural Network,CNN),期间配置和使用过theano和cuda-convnet、cuda-convnet2。为了增进CNN的理解和使用,特写此博文,以其与人交流,互有增益。正文之前,先说几点自己对于CNN的感触。先明确一点就是,Deep Learning是全部深度学习算法的总称,CNN是深度学习算法在图像处理领域的一个应用。

    • 第一点,在学习Deep learning和CNN之前,总以为它们是很了不得的知识,总以为它们能解决很多问题,学习了之后,才知道它们不过与其他机器学习算法如svm等相似,仍然可以把它当做一个分类器,仍然可以像使用一个黑盒子那样使用它。

    • 第二点,Deep Learning强大的地方就是可以利用网络中间某一层的输出当做是数据的另一种表达,从而可以将其认为是经过网络学习到的特征。基于该特征,可以进行进一步的相似度比较等。

    • 第三点,Deep Learning算法能够有效的关键其实是大规模的数据,这一点原因在于每个DL都有众多的参数,少量数据无法将参数训练充分。

    接下来话不多说,直接奔入主题开始CNN之旅。

    1. 神经网络

    首先介绍神经网络,这一步的详细可以参考资源1。简要介绍下。神经网络的每个单元如下:

     

    其对应的公式如下:

     

    其中,该单元也可以被称作是Logistic回归模型。当将多个单元组合起来并具有分层结构时,就形成了神经网络模型。下图展示了一个具有一个隐含层的神经网络。

     

    其对应的公式如下:

     

    比较类似的,可以拓展到有2,3,4,5,…个隐含层。

    神经网络的训练方法也同Logistic类似,不过由于其多层性,还需要利用链式求导法则对隐含层的节点进行求导,即梯度下降+链式求导法则,专业名称为反向传播。关于训练算法,本文暂不涉及。

    2 卷积神经网络

    在图像处理中,往往把图像表示为像素的向量,比如一个1000×1000的图像,可以表示为一个1000000的向量。在上一节中提到的神经网络中,如果隐含层数目与输入层一样,即也是1000000时,那么输入层到隐含层的参数数据为1000000×1000000=10^12,这样就太多了,基本没法训练。所以图像处理要想练成神经网络大法,必先减少参数加快速度。就跟辟邪剑谱似的,普通人练得很挫,一旦自宫后内力变强剑法变快,就变的很牛了。

    2.1 局部感知

    卷积神经网络有两种神器可以降低参数数目,第一种神器叫做局部感知野。一般认为人对外界的认知是从局部到全局的,而图像的空间联系也是局部的像素联系较为紧密,而距离较远的像素相关性则较弱。因而,每个神经元其实没有必要对全局图像进行感知,只需要对局部进行感知,然后在更高层将局部的信息综合起来就得到了全局的信息。网络部分连通的思想,也是受启发于生物学里面的视觉系统结构。视觉皮层的神经元就是局部接受信息的(即这些神经元只响应某些特定区域的刺激)。如下图所示:左图为全连接,右图为局部连接。

     

    在上右图中,假如每个神经元只和10×10个像素值相连,那么权值数据为1000000×100个参数,减少为原来的万分之一。而那10×10个像素值对应的10×10个参数,其实就相当于卷积操作。

    2.2 参数共享

    但其实这样的话参数仍然过多,那么就启动第二级神器,即权值共享。在上面的局部连接中,每个神经元都对应100个参数,一共1000000个神经元,如果这1000000个神经元的100个参数都是相等的,那么参数数目就变为100了。

    怎么理解权值共享呢?我们可以这100个参数(也就是卷积操作)看成是提取特征的方式,该方式与位置无关。这其中隐含的原理则是:图像的一部分的统计特性与其他部分是一样的。这也意味着我们在这一部分学习的特征也能用在另一部分上,所以对于这个图像上的所有位置,我们都能使用同样的学习特征。

    更直观一些,当从一个大尺寸图像中随机选取一小块,比如说 8x8 作为样本,并且从这个小块样本中学习到了一些特征,这时我们可以把从这个 8x8 样本中学习到的特征作为探测器,应用到这个图像的任意地方中去。特别是,我们可以用从 8x8 样本中所学习到的特征跟原本的大尺寸图像作卷积,从而对这个大尺寸图像上的任一位置获得一个不同特征的激活值。

    如下图所示,展示了一个3×3的卷积核在5×5的图像上做卷积的过程。每个卷积都是一种特征提取方式,就像一个筛子,将图像中符合条件(激活值越大越符合条件)的部分筛选出来。

     

    2.3 多卷积核

    上面所述只有100个参数时,表明只有1个10*10的卷积核,显然,特征提取是不充分的,我们可以添加多个卷积核,比如32个卷积核,可以学习32种特征。在有多个卷积核时,如下图所示:

     

    上图右,不同颜色表明不同的卷积核。每个卷积核都会将图像生成为另一幅图像。比如两个卷积核就可以将生成两幅图像,这两幅图像可以看做是一张图像的不同的通道。如下图所示,下图有个小错误,即将w1改为w0,w2改为w1即可。下文中仍以w1和w2称呼它们。

    下图展示了在四个通道上的卷积操作,有两个卷积核,生成两个通道。其中需要注意的是,四个通道上每个通道对应一个卷积核,先将w2忽略,只看w1,那么在w1的某位置(i,j)处的值,是由四个通道上(i,j)处的卷积结果相加然后再取激活函数值得到的。

     

     

     

    所以,在上图由4个通道卷积得到2个通道的过程中,参数的数目为4×2×2×2个,其中4表示4个通道,第一个2表示生成2个通道,最后的2×2表示卷积核大小。

    2.4 Down-pooling

    在通过卷积获得了特征 (features) 之后,下一步我们希望利用这些特征去做分类。理论上讲,人们可以用所有提取得到的特征去训练分类器,例如 softmax 分类器,但这样做面临计算量的挑战。例如:对于一个 96X96 像素的图像,假设我们已经学习得到了400个定义在8X8输入上的特征,每一个特征和图像卷积都会得到一个 (96 − 8 + 1) × (96 − 8 + 1) = 7921 维的卷积特征,由于有 400 个特征,所以每个样例 (example) 都会得到一个 7921 × 400 = 3,168,400 维的卷积特征向量。学习一个拥有超过 3 百万特征输入的分类器十分不便,并且容易出现过拟合 (over-fitting)。

    为了解决这个问题,首先回忆一下,我们之所以决定使用卷积后的特征是因为图像具有一种“静态性”的属性,这也就意味着在一个图像区域有用的特征极有可能在另一个区域同样适用。因此,为了描述大的图像,一个很自然的想法就是对不同位置的特征进行聚合统计,例如,人们可以计算图像一个区域上的某个特定特征的平均值 (或最大值)。这些概要统计特征不仅具有低得多的维度 (相比使用所有提取得到的特征),同时还会改善结果(不容易过拟合)。这种聚合的操作就叫做池化 (pooling),有时也称为平均池化或者最大池化 (取决于计算池化的方法)。

     

    至此,卷积神经网络的基本结构和原理已经阐述完毕。

    2.5 多层卷积

    在实际应用中,往往使用多层卷积,然后再使用全连接层进行训练,多层卷积的目的是一层卷积学到的特征往往是局部的,层数越高,学到的特征就越全局化。

    3 ImageNet-2010网络结构

    ImageNet LSVRC是一个图片分类的比赛,其训练集包括127W+张图片,验证集有5W张图片,测试集有15W张图片。本文截取2010年Alex Krizhevsky的CNN结构进行说明,该结构在2010年取得冠军,top-5错误率为15.3%。值得一提的是,在今年的ImageNet LSVRC比赛中,取得冠军的GoogNet已经达到了top-5错误率6.67%。可见,深度学习的提升空间还很巨大。

    下图即为Alex的CNN结构图。需要注意的是,该模型采用了2-GPU并行结构,即第1、2、4、5卷积层都是将模型参数分为2部分进行训练的。在这里,更进一步,并行结构分为数据并行与模型并行。数据并行是指在不同的GPU上,模型结构相同,但将训练数据进行切分,分别训练得到不同的模型,然后再将模型进行融合。而模型并行则是,将若干层的模型参数进行切分,不同的GPU上使用相同的数据进行训练,得到的结果直接连接作为下一层的输入。

     

    上图模型的基本参数为:
    
    • 输入:224×224大小的图片,3通道
    • 第一层卷积:11×11大小的卷积核96个,每个GPU上48个。
    • 第一层max-pooling:2×2的核。
    • 第二层卷积:5×5卷积核256个,每个GPU上128个。
    • 第二层max-pooling:2×2的核。
    • 第三层卷积:与上一层是全连接,3*3的卷积核384个。分到两个GPU上个192个。
    • 第四层卷积:3×3的卷积核384个,两个GPU各192个。该层与上一层连接没有经过pooling层。
    • 第五层卷积:3×3的卷积核256个,两个GPU上个128个。
    • 第五层max-pooling:2×2的核。
    • 第一层全连接:4096维,将第五层max-pooling的输出连接成为一个一维向量,作为该层的输入。
    • 第二层全连接:4096维
    • Softmax层:输出为1000,输出的每一维都是图片属于该类别的概率。

    4 DeepID网络结构

    DeepID网络结构是香港中文大学的Sun Yi开发出来用来学习人脸特征的卷积神经网络。每张输入的人脸被表示为160维的向量,学习到的向量经过其他模型进行分类,在人脸验证试验上得到了97.45%的正确率,更进一步的,原作者改进了CNN,又得到了99.15%的正确率。

    如下图所示,该结构与ImageNet的具体参数类似,所以只解释一下不同的部分吧。

     

    上图中的结构,在最后只有一层全连接层,然后就是softmax层了。论文中就是以该全连接层作为图像的表示。在全连接层,以第四层卷积和第三层max-pooling的输出作为全连接层的输入,这样可以学习到局部的和全局的特征。

    5 参考资源

    • [1] http://deeplearning.stanford.edu/wiki/index.php/UFLDL%E6%95%99%E7%A8%8B 栀子花对Stanford深度学习研究团队的深度学习教程的翻译
    • [2] http://blog.csdn.net/zouxy09/article/details/14222605 csdn博主zouxy09深度学习教程系列
    • [3] http://deeplearning.net/tutorial/ theano实现deep learning
    • [4] Krizhevsky A, Sutskever I, Hinton G E. Imagenet classification with deep convolutional neural networks[C]//Advances in neural information processing systems. 2012: 1097-1105.
    • [5] Sun Y, Wang X, Tang X. Deep learning face representation from predicting 10,000 classes[C]//Computer Vision and Pattern Recognition (CVPR), 2014 IEEE Conference on. IEEE, 2014: 1891-1898.

    更多内容欢迎关注微信公众后【雨石记】。

     

    展开全文
  • 神经网络——最易懂最清晰的一篇文章

    万次阅读 多人点赞 2018-08-24 15:43:20
    神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向--深度学习的基础。学习神经网络不仅可以让你掌握一门强大的机器学习方法,同时也可以更好地帮助你理解深度学习技术。  本文以一种简单的,循序的...

    神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向--深度学习的基础。学习神经网络不仅可以让你掌握一门强大的机器学习方法,同时也可以更好地帮助你理解深度学习技术。

      本文以一种简单的,循序的方式讲解神经网络。适合对神经网络了解不多的同学。本文对阅读没有一定的前提要求,但是懂一些机器学习基础会更好地帮助理解本文。

      神经网络是一种模拟人脑的神经网络以期能够实现类人工智能的机器学习技术。人脑中的神经网络是一个非常复杂的组织。成人的大脑中估计有1000亿个神经元之多。

    图1 人脑神经网络

     

      那么机器学习中的神经网络是如何实现这种模拟的,并且达到一个惊人的良好效果的?通过本文,你可以了解到这些问题的答案,同时还能知道神经网络的历史,以及如何较好地学习它。

      由于本文较长,为方便读者,以下是本文的目录:

      一.前言

      二.神经元

      三.单层神经网络(感知器)

      四.两层神经网络(多层感知器)

      五.多层神经网络(深度学习)

      六.回顾

      七.展望

      八.总结

      九.后记

      十.备注

     

    一. 前言

      让我们来看一个经典的神经网络。这是一个包含三个层次的神经网络。红色的是输入层,绿色的是输出层,紫色的是中间层(也叫隐藏层)。输入层有3个输入单元,隐藏层有4个单元,输出层有2个单元。后文中,我们统一使用这种颜色来表达神经网络的结构。

    图2 神经网络结构图

     

      在开始介绍前,有一些知识可以先记在心里:

    1. 设计一个神经网络时,输入层与输出层的节点数往往是固定的,中间层则可以自由指定;
    2. 神经网络结构图中的拓扑与箭头代表着预测过程时数据的流向,跟训练时的数据流有一定的区别;
    3. 结构图里的关键不是圆圈(代表“神经元”),而是连接线(代表“神经元”之间的连接)。每个连接线对应一个不同的权重(其值称为权值),这是需要训练得到的。  

      除了从左到右的形式表达的结构图,还有一种常见的表达形式是从下到上来表示一个神经网络。这时候,输入层在图的最下方。输出层则在图的最上方,如下图:

    图3 从下到上的神经网络结构图 

     

      从左到右的表达形式以Andrew Ng和LeCun的文献使用较多,Caffe里使用的则是从下到上的表达。在本文中使用Andrew Ng代表的从左到右的表达形式。

      下面从简单的神经元开始说起,一步一步介绍神经网络复杂结构的形成。

     

    二. 神经元

      1.引子 

      对于神经元的研究由来已久,1904年生物学家就已经知晓了神经元的组成结构。

      一个神经元通常具有多个树突,主要用来接受传入信息;而轴突只有一条,轴突尾端有许多轴突末梢可以给其他多个神经元传递信息。轴突末梢跟其他神经元的树突产生连接,从而传递信号。这个连接的位置在生物学上叫做“突触”。

      人脑中的神经元形状可以用下图做简单的说明:

    图4 神经元

     

       1943年,心理学家McCulloch和数学家Pitts参考了生物神经元的结构,发表了抽象的神经元模型MP。在下文中,我们会具体介绍神经元模型。

       

    图5 Warren McCulloch(左)和 Walter Pitts(右)  

      2.结构 

      神经元模型是一个包含输入,输出与计算功能的模型。输入可以类比为神经元的树突,而输出可以类比为神经元的轴突,计算则可以类比为细胞核。

      下图是一个典型的神经元模型:包含有3个输入,1个输出,以及2个计算功能。

      注意中间的箭头线。这些线称为“连接”。每个上有一个“权值”。

    图6 神经元模型 

     

      连接是神经元中最重要的东西。每一个连接上都有一个权重。

      一个神经网络的训练算法就是让权重的值调整到最佳,以使得整个网络的预测效果最好。

      我们使用a来表示输入,用w来表示权值。一个表示连接的有向箭头可以这样理解:在初端,传递的信号大小仍然是a,端中间有加权参数w,经过这个加权后的信号会变成a*w,因此在连接的末端,信号的大小就变成了a*w。

      在其他绘图模型里,有向箭头可能表示的是值的不变传递。而在神经元模型里,每个有向箭头表示的是值的加权传递。

    图7 连接(connection)  

     

      如果我们将神经元图中的所有变量用符号表示,并且写出输出的计算公式的话,就是下图。

    图8 神经元计算  

     

      可见z是在输入和权值的线性加权和叠加了一个函数g的值。在MP模型里,函数g是sgn函数,也就是取符号函数。这个函数当输入大于0时,输出1,否则输出0。

      下面对神经元模型的图进行一些扩展。首先将sum函数与sgn函数合并到一个圆圈里,代表神经元的内部计算。其次,把输入a与输出z写到连接线的左上方,便于后面画复杂的网络。最后说明,一个神经元可以引出多个代表输出的有向箭头,但值都是一样的。

      神经元可以看作一个计算与存储单元。计算是神经元对其的输入进行计算功能。存储是神经元会暂存计算结果,并传递到下一层。

    图9 神经元扩展 

     

      当我们用“神经元”组成网络以后,描述网络中的某个“神经元”时,我们更多地会用“单元”(unit)来指代。同时由于神经网络的表现形式是一个有向图,有时也会用“节点”(node)来表达同样的意思。 

      3.效果 

      神经元模型的使用可以这样理解:

      我们有一个数据,称之为样本。样本有四个属性,其中三个属性已知,一个属性未知。我们需要做的就是通过三个已知属性预测未知属性。

      具体办法就是使用神经元的公式进行计算。三个已知属性的值是a1,a2,a3,未知属性的值是z。z可以通过公式计算出来。

      这里,已知的属性称之为特征,未知的属性称之为目标。假设特征与目标之间确实是线性关系,并且我们已经得到表示这个关系的权值w1,w2,w3。那么,我们就可以通过神经元模型预测新样本的目标。

      4.影响

      1943年发布的MP模型,虽然简单,但已经建立了神经网络大厦的地基。但是,MP模型中,权重的值都是预先设置的,因此不能学习。

      1949年心理学家Hebb提出了Hebb学习率,认为人脑神经细胞的突触(也就是连接)上的强度上可以变化的。于是计算科学家们开始考虑用调整权值的方法来让机器学习。这为后面的学习算法奠定了基础。

    图10 Donald Olding Hebb 

     

      尽管神经元模型与Hebb学习律都已诞生,但限于当时的计算机能力,直到接近10年后,第一个真正意义的神经网络才诞生。

     

    三. 单层神经网络(感知器)

      1.引子  

      1958年,计算科学家Rosenblatt提出了由两层神经元组成的神经网络。他给它起了一个名字--“感知器”(Perceptron)(有的文献翻译成“感知机”,下文统一用“感知器”来指代)。

      感知器是当时首个可以学习的人工神经网络。Rosenblatt现场演示了其学习识别简单图像的过程,在当时的社会引起了轰动。

      人们认为已经发现了智能的奥秘,许多学者和科研机构纷纷投入到神经网络的研究中。美国军方大力资助了神经网络的研究,并认为神经网络比“原子弹工程”更重要。这段时间直到1969年才结束,这个时期可以看作神经网络的第一次高潮。

    图11 Rosenblat与感知器 

      2.结构

      下面来说明感知器模型。

      在原来MP模型的“输入”位置添加神经元节点,标志其为“输入单元”。其余不变,于是我们就有了下图:从本图开始,我们将权值w1, w2, w3写到“连接线”的中间。

    图12 单层神经网络 

     

      在“感知器”中,有两个层次。分别是输入层和输出层。输入层里的“输入单元”只负责传输数据,不做计算。输出层里的“输出单元”则需要对前面一层的输入进行计算。

      我们把需要计算的层次称之为“计算层”,并把拥有一个计算层的网络称之为“单层神经网络”。有一些文献会按照网络拥有的层数来命名,例如把“感知器”称为两层神经网络。但在本文里,我们根据计算层的数量来命名。

      假如我们要预测的目标不再是一个值,而是一个向量,例如[2,3]。那么可以在输出层再增加一个“输出单元”。

      下图显示了带有两个输出单元的单层神经网络,其中输出单元z1的计算公式如下图。

    图13 单层神经网络(Z1)

     

      可以看到,z1的计算跟原先的z并没有区别。

      我们已知一个神经元的输出可以向多个神经元传递,因此z2的计算公式如下图。

    图14 单层神经网络(Z2)

     

      可以看到,z2的计算中除了三个新的权值:w4,w5,w6以外,其他与z1是一样的。

      整个网络的输出如下图。

    图15 单层神经网络(Z1和Z2)

     

      目前的表达公式有一点不让人满意的就是:w4,w5,w6是后来加的,很难表现出跟原先的w1,w2,w3的关系。

      因此我们改用二维的下标,用wx,y来表达一个权值。下标中的x代表后一层神经元的序号,而y代表前一层神经元的序号(序号的顺序从上到下)。

      例如,w1,2代表后一层的第1个神经元与前一层的第2个神经元的连接的权值(这种标记方式参照了Andrew Ng的课件)。根据以上方法标记,我们有了下图。

    图16 单层神经网络(扩展)

     

      如果我们仔细看输出的计算公式,会发现这两个公式就是线性代数方程组。因此可以用矩阵乘法来表达这两个公式。

      例如,输入的变量是[a1,a2,a3]T(代表由a1,a2,a3组成的列向量),用向量a来表示。方程的左边是[z1,z2]T,用向量z来表示。

      系数则是矩阵W(2行3列的矩阵,排列形式与公式中的一样)。

      于是,输出公式可以改写成:

    g(W * a) = z;

     

      这个公式就是神经网络中从前一层计算后一层的矩阵运算。

      3.效果

      与神经元模型不同,感知器中的权值是通过训练得到的。因此,根据以前的知识我们知道,感知器类似一个逻辑回归模型,可以做线性分类任务。

      我们可以用决策分界来形象的表达分类的效果。决策分界就是在二维的数据平面中划出一条直线,当数据的维度是3维的时候,就是划出一个平面,当数据的维度是n维时,就是划出一个n-1维的超平面。

      下图显示了在二维平面中划出决策分界的效果,也就是感知器的分类效果。

    图17 单层神经网络(决策分界)

      

      4.影响 

      感知器只能做简单的线性分类任务。但是当时的人们热情太过于高涨,并没有人清醒的认识到这点。于是,当人工智能领域的巨擘Minsky指出这点时,事态就发生了变化。

      Minsky在1969年出版了一本叫《Perceptron》的书,里面用详细的数学证明了感知器的弱点,尤其是感知器对XOR(异或)这样的简单分类任务都无法解决。

      Minsky认为,如果将计算层增加到两层,计算量则过大,而且没有有效的学习算法。所以,他认为研究更深层的网络是没有价值的。(本文成文后一个月,即2016年1月,Minsky在美国去世。谨在本文中纪念这位著名的计算机研究专家与大拿。)

       

    图18 Marvin Minsky

      

      由于Minsky的巨大影响力以及书中呈现的悲观态度,让很多学者和实验室纷纷放弃了神经网络的研究。神经网络的研究陷入了冰河期。这个时期又被称为“AI winter”。

      接近10年以后,对于两层神经网络的研究才带来神经网络的复苏。

     

    四. 两层神经网络(多层感知器)

      1.引子

      两层神经网络是本文的重点,因为正是在这时候,神经网络开始了大范围的推广与使用。

      Minsky说过单层神经网络无法解决异或问题。但是当增加一个计算层以后,两层神经网络不仅可以解决异或问题,而且具有非常好的非线性分类效果。不过两层神经网络的计算是一个问题,没有一个较好的解法。

      1986年,Rumelhar和Hinton等人提出了反向传播(Backpropagation,BP)算法,解决了两层神经网络所需要的复杂计算量问题,从而带动了业界使用两层神经网络研究的热潮。目前,大量的教授神经网络的教材,都是重点介绍两层(带一个隐藏层)神经网络的内容。 

      这时候的Hinton还很年轻,30年以后,正是他重新定义了神经网络,带来了神经网络复苏的又一春。

            

    图19 David Rumelhart(左)以及 Geoffery Hinton(右)

     

      2.结构

      两层神经网络除了包含一个输入层,一个输出层以外,还增加了一个中间层。此时,中间层和输出层都是计算层。我们扩展上节的单层神经网络,在右边新加一个层次(只含有一个节点)。

      现在,我们的权值矩阵增加到了两个,我们用上标来区分不同层次之间的变量。

      例如ax(y)代表第y层的第x个节点。z1,z2变成了a1(2),a2(2)。下图给出了a1(2),a2(2)的计算公式。

    图20 两层神经网络(中间层计算)

     

      计算最终输出z的方式是利用了中间层的a1(2),a2(2)和第二个权值矩阵计算得到的,如下图。

    图21 两层神经网络(输出层计算)

     

      假设我们的预测目标是一个向量,那么与前面类似,只需要在“输出层”再增加节点即可。

      我们使用向量和矩阵来表示层次中的变量。a(1),a(2),z是网络中传输的向量数据。W(1)和W(2)是网络的矩阵参数。如下图。

    图22 两层神经网络(向量形式)

     

      使用矩阵运算来表达整个计算公式的话如下:

      g(W(1) * a(1)) = a(2); 

    g(W(2) * a(2)) = z;

     

      由此可见,使用矩阵运算来表达是很简洁的,而且也不会受到节点数增多的影响(无论有多少节点参与运算,乘法两端都只有一个变量)。因此神经网络的教程中大量使用矩阵运算来描述。

      需要说明的是,至今为止,我们对神经网络的结构图的讨论中都没有提到偏置节点(bias unit)。事实上,这些节点是默认存在的。它本质上是一个只含有存储功能,且存储值永远为1的单元。在神经网络的每个层次中,除了输出层以外,都会含有这样一个偏置单元。正如线性回归模型与逻辑回归模型中的一样。

      偏置单元与后一层的所有节点都有连接,我们设这些参数值为向量b,称之为偏置。如下图。

    图23 两层神经网络(考虑偏置节点)

     

      可以看出,偏置节点很好认,因为其没有输入(前一层中没有箭头指向它)。有些神经网络的结构图中会把偏置节点明显画出来,有些不会。一般情况下,我们都不会明确画出偏置节点。 

      在考虑了偏置以后的一个神经网络的矩阵运算如下:

      g(W(1) * a(1) + b(1)) = a(2); 

    g(W(2) * a(2) + b(2)) = z;

     

      需要说明的是,在两层神经网络中,我们不再使用sgn函数作为函数g,而是使用平滑函数sigmoid作为函数g。我们把函数g也称作激活函数(active function)。

      事实上,神经网络的本质就是通过参数与激活函数来拟合特征与目标之间的真实函数关系。初学者可能认为画神经网络的结构图是为了在程序中实现这些圆圈与线,但在一个神经网络的程序中,既没有“线”这个对象,也没有“单元”这个对象。实现一个神经网络最需要的是线性代数库。

      3.效果

      与单层神经网络不同。理论证明,两层神经网络可以无限逼近任意连续函数。

      这是什么意思呢?也就是说,面对复杂的非线性分类任务,两层(带一个隐藏层)神经网络可以分类的很好。

      下面就是一个例子(此两图来自colah的博客),红色的线与蓝色的线代表数据。而红色区域和蓝色区域代表由神经网络划开的区域,两者的分界线就是决策分界。

    图24 两层神经网络(决策分界)

      

      可以看到,这个两层神经网络的决策分界是非常平滑的曲线,而且分类的很好。有趣的是,前面已经学到过,单层网络只能做线性分类任务。而两层神经网络中的后一层也是线性分类层,应该只能做线性分类任务。为什么两个线性分类任务结合就可以做非线性分类任务?

      我们可以把输出层的决策分界单独拿出来看一下。就是下图。

    图25 两层神经网络(空间变换)

     

      可以看到,输出层的决策分界仍然是直线。关键就是,从输入层到隐藏层时,数据发生了空间变换。也就是说,两层神经网络中,隐藏层对原始的数据进行了一个空间变换,使其可以被线性分类,然后输出层的决策分界划出了一个线性分类分界线,对其进行分类。

      这样就导出了两层神经网络可以做非线性分类的关键--隐藏层。联想到我们一开始推导出的矩阵公式,我们知道,矩阵和向量相乘,本质上就是对向量的坐标空间进行一个变换。因此,隐藏层的参数矩阵的作用就是使得数据的原始坐标空间从线性不可分,转换成了线性可分。

      两层神经网络通过两层的线性模型模拟了数据内真实的非线性函数。因此,多层的神经网络的本质就是复杂函数拟合。

      下面来讨论一下隐藏层的节点数设计。在设计一个神经网络时,输入层的节点数需要与特征的维度匹配,输出层的节点数要与目标的维度匹配。而中间层的节点数,却是由设计者指定的。因此,“自由”把握在设计者的手中。但是,节点数设置的多少,却会影响到整个模型的效果。如何决定这个自由层的节点数呢?目前业界没有完善的理论来指导这个决策。一般是根据经验来设置。较好的方法就是预先设定几个可选值,通过切换这几个值来看整个模型的预测效果,选择效果最好的值作为最终选择。这种方法又叫做Grid Search(网格搜索)。

      了解了两层神经网络的结构以后,我们就可以看懂其它类似的结构图。例如EasyPR字符识别网络架构(下图)。

    图26 EasyPR字符识别网络

     

      EasyPR使用了字符的图像去进行字符文字的识别。输入是120维的向量。输出是要预测的文字类别,共有65类。根据实验,我们测试了一些隐藏层数目,发现当值为40时,整个网络在测试集上的效果较好,因此选择网络的最终结构就是120,40,65。

      4.训练

      下面简单介绍一下两层神经网络的训练。

      在Rosenblat提出的感知器模型中,模型中的参数可以被训练,但是使用的方法较为简单,并没有使用目前机器学习中通用的方法,这导致其扩展性与适用性非常有限。从两层神经网络开始,神经网络的研究人员开始使用机器学习相关的技术进行神经网络的训练。例如用大量的数据(1000-10000左右),使用算法进行优化等等,从而使得模型训练可以获得性能与数据利用上的双重优势。

      机器学习模型训练的目的,就是使得参数尽可能的与真实的模型逼近。具体做法是这样的。首先给所有参数赋上随机值。我们使用这些随机生成的参数值,来预测训练数据中的样本。样本的预测目标为yp,真实目标为y。那么,定义一个值loss,计算公式如下。

    loss = (yp - y)2

     

      这个值称之为损失(loss),我们的目标就是使对所有训练数据的损失和尽可能的小。

      如果将先前的神经网络预测的矩阵公式带入到yp中(因为有z=yp),那么我们可以把损失写为关于参数(parameter)的函数,这个函数称之为损失函数(loss function)。下面的问题就是求:如何优化参数,能够让损失函数的值最小。

      此时这个问题就被转化为一个优化问题。一个常用方法就是高等数学中的求导,但是这里的问题由于参数不止一个,求导后计算导数等于0的运算量很大,所以一般来说解决这个优化问题使用的是梯度下降算法。梯度下降算法每次计算参数在当前的梯度,然后让参数向着梯度的反方向前进一段距离,不断重复,直到梯度接近零时截止。一般这个时候,所有的参数恰好达到使损失函数达到一个最低值的状态。

      在神经网络模型中,由于结构复杂,每次计算梯度的代价很大。因此还需要使用反向传播算法。反向传播算法是利用了神经网络的结构进行的计算。不一次计算所有参数的梯度,而是从后往前。首先计算输出层的梯度,然后是第二个参数矩阵的梯度,接着是中间层的梯度,再然后是第一个参数矩阵的梯度,最后是输入层的梯度。计算结束以后,所要的两个参数矩阵的梯度就都有了。

      反向传播算法可以直观的理解为下图。梯度的计算从后往前,一层层反向传播。前缀E代表着相对导数的意思。

    图27 反向传播算法

     

      反向传播算法的启示是数学中的链式法则。在此需要说明的是,尽管早期神经网络的研究人员努力从生物学中得到启发,但从BP算法开始,研究者们更多地从数学上寻求问题的最优解。不再盲目模拟人脑网络是神经网络研究走向成熟的标志。正如科学家们可以从鸟类的飞行中得到启发,但没有必要一定要完全模拟鸟类的飞行方式,也能制造可以飞天的飞机。

      优化问题只是训练中的一个部分。机器学习问题之所以称为学习问题,而不是优化问题,就是因为它不仅要求数据在训练集上求得一个较小的误差,在测试集上也要表现好。因为模型最终是要部署到没有见过训练数据的真实场景。提升模型在测试集上的预测效果的主题叫做泛化(generalization),相关方法被称作正则化(regularization)。神经网络中常用的泛化技术有权重衰减等。

      5.影响

      两层神经网络在多个地方的应用说明了其效用与价值。10年前困扰神经网络界的异或问题被轻松解决。神经网络在这个时候,已经可以发力于语音识别,图像识别,自动驾驶等多个领域。

      历史总是惊人的相似,神经网络的学者们再次登上了《纽约时报》的专访。人们认为神经网络可以解决许多问题。就连娱乐界都开始受到了影响,当年的《终结者》电影中的阿诺都赶时髦地说一句:我的CPU是一个神经网络处理器,一个会学习的计算机。

      但是神经网络仍然存在若干的问题:尽管使用了BP算法,一次神经网络的训练仍然耗时太久,而且困扰训练优化的一个问题就是局部最优解问题,这使得神经网络的优化较为困难。同时,隐藏层的节点数需要调参,这使得使用不太方便,工程和研究人员对此多有抱怨。

      90年代中期,由Vapnik等人发明的SVM(Support Vector Machines,支持向量机)算法诞生,很快就在若干个方面体现出了对比神经网络的优势:无需调参;高效;全局最优解。基于以上种种理由,SVM迅速打败了神经网络算法成为主流。

    图28 Vladimir Vapnik

     

      神经网络的研究再次陷入了冰河期。当时,只要你的论文中包含神经网络相关的字眼,非常容易被会议和期刊拒收,研究界那时对神经网络的不待见可想而知。

     

    五. 多层神经网络(深度学习)

      1.引子  

      在被人摒弃的10年中,有几个学者仍然在坚持研究。这其中的棋手就是加拿大多伦多大学的Geoffery Hinton教授。

      2006年,Hinton在《Science》和相关期刊上发表了论文,首次提出了“深度信念网络”的概念。与传统的训练方式不同,“深度信念网络”有一个“预训练”(pre-training)的过程,这可以方便的让神经网络中的权值找到一个接近最优解的值,之后再使用“微调”(fine-tuning)技术来对整个网络进行优化训练。这两个技术的运用大幅度减少了训练多层神经网络的时间。他给多层神经网络相关的学习方法赋予了一个新名词--“深度学习”。

       很快,深度学习在语音识别领域暂露头角。接着,2012年,深度学习技术又在图像识别领域大展拳脚。Hinton与他的学生在ImageNet竞赛中,用多层的卷积神经网络成功地对包含一千类别的一百万张图片进行了训练,取得了分类错误率15%的好成绩,这个成绩比第二名高了近11个百分点,充分证明了多层神经网络识别效果的优越性。

      在这之后,关于深度神经网络的研究与应用不断涌现。

    图29 Geoffery Hinton 

     

      由于篇幅原因,本文不介绍CNN(Conventional Neural Network,卷积神经网络)与RNN(Recurrent Neural Network,递归神经网络)的架构,下面我们只讨论普通的多层神经网络。

      2.结构

      我们延续两层神经网络的方式来设计一个多层神经网络。

      在两层神经网络的输出层后面,继续添加层次。原来的输出层变成中间层,新加的层次成为新的输出层。所以可以得到下图。

    图30 多层神经网络

     

      依照这样的方式不断添加,我们可以得到更多层的多层神经网络。公式推导的话其实跟两层神经网络类似,使用矩阵运算的话就仅仅是加一个公式而已。

      在已知输入a(1),参数W(1),W(2),W(3)的情况下,输出z的推导公式如下:

         g(W(1) * a(1)) = a(2); 

        g(W(2) * a(2)) = a(3);

    g(W(3) * a(3)) = z;

     

      多层神经网络中,输出也是按照一层一层的方式来计算。从最外面的层开始,算出所有单元的值以后,再继续计算更深一层。只有当前层所有单元的值都计算完毕以后,才会算下一层。有点像计算向前不断推进的感觉。所以这个过程叫做“正向传播”。

      下面讨论一下多层神经网络中的参数。

      首先我们看第一张图,可以看出W(1)中有6个参数,W(2)中有4个参数,W(3)中有6个参数,所以整个神经网络中的参数有16个(这里我们不考虑偏置节点,下同)。

    图31 多层神经网络(较少参数)

     

      假设我们将中间层的节点数做一下调整。第一个中间层改为3个单元,第二个中间层改为4个单元。

      经过调整以后,整个网络的参数变成了33个。

    图32 多层神经网络(较多参数)

     

      虽然层数保持不变,但是第二个神经网络的参数数量却是第一个神经网络的接近两倍之多,从而带来了更好的表示(represention)能力。表示能力是多层神经网络的一个重要性质,下面会做介绍。

      在参数一致的情况下,我们也可以获得一个“更深”的网络。

    图33 多层神经网络(更深的层次)

     

      上图的网络中,虽然参数数量仍然是33,但却有4个中间层,是原来层数的接近两倍。这意味着一样的参数数量,可以用更深的层次去表达。

      3.效果

      与两层层神经网络不同。多层神经网络中的层数增加了很多。

      增加更多的层次有什么好处?更深入的表示特征,以及更强的函数模拟能力。

      更深入的表示特征可以这样理解,随着网络的层数增加,每一层对于前一层次的抽象表示更深入。在神经网络中,每一层神经元学习到的是前一层神经元值的更抽象的表示。例如第一个隐藏层学习到的是“边缘”的特征,第二个隐藏层学习到的是由“边缘”组成的“形状”的特征,第三个隐藏层学习到的是由“形状”组成的“图案”的特征,最后的隐藏层学习到的是由“图案”组成的“目标”的特征。通过抽取更抽象的特征来对事物进行区分,从而获得更好的区分与分类能力。

      关于逐层特征学习的例子,可以参考下图。

    图34 多层神经网络(特征学习)

     

      更强的函数模拟能力是由于随着层数的增加,整个网络的参数就越多。而神经网络其实本质就是模拟特征与目标之间的真实关系函数的方法,更多的参数意味着其模拟的函数可以更加的复杂,可以有更多的容量(capcity)去拟合真正的关系。

      通过研究发现,在参数数量一样的情况下,更深的网络往往具有比浅层的网络更好的识别效率。这点也在ImageNet的多次大赛中得到了证实。从2012年起,每年获得ImageNet冠军的深度神经网络的层数逐年增加,2015年最好的方法GoogleNet是一个多达22层的神经网络。

      在最新一届的ImageNet大赛上,目前拿到最好成绩的MSRA团队的方法使用的更是一个深达152层的网络!关于这个方法更多的信息有兴趣的可以查阅ImageNet网站。

      4.训练

      在单层神经网络时,我们使用的激活函数是sgn函数。到了两层神经网络时,我们使用的最多的是sigmoid函数。而到了多层神经网络时,通过一系列的研究发现,ReLU函数在训练多层神经网络时,更容易收敛,并且预测性能更好。因此,目前在深度学习中,最流行的非线性函数是ReLU函数。ReLU函数不是传统的非线性函数,而是分段线性函数。其表达式非常简单,就是y=max(x,0)。简而言之,在x大于0,输出就是输入,而在x小于0时,输出就保持为0。这种函数的设计启发来自于生物神经元对于激励的线性响应,以及当低于某个阈值后就不再响应的模拟。

      在多层神经网络中,训练的主题仍然是优化和泛化。当使用足够强的计算芯片(例如GPU图形加速卡)时,梯度下降算法以及反向传播算法在多层神经网络中的训练中仍然工作的很好。目前学术界主要的研究既在于开发新的算法,也在于对这两个算法进行不断的优化,例如,增加了一种带动量因子(momentum)的梯度下降算法。 

      在深度学习中,泛化技术变的比以往更加的重要。这主要是因为神经网络的层数增加了,参数也增加了,表示能力大幅度增强,很容易出现过拟合现象。因此正则化技术就显得十分重要。目前,Dropout技术,以及数据扩容(Data-Augmentation)技术是目前使用的最多的正则化技术。

      5.影响

      目前,深度神经网络在人工智能界占据统治地位。但凡有关人工智能的产业报道,必然离不开深度学习。神经网络界当下的四位引领者除了前文所说的Ng,Hinton以外,还有CNN的发明人Yann Lecun,以及《Deep Learning》的作者Bengio。

      前段时间一直对人工智能持谨慎态度的马斯克,搞了一个OpenAI项目,邀请Bengio作为高级顾问。马斯克认为,人工智能技术不应该掌握在大公司如Google,Facebook的手里,更应该作为一种开放技术,让所有人都可以参与研究。马斯克的这种精神值得让人敬佩。

       

    图35 Yann LeCun(左)和 Yoshua Bengio(右)

     

      多层神经网络的研究仍在进行中。现在最为火热的研究技术包括RNN,LSTM等,研究方向则是图像理解方面。图像理解技术是给计算机一幅图片,让它用语言来表达这幅图片的意思。ImageNet竞赛也在不断召开,有更多的方法涌现出来,刷新以往的正确率。

     

    六. 回顾

      1.影响  

      我们回顾一下神经网络发展的历程。神经网络的发展历史曲折荡漾,既有被人捧上天的时刻,也有摔落在街头无人问津的时段,中间经历了数次大起大落。

      从单层神经网络(感知器)开始,到包含一个隐藏层的两层神经网络,再到多层的深度神经网络,一共有三次兴起过程。详见下图。

    图36 三起三落的神经网络

     

      上图中的顶点与谷底可以看作神经网络发展的高峰与低谷。图中的横轴是时间,以年为单位。纵轴是一个神经网络影响力的示意表示。如果把1949年Hebb模型提出到1958年的感知机诞生这个10年视为落下(没有兴起)的话,那么神经网络算是经历了“三起三落”这样一个过程,跟“小平”同志类似。俗话说,天将降大任于斯人也,必先苦其心志,劳其筋骨。经历过如此多波折的神经网络能够在现阶段取得成功也可以被看做是磨砺的积累吧。

      历史最大的好处是可以给现在做参考。科学的研究呈现螺旋形上升的过程,不可能一帆风顺。同时,这也给现在过分热衷深度学习与人工智能的人敲响警钟,因为这不是第一次人们因为神经网络而疯狂了。1958年到1969年,以及1985年到1995,这两个十年间人们对于神经网络以及人工智能的期待并不现在低,可结果如何大家也能看的很清楚。

      因此,冷静才是对待目前深度学习热潮的最好办法。如果因为深度学习火热,或者可以有“钱景”就一窝蜂的涌入,那么最终的受害人只能是自己。神经网络界已经两次有被人们捧上天了的境况,相信也对于捧得越高,摔得越惨这句话深有体会。因此,神经网络界的学者也必须给这股热潮浇上一盆水,不要让媒体以及投资家们过分的高看这门技术。很有可能,三十年河东,三十年河西,在几年后,神经网络就再次陷入谷底。根据上图的历史曲线图,这是很有可能的。

      2.效果  

      下面说一下神经网络为什么能这么火热?简而言之,就是其学习效果的强大。随着神经网络的发展,其表示性能越来越强。

      从单层神经网络,到两层神经网络,再到多层神经网络,下图说明了,随着网络层数的增加,以及激活函数的调整,神经网络所能拟合的决策分界平面的能力。

    图37 表示能力不断增强

     

      可以看出,随着层数增加,其非线性分界拟合能力不断增强。图中的分界线并不代表真实训练出的效果,更多的是示意效果。

      神经网络的研究与应用之所以能够不断地火热发展下去,与其强大的函数拟合能力是分不开关系的。

      3.外因  

      当然,光有强大的内在能力,并不一定能成功。一个成功的技术与方法,不仅需要内因的作用,还需要时势与环境的配合。神经网络的发展背后的外在原因可以被总结为:更强的计算性能,更多的数据,以及更好的训练方法。只有满足这些条件时,神经网络的函数拟合能力才能得已体现,见下图。

    图38 发展的外在原因

     

      之所以在单层神经网络年代,Rosenblat无法制作一个双层分类器,就在于当时的计算性能不足,Minsky也以此来打压神经网络。但是Minsky没有料到,仅仅10年以后,计算机CPU的快速发展已经使得我们可以做两层神经网络的训练,并且还有快速的学习算法BP。

      但是在两层神经网络快速流行的年代。更高层的神经网络由于计算性能的问题,以及一些计算方法的问题,其优势无法得到体现。直到2012年,研究人员发现,用于高性能计算的图形加速卡(GPU)可以极佳地匹配神经网络训练所需要的要求:高并行性,高存储,没有太多的控制需求,配合预训练等算法,神经网络才得以大放光彩。

      互联网时代,大量的数据被收集整理,更好的训练方法不断被发现。所有这一切都满足了多层神经网络发挥能力的条件。

      “时势造英雄”,正如Hinton在2006年的论文里说道的

      “... provided that computers were fast enough, data sets were big enough, and the initial weights were close enough to a good solution. All three conditions are now satisfied.”,

     

      外在条件的满足也是神经网络从神经元得以发展到目前的深度神经网络的重要因素。

      除此以外,一门技术的发扬没有“伯乐”也是不行的。在神经网络漫长的历史中,正是由于许多研究人员的锲而不舍,不断钻研,才能有了现在的成就。前期的Rosenblat,Rumelhart没有见证到神经网络如今的流行与地位。但是在那个时代,他们为神经网络的发展所打下的基础,却会永远流传下去,不会退色。

     

    七. 展望

      1.量子计算

      回到我们对神经网络历史的讨论,根据历史趋势图来看,神经网络以及深度学习会不会像以往一样再次陷入谷底?作者认为,这个过程可能取决于量子计算机的发展。

      根据一些最近的研究发现,人脑内部进行的计算可能是类似于量子计算形态的东西。而且目前已知的最大神经网络跟人脑的神经元数量相比,仍然显得非常小,仅不及1%左右。所以未来真正想实现人脑神经网络的模拟,可能需要借助量子计算的强大计算能力。

      各大研究组也已经认识到了量子计算的重要性。谷歌就在开展量子计算机D-wave的研究,希望用量子计算来进行机器学习,并且在前段时间有了突破性的进展。国内方面,阿里和中科院合作成立了量子计算实验室,意图进行量子计算的研究。

      如果量子计算发展不力,仍然需要数十年才能使我们的计算能力得以突飞猛进的发展,那么缺少了强大计算能力的神经网络可能会无法一帆风顺的发展下去。这种情况可以类比为80-90年时期神经网络因为计算能力的限制而被低估与忽视。假设量子计算机真的能够与神经网络结合,并且助力真正的人工智能技术的诞生,而且量子计算机发展需要10年的话,那么神经网络可能还有10年的发展期。直到那时期以后,神经网络才能真正接近实现AI这一目标。

    图39 量子计算

     

      2.人工智能

      最后,作者想简单地谈谈对目前人工智能的看法。虽然现在人工智能非常火热,但是距离真正的人工智能还有很大的距离。就拿计算机视觉方向来说,面对稍微复杂一些的场景,以及易于混淆的图像,计算机就可能难以识别。因此,这个方向还有很多的工作要做。

      就普通人看来,这么辛苦的做各种实验,以及投入大量的人力就是为了实现一些不及孩童能力的视觉能力,未免有些不值。但是这只是第一步。虽然计算机需要很大的运算量才能完成一个普通人简单能完成的识图工作,但计算机最大的优势在于并行化与批量推广能力。使用计算机以后,我们可以很轻易地将以前需要人眼去判断的工作交给计算机做,而且几乎没有任何的推广成本。这就具有很大的价值。正如火车刚诞生的时候,有人嘲笑它又笨又重,速度还没有马快。但是很快规模化推广的火车就替代了马车的使用。人工智能也是如此。这也是为什么目前世界上各著名公司以及政府都对此热衷的原因。

      目前看来,神经网络要想实现人工智能还有很多的路要走,但方向至少是正确的,下面就要看后来者的不断努力了。

    图40 人工智能

     

    八 总结

      本文回顾了神经网络的发展历史,从神经元开始,历经单层神经网络,两层神经网络,直到多层神经网络。在历史介绍中穿插讲解神经网络的结构,分类效果以及训练方法等。本文说明了神经网络内部实际上就是矩阵计算,在程序中的实现没有“点”和“线”的对象。本文说明了神经网络强大预测能力的根本,就是多层的神经网络可以无限逼近真实的对应函数,从而模拟数据之间的真实关系。除此之外,本文回顾了神经网络发展的历程,分析了神经网络发展的外在原因,包括计算能力的增强,数据的增多,以及方法的创新等。最后,本文对神经网络的未来进行了展望,包括量子计算与神经网络结合的可能性,以及探讨未来人工智能发展的前景与价值。

     

    九. 后记

      本篇文章可以视为作者一年来对神经网络的理解与总结,包括实验的体会,书籍的阅读,以及思考的火花等。神经网络虽然重要,但学习并不容易。这主要是由于其结构图较为难懂,以及历史发展的原因,导致概念容易混淆,一些介绍的博客与网站内容新旧不齐。本篇文章着眼于这些问题,没有太多的数学推导,意图以一种简单的,直观的方式对神经网络进行讲解。在2015年最后一天终于写完。希望本文可以对各位有所帮助。

     

     

      作者很感谢能够阅读到这里的读者。如果看完觉得好的话,还请轻轻点一下赞,你们的鼓励就是作者继续行文的动力。本文的备注部分是一些对神经网络学习的建议,供补充阅读与参考。

      

      目前为止,EasyPR的1.4版已经将神经网络(ANN)训练的模块加以开放,开发者们可以使用这个模块来进行自己的字符模型的训练。有兴趣的可以下载

     

    十. 备注

      神经网络虽然很重要,但是对于神经网络的学习,却并不容易。这些学习困难主要来自以下三个方面:概念,类别,教程。下面简单说明这三点。

      1.概念

      对于一门技术的学习而言,首先最重要的是弄清概念。只有将概念理解清楚,才能顺畅的进行后面的学习。由于神经网络漫长的发展历史,经常会有一些概念容易混淆,让人学习中产生困惑。这里面包括历史的术语,不一致的说法,以及被遗忘的研究等。 

      历史的术语

      这个的代表就是多层感知器(MLP)这个术语。起初看文献时很难理解的一个问题就是,为什么神经网络又有另一个名称:MLP。其实MLP(Multi-Layer Perceptron)的名称起源于50-60年代的感知器(Perceptron)。由于我们在感知器之上又增加了一个计算层,因此称为多层感知器。值得注意的是,虽然叫“多层”,MLP一般都指的是两层(带一个隐藏层的)神经网络。

      MLP这个术语属于历史遗留的产物。现在我们一般就说神经网络,以及深度神经网络。前者代表带一个隐藏层的两层神经网络,也是EasyPR目前使用的识别网络,后者指深度学习的网络。

      不一致的说法

      这个最明显的代表就是损失函数loss function,这个还有两个说法是跟它完全一致的意思,分别是残差函数error function,以及代价函数cost function。loss function是目前深度学习里用的较多的一种说法,caffe里也是这么叫的。cost function则是Ng在coursera教学视频里用到的统一说法。这三者都是同一个意思,都是优化问题所需要求解的方程。虽然在使用的时候不做规定,但是在听到各种讲解时要心里明白。

      再来就是权重weight和参数parameter的说法,神经网络界由于以前的惯例,一般会将训练得到的参数称之为权重,而不像其他机器学习方法就称之为参数。这个需要记住就好。不过在目前的使用惯例中,也有这样一种规定。那就是非偏置节点连接上的值称之为权重,而偏置节点上的值称之为偏置,两者统一起来称之为参数。

      另外一个同义词就是激活函数active function和转移函数transfer function了。同样,他们代表一个意思,都是叠加的非线性函数的说法。

      被遗忘的研究

      由于神经网络发展历史已经有70年的漫长历史,因此在研究过程中,必然有一些研究分支属于被遗忘阶段。这里面包括各种不同的网络,例如SOM(Self-Organizing Map,自组织特征映射网络),SNN(Synergetic Neural Network,协同神经网络),ART(Adaptive Resonance Theory,自适应共振理论网络)等等。所以看历史文献时会看到许多没见过的概念与名词。

      有些历史网络甚至会重新成为新的研究热点,例如RNN与LSTM就是80年代左右开始的研究,目前已经是深度学习研究中的重要一门技术,在语音与文字识别中有很好的效果。 

      对于这些易于混淆以及弄错的概念,务必需要多方参考文献,理清上下文,这样才不会在学习与阅读过程中迷糊。

      2.类别

      下面谈一下关于神经网络中的不同类别。

      其实本文的名字“神经网络浅讲”并不合适,因为本文并不是讲的是“神经网络”的内容,而是其中的一个子类,也是目前最常说的前馈神经网络。根据下图的分类可以看出。

    图41 神经网络的类别

     

      神经网络其实是一个非常宽泛的称呼,它包括两类,一类是用计算机的方式去模拟人脑,这就是我们常说的ANN(人工神经网络),另一类是研究生物学上的神经网络,又叫生物神经网络。对于我们计算机人士而言,肯定是研究前者。

      在人工神经网络之中,又分为前馈神经网络和反馈神经网络这两种。那么它们两者的区别是什么呢?这个其实在于它们的结构图。我们可以把结构图看作是一个有向图。其中神经元代表顶点,连接代表有向边。对于前馈神经网络中,这个有向图是没有回路的。你可以仔细观察本文中出现的所有神经网络的结构图,确认一下。而对于反馈神经网络中,结构图的有向图是有回路的。反馈神经网络也是一类重要的神经网络。其中Hopfield网络就是反馈神经网络。深度学习中的RNN也属于一种反馈神经网络。

      具体到前馈神经网络中,就有了本文中所分别描述的三个网络:单层神经网络,双层神经网络,以及多层神经网络。深度学习中的CNN属于一种特殊的多层神经网络。另外,在一些Blog中和文献中看到的BP神经网络是什么?其实它们就是使用了反向传播BP算法的两层前馈神经网络。也是最普遍的一种两层神经网络。

      通过以上分析可以看出,神经网络这种说法其实是非常广义的,具体在文章中说的是什么网络,需要根据文中的内容加以区分。

      3.教程

      如何更好的学习神经网络,认真的学习一门课程或者看一本著作都是很有必要的。

      说到网络教程的话,这里必须说一下Ng的机器学习课程。对于一个初学者而言,Ng的课程视频是非常有帮助的。Ng一共开设过两门机器学习公开课程:一个是2003年在Standford开设的,面向全球的学生,这个视频现在可以在网易公开课上找到;另一个是2010年专门为Coursera上的用户开设的,需要登陆Coursera上才能学习。

      但是,需要注意点是,这两个课程对待神经网络的态度有点不同。早些的课程一共有20节课,Ng花了若干节课去专门讲SVM以及SVM的推导,而当时的神经网络,仅仅放了几段视频,花了大概不到20分钟(一节课60分钟左右)。而到了后来的课程时,总共10节的课程中,Ng给了完整的两节给神经网络,详细介绍了神经网络的反向传播算法。同时给SVM只有一节课,并且没有再讲SVM的推导过程。下面两张图分别是Ng介绍神经网络的开篇,可以大致看出一些端倪。

    图42 Ng与神经网络

     

      为什么Ng对待神经网络的反应前后相差那么大?事实上就是深度学习的原因。Ng实践了深度学习的效果,认识到深度学习的基础--神经网络的重要性。这就是他在后面重点介绍神经网络的原因。总之,对于神经网络的学习而言,我更推荐Coursera上的。因为在那个时候,Ng才是真正的把神经网络作为一门重要的机器学习方法去传授。你可以从他上课的态度中感受到他的重视,以及他希望你能学好的期望。

     

    版权说明:

      本文中的所有文字,图片,代码的版权都是属于作者和博客园共同所有。欢迎转载,但是务必注明作者与出处。任何未经允许的剽窃以及爬虫抓取都属于侵权,作者和博客园保留所有权利。

      

    参考文献:

      1.Neural Networks

      2.Andrew Ng Neural Networks 

      3.神经网络简史

      4.中科院 史忠植 神经网络 讲义

      5.深度学习 胡晓林

     

     

     这是转发博客园的一篇文章,博主:计算机的潜意识,目前是南大的人工智能方向的在读博士。博客里写了一些机器学习入门的内容,以及分享了他在github上的一个开源项目EasyPR,车牌识别系统。能为初学者提供非常大的帮助,有兴趣的朋友请务必移步前往,一看究竟。

    原文链接:https://www.cnblogs.com/subconscious/p/5058741.html

    展开全文
  • 神经网络学习 之 BP神经网络

    万次阅读 多人点赞 2015-11-30 21:17:56
    上一次我们讲了M-P模型,它实际上就是对单个神经元的一种建模,...本文具体来介绍一下一种非常常见的神经网络模型——反向传播(Back Propagation)神经网络。概述BP(Back Propagation)神经网络是1986年由Rumelhart和Mc

    上一次我们讲了M-P模型,它实际上就是对单个神经元的一种建模,还不足以模拟人脑神经系统的功能。由这些人工神经元构建出来的网络,才能够具有学习、联想、记忆和模式识别的能力。BP网络就是一种简单的人工神经网络。
    本文具体来介绍一下一种非常常见的神经网络模型——反向传播(Back Propagation)神经网络。

    概述

    BP(Back Propagation)神经网络是1986年由Rumelhart和McCelland为首的科研小组提出,参见他们发表在Nature上的论文 Learning representations by back-propagating errors

    BP神经网络是一种按误差逆传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一。BP网络能学习和存贮大量的 输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。它的学习规则是使用最速下降法,通过反向传播来不断 调整网络的权值和阈值,使网络的误差平方和最小。

    BP算法的基本思想

    上一次我们说到,多层感知器在如何获取隐层的权值的问题上遇到了瓶颈。既然我们无法直接得到隐层的权值,能否先通过输出层得到输出结果和期望输出的误差来间接调整隐层的权值呢?BP算法就是采用这样的思想设计出来的算法,它的基本思想是,学习过程由信号的正向传播与误差的反向传播两个过程组成。

    • 正向传播时,输入样本从输入层传入,经各隐层逐层处理后,传向输出层。若输出层的实际输出与期望的输出(教师信号)不符,则转入误差的反向传播阶段。
    • 反向传播时,将输出以某种形式通过隐层向输入层逐层反传,并将误差分摊给各层的所有单元,从而获得各层单元的误差信号,此误差信号即作为修正各单元权值的依据。

    这两个过程的具体流程会在后文介绍。

    BP算法的信号流向图如下图所示
    在这里插入图片描述
    BP网络特性分析——BP三要素

    我们分析一个ANN时,通常都是从它的三要素入手,即
    1)网络拓扑结构;
    2)传递函数;
    3)学习算法。

    在这里插入图片描述

    每一个要素的特性加起来就决定了这个ANN的功能特性。所以,我们也从这三要素入手对BP网络的研究。

    3.1 BP网络的拓扑结构

    上一次已经说了,BP网络实际上就是多层感知器,因此它的拓扑结构和多层感知器的拓扑结构相同。由于单隐层(三层)感知器已经能够解决简单的非线性问题,因此应用最为普遍。三层感知器的拓扑结构如下图所示。
    一个最简单的三层BP:
    这里写图片描述
    ###3.2 BP网络的传递函数
    BP网络采用的传递函数是非线性变换函数——Sigmoid函数(又称S函数)。其特点是函数本身及其导数都是连续的,因而在处理上十分方便。为什么要选择这个函数,等下在介绍BP网络的学习算法的时候会进行进一步的介绍。
    单极性S型函数曲线如下图所示。
    f(x)=11+exf(x)={1\over 1+e^{-x}}
    这里写图片描述
    双极性S型函数曲线如下图所示。
    f(x)=1ex1+exf(x)={1-e^{-x}\over 1+e^{-x}}

    这里写图片描述

    3.3 BP网络的学习算法

    BP网络的学习算法就是BP算法,又叫 δ 算法(在ANN的学习过程中我们会发现不少具有多个名称的术语), 以三层感知器为例,当网络输出与期望输出不等时,存在输出误差 E ,定义如下

    E=12(dO)2=12κ=1(dkok)2E={1\over 2}(d−O)^2={1\over 2}∑_{κ=1}^ℓ(d_k−o_k)^2

    将以上误差定义式展开至隐层,有
    E=12κ=1[dκf(netκ)]2=12κ=1[dκf(j=0mωjκyj)]2E={1\over 2}∑_{κ=1}^ℓ[d_κ−f(net_κ)]^2={1\over 2}∑_{κ=1}^ℓ[d_κ−f(∑_{j=0}^mω_{jκ}y_j)]^2

    进一步展开至输入层,有
    E=12κ=1dκf[j=0mωjκf(netj)]2=12κ=1dκf[j=0mωjκf(j=0nυijχi)]2E={1\over 2}∑_{κ=1}^ℓ{d_κ−f[∑_{j=0}^mω_{jκ}f(net_j)]}^2={1\over 2}∑_{κ=1}^ℓ{d_κ−f[∑_{j=0}^mω_{jκ}f(∑_{j=0}^nυ_{ij}χ_i)]}^2

    由上式可以看出,网络输入误差是各层权值ωjκω_{jκ}υijυ_{ij}的函数,因此调整权值可改变误差 EE。 显然,调整权值的原则是使误差不断减小,因此应使权值与误差的梯度下降成正比,即
    Δωjκ=ηEωjκj=0,1,2,,m;κ=1,2,,Δω_{jκ}=−η{∂E\over ∂ω_{jκ}}j=0,1,2,…,m;κ=1,2,…,ℓ

    Δυij=ηEυiji=0,1,2,,n;j=1,2,,mΔυ_{ij}=−η{∂E∂\over υ_{ij}}i=0,1,2,…,n;j=1,2,…,m

    对于一般多层感知器,设共有 hh 个隐层,按前向顺序各隐层节点数分别记为 m1,m2,,mhm_1,m_2,…,m_h,各隐层输出分别记为 y1,y2,,yhy_1,y_2,…,y_h,各层权值矩阵分别记为 W1,W2,,Wh,Wh+1W_1,W_2,…,W_h,W_{h+1},则各层权值调整公式为

    输出层

    Δωjκh+1=ηδh+1κyjh=η(dκoκ)oκ(1oκ)yjκ(j=0,1,2,,mh;κ=1,2,,ℓ)Δω^{h+1}_{jκ}=ηδ_{h+1}^κy^h_j=η(d_κ−o_κ)o_κ(1−o_κ)y^κ_j\tag{j=0,1,2,…,mh;κ=1,2,…,ℓ}

    hh 隐层

    Δωijh=ηδjhyih1=η(κ=1lδκoωjκh+1yjκ(1yjkappa)yih1(i=0,1,2,,m(h−1);j=1,2,,mh)Δω^h_{ij}=ηδ^h_jy^h_i−1=η(∑^l_{κ=1}δ^o_κω^{h+1}_{jκ}y^κ_j(1−y^k_jappa)y^h_i−1\tag{i=0,1,2,…,m(h−1);j=1,2,…,$m_h$}

    按以上规律逐层类推,则第一隐层权值调整公式

    Δωpq1=ηδq1χp=η(r=1m2δ2rωqr2)yq1(1yq1)χp(p=0,1,2,,n;j=1,2,,m1)Δω^1_{pq}=ηδ^1_qχ_p=η(∑^{m_2}_{r=1}δ……2——rω^2_{qr})y^1_q(1−y^1_q)χ_p\tag{p=0,1,2,…,n;j=1,2,…,$m_1$}

    容易看出,BP学习算法中,各层权值调整公式形式上都是一样的,均由3个因素决定,即:

    1. 学习率 ηη
    2. 本层输出的误差信号$ δ$
    3. 本层输入信号 YY(或XX

    其中输入层误差信号与网络的期望输出与实际输出之差有关,直接反应了输出误差,而各隐层的误差信号与前面各层的误差信号有关,是从输出层开始逐层反传过来的。

    可以看出BP算法属于δ学习规则类,这类算法常被称为误差的梯度下降算法。δ学习规则可以看成是Widrow-Hoff(LMS)学习规则的一般化(generalize)情况。LMS学习规则与神经元采用的变换函数无关,因而不需要对变换函数求导,δ学习规则则没有这个性质,要求变换函数可导。这就是为什么我们前面采用Sigmoid函数的原因。

    综上所述,BP三要素如下图所示。

    在这里插入图片描述

    下面我们会介绍BP网络的学习训练的具体过程。

    BP网络的训练分解

    训练一个BP神经网络,实际上就是调整网络的权重和偏置这两个参数,BP神经网络的训练过程分两部分:

    • 前向传输,逐层波浪式的传递输出值;
    • 逆向反馈,反向逐层调整权重和偏置;
      我们先来看前向传输。

    前向传输(Feed-Forward前向反馈)

    在训练网络之前,我们需要随机初始化权重和偏置,对每一个权重取[1,1][-1,1]的一个随机实数,每一个偏置取[0,1][0,1]的一个随机实数,之后就开始进行前向传输。

    神经网络的训练是由多趟迭代完成的,每一趟迭代都使用训练集的所有记录,而每一次训练网络只使用一条记录,抽象的描述如下:

    while 终止条件未满足:
        for record:dataset:
            trainModel(record)
    

    首先设置输入层的输出值,假设属性的个数为100,那我们就设置输入层的神经单元个数为100,输入层的结点NiN_i为记录第ii维上的属性值xix_i。对输入层的操作就这么简单,之后的每层就要复杂一些了,除输入层外,其他各层的输入值是上一层输入值按权重累加的结果值加上偏置,每个结点的输出值等该结点的输入值作变换
    这里写图片描述
    前向传输的输出层的计算过程公式如下:
    Ij=i=1ωijoi+θjI_j=\sum_{i=1}\omega_{ij}o_i+\theta_j
    oj=f(Ij)=11+eIjo_j=f(I_j)={1\over 1+e^{I_j}}
    对隐藏层和输出层的每一个结点都按照如上图的方式计算输出值,就完成前向传播的过程,紧接着是进行逆向反馈。

    逆向反馈(Backpropagation)

    逆向反馈从最后一层即输出层开始,我们训练神经网络作分类的目的往往是希望最后一层的输出能够描述数据记录的类别,比如对于一个二分类的问题,我们常常用两个神经单元作为输出层,如果输出层的第一个神经单元的输出值比第二个神经单元大,我们认为这个数据记录属于第一类,否则属于第二类。

    还记得我们第一次前向反馈时,整个网络的权重和偏置都是我们随机取,因此网络的输出肯定还不能描述记录的类别,因此需要调整网络的参数,即权重值和偏置值,而调整的依据就是网络的输出层的输出值与类别之间的差异,通过调整参数来缩小这个差异,这就是神经网络的优化目标。对于输出层:
    Ej=Oj(1Oj)(TjOj)E_j=O_j(1-O_j)(T_j-O_j)
    其中EjE_j表示第jj个结点的误差值,OjO_j表示第jj个结点的输出值,TjT_j记录输出值,比如对于2分类问题,我们用01表示类标1,10表示类别2,如果一个记录属于类别1,那么其T1=0T_1=0T2=1T_2=1

    中间的隐藏层并不直接与数据记录的类别打交道,而是通过下一层的所有结点误差按权重累加,计算公式如下:
    Ej=Oj(1Oj)kEkWjkE_j=O_j(1-O_j)\sum_kE_kW_{jk}
    其中WjkW_{jk}表示当前层的结点jj到下一层的结点kk的权重值,EkE_k下一层的结点kk的误差率。

    计算完误差率后,就可以利用误差率对权重和偏置进行更新,首先看权重的更新:
    这里写图片描述
    其中λλ表示表示学习速率,取值为0到1,学习速率设置得大,训练收敛更快,但容易陷入局部最优解,学习速率设置得比较小的话,收敛速度较慢,但能一步步逼近全局最优解。

    更新完权重后,还有最后一项参数需要更新,即偏置:
    这里写图片描述

    至此,我们完成了一次神经网络的训练过程,通过不断的使用所有数据记录进行训练,从而得到一个分类模型。不断地迭代,不可能无休止的下去,总归有个终止条件。

    训练终止条件

    每一轮训练都使用数据集的所有记录,但什么时候停止,停止条件有下面两种:

    1. 设置最大迭代次数,比如使用数据集迭代100次后停止训练
    2. 计算训练集在网络上的预测准确率,达到一定门限值后停止训练

    BP网络运行的具体流程

    网络结构

    输入层有nn个神经元,隐含层有pp个神经元,输出层有qq个神经元。

    变量定义

    输入变量:x=(x1,x2,,xn)x=(x_1,x_2,\dots,x_n)
    隐含层输入变量:hi=(hi1,hi2,,hip)hi=(hi_1,hi_2,\dots,hi_p)
    隐含层输出变量:ho=(ho1,ho2,,hop)ho=(ho_1,ho_2,\dots,ho_p)
    输出层输入变量:yi=(yi1,yi2,,yiq)yi=(yi_1,yi_2,\dots,yi_q)
    输出层输出变量:yo=(yo1,yo2,,yoq)yo=(yo_1,yo_2,\dots,yo_q)
    期望输出向量:do=(d1,d2,,dq)d_o=(d_1,d_2,\dots,d_q)
    输入层与中间层的连接权值:wihw_{ih}
    隐含层与输出层的连接权值:whow_{ho}
    隐含层各神经元的阈值:bhb_h
    输出层各神经元的阈值:bob_o
    样本数据个数:k=1,2,,mk=1,2,\dots,m
    激活函数:f()f(\cdot)
    误差函数:e=12o=1q(do(k)yoo(k))2e={1\over 2}\sum_{o=1}^{q}(d_o(k)-yo_o(k))^2
    ###第一步:网络初始化
    给各连接权值分别赋一个区间(1,1)(-1,1)内的随机数,设定误差函数ee,给定计算精度值ε\varepsilon和最大学习次数MM
    ###第二步:随机选取
    随机选取第kk个输入样本以及对应的期望输出
    x(k)=(x1(k),x2(k),,xn(k))do(k)=(d1(k),d2(k),,dq(k))x(k)=(x_1(k),x_2(k),\dots,x_n(k))\\ d_o(k)=(d_1(k),d_2(k),\dots,d_q(k))
    ###第三部:隐含层计算
    计算隐含层各神经元的输入和输出
    hih(k)=i=1nwihxi(k)bh(h=1,2,,p)hi_h(k)=\sum_{i=1}^nw_{ih}x_i(k)-b_h \tag{$h=1,2,\dots,p$}
    hih(k)=f(hih(k))(h=1,2,,p)hi_h(k)=f(hi_h(k)) \tag{$h=1,2,\dots,p$}
    yio(k)=h=1pwhohoh(k)bo(o=1,2,,q)yi_o(k)=\sum_{h=1}^pw_{ho}ho_h(k)-b_o \tag{o=1,2,$\dots$,q}
    yoo(k)=f(yio(k))(o=1,2,,q)yo_o(k)=f(yi_o(k))\tag{o=1,2,$\dots$,q}

    第四步:求偏导数

    利用网络期望输出和实际输出,计算误差函数对输出层的各神经元的偏导数δo(k)\delta_o(k)
    这里写图片描述这里写图片描述

    第六步:修正权值

    利用输出层各神经元的δo(k)\delta_o(k)和隐含层各神经元的输出来修正连接权值who(k)w_{ho}(k)
    这里写图片描述

    第七部:修正权值

    利用隐含层各神经元的δh(k)\delta_h(k)和输入层各神经元的输入修正连接权值。
    这里写图片描述

    第八步:计算全局误差

    E=12mk=1mo=1q(do(k)yo(k))2E={1\over 2m}\sum_{k=1}^m\sum_{o=1}^q(d_o(k)-y_o(k))^2

    第九步:判断模型合理性

    判断网络误差是否满足要求。
    当误差达到预设精度或者学习次数大于设计的最大次数,则结束算法。
    否则,选取下一个学习样本以及对应的输出期望,返回第三部,进入下一轮学习。

    BP网络的设计

    在进行BP网络的设计是,一般应从网络的层数、每层中的神经元个数和激活函数、初始值以及学习速率等几个方面来进行考虑,下面是一些选取的原则。

    1.网络的层数

    理论已经证明,具有偏差和至少一个S型隐层加上一个线性输出层的网络,能够逼近任何有理函数,增加层数可以进一步降低误差,提高精度,但同时也是网络 复杂化。另外不能用仅具有非线性激活函数的单层网络来解决问题,因为能用单层网络解决的问题,用自适应线性网络也一定能解决,而且自适应线性网络的 运算速度更快,而对于只能用非线性函数解决的问题,单层精度又不够高,也只有增加层数才能达到期望的结果。

    2.隐层神经元的个数

    网络训练精度的提高,可以通过采用一个隐含层,而增加其神经元个数的方法来获得,这在结构实现上要比增加网络层数简单得多。一般而言,我们用精度和 训练网络的时间来恒量一个神经网络设计的好坏:
    (1)神经元数太少时,网络不能很好的学习,训练迭代的次数也比较多,训练精度也不高。
    (2)神经元数太多时,网络的功能越强大,精确度也更高,训练迭代的次数也大,可能会出现过拟合(over fitting)现象。
    由此,我们得到神经网络隐层神经元个数的选取原则是:在能够解决问题的前提下,再加上一两个神经元,以加快误差下降速度即可。

    3.初始权值的选取

    一般初始权值是取值在(−1,1)之间的随机数。另外威得罗等人在分析了两层网络是如何对一个函数进行训练后,提出选择初始权值量级为s√r的策略, 其中r为输入个数,s为第一层神经元个数。

    4.学习速率

    学习速率一般选取为0.01−0.8,大的学习速率可能导致系统的不稳定,但小的学习速率导致收敛太慢,需要较长的训练时间。对于较复杂的网络, 在误差曲面的不同位置可能需要不同的学习速率,为了减少寻找学习速率的训练次数及时间,比较合适的方法是采用变化的自适应学习速率,使网络在 不同的阶段设置不同大小的学习速率。

    5.期望误差的选取

    在设计网络的过程中,期望误差值也应当通过对比训练后确定一个合适的值,这个合适的值是相对于所需要的隐层节点数来确定的。一般情况下,可以同时对两个不同 的期望误差值的网络进行训练,最后通过综合因素来确定其中一个网络。

    BP网络的局限性

    BP网络具有以下的几个问题:

    • (1)需要较长的训练时间:这主要是由于学习速率太小所造成的,可采用变化的或自适应的学习速率来加以改进。
    • (2)完全不能训练:这主要表现在网络的麻痹上,通常为了避免这种情况的产生,一是选取较小的初始权值,而是采用较小的学习速率。
    • (3)局部最小值:这里采用的梯度下降法可能收敛到局部最小值,采用多层网络或较多的神经元,有可能得到更好的结果。
      BP网络的改进

    P算法改进的主要目标是加快训练速度,避免陷入局部极小值等,常见的改进方法有带动量因子算法、自适应学习速率、变化的学习速率以及作用函数后缩法等。 动量因子法的基本思想是在反向传播的基础上,在每一个权值的变化上加上一项正比于前次权值变化的值,并根据反向传播法来产生新的权值变化。而自适应学习 速率的方法则是针对一些特定的问题的。改变学习速率的方法的原则是,若连续几次迭代中,若目标函数对某个权倒数的符号相同,则这个权的学习速率增加, 反之若符号相反则减小它的学习速率。而作用函数后缩法则是将作用函数进行平移,即加上一个常数。

    BP网络实现

    由于BP网络具有出色的非线性映射能力、泛化能力和容错能力,因此BP网络成了至今为止应用最广泛的人工神经网络。下图是Matlab下用BP网络做线性拟合的结果,效果很好。
    这里写图片描述

    % BP网络函数逼近实例
    % 1.首先定义正弦函数,采样率为20Hz,频率为1Hz
    k = 1; % 设定正弦信号频率
    p = [0:0.05:4];
    t = cos(k*pi*p) + 3*sin(pi*p);
    plot(p, t, '-'), xlabel('时间'); ylabel('输入信号');
    % 2.生成BP网络。用newff函数生成前向型BP网络,设定隐层中神经元数目为10
    % 分别选择隐层的传递函数为 tansig,输出层的传递函数为 purelin,
    % 学习算法为trainlm。
    net =
    newff(minmax(p),[10,10,1],{'tansig','tansig','purelin'},'trainlm');
    % 3.对生成的网络进行仿真并做图显示。
    y1 = sim(net,p); plot(p, t, '-', p, y1, '--')
    % 4.训练。对网络进行训练,设定训练误差目标为 1e-5,最大迭代次数为300,
    % 学习速率为0.05。
    net.trainParam.lr=0.05;
    net.trainParam.epochs=1000;
    net.trainParam.goal=1e-5;
    [net,tr]=train(net,p,t);
    %5.再次对生成的网络进行仿真并做图显示。
    y2 = sim(net,p);
    plot(p, t, '-', p, y2, '--')
    

    这是用C语言写的:用BP神经网络拟合函数:Y=sin(X)Y=sin(X)

    #include "math.h"
    #include "time.h"
    #include "stdio.h"
    #include "stdlib.h"
    #include "ctype.h"
    #define Ni 1
    #define Nm 4
    #define No 1
    #define L 100
    #define Enom 0.02
    #define loopmax 100000
    #define e 2.71828
    double E;
    double a,u,n;
    double W1[Ni][Nm],D1[Ni][Nm],W2[Nm][No],D2[Nm][No];
    double D22[Nm][No],D11[Ni][No];
    double a1[Ni][Nm],a2[Nm][No];
    double Pi[L][Ni],Pm[L][Nm],Po[L][No],T[L][No];
    double Xm[L][Nm],Xo[L][No];
    double Qm[L][Nm],Qo[L][No];
    void proceed();
    void proceedR();
    void forQ();
    void amend();
    void initiate();
    double newa(double a,double D);
    double cal(double d);
    double vcal(double d);
    main()
    {
        long int i;
    	int flag;
    	char choice;
        for(;;)
    	{
    		flag=0;
    		initiate();
    		for(i=0;;i++)
    		{
    			proceed();
    			if( E < Enom )
    			{ 
    				flag=1;
    				break;
    			}
    			if( i >= loopmax)
    			{
    				flag = -1;
    				break;
    			}
    			if(i%2500==0)
    				printf("第%10d轮误差:%20f,学习速率:%10f\n",i,E,a1[0][0]);
    			forQ();
    			amend();
    		}
    		if(flag>0)proceedR();
    		else printf("训练失败!\n");
    		for(;;)
    		{
    			choice=getchar();
    			printf("是否继续?(Y/N)\n");
    			choice=getchar();
    			choice=toupper(choice);
    			if(choice=='Y')break;
    			if(choice=='N')exit(0);
    		}
    	}
    }
    void initiate()
    {
    	int i,j;
    	int random;
    	double x;
    	double step;
    	int stime;	
    	long ltime;
    	ltime=time(NULL);
    	stime=(unsigned)ltime/2;
    	srand(stime);
    	a=0.02;
    	u=1;
        n=1;
    	printf("本程序将用BP神经网络拟合函数:Y=sin(X)\n\n");
    	for( i=0; i<Nm; i++)
    	{
    		for( j=0; j<Ni; j++)
    		{
    			random=rand()%100-50;
    			x=random;
    			x=x/100;
    			W1[j][i]=x;
    			D11[j][i]=0;
    			D1[j][i]=0;
    			a1[j][i]=0.01;
    		}
    		for( j=0; j<No; j++)
    		{
    			random=rand()%100-50;
    			x=random;
    			x=x/100;
    			W2[i][j]=x;
    			D22[i][j]=0;
    			D2[i][j]=0;
    			a2[i][j]=0.01;
    		}
    	}
        step=1.0/L;
    	for(i=0;i<L;i++)
    	{
    		x=i;
    		Pi[i][0]=x*step;
    		T[i][0]=sin(Pi[i][0]);
    	}
    	printf("初始化成功!\n\n下面将对神经网络进行训练请稍候。\n");
    }
    void proceed()
    {
    	int i, j, k;
    	E=0 ;
    	for( i=0; i<L; i++ )
    	{
    		for( j=0; j<Nm; j++ )
    		{
    			Pm[i][j] = 0;
    			for( k=0; k<Ni; k++ )
    			{
    				Pm[i][j] = Pi[i][k] * W1[k][j] + Pm[i][j];
    			}
    			Xm[i][j] = cal( Pm[i][j] );
    		}
    		for( j=0; j<No; j++)
    		{
    			Po[i][j] = 0;
    			for( k=0; k<Nm; k++)
    			{
    				Po[i][j] = Xm[i][k] * W2[k][j] + Po[i][j];
    			}
    			Xo[i][j] = cal( Po[i][j] );
    		    E = E + ( Xo[i][j] - T[i][j] ) * ( Xo[i][j] - T[i][j] ) / 2;
    		}
    	}
    }
    void forQ()
    {
    	int i,j,k;
    	for( i=0; i<L; i++ )
    	{
    		for( j=0; j<No; j++)
    		{
    			Qo[i][j] = ( T[i][j] - Xo[i][j] )* vcal( Xo[i][j] );
    		}
    		for(j=0; j<Nm; j++)
    		{
    			Qm[i][j]=0;
    			for( k=0; k<No; k++)
    			{
    				Qm[i][j] = Qo[i][k] * W2[j][k] + Qm[i][j];
    			}
    			Qm[i][j] = Qm[i][j] * vcal( Xm[i][j] );
    		}
    	}
    }
    void amend()
    {
    	int i,j,k;
    	double D;
    	for( i=0; i<Nm; i++)
    	{
    		for( j=0; j<Ni; j++)
    		{
    			D1[j][i]=0;
    		}
    		for( j=0; j<No; j++)
    		{
    			D2[i][j]=0;
    		}
    	}
    	for( i=0; i<Ni; i++)
    	{
    		for( j=0; j<Nm; j++)
    		{
    			for( k=0; k<L; k++)
    			{
    				D1[i][j] = Qm[k][j] * Pi[k][i] + D1[i][j];
    			}
                 D = D1[i][j] * D11[i][j]  ;//为D11付初值
    			 a1[i][j] = newa( a1[i][j] , D );  // a 付初值
    			 W1[i][j] = W1[i][j] + a1[i][j] * ( n * D1[i][j] + ( 1 - n ) * D11[i][j] );
    			 D11[i][j] = D1[i][j];
    		}
    	}
        for( i=0; i<Nm; i++)
    	{
    		for( j=0; j<No; j++)
    		{
    			for( k=0; k<L; k++)
    			{
    				D2[i][j] = Qo[k][j] * Xm[k][i] + D2[i][j];
    			}
    			D = D2[i][j] * D22[i][j]  ;//为D11付初值
                a2[i][j] = newa( a2[i][j] , D ); 
    			W2[i][j] = W2[i][j] + a2[i][j] * ( n * D2[i][j] + ( 1 - n ) * D22[i][j] );
    			D22[i][j] = D2[i][j];
    		}
    	}
    }
     void proceedR()
    {
    	int i, j;
    	float x;
    	double input,output;
    	char choice;
    	for(;;)
    	{
    		for(;;)
    		{
    			printf("在此输入需要计算的值(0,1):\n");
    			scanf("%f",&x);
    			input=(double)x;
    			if((input>=0)&(input<=1))break;			
    			printf("注意输入值应介于0、1之间!\n");
    			for(;;)
    			{
    				choice=getchar();
    				printf("是否继续?(Y/N)\n");
    				choice=getchar();
    				choice=toupper(choice);
    				if(choice=='Y')break;
    				if(choice=='N')exit(0);			
    			}
    		}
    		for(i=0;i<Nm;i++)
    		{
    			Pm[0][i]=0;
    			for( j=0; j<Ni; j++ )
    			{
    				Pm[0][i] =  input* W1[j][i]+Pm[0][i] ;
    			}
    			Xm[0][i] = cal( Pm[0][i] );
    		}
    		for( i=0; i<No; i++)
    		{
    			Po[0][i] = 0;
    			for( j=0; j<Nm; j++)
    			{
    				Po[0][i] = Xm[0][j] * W2[j][i]+Po[0][i];
    			}
    		}
    		output=cal( Po[0][0] );
    		printf("输入值为%20f对应的结果为%f\n",input,output);
    		printf("输入值为%20f对应的正常结果为%f\n",input,sin(input));
    		for(;;)
    		{
    			choice=getchar();
    			printf("是否继续?(Y/N)\n");
    			choice=getchar();
    			choice=toupper(choice);
    			if(choice=='Y')break;
    			if(choice=='N')exit(0);			
    		}
    	}
    }
    
    double newa(double a, double D)
    {
    	if( D > 0 )
    	{
    		{
    			if(a<=0.04)
    				a = a * 2;
    			else a=0.08;
    		}
    	}
    	else
    		if ( D < 0)
    		{
    			if(a>=0.02)
    			{
    				a = a / 2;
    			}
    			else a=0.01;
    		}
    	return a;
    }
    double cal(double d)
    {
    	d =  - (d * u);                                //              chushihua 
    	d = exp( d );
    	d = 1 / ( 1 + d );
    	return d;
    }
    double vcal(double d)
    {
    	return u * d * ( 1 - d );
    }
    
    
    
    展开全文
  • CNN笔记:通俗理解卷积神经网络

    万次阅读 多人点赞 2016-07-02 22:14:50
    通俗理解卷积神经网络(cs231n与5月dl班课程笔记) 1 前言 2012年我在北京组织过8期machine learning读书会,那时“机器学习”非常火,很多人都对其抱有巨大的热情。当我2013年再次来到北京时,有...

                   通俗理解卷积神经网络(cs231n与5月dl班课程笔记)

     

     

     

    1 前言

        2012年我在北京组织过8期machine learning读书会,那时“机器学习”非常火,很多人都对其抱有巨大的热情。当我2013年再次来到北京时,有一个词似乎比“机器学习”更火,那就是“深度学习”。

        本博客内写过一些机器学习相关的文章,但上一篇技术文章“LDA主题模型”还是写于2014年11月份,毕竟自2015年开始创业做在线教育后,太多的杂事、琐碎事,让我一直想再写点技术性文章但每每恨时间抽不开。然由于公司在不断开机器学习、深度学习等相关的在线课程,耳濡目染中,总会顺带着学习学习。

        我虽不参与讲任何课程(我所在公司“七月在线”的所有在线课程都是由目前讲师团队的100多位讲师讲),但依然可以用最最小白的方式 把一些初看复杂的东西抽丝剥茧的通俗写出来。这算重写技术博客的价值所在。

        在dl中,有一个很重要的概念,就是卷积神经网络CNN,基本是入门dl必须搞懂的东西。本文基本根据斯坦福的机器学习公开课、cs231n、与七月在线寒小阳讲的5月dl班所写,是一篇课程笔记。

        一开始本文只是想重点讲下CNN中的卷积操作具体是怎么计算怎么操作的,但后面不断补充,包括增加不少自己的理解,故写成了关于卷积神经网络的通俗导论性的文章。有何问题,欢迎不吝指正。

     

     

    2 人工神经网络

    2.1 神经元

        神经网络由大量的神经元相互连接而成。每个神经元接受线性组合的输入后,最开始只是简单的线性加权,后来给每个神经元加上了非线性的激活函数,从而进行非线性变换后输出。每两个神经元之间的连接代表加权值,称之为权重(weight)。不同的权重和激活函数,则会导致神经网络不同的输出。

        举个手写识别的例子,给定一个未知数字,让神经网络识别是什么数字。此时的神经网络的输入由一组被输入图像的像素所激活的输入神经元所定义。在通过非线性激活函数进行非线性变换后,神经元被激活然后被传递到其他神经元。重复这一过程,直到最后一个输出神经元被激活。从而识别当前数字是什么字。

        神经网络的每个神经元如下

        基本wx + b的形式,其中

    • 表示输入向量
    • 为权重,几个输入则意味着有几个权重,即每个输入都被赋予一个权重
    • b为偏置bias
    • g(z) 为激活函数
    • a 为输出

        如果只是上面这样一说,估计以前没接触过的十有八九又必定迷糊了。事实上,上述简单模型可以追溯到20世纪50/60年代的感知器,可以把感知器理解为一个根据不同因素、以及各个因素的重要性程度而做决策的模型。

        举个例子,这周末北京有一草莓音乐节,那去不去呢?决定你是否去有二个因素,这二个因素可以对应二个输入,分别用x1、x2表示。此外,这二个因素对做决策的影响程度不一样,各自的影响程度用权重w1、w2表示。一般来说,音乐节的演唱嘉宾会非常影响你去不去,唱得好的前提下 即便没人陪同都可忍受,但如果唱得不好还不如你上台唱呢。所以,我们可以如下表示:

    • :是否有喜欢的演唱嘉宾。 = 1 你喜欢这些嘉宾, = 0 你不喜欢这些嘉宾。嘉宾因素的权重 = 7
    • :是否有人陪你同去。 = 1 有人陪你同去, = 0 没人陪你同去。是否有人陪同的权重 = 3。

        这样,咱们的决策模型便建立起来了:g(z) = g( * + * + b ),g表示激活函数,这里的b可以理解成 为更好达到目标而做调整的偏置项。

        一开始为了简单,人们把激活函数定义成一个线性函数,即对于结果做一个线性变化,比如一个简单的线性激活函数是g(z) = z,输出都是输入的线性变换。后来实际应用中发现,线性激活函数太过局限,于是人们引入了非线性激活函数。

    2.2 激活函数

        常用的非线性激活函数有sigmoid、tanhrelu等等,前两者sigmoid/tanh比较常见于全连接层,后者relu常见于卷积层。这里先简要介绍下最基础的sigmoid函数(btw,在本博客中SVM那篇文章开头有提过)。

        sigmoid的函数表达式如下

        其中z是一个线性组合,比如z可以等于:b + * + *通过代入很大的正数或很小的负数到g(z)函数中可知,其结果趋近于0或1

        因此,sigmoid函数g(z)的图形表示如下( 横轴表示定义域z,纵轴表示值域g(z) ):

        也就是说,sigmoid函数的功能是相当于把一个实数压缩至0到1之间。当z是非常大的正数时,g(z)会趋近于1,而z是非常小的负数时,则g(z)会趋近于0

        压缩至0到1有何用处呢?用处是这样一来便可以把激活函数看作一种“分类的概率”,比如激活函数的输出为0.9的话便可以解释为90%的概率为正样本。

        举个例子,如下图(图引自Stanford机器学习公开课

        z = b + * + *,其中b为偏置项 假定取-30,都取为20

    • 如果 = 0  = 0,则z = -30,g(z) = 1/( 1 + e^-z )趋近于0。此外,从上图sigmoid函数的图形上也可以看出,当z=-30的时候,g(z)的值趋近于0
    • 如果 = 0 = 1,或 =1 = 0,则z = b + * + * = -30 + 20 = -10,同样,g(z)的值趋近于0
    • 如果 = 1 = 1,则z = b + * + * = -30 + 20*1 + 20*1 = 10,此时,g(z)趋近于1。

        换言之,只有都取1的时候,g(z)→1,判定为正样本;取0的时候,g(z)→0,判定为负样本如此达到分类的目的。

    2.3 神经网络

        将下图的这种单个神经元

        组织在一起,便形成了神经网络。下图便是一个三层神经网络结构

        上图中最左边的原始输入信息称之为输入层,最右边的神经元称之为输出层(上图中输出层只有一个神经元),中间的叫隐藏层。

        啥叫输入层、输出层、隐藏层呢?

    • 输入层(Input layer),众多神经元(Neuron)接受大量非线形输入讯息。输入的讯息称为输入向量。
    • 输出层(Output layer),讯息在神经元链接中传输、分析、权衡,形成输出结果。输出的讯息称为输出向量。
    • 隐藏层(Hidden layer),简称“隐层”,是输入层和输出层之间众多神经元和链接组成的各个层面。如果有多个隐藏层,则意味着多个激活函数。

        同时,每一层都可能由单个或多个神经元组成,每一层的输出将会作为下一层的输入数据。比如下图中间隐藏层来说,隐藏层的3个神经元a1、a2、a3皆各自接受来自多个不同权重的输入(因为有x1、x2、x3这三个输入,所以a1 a2 a3都会接受x1 x2 x3各自分别赋予的权重,即几个输入则几个权重),接着,a1、a2、a3又在自身各自不同权重的影响下 成为的输出层的输入,最终由输出层输出最终结果。

        上图(图引自Stanford机器学习公开课)中

    • 表示第j层第i个单元的激活函数/神经元
    • 表示从第j层映射到第j+1层的控制函数的权重矩阵 

        此外,输入层和隐藏层都存在一个偏置(bias unit),所以上图中也增加了偏置项:x0、a0。针对上图,有如下公式

        此外,上文中讲的都是一层隐藏层,但实际中也有多层隐藏层的,即输入层和输出层中间夹着数层隐藏层,层和层之间是全连接的结构,同一层的神经元之间没有连接。

     

     

    3 卷积神经网络之层级结构

       cs231n课程里给出了卷积神经网络各个层级结构,如下图

        上图中CNN要做的事情是:给定一张图片,是车还是马未知,是什么车也未知,现在需要模型判断这张图片里具体是一个什么东西,总之输出一个结果:如果是车 那是什么车

        所以

    • 最左边是数据输入层,对数据做一些处理,比如去均值(把输入数据各个维度都中心化为0,避免数据过多偏差,影响训练效果)、归一化(把所有的数据都归一到同样的范围)、PCA/白化等等。CNN只对训练集做“去均值”这一步。

        中间是

    • CONV:卷积计算层,线性乘积 求和。
    • RELU:激励层,上文2.2节中有提到:ReLU是激活函数的一种。
    • POOL:池化层,简言之,即取区域平均或最大。

        最右边是

    • FC:全连接层

        这几个部分中,卷积计算层是CNN的核心,下文将重点阐述。


    4 CNN之卷积计算层

    4.1 CNN怎么进行识别
       简言之,当我们给定一个"X"的图案,计算机怎么识别这个图案就是“X”呢?一个可能的办法就是计算机存储一张标准的“X”图案,然后把需要识别的未知图案跟标准"X"图案进行比对,如果二者一致,则判定未知图案即是一个"X"图案。

       而且即便未知图案可能有一些平移或稍稍变形,依然能辨别出它是一个X图案。如此,CNN是把未知图案和标准X图案一个局部一个局部的对比,如下图所示 [图来自参考文案25]


    而未知图案的局部和标准X图案的局部一个一个比对时的计算过程,便是卷积操作。卷积计算结果为1表示匹配,否则不匹配。

    具体而言,为了确定一幅图像是包含有"X"还是"O",相当于我们需要判断它是否含有"X"或者"O",并且假设必须两者选其一,不是"X"就是"O"。



    理想的情况就像下面这个样子:

    标准的"X"和"O",字母位于图像的正中央,并且比例合适,无变形

    对于计算机来说,只要图像稍稍有一点变化,不是标准的,那么要解决这个问题还是不是那么容易的:


    计算机要解决上面这个问题,一个比较天真的做法就是先保存一张"X"和"O"的标准图像(就像前面给出的例子),然后将其他的新给出的图像来和这两张标准图像进行对比,看看到底和哪一张图更匹配,就判断为哪个字母。

    但是这么做的话,其实是非常不可靠的,因为计算机还是比较死板的。在计算机的“视觉”中,一幅图看起来就像是一个二维的像素数组(可以想象成一个棋盘),每一个位置对应一个数字。在我们这个例子当中,像素值"1"代表白色,像素值"-1"代表黑色。


    当比较两幅图的时候,如果有任何一个像素值不匹配,那么这两幅图就不匹配,至少对于计算机来说是这样的。

    对于这个例子,计算机认为上述两幅图中的白色像素除了中间的3*3的小方格里面是相同的,其他四个角上都不同:


    因此,从表面上看,计算机判别右边那幅图不是"X",两幅图不同,得出结论:


    但是这么做,显得太不合理了。理想的情况下,我们希望,对于那些仅仅只是做了一些像平移,缩放,旋转,微变形等简单变换的图像,计算机仍然能够识别出图中的"X"和"O"。就像下面这些情况,我们希望计算机依然能够很快并且很准的识别出来:


    这也就是CNN出现所要解决的问题。

    Features


    对于CNN来说,它是一块一块地来进行比对。它拿来比对的这个“小块”我们称之为Features(特征)。在两幅图中大致相同的位置找到一些粗糙的特征进行匹配,CNN能够更好的看到两幅图的相似性,相比起传统的整幅图逐一比对的方法。

    每一个feature就像是一个小图(就是一个比较小的有值的二维数组)。不同的Feature匹配图像中不同的特征。在字母"X"的例子中,那些由对角线和交叉线组成的features基本上能够识别出大多数"X"所具有的重要特征。


    这些features很有可能就是匹配任何含有字母"X"的图中字母X的四个角和它的中心。那么具体到底是怎么匹配的呢?如下:






    看到这里是不是有了一点头目呢。但其实这只是第一步,你知道了这些Features是怎么在原图上面进行匹配的。但是你还不知道在这里面究竟进行的是怎样的数学计算,比如这个下面3*3的小块到底干了什么?


    这里面的数学操作,就是我们常说的“卷积”操作。接下来,我们来了解下什么是卷积操作。

    4.2 什么是卷积

        对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:因为每个神经元的多个权重固定,所以又可以看做一个恒定的滤波器filter)做内积(逐个元素相乘再求和)的操作就是所谓的『卷积』操作,也是卷积神经网络的名字来源。

        非严格意义上来讲,下图中红框框起来的部分便可以理解为一个滤波器,即带着一组固定权重的神经元。多个滤波器叠加便成了卷积层。

        OK,举个具体的例子。比如下图中,图中左边部分是原始输入数据,图中中间部分是滤波器filter,图中右边是输出的新的二维数据。

        分解下上图

    对应位置上是数字先相乘后相加 =

        中间滤波器filter与数据窗口做内积,其具体计算过程则是:4*0 + 0*0 + 0*0 + 0*0 + 0*1 + 0*1 + 0*0 + 0*1 + -4*2 = -8

    4.3 图像上的卷积

        在下图对应的计算过程中,输入是一定区域大小(width*height)的数据,和滤波器filter(带着一组固定权重的神经元)做内积后等到新的二维数据。

        具体来说,左边是图像输入,中间部分就是滤波器filter(带着一组固定权重的神经元),不同的滤波器filter会得到不同的输出数据,比如颜色深浅、轮廓。相当于如果想提取图像的不同特征,则用不同的滤波器filter,提取想要的关于图像的特定信息:颜色深浅或轮廓。

        如下图所示

      

     

    4.4 GIF动态卷积图

        在CNN中,滤波器filter(带着一组固定权重的神经元)对局部输入数据进行卷积计算。每计算完一个数据窗口内的局部数据后,数据窗口不断平移滑动,直到计算完所有数据。这个过程中,有这么几个参数: 
      a. 深度depth:神经元个数,决定输出的depth厚度。同时代表滤波器个数。
      b. 步长stride:决定滑动多少步可以到边缘。

      c. 填充值zero-padding:在外围边缘补充若干圈0,方便从初始位置以步长为单位可以刚好滑倒末尾位置,通俗地讲就是为了总长能被步长整除。 

      这里写图片描述 

        cs231n课程中有一张卷积动图,貌似是用d3js 和一个util 画的,我根据cs231n的卷积动图依次截取了18张图,然后用一gif 制图工具制作了一gif 动态卷积图。如下gif 图所示

        可以看到:

    • 两个神经元,即depth=2,意味着有两个滤波器。
    • 数据窗口每次移动两个步长取3*3的局部数据,即stride=2。
    • zero-padding=1。

        然后分别以两个滤波器filter为轴滑动数组进行卷积计算,得到两组不同的结果。

        如果初看上图,可能不一定能立马理解啥意思,但结合上文的内容后,理解这个动图已经不是很困难的事情:

    • 左边是输入(7*7*3中,7*7代表图像的像素/长宽,3代表R、G、B 三个颜色通道)
    • 中间部分是两个不同的滤波器Filter w0、Filter w1
    • 最右边则是两个不同的输出

        随着左边数据窗口的平移滑动,滤波器Filter w0 / Filter w1对不同的局部数据进行卷积计算。

        值得一提的是:

    1. 左边数据在变化,每次滤波器都是针对某一局部的数据窗口进行卷积,这就是所谓的CNN中的局部感知机制。
    • 打个比方,滤波器就像一双眼睛,人类视角有限,一眼望去,只能看到这世界的局部。如果一眼就看到全世界,你会累死,而且一下子接受全世界所有信息,你大脑接收不过来。当然,即便是看局部,针对局部里的信息人类双眼也是有偏重、偏好的。比如看美女,对脸、胸、腿是重点关注,所以这3个输入的权重相对较大。

    与此同时,数据窗口滑动,导致输入在变化,但中间滤波器Filter w0的权重(即每个神经元连接数据窗口的权重)是固定不变的,这个权重不变即所谓的CNN中的参数(权重)共享机制。

    • 再打个比方,某人环游全世界,所看到的信息在变,但采集信息的双眼不变。btw,不同人的双眼 看同一个局部信息 所感受到的不同,即一千个读者有一千个哈姆雷特,所以不同的滤波器 就像不同的双眼,不同的人有着不同的反馈结果。

        我第一次看到上面这个动态图的时候,只觉得很炫,另外就是据说计算过程是“相乘后相加”,但到底具体是个怎么相乘后相加的计算过程 则无法一眼看出,网上也没有一目了然的计算过程。本文来细究下。

        首先,我们来分解下上述动图,如下图

        接着,我们细究下上图的具体计算过程。即上图中的输出结果1具体是怎么计算得到的呢?其实,类似wx + b,w对应滤波器Filter w0,x对应不同的数据窗口,b对应Bias b0,相当于滤波器Filter w0与一个个数据窗口相乘再求和后,最后加上Bias b0得到输出结果1,如下过程所示:

    1* 0 + 1*0 + -1*

    +

    -1*0 + 0*0 + 1*1

    +

    -1*0 + -1*0 + 0*1

     

    +

    -1*0 + 0*0 + -1*0

    +

    0*0 + 0*1 + -1*1

    +

    1*0 + -1*0 + 0*2

     

    +

    0*0 + 1*0 + 0*0

    +

    1*0 + 0*2 + 1*0

    +

    0*0 + -1*0 + 1*0

     

    +

     

    1

    =

    1

        然后滤波器Filter w0固定不变,数据窗口向右移动2步,继续做内积计算,得到0的输出结果

        最后,换做另外一个不同的滤波器Filter w1、不同的偏置Bias b1,再跟图中最左边的数据窗口做卷积,可得到另外一个不同的输出。

     

     

    5 CNN之激励层与池化层

    5.1 ReLU激励层

        2.2节介绍了激活函数sigmoid,但实际梯度下降中,sigmoid容易饱和、造成终止梯度传递,且没有0中心化。咋办呢,可以尝试另外一个激活函数:ReLU,其图形表示如下

        ReLU的优点是收敛快,求梯度简单。

    5.2 池化pool层

        前头说了,池化,简言之,即取区域平均或最大,如下图所示(图引自cs231n)

        上图所展示的是取区域最大,即上图左边部分中 左上角2x2的矩阵中6最大,右上角2x2的矩阵中8最大,左下角2x2的矩阵中3最大,右下角2x2的矩阵中4最大,所以得到上图右边部分的结果:6 8 3 4。很简单不是?

     

     

    6 后记

        本文基本上边看5月dl班寒讲的CNN视频边做笔记,之前断断续续看过不少CNN相关的资料(包括cs231n),但看过视频之后,才系统了解CNN到底是个什么东西,作为听众 寒讲的真心赞、清晰。然后在写CNN相关的东西时,发现一些前置知识(比如神经元、多层神经网络等也需要介绍下),包括CNN的其它层次机构(比如激励层),所以本文本只想简要介绍下卷积操作的,但考虑到知识之间的前后关联,所以越写越长,便成本文了。

        此外,在写作本文的过程中,请教了我们讲师团队里的寒、冯两位,感谢他两。同时,感谢爱可可老师的微博转发,感谢七月在线所有同事。

    以下是修改日志:

    • 2016年7月5日,修正了一些笔误、错误,以让全文更通俗、更精准。有任何问题或槽点,欢迎随时指出。
    • 2016年7月7日,第二轮修改完毕。且根据cs231n的卷积动图依次截取了18张图,然后用制图工具制作了一gif 动态卷积图,放在文中4.3节。
    • 2016年7月16日,完成第三轮修改。本轮修改主要体现在sigmoid函数的说明上,通过举例和统一相关符号让其含义更一目了然、更清晰。
    • 2016年8月15日,完成第四轮修改,增补相关细节。比如补充4.3节GIF动态卷积图中输入部分的解释,即7*7*3的含义(其中7*7代表图像的像素/长宽,3代表R、G、B 三个颜色通道)。不断更易懂。
    • 2016年8月22日,完成第五轮修改。本轮修改主要加强滤波器的解释,及引入CNN中滤波器的通俗比喻。

        July、最后修改于二零一六年八月二十二日中午于七月在线办公室。

     


    7 参考文献及推荐阅读

    1. 人工神经网络wikipedia
    2. 斯坦福机器学习公开课
    3. http://neuralnetworksanddeeplearning.com/
    4. 雨石 卷积神经网络:http://blog.csdn.net/stdcoutzyx/article/details/41596663
    5. cs231n 神经网络结构与神经元激励函数:http://cs231n.github.io/neural-networks-1/中译版
    6. cs231n 卷积神经网络:http://cs231n.github.io/convolutional-networks/
    7. 七月在线寒老师讲的5月dl班第4次课CNN与常用框架视频,已经剪切部分放在七月在线官网:julyedu.com
    8. 七月在线5月深度学习班第5课CNN训练注意事项部分视频:https://www.julyedu.com/video/play/42/207
    9. 七月在线5月深度学习班:https://www.julyedu.com/course/getDetail/37
    10. 七月在线5月深度学习班课程笔记——No.4《CNN与常用框架》:http://blog.csdn.net/joycewyj/article/details/51792477
    11. 七月在线6月数据数据挖掘班第7课视频:数据分类与排序
    12. 手把手入门神经网络系列(1)_从初等数学的角度初探神经网络:http://blog.csdn.net/han_xiaoyang/article/details/50100367
    13. 深度学习与计算机视觉系列(6)_神经网络结构与神经元激励函数:http://blog.csdn.net/han_xiaoyang/article/details/50447834
    14. 深度学习与计算机视觉系列(10)_细说卷积神经网络:http://blog.csdn.net/han_xiaoyang/article/details/50542880
    15. zxy 图像卷积与滤波的一些知识点:http://blog.csdn.net/zouxy09/article/details/49080029
    16. zxy 深度学习CNN笔记:http://blog.csdn.net/zouxy09/article/details/8781543/
    17. http://www.wildml.com/2015/11/understanding-convolutional-neural-networks-for-nlp/中译版
    18. 《神经网络与深度学习》中文讲义:http://vdisk.weibo.com/s/A_pmE4iIPs9D
    19. ReLU与sigmoid/tanh的区别:https://www.zhihu.com/question/29021768
    20. CNN、RNN、DNN内部网络结构区别:https://www.zhihu.com/question/34681168
    21. 理解卷积:https://www.zhihu.com/question/22298352
    22. 神经网络与深度学习简史:1 感知机和BP算法4 深度学习的伟大复兴
    23. 在线制作gif 动图:http://www.tuyitu.com/photoshop/gif.htm
    24. 支持向量机通俗导论(理解SVM的三层境界)
    25. CNN究竟是怎样一步一步工作的? 本博客把卷积操作具体怎么个计算过程写清楚了,但这篇把为何要卷积操作也写清楚了,而且配偶图非常形象,甚赞。
    展开全文
  • 卷积神经网络概念与原理

    万次阅读 多人点赞 2016-09-05 10:00:27
    一、卷积神经网络的基本概念 受Hubel和Wiesel对猫视觉皮层电生理研究启发,有人提出卷积神经网络(CNN),Yann Lecun 最早将CNN用于手写数字识别并一直保持了其在该问题的霸主地位。近年来卷积神经网络在多个方向...
  • 详解BP神经网络

    万次阅读 多人点赞 2018-05-06 11:30:41
      BP神经网络学习算法可以说是目前最成功的神经网络学习算法。显示任务中使用神经网络时,大多数是使用BP算法进行训练.   在我看来BP神经网络就是一个”万能的模型+误差修正函数“,每次根据训练得到的结果与...
  • 最近一段时间在研究如何利用...发现神经网络模型可以来预测,并且有很多是结合时间序列或者SVM(支持向量机)等组合模型来进行预测,本文结合实际数据,选取了常用的BP神经网络算法,其算法原理,因网上一大堆,所以...
  • 利用MATLAB 进行BP神经网络的预测(含有神经网络工具箱) 最近一段时间在研究如何利用预测其销量个数,在网上搜索了一下,发现了很多模型来预测,比如利用回归模型、时间序列模型,GM(1,1)模型,可是自己在结合...
  • 神经网络

    千次阅读 2017-11-03 14:44:40
    神经网络7.1 什么是人工神经网络人工神经网络受到生物神经网络的启发。构造人工神经元来模仿生物神经元来工作。生物神经网络的基本工作原理:一个神经元的输入端有多个树突,主要是用来接收输入信息的。输入信息进过...
  • 卷积神经网络超详细介绍

    万次阅读 多人点赞 2018-09-19 10:16:59
    1、卷积神经网络的概念 2、 发展过程 3、如何利用CNN实现图像识别的任务 4、CNN的特征 5、CNN的求解 6、卷积神经网络注意事项 7、CNN发展综合介绍 8、LeNet-5结构分析 9、AlexNet 10、ZFNet 10.1 意义 ...
  • 人工神经网络——径向基函数(RBF)神经网络

    万次阅读 多人点赞 2015-10-24 15:32:45
    本文摘自:《模式识别与智能计算——matlab技术实现第三版》与《matlab神经网络43个案例分析》 【注】蓝色字体为自己的理解部分 径向基函数神经网络的优点:逼近能力,分类能力和学习速度等方面都优于BP神经网络...
  • python3_实现BP神经网络 + BP神经网络应用实例

    万次阅读 多人点赞 2018-07-29 22:10:28
    1.BP神经网络简介 BP神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照逆向传播算法训练的多层前馈神经网络,是目前应用最广泛的神经网络。 优点:具有任意复杂的模式分类能力和优良的...
  • 基于BP神经网络的回归预测

    万次阅读 多人点赞 2019-05-18 17:18:50
    误差反向传播神经网络简称为BP(Back Propagation)网络,它是一种具有三层或三层以上的多层神经网络,每一层都由若干个神经元组成。如图所示为一个BP神经网络的结构图,它的左、右各层之间各个神经元实现全连接,即左...
  • 深度学习 CNN卷积神经网络 LeNet-5详解

    万次阅读 多人点赞 2017-10-18 16:04:35
    卷积神经网络( Convolutional Neural Network, CNN): 是一种常见的深度学习架构,受生物自然视觉认知机制(动物视觉皮层细胞负责检测光学信号)启发而来,是一种特殊的多层前馈神经网络。它的人工神经元可以响应...
  • 一文让你彻底了解卷积神经网络

    万次阅读 多人点赞 2018-08-03 09:27:11
    卷积神经网络(Convolutional Neural Network,CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。 它包括卷积层(convolutional layer)和池化层(pooling ...
  • 深度学习 --- 卷积神经网络CNN(LeNet-5网络详解)

    万次阅读 多人点赞 2018-11-26 11:43:31
    卷积神经网络(Convolutional Neural Network,CNN)是一种前馈型的神经网络,其在大型图像处理方面有出色的表现,目前已经被大范围使用到图像分类、定位等领域中。相比于其他神经网络结构,卷积神经网络需要的参数...
  • 神经网络BP反向传播算法原理和详细推导流程

    万次阅读 多人点赞 2018-05-09 22:25:53
    使用反向传播算法的多层感知器又称为BP神经网络。BP算法是一个迭代算法,它的基本思想为:(1)先计算每一层的状态和激活值,直到最后一层(即信号是前向传播的);(2)计算每一层的误差,误差的计算过程是从最后一...
  • 神经网络从原理到实现

    万次阅读 多人点赞 2016-11-29 17:14:10
    在机器学习和认知科学领域,人工神经网络(artificial neural network,缩写ANN),简称神经网络(neural network,缩写NN)或类神经网络,是一种模仿生物神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的...
  • 最近在学习《Deep Learning》这本书,书中在前馈神经网络、全连接神经网络以及卷积神经网络等内容中,都有提到反向传播算法,这一算法可以说是神经网络中求解参数比较核心的部分了。为了更好地理解神经网络工作的...
  • 循环神经网络(RNN, Recurrent Neural Networks)介绍

    万次阅读 多人点赞 2015-09-23 13:24:09
    循环神经网络(RNN, Recurrent Neural Networks)介绍   这篇文章很多内容是参考:...  循环神经网络(Recurrent Neural N
  • 1.1神经网络来源1.2了解感知器认知过程1.3感知器代码实现逻辑或和与1.4感知器网络和S型神经元及激活函数1.5神经网络之结构详解1.6.1神经网络BP算法前置知识1.6.2神经网络BP算法W7过程演练1.6.3神经网络BP算法W1过程...
  • 神经网络学习(十三)卷积神经网络的MATLAB实现

    万次阅读 多人点赞 2018-03-27 16:08:28
    系列博客是博主学习神经网络中相关的笔记和一些个人理解,仅为作者记录笔记之用,不免有很多细节不对之处。 卷积神经网络回顾 上一节,我们简单探讨了卷积神经网络的反向传播算法,本节我们着手实现了一个...
  • 深度神经网络总结

    万次阅读 多人点赞 2019-01-09 17:52:24
    深度神经网络(Deep Neural Networks,DNN)可以理解为有很多隐藏层的神经网络,又被称为深度前馈网络(DFN),多层感知机(Multi-Layer perceptron,MLP)。 1 前向传播算法 1.1 从感知机到神经网络 感知机的模型...
  • MATLAB中神经网络工具箱的使用

    万次阅读 多人点赞 2017-03-24 19:20:18
    今夕何夕兮,前些天把玩了一下MATLAB中神经网络工具箱的使用,忽有“扪参历井仰胁息”之感。别的倒是没什么,只是神经网络的数据组织结构有些“怪异”,要是不小心就会导致工具箱报错。以下便是神经网络工具箱的正确...
  • 一、最简单的神经网络--Bp神经网络

    万次阅读 多人点赞 2018-09-04 20:44:38
    在之前的文章中,有提到过,所谓的 AI 技术,本质上是一种数据处理处理技术,它的强大来自于两方面:1.互联网的发展带来的海量数据信息 2.计算机深度学习算法的快速发展。 所以说 AI 其实并没有什么神秘,只是在算法...
  • 基于遗传算法的BP神经网络优化算法

    万次阅读 多人点赞 2016-04-10 20:22:41
    遗传算法优化BP神经网络分为BP神经网络结构确定、遗传算法优化和 BP神经网络预测3个部分。其中,BP神经网络结构确定部分根据拟合函数输入输出参数个数确定 BP神经网络结构,这样就可以确定遗传算法的优化参数个数,...
  • 卷积神经网络(CNN)基础介绍

    万次阅读 多人点赞 2016-01-16 20:31:52
    卷积神经网络(CNN)基础介绍
  • 人工神经网络简介

    万次阅读 多人点赞 2015-12-12 14:20:37
    人工神经网络简介

空空如也

1 2 3 4 5 ... 20
收藏数 160,682
精华内容 64,272
关键字:

神经网络