维基百科上的中文版反向传播算法的翻译不是特别准确,英文原版的结构也不是很容易理解,于是结合了各方资料重新写了一个版本。以下是中英维基百科的链接。
BackPropagation - Wikipedia
反向传播算法 - 维基百科中文版网站
反向传播(Backpropagation,缩写为BP)是一种用于人工神经网络的方法,用于计算在计算网络中使用的权重需要用到的梯度。反向传播是“误差反向传播”的简写,因为误差是在输出时计算的,并且从输出层往后分布于网络的各个层。它通常被用来训练深层神经网络。
反向传播是将delta规则推广到多层前馈网络,通过使用链规则迭代计算每个层的梯度来实现。它与高斯-牛顿算法密切相关,是神经反向传播研究(生物学上)的一部分。
反向传播是一种更通用的技术称作自动微分的特例。在学习的中,反向传播通常被梯度下降优化算法所使用,通过计算损失函数的梯度来更新神经元权重,以最小化损失函数。
动机
任何监督学习算法的目标都是找到一个将一组输入映射到其正确的输出的最佳函数,反向传播的动机是训练一个多层神经网络,使其能够学习适当的内部表达式,从而可以学习任何输入到输出的映射。
直观理解
作为一个优化问题学习
为了理解反向传播算法的数学推导,首先要对神经元的实际输出与特定训练示例的正确输出之间的关系进行一些直觉理解。考虑一个简单的神经网络,它有两个输入单元,一个输出单元,没有隐藏单元,每个神经元使用一个线性输出(这与实际神经网络上的大多数工作不同,实际中从输入到输出的映射基本都是非线性的),即其输入的加权和。(下图中 y 应改为 t )
最初,在训练之前,权重会被随机设置,接着神经元从训练样本中学习,在这种情况下,训练样本由一组元组 ( x 1 , x 2 , y ) (x_1,x_2,y) (x1,x2,y)组成,其中 x 1 , x 2 x_1,x_2 x1,x2是网络的输入, y y y是正确的输出(当网络被训练时,由这些输入而应该得到的输出)。这个最初的网络,在给定了 x 1 , x 2 x_1,x_2 x1,x2后,会计算出一个输出结果 t t t,很可能会与 y y y不同(因为给了随机权重)。度量预期输出 y y y和实际输出 t t t之间的误差常用的方法是计算它们的平方误差:
E = ( t − y ) 2 E=(t-y)^{2} E=(t−y)2
其中 E E E就是误差。
这里给一个例子,我们考虑这个网络的训练集只有一个样本 ( 1 , 1 , 0 ) (1,1,0) (1,1,0),因此输入 x 1 , x 2 x_1,x_2 x1,x2分别为1和1,正确的输出为 y = 0 y=0 y=0。现在若将实际输出 t 画在 x 轴(图中标为y了,本文为了了统一符号,应改为 t ),误差 E 画在 y 轴,得出的是一条抛物线。抛物线的极小值对应输出 t ,最小化了误差 E 。对于单一训练实例,极小值还会接触到 x 轴,这意味着误差为零,网络可以产生与期望输出 y 完全匹配的输出 t。因此,把输入映射到输出的问题就化为了一个找到一个能产生最小误差的函数的最优化问题。
然而,一个神经元的输出取决于其所有输入的加权总和:
t = x 1 w 1 + x 2 w 2 t=x_{1} w_{1}+x_{2} w_{2} t=x1w1+x2w2
其中 w 1 , w 2 w_1,w_2 w1,w2是从输入单元到输出单元的权重。因此,误差取决于出入到该神经元的权重,也是网络要学习最终需要改变的。若每个权重都画在一个水平的轴上,而误差画在垂直轴上,得出的就是一个抛物面(若一个神经元有 k 个权重,则误差曲面的维度就会是 k+1,因而就是二维抛物线的 k+1 维等价)。
反向传播算法的目的是找到一组能最大限度地减小误差的权重。寻找抛物线或任意维度中的任何函数的极大值的方法有若干种。第一种方法是求解方程组,但这仅适用于线性系统的网络,然而我们需要的是可以训练多层非线性网络的方法(因为多层线性网络与单层网络等价)。第二种方法,也是在反向传播中使用的方法是梯度下降法。
运用类比理解梯度下降法
梯度下降法背后的直观感受可以用假设情境进行说明。一个被卡在山上的人正在试图下山(即试图找到极小值)。大雾使得能见度非常低。因此,下山的道路是看不见的,所以他必须利用局部信息来找到极小值。他可以使用梯度下降法,该方法涉及到察看在他当前位置山的陡峭程度,然后沿着负陡度(即下坡)最大的方向前进。如果他要找到山顶(即极大值)的话,他需要沿着正陡度(即上坡)最大的方向前进。使用此方法,他会最终找到下山的路。不过,要假设山的陡度不能通过简单地观察得到,而需要复杂的工具测量,而这个工具此人恰好有。需要相当长的一段时间用仪器测量山的陡峭度,因此如果他想在日落之前下山,就需要最小化仪器的使用率。问题就在于怎样选取他测量山的陡峭度的频率才不致偏离路线。
在这个类比中,此人代表反向传播算法,而下山路径表示能使误差最小化的权重集合。山的陡度表示误差曲面在该点的斜率。他要前行的方向对应于误差曲面在该点的梯度。用来测量陡峭度的工具是微分(误差曲面的斜率可以通过对平方误差函数在该点求导数计算出来)。他在两次测量之间前行的距离(与测量频率成正比)是算法的学习速率。参见限制一节中对此类型“爬山”算法的限制的讨论。
概括
由于反向传播使用梯度下降法,需要计算平方误差函数对网络权值的导数。假设对于一个输出神经元,平方误差函数为:
E = 1 2 ( t − y ) 2 E=\frac{1}{2}(t-y)^{2} E=21(t−y)2
其中, E E E为平方误差, t t t为训练样本的目标输出, y y y为输出神经元的实际输出。
加入系数1/2是为了抵消微分出来的指数。之后,该表达式会乘以一个任意的学习率,因此常系数无关紧要。对于每个神经元 j j j,它的输出 a j a_j aj定义为
a j = φ ( net j ) = φ ( ∑ i = 1 n w i j a i ) a_{j}=\varphi\left(\text { net }_{j}\right)=\varphi\left(\sum_{i=1}^{n} w_{i j} a_{i}\right) aj=φ( net j)=φ(i=1∑nwijai)
通向一个神经元的输入 n e t j net_j netj是之前神经元输出 a j a_j aj的加权和。若该神经元处于输入层后的第一层,输入层的输出 a i a_i ai就是网络的输入 x i x_i xi。该神经元的输入数量是 n n n。变量 w i j w_{ij} wij表示神经元 i , j i,j i,j之间的权值。
激活函数 φ \varphi φ一般是非线性可微函数。常用的激活函数是sigmoid函数
φ ( z ) = 1 1 + e − z \varphi(z)=\frac{1}{1+e^{-z}} φ(z)=1+e−z1
其导数形式
∂ φ ∂ z = φ ( 1 − φ ) \frac{\partial \varphi}{\partial z}=\varphi(1-\varphi) ∂z∂φ=φ(1−φ)
反向传播算法主要由两个阶段组成:激励传播与权值更新。
第一阶段:激励传播
每次迭代中的传播环节包含两步:
- (向前传播阶段)将训练数据输入网络以获得激励响应(实际输出)。
- (反向传播阶段)将激励响应同目标输出求差,从而获得输出层、隐藏层的响应误差。
第一阶段即损失函数的计算,可以描述如下:
J ( w 0 , w 1 , … , w n ) = 1 2 m ∑ i = 1 m ( h w ( x ( i ) ) − y ( i ) ) 2 J\left(w_{0}, w_{1}, \ldots, w_{n}\right)=\frac{1}{2 m} \sum_{i=1}^{m}\left(h_{w}\left(x^{(i)}\right)-y^{(i)}\right)^{2} J(w0,w1,…,wn)=2m1i=1∑m(hw(x(i))−y(i))2
其中 h w ( x ( i ) ) h_{w}\left(x^{(i)}\right) hw(x(i))即为 a i a_i ai。
第二阶段:权值更新
对于每一个神经元上的权值,按照以下步骤进行更新:
- 将输入和误差相乘,从而获得权重的梯度;
- 将这个梯度乘上一个比例并取反后加到权重上。
这个比例(学习率)将会影响到训练过程的速度和效果,因此成为“训练因子”。梯度的方向指明了误差扩大的方向,因此在更新权重的时候需要对其取反,从而减小权重引起的误差。
第二阶段即使用梯度下降的权值更新公式,可以描述如下:
w j : = w j − α ∑ i = 1 m ( h w ( x ( i ) ) − y ( i ) ) x j ( i ) w_{j} :=w_{j}-\alpha \sum_{i=1}^{m}\left(h_{w}\left(x^{(i)}\right)-y^{(i)}\right) x_{j}^{(i)} wj:=wj−αi=1∑m(hw(x(i))−y(i))xj(i)
α \alpha α即学习率,超参。
第 1 和第 2 阶段可以反复循环迭代,直到网络对输入的响应达到满意的预定的目标范围为止。
算法
BP算法的名称意味着误差会从输出结点反向传播到输入结点。严格地讲,反向传播算法对网络的可修改权值计算了网络误差的梯度。这个梯度会在简单随机梯度下降法中经常用来求最小化误差的权重。通常“反向传播”这个词使用更一般的含义,用来指涵盖了计算梯度以及在随机梯度下降法中使用的整个过程。在适用反向传播算法的网络中,它通常可以快速收敛到令人满意的极小值。
BP算法
训练集 { ( x ( 1 ) , y ( 1 ) ) , … , ( x ( m ) , y ( m ) ) } \left\{\left(x^{(1)}, y^{(1)}\right), \ldots,\left(x^{(m)}, y^{(m)}\right)\right\} { (x(1),y(1)),…,(x(m),y(m))}
设 Δ i j ( l ) = 0 ( for all l , i , j ) \Delta_{i j}^{(l)}=0(\text { for all } l, i, j) Δij(l)=0( for all l,i,j)
For i = 1 to m \begin{array}{l}{\text {For } i=1 \text { to } m}\end{array} For i=1 to m
Set a ( 1 ) = x ( i ) Perform forward propagation to compute a ( l ) for l = 2 , 3 , … , L Using y ( i ) , compute δ ( L ) = a ( L ) − y ( i ) Compute δ ( L − 1 ) , δ ( l + 1 ) , … , δ ( 2 ) Δ i j ( l ) : = Δ i j ( l ) + a j ( l ) δ i ( l + 1 ) \begin{array}{l}{\text { Set } a^{(1)}=x^{(i)}} \\ {\text { Perform forward propagation to compute } a^{(l)} \text { for } l=2,3, \ldots, L} \\ {\text { Using } y^{(i)}, \text { compute } \delta^{(L)}=a^{(L)}-y^{(i)}} \\ {\text { Compute } \delta^{(L-1)}, \delta^{(l+1)}, \ldots, \delta^{(2)}} \\ {\Delta_{i j}^{(l)} :=\Delta_{i j}^{(l)}+a_{j}^{(l)} \delta_{i}^{(l+1)}}\end{array} Set a(1)=x(i) Perform forward propagation to compute a(l) for l=2,3,…,L Using y(i), compute δ(L)=a(L)−y(i) Compute δ(L−1),δ(l+1),…,δ(2)Δij(l):=Δij(l)+aj(l)δi(l+1)
D i j ( l ) : = 1 m Δ i j ( l ) + λ W i j ( l ) if j ≠ 0 D i j ( l ) : = 1 m Δ i j ( l ) if j = 0 \begin{array}{l}{D_{i j}^{(l)} :=\frac{1}{m} \Delta_{i j}^{(l)}+\lambda W_{i j}^{(l)}} & {\text { if } j \neq 0} \\ {D_{i j}^{(l)} :=\frac{1}{m} \Delta_{i j}^{(l)}} & {\text { if } j=0}\end{array} Dij