前言
想要理解神经网络的工作原理,反向传播(BP)是必须搞懂的东西。BP其实并不难理解,说白了就是用链式法则(chain rule)算算算。本文试图以某个神经网络为例,尽可能直观,详细,明了地说明反向传播的整个过程。
正向传播
在反向传播之前,必然是要有正向传播的。正向传播时的所有参数都是预先随机取的,没人能说这样的参数好不好,得要试过才知道,试过之后,根据得到的结果与目标值的差距,再通过反向传播取修正各个参数。下图就是一个神经网络,我们以整个为例子来说明整个过程
图1:神经网络图
我懒,此图取自参考文献[1],图中的各个符号说明如下(顺序从下往上):
xi:输入样本中的第i个特征的值
vih:xi与隐层第h个神经元连接的权重
αh:第h个隐层神经元的输入,αh=∑i=1dvihxi
bh:第h个隐层神经元的输出,某个神经元的输入和输出有关系f(αh)=bh,其中f(x)为**函数,比如Sigmoid函数f(x)=1+e−x1
whj:隐层第h个神经元和输出层第j个神经元连接的权重
βj:输出层第j个神经元的输入,βj=∑h=1qwhjbh
yj:第j个输出层神经元的输出,f(βj)=yj,f(x)为**函数
为了方便书写,我们假设截距项bias已经在参数w和v之中了,也就是说在输入数据的时候,我们增添了一个x0=1,由于我懒,图中没有画出来,但心里要清楚这一点。
相信看了图之后,神经网络的正向传播就相当简单明了了,不过,这里我还是啰嗦一句,举个例子,比如输出yj的计算方法为
yj=f(βj)=f(h=1∑qwhjbh)=f(h=1∑qwhjf(αh))=f(h=1∑qwhjf(i=1∑dvihxi))
反向传播
好了,通过正向传播,我们就已经得到了l个y的值了,将它们与目标值t,也就是我们期望它们成为的值作比较,并放入损失函数中,记作L。
损失L可以自行选择,比如常见的均方误差L=21∑j=1l(yj−tj)2
利用这个误差,我们将进行反向传播,以此来更新参数w和v。更新时,我们采用的是梯度下降法,也就是
{w:=w+Δwv:=v+Δv
其中,Δw=−η∂w∂L,Δv=−η∂v∂L,η为学习率。
下面要做的工作就是计算出每个参数的梯度,这也就是链式法则发挥作用的地方了。
比如,我们要计算whj。从网络结构中不难看出whj影响了βj从而影响了yj,最终影响了L所以我们有
Δwhj=−η∂whj∂βj∂βj∂yj∂yj∂L
只要确定了损失函数L和**函数f(x),上面所有的都是可以算的,而且∂whj∂βh=bh这点是显而易见的。并且,∂βj∂yj=∂βj∂f(βj)就是**函数的导数。
同理,vih影响了αh,从而影响了bh,从而影响了β1,β2,…,βl,从而影响了y1,y2,…,yl,最终影响了L。
Δvih=−η∂vih∂αh∂αh∂bhj=1∑l(∂bh∂βj∂βj∂yj∂yj∂L)
其中,∂vih∂αh=xi,∂bh∂βj=whj,∂βj∂yj=∂βj∂f(βj)和∂αh∂bh=∂αh∂f(αh)是**函数的导数。
至此,我们已经可以算出Δw和Δv,从而更新参数了。
关于**函数的几点说明
从推出的公式中不难看出,随着反向传播向输出层这个方向的推进,**函数的影响也就越来越来了。通俗一点来说,在计算Δwhj,我们只乘了一个**函数的导数,然而在计算Δvih时,我们乘了多个**函数的导数。
Δwhj=−η∂whj∂βjf′(βj)∂yj∂L
Δvih=−η∂vih∂αhf′(αh)j=1∑l(∂bh∂βjf′(βj)∂yj∂L)
不难推断出,如果隐层的层数更多的话,**函数的影响还要更大。
一个比较传统的**函数时Sigmoid函数,其图像如下所示。
图2:Sigmoid函数
不难发现,当x比较大的时候,或比较小的时候,f′(x)是趋近于0的,当神经网络的层数很深的时候,这么多个接近0的数相乘就会导致传到输出层这边的时候已经没剩下多少信息了,这时梯度对模型的更新就没有什么贡献了。那么大多数神经元将会饱和,导致网络就几乎不学习。这其实也是Sigmoid函数现在在神经网络中不再受到青睐的原因之一。
另一个原因是Sigmoid 函数不是关于原点中心对称的,这会导致梯度在反向传播过程中,要么全是正数,要么全是负数。导致梯度下降权重更新时出现 Z 字型的下降。
所以,就出现了ReLU这个**函数 f(x)=max(0,x),其图像如下图所示。
图3:ReLU函数
ReLU 对于 SGD 的收敛有巨大的加速作用,而且只需要一个阈值就可以得到**值,而不用去算一大堆复杂的(指数)运算。
不过,由于它左半边的状态,ReLU在训练时比较脆弱并且可能“死掉”。
因此,人们又研究出了Leaky ReLU,PReLU等等的**函数。这里不展开讨论。
参考文献
[1] 周志华. 机器学习 : = Machine learning[M]. 清华大学出版社, 2016.
[2] http://cs231n.github.io/neural-networks-1/
[2] http://www.jianshu.com/p/6df4ab7c235c