反向传播

简介

误差反向传播算法简称反向传播算法(Back Propagation)。使用反向传播算法的多层感知器又称为BP神经网络。

BP算法是一个迭代算法,它的基本思想如下:

  1. 将训练集数据输入到神经网络的输入层,经过隐藏层,最后达到输出层并输出结果,这就是前向传播过程。
  2. 由于神经网络的输出结果与实际结果有误差,则计算估计值与实际值之间的误差,并将该误差从输出层向隐藏层反向传播,直至传播到输入层;
  3. 在反向传播的过程中,根据误差调整各种参数的值(相连神经元的权重),使得总损失函数减小。
  4. 迭代上述三个步骤(即对数据进行反复训练),直到满足停止准则。

示例

有如下一个神经网络:

反向传播

第一层是输入层,包含两个神经元 i1i_1i2i_2 和偏置项 b1b_1;第二层是隐藏层,包含两个神经元 h1h_1h2h_2 和偏置项 b2b_2;第三层是输出 o1o_1o2o_2。每条线上标的 wiw_i 是层与层之间连接的权重。**函数是 sigmodsigmod 函数。我们用 zz 表示某神经元的加权输入和;用 aa 表示某神经元的输出。

上述各参数赋值如下:

参数
i1i_1 0.05
i2i_2 0.10
w1w_1 0.15
w2w_2 0.20
w3w_3 0.25
w4w_4 0.30
w5w_5 0.40
w6w_6 0.45
w7w_7 0.50
w8w_8 0.55
b1b_1 0.35
b2b_2 0.60
o1o_1 0.01
o2o_2 0.99

Step 1 前向传播

输入层 —> 隐藏层

神经元 h1h_1 的输入加权和:
反向传播
神经元 h1h_1 的输出 ah1a_{h1}
ah1=11+ezh1=11+e0.3775=0.593269992 a_{h1} = \frac{1}{1+e^{-z_{h1}}} = \frac{1}{1+e^{-0.3775}} = 0.593269992
同理可得,神经元 h2h_2 的输出 ah2a_{h2}
ah2=0.596884378 a_{h2} = 0.596884378

隐藏层 —> 输出层

计算输出层神经元 o1o1o2o2 的值:
反向传播
前向传播的过程就结束了,我们得到的输出值是 [0.751365069,0.772928465][0.751365069, 0.772928465] ,与实际值 [0.01,0.99][0.01, 0.99] 相差还很远。接下来我们对误差进行反向传播,更新权值,重新计算输出。

Step 2 反向传播

  1. 计算损失函数:

Etotal=12(targetoutput)2 E_{total} = \sum\frac{1}{2}(target - output)^2

但是有两个输出,所以分别计算 o1o_1o2o_2 的损失值,总误差为两者之和:
Eo1=12(0.010.751365069)2=0.274811083Eo2=12(0.990.772928465)2=0.023560026Etotal=Eo1+Eo2=0.274811083+0.023560026=0.298371109 E_{o_1} = \frac {1}{2}(0.01 - 0.751365069)^2 = 0.274811083 \\ E_{o_2} = \frac {1}{2}(0.99 - 0.772928465)^2 = 0.023560026 \\ E_{total} = E_{o_1} + E_{o_2} = 0.274811083 + 0.023560026 = 0.298371109

  1. 隐藏层 —> 输出层的权值更新

以权重参数 w5w_5 为例,如果我们想知道 w5w_5 对整体损失产生了多少影响,可以用整体损失对 w5w_5 求偏导:
Etotalw5=Etotalao1ao1zo1zo1w5 \frac{\partial E_{total}}{\partial w_5} = {\frac {\partial E_{total}}{\partial a_{o_1}}}*{\frac {\partial a_{o_1}}{\partial z_{o_1}} }*{ \frac {\partial z_{o_1}} {\partial w_5} }
下面的图可以更直观了解误差是如何反向传播的:

反向传播

我们现在分别来计算每个式子的值:

