本文结合维基百科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 o_j} \frac{\partial o_j}{\partial\mathrm{net_j}} = \begin{cases} (o_{j}-t_{j})\varphi(\mbox{net}_{j})(1-\varphi(\mbox{net}_{j})) & \mbox{if } j \mbox{ is an output neuron,}\\ (\sum_{l\in L} \delta_{l} w_{jl})\varphi(\mbox{net}_{j})(1-\varphi(\mbox{net}_{j})) & \mbox{if } j \mbox{ is an inner neuron.} \end{cases} $$
$$$$
给定学习率,我们可以得到权重的调整度为:
$$\Delta w_{ij} = - \alpha \frac{\partial E}{\partial w_{ij}} $$
与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)$即可套(拟)牛顿法。