开发者学堂课程【神经网络概览及算法详解:误差反向传播算法-1】学习笔记与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/40/detail/929
误差反向传播算法-1
内容简介:
一、误差反向传播算法
二、多层感知器实例
一、误差反向传播算法
误差反向传播算法也就是我们常说的BP算法。在做单层感知器训练的时候根据他的输出值的不一样,实际上可以分为两种,一种是离散型的,一个是连续型的。
离散型,我们按照离散感知器学习规则,如果是连续型,我们就会使用δ算法及δ算法的变种比如说像lms这种学习规则。
一旦我们确定了学习规则之后,我们做的逻辑就是对每一个输入都会有一个预期的输出。然后我们通过这个模型来又得到一个实际的输出,我们去比较实际输出和预期输出是否一致,如果不一致,两个有一个差,然后我们基于这个差来调整感知器的权重和阈值,直到这个差小到一定程度,我们可以接受了,那么我们就可以完成这个模型训练了。具体来说,他们逻辑是这样,首先你要定一个包含杆感知器参数的损失函数,用来衡量当前模型是好还是坏,这个地方说的不是特别准确,对连续型的来讲,我们可以把它叫做损失函数,对分类的这种这种离散性的来讲,叫学习信号叫误差。定义好这个东西之后,我们权且把它全部叫做损失函数。
我们来调整我们模型中的参数的值,让这个损失函数的慢慢的变小,当这个损失函数小到一定程度。使得这个实际输出结果和预期输出结果的差,我们能够接受他的时候,那我们就得到了我们想要的模型。那么多层感知器呢,一般也是使用这种逻辑,但是多层感知器存在一个很要命的问题,那就是这种单层感知器来讲,它只有两层输入和输出。当你调整参数的时候,你每次调整完参数,你实际上就可以直接影响到输出。
但对于多层感知器来说多了一个隐藏层。这个隐藏层它的输出结果并不是最终直接的输出结果,所以你调整起来的时候会有问题。不像那个单层感知器效果那么明显,或者说能调整方向那么正确。特别是多层感知器如果有多隐层的话,那你这个复杂程度会越来越高。也就是说没有办法定义隐藏层的损失函数。你得到的是一个整体的损失函数。我们来看一下,像这种,单隐藏层的,多层感知器,三层的,一层输入,一层输出,一层隐藏,这时候实际上有两组权重需要调整。那实际上,根据我们之前的思路。
预期输出和实际输出的差,你去调整的话,实际上,你的预期输出是输出层的输出而并不是调整的隐藏层的输出,所以你在做调整的时候,困难就会很大,比单层感知器要麻烦的多。
二、多层感知器实例
我们来看一个多层感知器的例子,
多层感知器也训练完成了。
结构是这样的,有三层,输入层有三个节点,一个是偏置,两个输入项目的分量,隐藏层两个节点。
h1,h2,输出层一个节点O,它们的权重我们已经求出来了b的权重是0、1,x1的权重是1、0,x2的权重是1、1,,隐藏层到输出层权重也算出来了,是2和3,这样,整个网络结构包括网络参数就完全知道了。
首先,隐藏层和最终输出层的关系,h1=b•0+x1•1+x2•1=x1+x2,h2=b•1+x1•0+x2•1=x2+b,我们假设它的激活函数就没有,就直接一个简单的累加求和然后最终输出的时候激活函数是平方,O的净输出等于2h1+3h2,假设O的激活函数是平方,那就平方一下,就等于这个式子(2x1+5x2+3b)^2。当X1发生变化的时候,他肯定对h1有影响,那么怎么来衡量这个影响呢,通常使用导数来表示,h1对x1求导,
回忆一下导数的概念,实际上导数表示的是什么呢?表示的是在这一点的变化率,用极限的概念来表示这一点的变化率。但如果X1的变化非常小的时候,这个导数就表示h1的变化的量,因为这个h1她比较特殊,她除了受X1的影响,还受x2和b的影响,b的影响为零。
h1他本身依赖于多个变量,这个时候我们再去衡量h1对X1的影响时呢,需要用偏导数来表示,就是h1对X1求偏导。同样,当x2发生变化的时候呢,他对h1的值也有影响,那么,h2依赖于多个变量的影响,x2的影响用偏导数来表示,就是h1对X2求偏导。同样呢O的变化,h1的变化呢,也会影响到O。
O同样依赖于多个变量,依赖于h1,h2,所以h1的影响用偏导数来表示,O对h1求偏导。
那么我们来具体的衡量一下。X1变化的时候,对O的影响,注意一下,这个时候呢实际上这个函数,直接对X1求导的话,不能直接求,这时候就要用到链式求导法,假设u=f(g(x)),那么y=f(u),y对u求导,u又是x的函数,再用u对x求导,最后乘起来就行了。这儿一样还是引入一个中间量u,u=2x1+5x2+3b所以o等于u的平方了,那么o对x1的偏导就是o对u的偏导乘以u对X1的偏导。所以如果我们想用数量来衡量X1的变化对o的变化有多大的时候,我们也可以用这个方式。
同样X1变化的时候,我们就得到这个结果,X2变化的时候,求下这个值。这个时候有人可能会质疑了,X2变化的时候有两个路径来影响O,一个是通过h1一个是通过h2。实际上呢,我们可以看o就等于2h1+3h2,o的这个表达式就已经把h1和h2对它的影响综合到一块了,我们直接用o对x2求导就表明了x2变化的时候对o的影响,同样用链式求导法求出x2对o的影响,同理,还可以求出b变化是对O的影响。从输入建立到输出的关系,当网络结构简单时,我们可以看一下它的遍历路径,b变化会影响h1,影响到o,b变化会影响h2,影响到o,那么x1变化的时候也会影响到h1,影响到o,影响到h2,影响到o。
X2变化的时候也会影响到h1,影响到o,同样X2变化的时候,通过h2也能影响到o。路径比较可控,因为它结构比较简单。如果输入变量变多,输入节点增多,隐藏层变多或者隐藏层中的神经元增多,变成两层了,或者说隐藏层中的节点个数变多了。
那么,我们求偏导的次数就会快速增加。他实际上与神经元个数的二次方成正比。
计算量就会非常大。使得学习过程变得仅仅理论上可行(这也是闵斯基看衰ANN的原因)神经元不能解决非线性问题,如果是多层的,训练的时候有问题,如果训练量过大,没有办法得到最终的结果,只有理论上可行。
如果有一个两个隐藏层,每个隐藏层十个节点的结构,输入变量x1将会有100条路径影响到输出变量O。那这个量是非常大的,那么,从输入到输出的链式求导顺序关注的是输入对输出的影响。事实上,通过简单计算能得到模型输出和实际输出的差异,我们更想知道的是,输出O的变化对前面的路径(输入+权重参数)有什么影响。比如说我们输入值已经知道了,然后权重确定之后,我们想求输出是非常简单的。
反过来我们如果知道输出值,我们也知道期望输出值,这时候如果输出值和期望输出值不一致,我们可以算出差来,需要调节前面的权重让这个差接近于零,因为需要调节的权重数太多,我们怎么调节这个参数,才能使b和0的值趋向于0,这个是非常困难的。