计算 Etotalao1\frac {\partial E_{total}} {\partial a_{o_1}}
Etotal=12(targeto1ao1)2+12(targeto2ao1)2Etotalao1=212(targeto1ao1)1Etotalao1=(targeto1ao1)=0.7513650690.01=0.741365069 E_{total} = \frac {1}{2}(target_{o_1} - a_{o_1})^2 + \frac {1}{2}(target_{o_2} - a_{o_1})^2 \\ \frac {\partial E_{total}} {\partial a_{o_1}} = 2 * \frac {1}{2} (target_{o_1} - a_{o_1})*-1 \\ \frac {\partial E_{total}} {\partial a_{o_1}} = -(target_{o_1} - a_{o_1}) = 0.751365069-0.01=0.741365069 \\
计算 Etotalao1\frac {\partial E_{total}} {\partial a_{o_1}}
ao1=11+ezo1ao1zo1=ao1(1ao1)=0.751365069(10.751365069)=0.186815602 a_{o_1} = \frac {1}{1+e^{-z_{o_1}}} \\ \frac {\partial a_{o_1}} {\partial z_{o_1}} = a_{o_1}*(1-a_{o_1}) = 0.751365069*(1-0.751365069) = 0.186815602
计算 zo1w5\frac {\partial z_{o_1}} {\partial w_5}
zo1=w5ah1+w6ah2+b21zo1w5=ah1=0.593269992 z_{o_1} = w_5*a_{h1} + w_6*a_{h2} + b_2*1 \\ \frac {\partial z_{o_1}} {\partial w_5} = a_{h_1} = 0.593269992
最后三者相乘:
Etotalw5=0.7413650690.1868156020.593269992=0.082167041 \frac {\partial E_{total}} {\partial w_5} = 0.741365069*0.186815602*0.593269992 = 0.082167041
这样我们就算出整体损失 EtotalE_{total}w5w_5 的偏导值。
Etotalw5=(targeto1ao1)ao1(1ao1)ah1 \frac {\partial E_{total}} {\partial w_5} = -(target_{o_1} - a_{o_1}) * a_{o_1}*(1-a_{o_1}) * a_{h_1}
针对上述公式,为了表达方便,使用 δo1\delta_{o_1} 来表示输出层的误差:
δo1=Etotalao1ao1zo1=Etotalzo1δo1=(targeto1ao1)ao1(1ao1) \delta_{o_1} = {\frac {\partial E_{total}}{\partial a_{o_1}}}*{\frac {\partial a_{o_1}}{\partial z_{o_1}} } = \frac {\partial E_{total}} {\partial z_{o_1}} \\ \delta_{o_1} = -(target_{o_1} - a_{o_1}) * a_{o_1}*(1-a_{o_1})
因此整体损失 EtotalE_{total}w5w_5 的偏导值可以表示为:
Etotalw5=δo1ah1 \frac {\partial E_{total}}{\partial w_5} = \delta_{o_1}*a_{h_1}
最后我们来更新 w5w_5 的值:
w5+=w5ηEtotalw5=0.40.50.082167041=0.35891648η: w_5^+ = w_5 - \eta * \frac {\partial E_{total}} {\partial w_5} = 0.4 - 0.5*0.082167041 = 0.35891648 \qquad \eta: 学习率
同理可更新 w6,w7,w8w_6, w_7, w_8
w6+=0.408666186w7+=0.511301270w8+=0.561370121 w_6^+ = 0.408666186 \\ w_7^+ = 0.511301270 \\ w_8^+ = 0.561370121

  1. 隐藏层 —> 隐藏层的权值更新:

计算 Etotalw1\frac {\partial E_{total}} {\partial w_1} 与上述方法类似,但需要注意下图:

反向传播

计算 Etotalah1\frac {\partial E_{total}} {\partial a_{h_1}}
Etotalah1=Eo1ah1+Eo2ah1 \frac {\partial E_{total}} {\partial a_{h_1}} = \frac {\partial E_{o_1}} {\partial a_{h_1}} + \frac {\partial E_{o_2}} {\partial a_{h_1}}

先计算 Eo1ah1\frac {\partial E_{o_1}} {\partial a_{h_1}}

反向传播

