神经网络反向传播算法 推导
(一) 概念及基本思想
误差反向传播算法简称反向传播算法(即BP算法)。使用反向传播算法的多层感知器又称为BP神经网络。BP算法是一个迭代算法。
它的基本思想为:
(1)先计算每一层的状态和激活值,直到最后一层(即信号是前向传播的);
(2)计算每一层的误差,误差的计算过程是从最后一层向前推进的(这就是反向传播算法名字的由来);
(3)更新参数(目标是误差变小)。
迭代前面两个步骤,直到满足停止准则(比如相邻两次迭代的误差的差别很小)。
首先进行记号的说明:
标记 | 含义 |
---|---|
n l n_{l} nl | 表示第 l l l层神经元的个数 |
f ( ⋅ ) f(\cdot) f(⋅) | 表示神经元的激活函数 |
W ( l ) W^{(l)} W(l) | 表示第 l − 1 l-1 l−1层到第 l l l层的权重矩阵 |
w i j ( l ) w^{(l)}_{ij} wij(l) | 是权重矩阵中的元素,表示第 l − 1 l-1 l−1层第 j j j个神经元到第 l l l层第 i i i个神经元的连接的权重(注意标号的顺序) |
b ( l ) = ( b 1 ( l ) , b 2 ( l ) , ⋯ b n l ( l ) ) T ∈ R n l b^{(l)}=(b^{(l)}_{1},b^{(l)}_{2},\cdots b^{(l)}_{n_{l}})^{T}\\\in \mathbb{R}^{n_{l}} b(l)=(b1(l),b2(l),⋯bnl(l))T∈Rnl | 表示 l − 1 l-1 l−1层到第 l l l层的偏置单元 |
z ( l ) = ( z 1 ( l ) , z 2 ( l ) , ⋯ z n l ( l ) ) T ∈ R n l z^{(l)}=(z^{(l)}_{1},z^{(l)}_{2},\cdots z^{(l)}_{n_{l}})^{T}\\\in \mathbb{R}^{n_{l}} z(l)=(z1(l),z2(l),⋯znl(l))T∈Rnl | 表示 l l l层神经元的状态 |
a ( l ) = ( a 1 ( l ) , a 2 ( l ) , ⋯ a n l ( l ) ) T ∈ R n l a^{(l)}=(a^{(l)}_{1},a^{(l)}_{2},\cdots a^{(l)}_{n_{l}})^{T}\\\in \mathbb{R}^{n_{l}} a(l)=(a1(l),a2(l),⋯anl(l))T∈Rnl | 表示 l l l层神经元的激活值(即输出值) |
下面以三层感知器(即只含有一个隐藏层的多层感知器)为例介绍反向传播算法(BP 算法)。
(二)信息的前向传播
根据图一的神经网络图,第2层神经元的状态及激活值可以通过下面的方法计算得到:
z
1
(
2
)
=
w
11
(
2
)
x
1
+
w
12
(
2
)
x
2
+
w
13
(
2
)
x
3
+
b
1
(
2
)
z_{1}^{(2)}=w _{11}^{(2)}x_{1}+w _{12}^{(2)}x_{2}+w _{13}^{(2)}x_{3}+b_{1}^{(2)}
z1(2)=w11(2)x1+w12(2)x2+w13(2)x3+b1(2)
z
2
(
2
)
=
w
21
(
2
)
x
1
+
w
22
(
2
)
x
2
+
w
23
(
2
)
x
3
+
b
2
(
2
)
z_{2}^{(2)}=w _{21}^{(2)}x_{1}+w _{22}^{(2)}x_{2}+w _{23}^{(2)}x_{3}+b_{2}^{(2)}
z2(2)=w21(2)x1+w22(2)x2+w23(2)x3+b2(2)
z
3
(
2
)
=
w
31
(
2
)
x
1
+
w
32
(
2
)
x
2
+
w
33
(
2
)
x
3
+
b
3
(
2
)
z_{3}^{(2)}=w _{31}^{(2)}x_{1}+w _{32}^{(2)}x_{2}+w _{33}^{(2)}x_{3}+b_{3}^{(2)}
z3(2)=w31(2)x1+w32(2)x2+w33(2)x3+b3(2)
a
1
(
2
)
=
f
(
z
1
(
2
)
)
a_{1}^{(2)}=f(z_{1}^{(2)})
a1(2)=f(z1(2))
a
2
(
2
)
=
f
(
z
2
(
2
)
)
a_{2}^{(2)}=f(z_{2}^{(2)})
a2(2)=f(z2(2))
a
3
(
2
)
=
f
(
z
3
(
2
)
)
a_{3}^{(2)}=f(z_{3}^{(2)})
a3(2)=f(z3(2)) 类似地,第3层神经元的状态及激活值可以通过下面的计算得到:
z
1
(
3
)
=
w
11
(
3
)
a
1
(
2
)
+
w
12
(
3
)
a
2
(
2
)
+
w
13
(
3
)
a
3
(
2
)
+
b
1
(
3
)
z_{1}^{(3)}=w _{11}^{(3)}a_{1}^{(2)}+w _{12}^{(3)}a_{2}^{(2)}+w _{13}^{(3)}a_{3}^{(2)}+b_{1}^{(3)}
z1(3)=w11(3)a1(2)+w12(3)a2(2)+w13(3)a3(2)+b1(3)
z
2
(
3
)
=
w
21
(
3
)
a
1
(
2
)
+
w
22
(
3
)
a
2
(
2
)
+
w
23
(
3
)
a
3
(
2
)
+
b
2
(
3
)
z_{2}^{(3)}=w _{21}^{(3)}a_{1}^{(2)}+w _{22}^{(3)}a_{2}^{(2)}+w _{23}^{(3)}a_{3}^{(2)}+b_{2}^{(3)}
z2(3)=w21(3)a1(2)+w22(3)a2(2)+w23(3)a3(2)+b2(3)
a
1
(
3
)
=
f
(
z
1
(
3
)
)
a_{1}^{(3)}=f(z_{1}^{(3)})
a1(3)=f(z1(3))
a
2
(
3
)
=
f
(
z
2
(
3
)
)
a_{2}^{(3)}=f(z_{2}^{(3)})
a2(3)=f(z2(3)) 可总结出,第
l
(
2
≤
l
≤
L
)
l(2\leq l\leq L)
l(2≤l≤L)层神经元的状态及激活值为(下面是向量表示形式):
z
(
l
)
=
W
(
l
)
a
(
l
−
1
)
+
b
(
l
)
z^{(l)}=W^{(l)}a^{(l-1)}+b^{(l)}
z(l)=W(l)a(l−1)+b(l)
a
(
l
)
=
f
(
z
(
l
)
)
a^{(l)}=f(z^{(l)})
a(l)=f(z(l)) 对于L层感知器,网络的最终输出为
a
(
L
)
a^{(L)}
a(L),前馈神经网络信息的前向传递过程如下:
x
=
a
(
1
)
→
z
(
2
)
→
⋯
→
a
(
L
−
1
)
→
z
(
L
)
→
a
(
L
)
=
y
\mathbf{x=a^{(1)}\rightarrow z^{(2)}\rightarrow \cdots \rightarrow a^{(L-1)}\rightarrow z^{(L)}\rightarrow a^{(L)}=y}
x=a(1)→z(2)→⋯→a(L−1)→z(L)→a(L)=y
(三)误差反向传播
信息前向传播指的是已知各个神经元的参数后,得到神经网络的输出。但是怎么得到各个神经元的参数呢? 误差反向传播算法解决的就是这个问题。
假设训练数据为 { ( x ( 1 ) , y ( 1 ) ) , ( x ( 2 ) , y ( 2 ) ) , ⋯ , ( x ( i ) , y ( i ) ) , ⋯ , ( x ( N ) , y ( N ) ) } \mathbf{\left \{ (x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),\cdots ,(x^{(i)},y^{(i)}),\cdots ,(x^{(N)},y^{(N)}) \right \}} {(x(1),y(1)),(x(2),y(2)),⋯,(x(i),y(i)),⋯,(x(N),y(N))},共有 N N N个。又假设输出数据为 n L n_{L} nL 维的,即 y ( i ) = ( y 1 ( i ) , ⋯ , y n L ( i ) ) T \mathbf{y^{(i)}=(y^{(i)}_{1},\cdots ,y^{(i)}_{n_{L}})^{T}} y(i)=(y1(i),⋯,ynL(i))T。
对某个训练数据 ( x ( i ) , y ( i ) ) (x^{(i)},y^{(i)}) (x(i),y(i))来说,其代价函数可写为: E ( i ) = 1 2 ∥ y ( i ) − o ( i ) ∥ = 1 2 ∑ k = 1 n L ( y k ( i ) − o k ( i ) ) 2 E^{(i)}=\frac{1}{2}\left \| y^{(i)} -o^{(i)}\right \|=\frac{1}{2}\sum_{k=1}^{n_{L}}(y^{(i)}_{k}-o^{(i)}_{k})^{2} E(i)=21∥∥∥y(i)−o(i)∥∥∥=21k=1∑nL(yk(i)−ok(i))2
说明:
- y ( i ) y^{(i)} y(i)指的是期望的输出(是训练数据给出的已知值), o ( i ) o^{(i)} o(i)是神经网络对输入 x ( i ) x^{(i)} x(i) 产生的实际输出;
- 代价函数中系数1/2不是必须的,它的存在仅仅为了后续计算时更加方便;
- 代价函数 E ( i ) E^{(i)} E(i)仅和权重矩阵 W ( l ) W^{(l)} W(l)和偏置向量 b ( l ) b^{(l)} b(l)相关,调整权重和偏置可以减少或增大代价(误差)。
显然,所有训练数据的总体(平均)代价可写为: E t o t a l = 1 N ∑ i = 1 N E ( i ) E_{total}=\frac{1}{N}\sum_{i=1}^{N}E_{(i)} Etotal=N1i=1∑NE(i) 目标就是调整权重和偏置使得总体代价(误差)变小,求得总体代价取最小值时对应的各个神经元的参数(即权重和偏置)。
如果采用梯度下降法(或者称为“批量梯度下降法”),可以用下面公式更新参数 w i j ( l ) , b i ( l ) , 2 ≤ l ≤ L w^{(l)}_{ij},b^{(l)}_{i},2 \leq l \leq L wij(l),bi(l),2≤l≤L: W ( l ) = W ( l ) − μ ∂ E t o t a l ∂ W ( l ) = W ( l ) − μ N ∑ i = 1 N ∂ E ( i ) ∂ W ( l ) W^{(l)}=W^{(l)}-\mu \frac{\partial E_{total}}{\partial W^{(l)}}=W^{(l)}-\frac{\mu }{N}\sum_{i=1}^{N}\frac{\partial E_{(i)}}{\partial W^{(l)}} W(l)=W(l)−μ∂W(l)∂Etotal=W(l)−Nμi=1∑N∂W(l)∂E(i) b ( l ) = b ( l ) − μ ∂ E t o t a l ∂ b ( l ) = b ( l ) − μ N ∑ i = 1 N ∂ E ( i ) ∂ b ( l ) b^{(l)}=b^{(l)}-\mu \frac{\partial E_{total}}{\partial b^{(l)}}=b^{(l)}-\frac{\mu }{N}\sum_{i=1}^{N}\frac{\partial E_{(i)}}{\partial b^{(l)}} b(l)=b(l)−μ∂b(l)∂Etotal=b(l)−Nμi=1∑N∂b(l)∂E(i) 由上面的公式可知,只需求得每一个训练数据的代价函数 E ( i ) E_{(i)} E(i)对参数的偏导数 ∂ E ( i ) ∂ W ( l ) , ∂ E ( i ) ∂ b ( l ) \frac{\partial E_{(i)}}{\partial W^{(l)}},\frac{\partial E_{(i)}}{\partial b^{(l)}} ∂W(l)∂E(i),∂b(l)∂E(i) 即可得到参数的迭代更新公式。
为了简单起见,在下面的推导中,去掉下标,直接记为 E E E(它是单个训练数据的误差)。
下面将求解一种简单的情况:图一所示的神经网络,最后再归纳出通用公式。
(1)输出层的权重参数更新
把
E
E
E展开到隐藏层,有:
由求导的链式法则,对“输出层神经元的权重参数”求偏导,有:
如果我们把
∂
E
∂
z
i
(
l
)
\frac{\partial E}{\partial z_{i}^{(l)}}
∂zi(l)∂E记为
δ
i
(
l
)
\delta _{i}^{(l)}
δi(l),即:
则可以将
∂
E
∂
w
11
(
3
)
\frac{\partial E}{\partial w^{(3)}_{11}}
∂w11(3)∂E写为:
对于输出层神经元的其他权重参数,同样可以求得:
说明:
引入 δ i ( l ) \delta ^{(l)}_{i} δi(l),不仅能够简化求偏导的表达式;还可以通过 δ i ( l + 1 ) \delta ^{(l+1)}_{i} δi(l+1)来求解 δ i ( l ) \delta ^{(l)}_{i} δi(l)(后面会说明),这样可以充分利用之前计算过的解雇哦来加快整个计算过程。
推广到一般情况,假设神经网络共
L
L
L层,有:
如果把上面的两个表达式为矩阵(向量)的形式,则有:
说明:
符号 ⊙ \odot ⊙表示Element-wise Product Operator。把对应位置的元素分别相乘即可。即:
向量式子
δ
(
L
)
=
−
(
y
−
a
(
L
)
)
⊙
f
′
(
z
(
L
)
)
\delta ^{(L)}=-(y-a^{(L)})\odot f^{'}(z^{(L)})
δ(L)=−(y−a(L))⊙f′(z(L)) 在之前的例子中,表达的就是下面两个式子:
(2)隐藏层的权重参数更新
对“隐藏层神经元的权重参数”求偏导,利用
δ
i
(
l
)
\delta ^{(l)}_{i}
δi(l)的定义,有:
其中,
δ
i
(
l
)
,
2
≤
l
≤
L
−
1
\delta ^{(l)}_{i},2\leq l \leq L-1
δi(l),2≤l≤L−1的推导如下:
上面的式子为什么有
∂
E
∂
z
i
(
l
)
=
∑
j
=
1
n
l
+
1
∂
E
∂
z
j
(
l
+
1
)
∂
z
j
(
l
+
1
)
∂
z
i
(
l
)
\frac{\partial E}{\partial z_{i}^{(l)}}=\sum_{j=1}^{n_{l+1}}\frac{\partial E}{\partial z_{j}^{(l+1)}}\frac{\partial z_{j}^{(l+1)}}{\partial z_{i}^{(l)}}
∂zi(l)∂E=∑j=1nl+1∂zj(l+1)∂E∂zi(l)∂zj(l+1)呢?
这里利用的是“函数之和的求导法则”和“求导的链式法则”。
如果把 E E E从后往前展开,当展开到 l + 1 l+1 l+1层时, E E E可看作是 z ( l + 1 ) z^{(l+1)} z(l+1)的函数;如果再往前展开一层到 l l l层, E E E可看作是 z ( l ) z^{(l)} z(l)的函数。 E E E对 l l l层的某个 z i ( l ) z^{(l)}_{i} zi(l)求导时,由于 l + 1 l+1 l+1层的每个神经元都和 z i ( l ) z^{(l)}_{i} zi(l)所在神经元有连接,所以在函数 E E E中,自变量 z i ( l ) z^{(l)}_{i} zi(l)出现了 n l + 1 n_{l+1} nl+1次,出现的每一次对应一个 z j ( l + 1 ) , 1 ≤ j ≤ n l + 1 z_{j}^{(l+1)},1\leq j \leq n_{l+1} zj(l+1),1≤j≤nl+1,从而由“函数之和的求导法则”及“求导的链式法则”有:
推导过程示意图:下面看一个简单例子,在图一所示的神经网络中,有: ∂ E ∂ z 1 ( 2 ) = ∑ j = 1 2 ∂ E ∂ z j ( 3 ) ∂ z j ( 3 ) ∂ z 1 ( 2 ) \frac{\partial E}{\partial z_{1}^{(2)}}=\sum_{j=1}^{2}\frac{\partial E}{\partial z_{j}^{(3)}}\frac{\partial z_{j}^{(3)}}{\partial z_{1}^{(2)}} ∂z1(2)∂E=j=1∑2∂zj(3)∂E∂z1(2)∂zj(3)
由于 z j ( l + 1 ) = ∑ i = 1 n l w j i ( l + 1 ) a i l + b j ( l + 1 ) = ∑ i = 1 n l w j i ( l + 1 ) f ( z i ( l ) ) + b j ( l + 1 ) z_{j}^{(l+1)}=\sum_{i=1}^{n_{l}}w_{ji}^{(l+1)}a_{i}^{l}+b_{j}^{(l+1)}=\sum_{i=1}^{n_{l}}w_{ji}^{(l+1)}f(z^{(l)}_{i})+b_{j}^{(l+1)} zj(l+1)=∑i=1nlwji(l+1)ail+bj(l+1)=∑i=1nlwji(l+1)f(zi(l))+bj(l+1),
所以有: ∂ z j ( l + 1 ) ∂ z i ( l ) = ∂ z j ( l + 1 ) ∂ a i ( l ) ∂ a i ( l ) ∂ z i ( l ) = w j i ( l + 1 ) f ′ ( z i ( l ) ) \frac{\partial z_{j}^{(l+1)}}{\partial z_{i}^{(l)}}=\frac{\partial z_{j}^{(l+1)}}{\partial a_{i}^{(l)}}\frac{\partial a_{i}^{(l)}}{\partial z_{i}^{(l)}}=w_{ji}^{(l+1)}f^{'}(z^{(l)}_{i}) ∂zi(l)∂zj(l+1)=∂ai(l)∂zj(l+1)∂zi(l)∂ai(l)=wji(l+1)f′(zi(l)) 把该式带入到前面计算的 δ i ( l ) \delta ^{(l)}_{i} δi(l)中,有:
上面的公式是BP算法最核心的公式。它利用 l + 1 l+1 l+1层的 δ ( l + 1 ) \delta ^{(l+1)} δ(l+1)来计算 l l l层的 δ ( l ) \delta ^{(l)} δ(l),这就是“误差反向传播算法”。
若要表达为矩阵(向量)的形式,有:
(3)输出层与隐藏层的偏置参数更新
计算公式如下所示:
若要表示为矩阵(向量)的形式,有:
▽
b
(
l
)
E
=
δ
(
l
)
\triangledown _{b^{(l)}}E=\delta ^{(l)}
▽b(l)E=δ(l)
(4)反向传播算法的4个核心公式
写成对应的矩阵(向量)的形式:
或者表示为:
(5)BP算法计算:某个训练数据的代价函数对参数的偏导数
(6)总结:用“梯度下降”算法更新参数
- 用BP算法4个核心公式求得每一个训练数据的代价函数对参数的偏导数
- 按照下面的公式更新参数: W ( l ) = W ( l ) − μ ∂ E t o t a l ∂ W ( l ) = W ( l ) − μ N ∑ i = 1 N ∂ E ( i ) ∂ W ( l ) W^{(l)}=W^{(l)}-\mu \frac{\partial E_{total}}{\partial W^{(l)}}=W^{(l)}-\frac{\mu }{N}\sum_{i=1}^{N}\frac{\partial E_{(i)}}{\partial W^{(l)}} W(l)=W(l)−μ∂W(l)∂Etotal=W(l)−Nμi=1∑N∂W(l)∂E(i) b ( l ) = b ( l ) − μ ∂ E t o t a l ∂ b ( l ) = b ( l ) − μ N ∑ i = 1 N ∂ E ( i ) ∂ b ( l ) b^{(l)}=b^{(l)}-\mu \frac{\partial E_{total}}{\partial b^{(l)}}=b^{(l)}-\frac{\mu }{N}\sum_{i=1}^{N}\frac{\partial E_{(i)}}{\partial b^{(l)}} b(l)=b(l)−μ∂b(l)∂Etotal=b(l)−Nμi=1∑N∂b(l)∂E(i)
- 迭代执行第1步和第2步,直到满足停止准则(比如:相邻两次迭代的误差的差别很小,或者直接限制迭代的次数)。
说明:每对参数进行一次更新都要遍历整个训练数据集,当训练数据集不大时这不是问题,但当训练数据集非常大时,可以采用随机梯度下降法(即每次仅使用一个训练数据来更新参数)。