简介
误差反向传播算法简称反向传播算法(Back Propagation)。使用反向传播算法的多层感知器又称为BP神经网络。
BP算法是一个迭代算法,它的基本思想如下:
- 将训练集数据输入到神经网络的输入层,经过隐藏层,最后达到输出层并输出结果,这就是前向传播过程。
- 由于神经网络的输出结果与实际结果有误差,则计算估计值与实际值之间的误差,并将该误差从输出层向隐藏层反向传播,直至传播到输入层;
- 在反向传播的过程中,根据误差调整各种参数的值(相连神经元的权重),使得总损失函数减小。
- 迭代上述三个步骤(即对数据进行反复训练),直到满足停止准则。
示例
有如下一个神经网络:

第一层是输入层,包含两个神经元 i1,i2 和偏置项 b1;第二层是隐藏层,包含两个神经元 h1,h2 和偏置项 b2;第三层是输出 o1,o2。每条线上标的 wi 是层与层之间连接的权重。**函数是 sigmod 函数。我们用 z 表示某神经元的加权输入和;用 a 表示某神经元的输出。
上述各参数赋值如下:
参数 |
值 |
i1 |
0.05 |
i2 |
0.10 |
w1 |
0.15 |
w2 |
0.20 |
w3 |
0.25 |
w4 |
0.30 |
w5 |
0.40 |
w6 |
0.45 |
w7 |
0.50 |
w8 |
0.55 |
b1 |
0.35 |
b2 |
0.60 |
o1 |
0.01 |
o2 |
0.99 |
Step 1 前向传播
输入层 —> 隐藏层
神经元 h1 的输入加权和:

神经元 h1 的输出 ah1 :
ah1=1+e−zh11=1+e−0.37751=0.593269992
同理可得,神经元 h2 的输出 ah2 :
ah2=0.596884378
隐藏层 —> 输出层
计算输出层神经元 o1 和 o2 的值:

前向传播的过程就结束了,我们得到的输出值是 [0.751365069,0.772928465] ,与实际值 [0.01,0.99] 相差还很远。接下来我们对误差进行反向传播,更新权值,重新计算输出。
Step 2 反向传播
- 计算损失函数:
Etotal=∑21(target−output)2
但是有两个输出,所以分别计算 o1 和 o2 的损失值,总误差为两者之和:
Eo1=21(0.01−0.751365069)2=0.274811083Eo2=21(0.99−0.772928465)2=0.023560026Etotal=Eo1+Eo2=0.274811083+0.023560026=0.298371109
- 隐藏层 —> 输出层的权值更新
以权重参数 w5 为例,如果我们想知道 w5 对整体损失产生了多少影响,可以用整体损失对 w5 求偏导:
∂w5∂Etotal=∂ao1∂Etotal∗∂zo1∂ao1∗∂w5∂zo1
下面的图可以更直观了解误差是如何反向传播的:

我们现在分别来计算每个式子的值:
计算 ∂ao1∂Etotal :
Etotal=21(targeto1−ao1)2+21(targeto2−ao1)2∂ao1∂Etotal=2∗21(targeto1−ao1)∗−1∂ao1∂Etotal=−(targeto1−ao1)=0.751365069−0.01=0.741365069
计算 ∂ao1∂Etotal :
ao1=1+e−zo11∂zo1∂ao1=ao1∗(1−ao1)=0.751365069∗(1−0.751365069)=0.186815602
计算 ∂w5∂zo1 :
zo1=w5∗ah1+w6∗ah2+b2∗1∂w5∂zo1=ah1=0.593269992
最后三者相乘:
∂w5∂Etotal=0.741365069∗0.186815602∗0.593269992=0.082167041
这样我们就算出整体损失 Etotal 对 w5 的偏导值。
∂w5∂Etotal=−(targeto1−ao1)∗ao1∗(1−ao1)∗ah1
针对上述公式,为了表达方便,使用 δo1 来表示输出层的误差:
δo1=∂ao1∂Etotal∗∂zo1∂ao1=∂zo1∂Etotalδo1=−(targeto1−ao1)∗ao1∗(1−ao1)
因此整体损失 Etotal 对 w5 的偏导值可以表示为:
∂w5∂Etotal=δo1∗ah1
最后我们来更新 w5 的值:
w5+=w5−η∗∂w5∂Etotal=0.4−0.5∗0.082167041=0.35891648η:学习率
同理可更新 w6,w7,w8 :
w6+=0.408666186w7+=0.511301270w8+=0.561370121
- 隐藏层 —> 隐藏层的权值更新:
计算 ∂w1∂Etotal 与上述方法类似,但需要注意下图:

计算 ∂ah1∂Etotal :
∂ah1∂Etotal=∂ah1∂Eo1+∂ah1∂Eo2
先计算 ∂ah1∂Eo1 :

同理可得:
∂ah1∂Eo2=−0.019049119
两者相加得:
∂ah1∂Etotal=0.055399425−0.019049119=0.036350306
计算 zh1ah1 :
zh1ah1=ah1∗(1−ah1)=0.593269992∗(1−0.593269992)=0.2413007086
计算 ∂w1∂zh1
∂w1∂zh1=i1=0.05
最后三者相互乘:
∂w1∂Etotal=0.036350306∗0.2413007086∗0.05=0.000438568
为了简化公式,用 δh1 表示隐藏层单元 h1 的误差:

最后更新 w1 的权值:
w1+=w1−η∗∂w1∂Etotal=0.15−0.5∗0.000438568=0.149780716
同理,更新 w2,w3,w4 权值:
w2+=0.19956143w3+=0.24975114w4+=0.29950229
这样,反向传播算法就完成了,最后我们再把更新的权值重新计算,不停地迭代。在这个例子中第一次迭代之后,总误差 Etotal 由0.298371109下降至0.291027924。迭代10000次后,总误差为0.000035085,输出为[0.015912196,0.984065734](原输入为[0.01,0.99] ,证明效果还是不错的。
公式推导

符号说明
符号 |
说明 |
nl |
网络层数 |
yj |
输出层第 j 类标签 |
Sl |
第 l 层神经元个数(不包括偏置项) |
g(x) |
**函数 |
wijl |
第 l−1 层的第 j 个神经元连接到第 l 层第 i 个神经元的权重 |
bil |
第 l 层的第 i 个神经元的偏置 |
zil |
第 l 层的第 i 个神经元的输入加权和 |
ail |
第 l 层的第 i 个神经元的输出(**值) |
δil |
第 l 层的第 i 个神经元产生的错误 |
推导过程
基本公式

梯度方向传播公式推导
初始条件

递推公式

反向传播伪代码
- 输入训练集。
- 对于训练集的每个样本 x ,设输入层对应的**值为 al :
- 前向传播:zl=wl∗al−1+bl,al=g(zl)
- 计算输出层产生的误差:δL=∂aL∂J(θ)⊙g′(zL)
- 反向传播错误:δl=((wl+1)T∗δl+1)⊙g′(zl)
- 使用梯度下降训练参数:
- wl⇢wl−mα∑xδx,l∗(ax,l−1)T
- bl⇢bl−mη∑xδx,l
交叉熵损失函数推导
对于多分类问题,softmax 函数可以将神经网络的输出变成一个概率分布。它只是一个额外的处理层,下图展示了加上了 softmax 回归的神经网络结构图:

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

softmax 偏导数计算:
∂ainl∂yjp={−yip∗yjpi̸=jyip∗(1−yip)i=j
推导过程

参考自: