lecture3-线性神经元和算法
Hinton第三课
这节课主要是介绍NN的输出端常用的神经元,然后重点是说明怎么使用BP来计算偏导数,在Hinton这一课中,他提供了他1986年参与写的《并行分布处理》一书的第8章,49页,这本书的编者是当你的认知神经界的Rumelhart, D. E和McClelland, J. L,想想估计那时候Hinton应该很年轻吧,这本书网上很难找到,但是发现http://psych.stanford.edu/~jlm/papers/ ,这里居然有全本。
一、学习线性神经元的权重
这里介绍的线性神经元和之前介绍的感知机不同,感知机的训练总是会使得权重接近一个好的结果,但是在线性神经元中,这个输出总是会更加接近一个目标输出。感知机的收敛是通过确保当我们改变权重的时候,就是更加靠近一个理想权重的时候。这也使得感知机无法扩展成更复杂的网络,因为在更复杂的网络中,当你将两个好的权重集合进行平均,会得到一个坏的集合(个人理解,它无法完成那种线性+线性还是线性这种惯性,两个好的权重集合相加,得到的集合却不是好的集合,因为感知机的阈值原理)。所以对于多层NN来说,通常不会使用感知机的训练方法,所以也就 没有多层感知机的说法。对于多层NN来说,我们需要一个不同的训练方法,不似以往的使得权重更加的靠近理想值,而是使得真实的输出靠近目标输出,这对于非凸问题(对两个好的权重集合进行平均,得到的不是一个好的权重集合)也是适用的,但是在感知学习中,即使当权重更加的合理,但是得到的目标输出却有可能差了千里。
让输出更加符合目标输出的学习的最简单的例子就是用平方误差测量的方法来学习一个线性神经元了,线性神经元,在电子工程中也叫做线性过滤器,有着一个实值(连续值)输出,简单的对所连接的输入神经进行权值求和。
上图中的输出Y,是神经元的目标估计值,是通过用权值乘以输入的每一项并最后求和得到的,第二个等式后面是他们的矩阵写法。这里的学习目标就是使得在所有训练样本上神经元的目标估计值和目标真实值之间的误差和最小,通常采用的测量方法就是误差平方和的方法,但是对于标准的工程方法来说,这可以通过基于每个样本的值写上一大堆的式子,然后直接求解就能计算出一个很好的权值集合,但是为什么不采用这个方法?首先,第一个回答,也是科学的回答,是我们需要一个真实的神经元也能使用的方法,而真实的神经元也通常不是为了求一系列的式子的解(我们大脑对数学不擅长,对视觉识别等等很擅长);其次,第二个回答,也是工程上的回答,我们需要一个方法能够生成多层,非线性网络。因为通过分析得来的结果通常都是依赖于是线性的并且有着一个平方误差测量结果。下面介绍的迭代的方法,通常来说不高效,但是却很容易学习并生成更复杂的网络。
例子:通过一个很简单的例子来说明如何迭代的去学习到线性神经元的权重。假设你每天都会去一个咖啡厅吃午饭,菜单上只有三道菜fish,chips和ketchup,每天都会点上几份并记账,在某天有钱了去结钱的时候服务员和你说总价,你就会想知道每道菜的单价是多少。下面就是计算的方法:
就是先随机定价格,然后在通过每餐吃了多少来不断的计算,看看我们计算的和他叫我们付的钱的差距,然后在调整我们定的价格。
上图是服务员和我们说的总价,而这里的每道不同的菜也都是真实的,只是我们不知道,我们现在想秀一下,自己来计算这个值。
假设我们开始猜每个菜的价格都是50,50,50,然后得到了500的总价,这与给我们的价格850相差了350,然后通过图中右边的学习规则,得到了新的单价(权值)为70,100,80.。注意到这里的权值其实离我们的真实值差的更远了,但是这不是我们要的目的,我们的目的是计算整个模型,使得我们计算出来的总价和我们要付的钱的差距最小,(也就相当于在店家收益不变的情况下我们来给出我们的菜的价格)。
上面的思路清晰了,现在就是解决这个delta-rule的问题了。
如上图所示,我们要的就是使得这个误差函数最小,其中就是真实目标值和NN预测的值的差距,前面的1/2是为了后面的求导的时候可以抵消而引进的,虽说权值不重要,但是我们的目标预测也是通过调节权值来体现的,所以还是要对他进行求偏导,这里用到的链式法则相信任何一本高数书上都有,(这里的Dy在没有数学上的歧义的时候可以消除,但是一般不建议,因为前面的Dy/DW是偏导,因为这个y中有很多的w(i),我们这里只对一个具体的w(i)求导,所以dy / dw(i) = x(i),这里是因为例子是线性的,所以这里在采用不同的激活函数的时候是不同的,需要注意到)在求得误差在每个w(i)上的导数后,前面加上负号,然后在加个学习率(也就是高数书中例子下山的步长),最后就得到了关于w(i)的每次迭代的改变量。
在训练结束后,也许不能得到完美的结果但是仍然能够得到对完美的权值的逼近权值集合,在学习率足够小的情况下,并且训练的时间足够长,得到的结果就越能靠近完美值;并且在当其中的样本的任意两个特征高度相关的时候,训练就会变得很慢,而且当这里例子中的鱼和chips吃的一样多的时候,那么就没法决定这个价格是因为鱼而定的,通常会学习到一样的结果。
一般来说会觉得这里的学习算法和之前的感知学习很像:
当选择的学习率很大,那么整个系统是不稳定的,但是选的太小,就会使得学习时间太长
二、线性神经元的错误表面
在通过理解了错误平面的形状之后,就能更加的好理解线性神经元是怎么学习的。下面就是通过几何的形式来理解但学习线性神经元权值的时候所发生的事情。和之前的感知学习一样,引入权重空间概念:
如上图所示,上图右边第一个示意图是水平方向表示权重(所有的权重表示成一维的),竖直方向表示损失大小。因此在水平平面中的点相对于不同的权重,竖直上意味着在所有训练样本上的误差和。对于一个用平方误差测量的线性神经元来说,他的函数图就是这样的一个二次碗形(凸函数),竖直方向上看,就是个抛物线,而水平方向上看,就是个椭圆。但是对于多层,非线性网络来说,他的误差表面更加的复杂,当权重都不是很大的时候,这个误差表面通常都是光滑的,但是却有着许多的局部最小值,使用这样的图形,就能画出delta-rule的过程了:
deleta-rule是通过计算误差关于权重的偏导,如果说希望以最快的速度达到最小值,至少是局部最小,那么就是梯度的方向了,上图中的方法叫做batch学习,就是批量学习,一次先计算所有的样本,然后在更新权重,另一种叫在线学习,就是计算一个样本,就更新一次,但是因为每个样本所表现的信息不同,所以上图中右边的那个可以发现每次的迭代都是忽左忽右的,这就是被单个样本所牵制的结果。通过使用这个错误表面图形,我们就能知道他其实学习过程是很慢的。如果这个椭圆的形状很狭长,这是当训练样本都几乎平行的时候(就是差不多成线带状样本分布),那么这时候求得的梯度,就很尴尬了:
上图中红色表示的梯度是我们不想移动太多的地方,因为移动大了就超出范围了,而与他差不多正交的方向,就是我们想移动多的方向,它却移动的很少,所以当我们的数据分布是这个德行的,那么训练的时间就肯定会很长了,因为这个样本或者当前的梯度的确是这个方向,但是却不是全局梯度(自己编的),只是局部梯度(自己编的)。
三、学习逻辑输出神经元的权重
将之前的线性神经元的学习规则扩展到非线性神经元的多层网络,我们需要两步。首先,需要将学习规则扩展到单个非线性神经元,然后就是扩展到多层网络。在第一步中,采用的非线性神经元是逻辑神经元,虽然有众多不同的非线性神经元可以选择,但是因为逻辑神经元的一些很好的特性,所以才选择它的:
首先他只有一个输入 z,z是通过将所有的输入线性相加得到的,输出却是非线性的平滑曲线,而且当z很大的时候输出值是无限的接近1的,当z很小的时候,输出值是无限的接近0的,而且变化平滑,重要的是它的偏导数还那么容易求:
上图就是一个逻辑神经元的偏导结果和他的关于一个输入 z 的导数。将上图中的进行整合,就能够很好的关于权值的求导了;
上图就是最后在基于逻辑神经元下的误差关于某个权重的求导结果,,中间红色框起来的,恰好就是逻辑神经元的导数的结果。
四、BP算法
现在在选择了非线性NN的输出之后,就是本课的中心问题,怎么去学习多层的特征。BP也就是在1980年代在NN领域中一个重要的进步。
穿插:这是一个没多大效用,但是差不多人人都想过的算法。如果一个NN网络没有隐藏单元,那么它就狠首先因为只有输入-输出模型来映射;通过人为添加一层手动编码的特征层(之前的感知机课程)可以让这个网络更加强大,但是困难在于如何去设计这个特征,而这就没法通过学习算法学习到了。我们想要的是找到这样的一种特征,它不需要深入具体的任务内部或者重复的实验去观察它如何很好的工作(就是找到一个能够泛化的特征)。所以最好就是让计算机自己深入具体的任务,然后通过多次的循环实验找到如何正确很好的工作:
扰乱学习,就是首先先随机初始化权重,然后针对某一个具体的权重上的权值,通过随机扰动,如果这次的改变的确提升了最后的效果,那么就保留这次的改变,这就像是一种增强学习一样。但是这种做法非常的低效,因为不但需要计算多层的前馈,而且还要反复的试验就为了一个权重(而且还不是在一个样本上测试),那么当权重的数量多起来后,那么时间复杂度完全不可想象;另一个随机扰动权重的学习方法的问题是在学习的最后,任何的较大的扰动都会使得结果变坏,那么可想而知这个网络会变得很动荡。 这时候为了计算时间的减少,肯定提出了并行的想法,就是先对所有的权重进行扰动,然后在看由权重改变所带来的结果的改变(可想而知这完全没用,这和每次随机初始化没什么差别,而且比单个扰动还不靠谱);一个较好的想法是随机扰动隐藏单元的激活值,如图中红点和绿点。但是如果知道了在一个样本上如何扰动隐藏单元的激活值并使得模型效果更好,那么计算这几个隐藏单元所涉及的权重也是很简单的,这当神经元的数量远远少于权重的数量的时候是好的方法,但是这些缺陷,都不如这个BP。
BP的想法就是不知道隐藏单元应该怎么做,但是能够计算这个误差的改变是如何随着一个隐藏单元的激活值改变而改变的。所以从反方向考虑,不去寻找合适的激活值去训练隐藏单元,而是使用误差导数去分配给每个隐藏单元激活值,告诉他们怎么逼近。而且因为一个隐藏单元的改变会改变之后所有单元的激活值,所以在误差导数回传的时候就需要综合考虑 了,就是要对所有的隐藏单元都要同时考虑。
首先介绍BP在单个样本下的情况:
如上图所示:首先将误差转换成一个误差导数,上图中右下角就是一个NN的部分示意图,上层是输出层 第 j 层,下层是一层隐藏层 i ,所以如上图所示,将所有输出层的误差导数传递到下一层的和他有链接关系的神经元上,这就是BP的由来,上图中DE/ Dy_ j 是可以直接用误差求导,然后通过所有输出单元的误差回向传播(就是乘以前馈的时候用的权值在相加),就是图中的 y_ i 的误差,然后用这个误差来对这个单元求导 :
上图就是BP在前馈网络下的求导,上图左边就是前馈的过程,右边就是BP关于输出层和隐藏层的求导
这部分还有具体的: http://blog.csdn.net/shouhuxianjian/article/details/39076953 之前参考《神经网络与机器学习一书中BP部分写得》。
五、怎么使用由Bp计算的导数
指出如何在一个多层网络中获得所有权重的误差导数是学习整个网络的关键。但是在全部明白各异学习过程之前还是有很多的问题需要去处理。例如,需要决定更新权重的频率,还有在使用大网络的情况下如何阻止网络过拟合。Bp是一个高效计算对于单个训练样本的情况下误差关于每个权重的求偏导的方法,但是这不是一个学习算法,所以需要指定其他的东西去得到一个合适的学习方法。为了得到一个完整的具体的学习过程,需要知道如何运用这些误差导数:优化问题,如何在每个独立的样本上使用误差导数去查找一个好的权重集合(在lecture6中具体介绍);泛化问题,如何确保学到的权重对于非训练集的样本一样适用(就是可以用来做预测,在lecture7中具体介绍)。
对于使用权重导数上的优化问题:1、更新权值的频率:Online训练一个样本就进行更新,因为是采用的在线更新的形式,所以在权重空间上它的走向就是之字形的;full batch:在扫完所有的训练数据后进行一次权值更新,这个方法的缺点就是有可能会初始化不好,而且如果遇到一个超大的训练集合,我们不希望扫描所有的训练样本就为了更新某些权值,而且这些权值还是不好的。实际上,不需要这么干,可以把上述的优点结合起来,就是第三个方法mini-batch:随机的将样本分成几个mini-batch,然后训练一个mini-batch就更新一次权值,他不会像在线学习一样那么左右动荡,而且也不会因为训练样本太大而权重更新太慢,或者训练困难;
2、每次更新权重的步长多大(lecture6中具体说明):a、是使用一个固定的学习率?每次的下降步长固定的;b、还是使用一个自适应全局学习率?让机器决定,如果是稳步向前的那么就加大这个学习率;c、还是对每个分开的连接都使用一个自适应的学习率?这样就使得有些权重更新的快,有些权重更新的慢;d、不要使用梯度方向的下降?如上面说道的一个狭长的椭圆,那个情况的梯度的方向反而不是我们希望的方向,我们希望的是直指中心的方向。
如何防止模型的过拟合:训练的数据包含的从输入映射到输出的规律信息,但是它通常有两种噪音在里面:目标值有时候不可信(通常是一些小的错误);采样错误,比如一些特别的样本被我们选择了,而这些样本却是类似异常点的存在,会让网络偏离好的方向。当我们拟合模型的时候,无法知道这个规律是真的,还是来自于采样错误带的,而模型要做的就是同时拟合不同的规律,如果模型很有可调控性,那么他就可以很好的你和采样错误,这其实是个灾难。
上图中的六个黑点,就是样本,这里有两种拟合的模型,线性(2元)和多项式(6元),但是相比较来说训练集是红色的拟合的最好,但是在预测的时候,它产生的误差一般是很大的,(之前的ng的机器学习中有介绍过欠拟合和过拟合的概念),但是对于NN来说,一般是过拟合的情况大于欠拟合的情况,而对应过拟合的情况一般有下面几种方法:
权重衰减:就是在目标函数上加上所有权重的平方和
权重共享:参考CNN,他的一个特点就是权重共享
早点停止:通过使用learing curve(之前的博文中有的),当发现模型训练开始下降的时候停止训练
模型平均:对于差不多的训练模型来说,在期望的部分将这几个模型进行一起求平均,这可以减少错误
NN的贝叶斯拟合:这是一个模型平均的理想模型
dropout:在训练的时候随机让某些隐藏单元失效
通常的预训练:更加的复杂,而且超出了本课的要求,会在后面的课中讲解。