第二个标题:一般而特殊的前馈神经网络
前馈神经网络
在文章《逻辑回归到神经网络》(以下简写《LR到NN》)中,小夕为大家描述了一个从逻辑回归延伸到神经网络的过程。在《一般化机器学习与神经网络》中,小夕阐述了神经网络的一般性。这一篇会完全进入神经网络的状态,阐述神经网络的特殊性。
其实在《LR到NN》中的这张简单的图,就是本文要讲的前馈神经网络(feed-forward neural network)。
可以看到,这种简单粗暴的连法,恰恰就是神经网络最经典的模型。即隐含层的每个单元(神经元)均只接受前一层(对于只有一个隐含层的前馈网络,前一层即输入层)的输出作为输入,并输出结果到后一层(对于只有一个隐含层的前馈网络,后一层即输出层)。将这种神经网络看成数据结构中的“图”的话,那就是一个“有向无环图”(即前馈网络中是不存在反馈的)。
这里的边,即单元与单元之间连接的强度,也即权重。设想一下,当两个单元之间的权重为0时,一个单元的输出就无法再通过这条边传递给另一个单元了,即这两个单元之间断开连接了(不存在这条边了),因此神经网络模型中的模型参数不仅仅是个数字了,由于这张基于生物学中的神经系统的模型可视化图的存在,神经网络模型中的参数还代表着两个神经元之间的连接强度。
在《一般化机器学习与神经网络》中,小夕讲过了,所谓的前向算法,就是计算了一下模型的假设函数而已,只不过计算的过程可视化出来后就是一个沿着神经网络“向前推进”的样子,因此起了个名字而已。这里就不再赘述这个俗俗的假算法啦。
根据机器学习框架,假设函数有了,我们还需要考虑什么呢?当然是如何得到这个假设函数啦~也就是如何训练神经网络这个一般而特殊的机器学习模型(即学习模型参数)。
石器时代
假设你是一个完全不懂数学的生物学家(虽然学生物的数学也很厉害的,吧),你觉得从生物学的角度来看(将模型参数看作神经元之间的连接强度),这个神经网络训练好之后应该是什么样子的呢?
回想一下高中生物,如果两个神经元紧紧相连,那么一个神经元的兴奋必然导致与之相连的神经元的兴奋。如果经过无数次实验,我们发现对于神经元A和神经元B,只要A兴奋,那么B一定兴奋,那么就说明A与B之间肯定连接非常紧密(就像一条绳子的蚂蚱,一个跳起来肯定把另一个带起来),也就是说A到B的连接强度非常大!也就是说,A到B这个模型参数的值肯定很大。
将这个生物学思想往数学上靠一下,那就是“如果神经元A的激活带来B的激活,就代表A与B具有相关性,因此A与B之间的连接权重应该被加强,即应增大模型参数(下标BA代表从A出发,到达B的有向边)”。
这个思想叫什么呢?叫“Hebb规则”,这个思想是神经网络的学习算法的最本质,也是最原始的思想。
那么如何去实现这个思想呢?
青铜时代
设想一下,我们的网络到达了这么一种状态:
显然,模型犯错了!输出单元(输出层在这里只有一个单元)应该是1,结果预测的是0!也就是应该兴奋,实际在睡觉!而根据Hebb规则,我们应该让输出单元加强与那些兴奋的神经元的连接,也就是增大与“隐含层输出为1(专业说法叫被激活)的神经元”的连接!减弱与“隐含层输出为0(未激活)的神经元”的连接!
再想一下,“隐单元未激活/输出为0”代表着什么?
还记得《逻辑回归到神经网络》中放大的这个隐单元的图吗?
隐单元的核心就是激活函数,比如sigmoid、tanh等。如下sigmoid:
因此隐单元输出为0时,也就是未激活时,就意味着隐单元的输入为负值!
所以,为了迎合Hebb规则,应该让未激活的神经元减小权重,激活的神经元增加权重,那么我们可以直接让权重加上隐单元的输入啊:
即对于全部的隐单元:w=w+a。(注:a为隐单元的输入,未激活的神经元的a为负,激活的为正)
而对于如下这种情况,也就是应该输出0,实际输出了1的情况:
通过跟前面一样的推理我们发现,只要让w的更新方式与前面相反,即:
对于全部的隐单元:w=w-a。(注:a为隐单元的输入,未激活的神经元的a为负,激活的为正)
那么有没有办法将上面两种情况合起来表示呢?
机智的你应该想到了,那就是:
w=w+(真实值-预测值)*a
对啊,用这条通用的规则,就可以反复的更新隐藏层到输出层的权重了~这个规则叫什么呢?这就是1986年认知心理学家Rumellhart等人提出的δ学习规则,也叫广义Hebb规则,这是对神经网络学习算法的Hebb思想的直接实现!
等等,有没有觉得似曾相识呢?赶紧翻开书,看看BP算法的权重更新公式!有没有发现BP中的权重更新公式与这个规则所表达的意思惊人的相似!
相似就对了~
铁器时代
想一想,在广义Hebb规则中,我们做了一些简化:
首先,权重更新的方向很明确,但是更新的步长我们是直接用了隐单元的输入a,而没有证明这个a是最合理的步长。其次,我们这里直接用真实值减去预测值,也是很启发式的做法。
那么显然这个广义Hebb规则在数学上极有可能是非最优的,毕竟这是一个启发式的(即拍脑袋的)算法。那么如何得到最优的做法呢?那就是从这个规则的目的着手去提出更上层的理论!
广义Hebb规则的目的是什么呢?
这个规则的直接目的是让最终的输出逼近真实输出,也就是减小模型输出与真实输出之间的误差。具体做法是让每个隐单元的权重个性化修改,来向着使误差减小的方向移动。
等等!再重复一遍,具体做法是让每个隐单元的权重个性化修改,来向着使误差减小的方向移动。
再再重复一遍!具体做法是让每个隐单元的权重个性化修改,来向着使误差减小的方向移动!
所以我们可以怎样做?如果有一个函数可以直接描述这个误差!(这不就是损失函数做的事儿吗!)那么!以权重为误差的自变量,使误差减小的方向不就是权重的负梯度方向吗。那让权重沿着这个方向移动不久好了吗?(这不就是梯度下降法吗!)
如图,自变量(x轴)是权重,因变量(y轴)是误差!显然使误差减小的方向就是权重的负梯度方向啊~
所以!求出此时权重的负梯度(即此时每个隐单元的权重的导数!)!然后让权重向这个方向移动一定的步长!反复这个移动的过程!直到误差最小,即训练完成!得到最优的权重!
所以说这是什么?这就是梯度下降法呀~同时,这还是BP算法对隐含层与输出层连接权重的更新方式啊!
那么如何更新输入层到隐含层的权重呢?
一样的呀,数学思想都这么清晰了~误差依然是误差,只需要将自变量换成输入层到隐含层的权重,不就可以啦~其他的完全照旧啊。
只不过,损失函数是“间接包含”输入层到隐含层的权重的,因此在求此时的负梯度时,要进行链式求导~也就是下面这个烂大街的推理过程:
这个推理过程摘自http://blog.csdn.net/lu597203933/article/details/46575803,有兴趣的可以去看看,反正哪里都能找到这个推导过程~
数学好的一眼就看懂了,不太好的就随便找个讲BP算法的书或者帖子啦,这是真正的烂大街推理过程。。。因此,各层权重的负梯度利用上面的链式求导法则就很轻松的求出来了,然后w=w-α*负梯度,就可以啦~其中,α是步长~
看,源于训练神经网络的最naïve的Hebb思想,为了实现这个思想而提出了δ算法,用数学去描述δ算法的本质目标,得出通过引入损失函数并(链式求导)求解负梯度来更新权重的过程,即误差反向传播算法(BackPropagation,简称BP算法)。
╮(╯▽╰)╭
只不过在神经网络中可视化一下,看起来就像一个人们定义的误差从模型输出层向输入层传播而已啦,然后起了个形象的名字叫所谓的误差反向传播算法。
不过,人们抽象出来的这个前向与反向算法的概念还是有更多原因的,一是可以帮助人们理解,使其可以从生物学模型上得到解释,进而以这种思想变形出其他形式的前向与反向传播算法来描述或训练更复杂的神经网络;另一方面也是给我们程序猿(喵)们提供了一种简洁无脑的编程模型,使得哪怕不懂链式求导等BP算法原理的程序猿也能轻松的写出来这个数学上不算太简单的算法。
╮(╯▽╰)╭哎,要是小夕早出生了几十年,说不定提出BP算法的就是小夕了(捂脸光速逃\(//∇//)\