同理可得:
Eo2ah1=0.019049119 \frac {\partial E_{o_2}} {\partial a_{h_1}} = -0.019049119
两者相加得:
Etotalah1=0.0553994250.019049119=0.036350306 \frac {\partial E_{total}} {\partial a_{h_1}} = 0.055399425 - 0.019049119 = 0.036350306
计算 ah1zh1\frac {a_{h_1}} {z_{h_1}}
ah1zh1=ah1(1ah1)=0.593269992(10.593269992)=0.2413007086 \frac {a_{h_1}} {z_{h_1}} = a_{h_1} * (1-a_{h_1}) = 0.593269992*(1-0.593269992) = 0.2413007086
计算 zh1w1\frac {\partial z_{h_1}} {\partial w_1}
zh1w1=i1=0.05 \frac {\partial z_{h_1}} {\partial w_1} = i_1 = 0.05
最后三者相互乘:
Etotalw1=0.0363503060.24130070860.05=0.000438568 \frac {\partial E_{total}} {\partial w_1} = 0.036350306 * 0.2413007086 * 0.05 = 0.000438568

为了简化公式,用 δh1\delta_{h_1} 表示隐藏层单元 h1h_1 的误差:

反向传播

最后更新 w1w_1 的权值:
w1+=w1ηEtotalw1=0.150.50.000438568=0.149780716 w_1^+ = w_1 - \eta * \frac {\partial E_{total}} {\partial w_1} = 0.15 - 0.5*0.000438568 = 0.149780716
同理,更新 w2,w3,w4w_2, w_3, w_4 权值:
w2+=0.19956143w3+=0.24975114w4+=0.29950229 w_2^+ = 0.19956143 \\ w_3^+ = 0.24975114 \\ w_4^+ = 0.29950229
这样,反向传播算法就完成了,最后我们再把更新的权值重新计算,不停地迭代。在这个例子中第一次迭代之后,总误差 EtotalE_{total} 由0.298371109下降至0.291027924。迭代10000次后,总误差为0.000035085,输出为[0.015912196,0.984065734]([0.01,0.99][0.015912196,0.984065734](原输入为[0.01,0.99] ,证明效果还是不错的。

公式推导

反向传播

符号说明

符号 说明
nln_l 网络层数
yjy_j 输出层第 jj 类标签
SlS_l ll 层神经元个数(不包括偏置项)
g(x)g(x) **函数
wijlw_{ij}^{l} l1l-1 层的第 jj 个神经元连接到第 ll 层第 ii 个神经元的权重
bilb_i^{l} ll 层的第 ii 个神经元的偏置
zilz_i^{l} ll 层的第 ii 个神经元的输入加权和
aila_i^{l} ll 层的第 ii 个神经元的输出(**值)
δil\delta_i^{l} ll 层的第 ii 个神经元产生的错误

推导过程

基本公式

反向传播

梯度方向传播公式推导

初始条件

反向传播

递推公式

反向传播

反向传播伪代码

  1. 输入训练集。
  2. 对于训练集的每个样本 x\vec x ,设输入层对应的**值为 ala^l
    • 前向传播:zl=wlal1+bl,al=g(zl)z^l = w^l*a^{l-1}+b^l, a^l = g(z^l)
    • 计算输出层产生的误差:δL=J(θ)aLg(zL)\delta^L = \frac {\partial J(\theta)} {\partial a^L} \odot g'(z^L)
    • 反向传播错误:δl=((wl+1)Tδl+1)g(zl)\delta^l = ((w^{l+1})^T*\delta^{l+1}) \odot g'(z^l)
  3. 使用梯度下降训练参数:
    • wlwlαmxδx,l(ax,l1)Tw^l \dashrightarrow w^l - \frac {\alpha} {m} \sum_x\delta^{x, l}*(a^{x, l-1})^T
    • blblηmxδx,lb^l \dashrightarrow b^l - \frac {\eta} {m} \sum_x\delta^{x, l}

交叉熵损失函数推导

对于多分类问题,softmaxsoftmax 函数可以将神经网络的输出变成一个概率分布。它只是一个额外的处理层,下图展示了加上了 softmaxsoftmax 回归的神经网络结构图:

反向传播

递推公式仍然和上述递推公式保持一致。初始条件如下:

反向传播

softmaxsoftmax 偏导数计算:
yjpainl={yipyjpijyip(1yip)i=j \frac {\partial y_j^p} {\partial a_i^{nl}} = \left\{ \begin{aligned} -y_i^p*y_j^p \qquad i \neq j \\ y_i^p*(1-y_i^p) i = j \end{aligned} \right.

推导过程

反向传播


参考自: