Press "Enter" to skip to content

小白也能看懂的神经网络:从神经元到深度学习(上)

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

 

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

 

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

 

 

图1 人脑神经网络

 

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

 

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

 

一.前言

 

二.神经元

 

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

 

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

 

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

 

六.回顾

 

七.展望

 

八.总结

 

九.后记

 

十.备注

 

一、前言

 

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

 

 

图2 神经网络结构图

 

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

 

 

设计一个神经网络时,输入层与输出层的节点数往往是固定的,中间层则可以自由指定;

 

神经网络结构图中的拓扑与箭头代表着预测过程时数据的流向,跟训练时的数据流有一定的区别;

 

结构图里的关键不是圆圈(代表“神经元”),而是连接线(代表“神经元”之间的连接)。每个连接线对应一个不同的权重(其值称为权值),这是需要训练得到的。

 

 

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

 

 

图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的关系。

 

因此我们改用二维的下标,用W(x,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

 

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

 

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注