神经网络之后向传播算法

本文结合维基百科http://en.wikipedia.org/wiki/Backpropagation的说明,对神经网络的后向传播算法做一个总结,并作简单的公式推导。

典型的只含有1个隐层的3层神经网络的后向传播算法流程如下:

initialize network weights (often small random values)
  do
     forEach training example ex
        prediction = neural-net-output(network, ex)  // forward pass
        actual = teacher-output(ex)
        compute error (prediction - actual) at the output units
        compute $\Delta$ $w_h$ for all weights from hidden layer to output layer  // backward pass
        compute $\Delta$ $w_i$ for all weights from input layer to hidden layer   // backward pass continued
        update network weights // input layer not modified by error estimate
  until all examples classified correctly or another stopping criterion satisfied
  return the network

 简单的说明,即当网络的预测结果出来之后,与真实结果相比,计算出错误率,然后对每个权重$w_{ij}$计算其对错误率的偏导数,然后根据偏导数(梯度)调整权重。

记号:

1、$net_j$记为第$j$个神经元的原始输出;

2、$o_j$记为第$j$个神经元的最终输出;

3、转换函数记为$\varphi(\mbox{net}_{j}) = \varphi\left(\sum_{k=1}^{n}w_{kj}x_k\right)=o_{j} $;

4、$E$为整个网络的误差函数,一般为目标值$t$与预测值(输出值)$y$的函数$E=f(t,y)$;

5、$L_j$记为节点$j$的所有输出节点的集合,不引起歧义情况下会省略下标。

我们最终要求出的是$\frac{\partial E}{\partial w_{ij}}$,根据链式法则有:

$$\frac{\partial E}{\partial w_{ij}} = \frac{\partial E}{\partial o_j} \frac{\partial o_j}{\partial\mathrm{net_j}} \frac{\partial \mathrm{net_j}}{\partial w_{ij}} $$

根据定义,$net_j$是$w_{ij}$的线性函数,因此右边最后一项:

$$\frac{\partial \mathrm{net_j}}{\partial w_{ij}} = \frac{\partial}{\partial w_{ij}}\left(\sum_{k=1}^{n}w_{kj}x_k\right) = x_i$$

右边第二项为转换函数$\varphi(z)$的导数,一般用的比较多的是logistic函数,$ \varphi(z) = \frac{1}{1+e^{-z}} $,其导数为

$$\frac {\partial\varphi}{\partial z} = \varphi(1-\varphi)$$

主要推导的是右部第一项$\frac{\partial E}{\partial o_j}$。

当$j$在输出层时,是比较好计算的,即为$E$对$y$的偏导数:$\frac{\partial E}{\partial o_j} = \frac{\partial E}{\partial y} $。

当$j$在隐层时,我们有以下关系:

$$ \frac{\partial E}{\partial o_j} = \sum_{l \in L} \left(\frac{\partial E}{\partial \mathrm{net}_l}\frac{\partial \mathrm{net}_l}{\partial o_j}\right) = \sum_{l \in L} \left(\frac{\partial E}{\partial o_{l}}\frac{\partial o_{l}}{\partial \mathrm{net}_l}w_{jl}\right) $$

这是一个递推公式,从后层逐渐往前层递推,而最后层即是输出层,由上面公式给出,综合起来,我们有:

 $$\dfrac{\partial E}{\partial w_{ij}} = \delta_{j} x_{i}$$  

where,

$$\delta_{j} =\frac{\partial E}{\partial net_j}= \frac{\partial E}{\partial o_j} \frac{\partial o_j}{\partial\mathrm{net_j}} = \begin{cases} \frac{\partial E}{\partial y_j}\varphi '(\mbox{net}_{j}) & \mbox{if } j \mbox{ is an output neuron,}\\ (\sum_{l\in L} \delta_{l} w_{jl})\varphi '(\mbox{net}_{j}) & \mbox{if } j \mbox{ is an inner neuron.} \end{cases} $$

$$$$

代表在节点$j$的净输出(非最终输出)对损失函数造成的影响。

给定学习率,我们可以得到权重的调整度为:

$$\Delta w_{ij} = - \alpha \frac{\partial E}{\partial w_{ij}} $$

 

 

 偏置的调整

偏置权重与普通权重只有一个不同之处,即它的输入永远为1,因此将$x_i=1$带入上述诸式,便得到偏置调整的公式。

 

调整input参数

有的场景,我们可能同时要调整输入。这时我们可以做个等价替换,在真实的输入层前再加一层作为实际输入层,新加的一层与真实输入层节点一一对应,只有对应节点相连。我们每次的实际输入都是全1向量,而实际的输入体现在第一层对应节点的连线的权重上,这样,我们把样本输入从输入等价转换到权重上。

第一层的权重矩阵为对角阵,对角线上的数据即为样本输入。第一层的转换函数为线性函数$\varphi(x)=x$。这样安排,即可套入上面所说的后向传播算法中。此时在第一层,

$$\varphi '(x)=1~~and~~x_i=1$$

 $$\dfrac{\partial E}{\partial w_{ij}} = \delta_{j} x_{i}=(\sum_{l\in L} \delta_{l} w_{jl})\varphi '(\mbox{net}_{j})x_i=\sum_{l\in L} \delta_{l} w_{jl}$$ 

 

AutoEncoder调整input参数

AutoEncoder是特殊的三层bp网络,输出与输入相等,即是无监督的。对AutoEncoder网络,调整一般权重与上述推导一样,而调整input向量则有所不同。

我们看网络的误差函数$E=f(t,y)$,当是一般网络时$t$因为是目标输出,所以是不变的,当是AutoEncoder网络时,$t$即为input,是可变的,当调整input时,t也跟着调整。

设第$i$个输入为$v_i$,根据链式法则,我们得到:

$$\frac{\partial E}{\partial v_i}=\frac{\partial E}{\partial y}\frac{\partial y}{\partial v_i}+\frac{\partial E}{\partial t}=\sum_{l\in L} \delta_{l} w_{jl}+\frac{\partial E}{\partial t}$$

特别地,当$E=\frac{1}{2}\sum{(y-t)^2}$时,上式变为:

$$\frac{\partial E}{\partial v_i}=\sum_{l\in L} \delta_{l} w_{jl}+(v_i-O_i)$$

 

Norm规整

有时我们需要进一步的限制,在激活函数处理之后,还要求输入向量长度必须为1,隐层向量长度也必须为1。那么在规整化处理这一层,怎么求梯度呢?

设该层节点个数为$k$,输入向量为$x$,权重为$W$,激活函数为$\varphi$,则归一化因子为$Z=||\{\varphi(net_1),\varphi(net_2),...,\varphi(net_k)\}||=[\sum_{i=1}^k \varphi^2(net_i)]^{\frac{1}{2}}$。

则$$o_i=\frac{\varphi(net_i)}{Z}$$

于是

$$\frac{\partial o_i}{\partial net_i}=\frac{\varphi '(net_i)Z-\varphi(net_i)\frac{\partial Z}{\partial net_i}}{Z^2}$$

其中

$$\frac{\partial Z}{\partial net_i}=\frac{\varphi (net_i) \varphi '(net_i)}{Z}$$

带入得最终公式:

$$\frac{\partial o_i}{\partial net_i}=\frac{\varphi '(net_i)}{Z}(1-o_i^2)$$

 对比上述公式,有两点不同:1)梯度也被归一化因子$Z$归一化,归一化后减去了$o_i$的二次项。

若在输入层进行了规整化处理,那么在输入层,取$\varphi '(net_i)=1$,得

$$\frac{\partial o_i}{\partial net_i}=\frac{1-o_i^2}{Z}$$

 

当一个节点的净输出$net_i$改变时,会影响整个$Z$值的改变,进而也会影响到其它节点的输出$o_j$的改变,下面计算$\frac{\partial o_j}{\partial net_i},when i\neq j$。

$$\frac{\partial o_j}{\partial net_i}=\frac{\partial o_j}{\partial Z}\frac{\partial Z}{\partial net_i}=-\frac{\varphi(net_j)}{Z^2}o_i \varphi '(net_i)=-\frac{\varphi '(net_i)}{Z}o_io_j$$

综合起来,对所有的节点,我们得到如下公式:

$$\frac{\partial o_j}{\partial net_i}=\frac{\varphi '(net_i)}{Z}(\delta_{ij}- o_io_j)$$

因此

$$\frac{\partial E}{\partial net_i}=\sum_j \frac{\partial E}{\partial o_j}\frac{\partial o_j}{\partial net_i}=\frac{\varphi '(net_i)}{Z}\sum_j \frac{\partial E}{\partial o_j}(\delta_{ij}- o_io_j)$$

与L-BFGS算法的区别

L-BFGS是拟牛顿法,是针对目标函数求全局最优点的算法。而后向传播是神经网络优化算法,当然,其目标函数是$E$。神经网络优化,是基于样本的,有监督的,即$E$是样本和权重(==>待调整系数)的函数,每个样本给定,对应一个配置,样本值可看作超参数,权重是变量,等价于给定超参数的情况下求全局最优的变量。当一个样本优化完毕后,再优化下一个样本。

L-BFGS可以看为,超参数隐含已给定,因此是无监督的。

从广义上来讲,将全部样本囊括,然后可以写出一个广义的目标函数,对应批量优化。

狭义上来说,每个样本对应一个目标函数,对应增量优化。

不管增量优化批量优化,神经网络都有一个目标函数,样本给定后,这个目标函数是所有权重的函数$E=E(T,O(X,W))=E(W;X,T)$,$(X,T)$即是样本。对分层神经网络,O(W;X)是嵌套函数。

对于只有输入输出两层的网络:

$$O(W;X)=\varphi(W\times X)$$

只要求出梯度向量$g_k=\nabla E(W)$和海森矩阵$H_k=\nabla^2E(W)$即可套(拟)牛顿法。

 

附录

softmax函数

$$h_j=\frac{e^{z_j}}{\sum e^{z_i}}$$

$$\frac{\partial h_i}{\partial z_j}=h_i(\delta_{ij}-h_j) $$

 

logistic函数

$$ \varphi(z) = \frac{1}{1+e^{-z}} $$

$$\frac {\partial\varphi}{\partial z} = \varphi(1-\varphi)$$

 

hj=ezjezi

posted @ 2014-11-17 16:16  五色光  阅读(5380)  评论(4编辑  收藏  举报