反向传播推导
反向传播算法是用来训练神经网络最常用且有效的算法。其主要思想是:
(1) 将训练集数据输入到网络的输入端, 经过隐藏层, 最后达到输出层并输出结果, 这是网络的前向传播过程。
(2) 由于网络的输出结果与实际标签有误差(用损失函数来衡量
), 则计算预测值与实际值之间的误差, 并将该误差从输出层向隐藏层反向传播, 直至传播到输入层
(3) 在反向传播的过程中, 根据误差调整各个参数的值,不断迭代上述过程, 直至收敛
上述是一个3
层的人工神经网络, layer1
到layer3
分别是输入层、隐藏层和输出层。如图, 先定义一些变量:
w
j
k
l
w^l_{jk}
wjkl表示第l-1
层的第k
个神经元连接到第 l
层的第j
个神经元的权重;
b
j
l
b^l_j
bjl表示第l
层的第j
个神经元的偏置
a
j
l
a^l_j
ajl表示第l
层的第j
个神经元的输出,
σ
\sigma
σ表示激活函数, 即:
a j l = σ ( ∑ k w j k l a k l − 1 + b j l ) a^l_j = \sigma (\sum_k w^l_{jk} a^{l-1}_k +b^l_j) ajl=σ(k∑wjklakl−1+bjl)
z
j
l
z^l_j
zjl表示第l
层的第j
个神经元的输入, 即
z j l = ∑ k w j k l a k l − 1 + b j l z^l_j = \sum_k w^l_{jk} a^{l-1}_k + b^l_j zjl=k∑wjklakl−1+bjl
a j l = σ ( z j l ) a^l_j = \sigma(z^l_j) ajl=σ(zjl)
损失函数
用来衡量网络输出与真实标签之间的误差, 我们用常见的均方误差来计算
C
=
1
2
∑
x
∣
∣
y
(
x
)
−
a
L
(
x
)
∣
∣
2
C = \frac{1}{2} \sum_x || y(x) - a^L(x)||^2
C=21x∑∣∣y(x)−aL(x)∣∣2
x
表示输入数据, y
表示真实标签,
a
L
a^L
aL表示预测的输出, L
表示网络最大的层数, 也就是第L
层
公式推导
首先, 将第l
层第j
个神经元中产生的误差定义为:
δ
j
l
=
∂
C
∂
z
j
l
\delta^l_j = \frac{\partial C}{\partial z^l_j}
δjl=∂zjl∂C
公式1 (计算最后一层神经网络产生的误差):
推导:
δ
j
L
=
∂
C
∂
z
j
L
=
∂
C
∂
a
j
L
⋅
∂
a
j
L
∂
z
j
L
\delta^L_j = \frac{\partial C}{\partial z^L_j} = \frac{\partial C}{\partial a^L_j} \cdot \frac{\partial a^L_j}{\partial z^L_j}
δjL=∂zjL∂C=∂ajL∂C⋅∂zjL∂ajL
所以, 最后一层神经网络产生的误差为:
δ
L
=
∂
C
∂
a
L
∂
a
L
∂
z
L
=
∇
a
C
⊙
σ
′
(
z
L
)
\delta^L = \frac{\partial C}{\partial a^L} \frac{\partial a^L}{\partial z^L} = \nabla_aC \odot \sigma^{'}(z^L)
δL=∂aL∂C∂zL∂aL=∇aC⊙σ′(zL)
公式2 (由后往前, 计算每一层神经网络产生的误差):
推导:
δ
j
l
=
∂
C
∂
z
j
l
=
∑
k
∂
C
∂
z
k
l
+
1
⋅
∂
z
k
l
+
1
∂
a
j
l
⋅
∂
a
j
l
∂
z
j
l
=
∑
k
δ
k
l
+
1
⋅
∂
(
w
k
j
l
+
1
a
j
l
+
b
k
l
+
1
)
∂
a
j
l
⋅
σ
′
(
z
j
l
)
=
∑
k
δ
k
l
+
1
⋅
w
k
j
l
+
1
⋅
σ
′
(
z
j
l
)
\delta^l_j = \frac{\partial C}{\partial z^l_j} = \sum_k \frac{\partial C}{\partial z^{l+1}_k} \cdot \frac{\partial z^{l+1}_k}{\partial a^l_j} \cdot \frac{\partial a^l_j}{\partial z^l_j} \\ = \sum_k \delta^{l+1}_k \cdot \frac{\partial(w^{l+1}_{kj}a^l_j + b^{l+1}_k)}{\partial a^l_j} \cdot \sigma^{'}(z^l_j)\\ = \sum_k \delta^{l+1}_k \cdot w^{l+1}_{kj} \cdot \sigma^{'}(z^l_j)
δjl=∂zjl∂C=k∑∂zkl+1∂C⋅∂ajl∂zkl+1⋅∂zjl∂ajl=k∑δkl+1⋅∂ajl∂(wkjl+1ajl+bkl+1)⋅σ′(zjl)=k∑δkl+1⋅wkjl+1⋅σ′(zjl)
因此, 除最后一次其他产生的误差为:
δ
l
=
(
(
w
l
+
1
)
T
σ
l
+
1
)
⊙
σ
′
(
z
l
)
\delta^l = ((w^{l+1})^T \sigma^{l+1}) \odot \sigma^{'}(z^l)
δl=((wl+1)Tσl+1)⊙σ′(zl)
反向传播算法伪代码:
-
输入训练集
-
对于训练集中的每个样本
x
, 设置输入层(Input layer
)对应的激活值 a 1 a^1 a1: -
前向传播
z l = w l a l − 1 + b l , a l = σ ( z l ) z^l = w^l a^{l-1} +b^l, a^l = \sigma(z^l) zl=wlal−1+bl,al=σ(zl) -
计算输出层产生的误差:
δ L = ∂ C ∂ a L ∂ a L ∂ z L = ∇ a C ⊙ σ ′ ( z L ) \delta^L = \frac{\partial C}{\partial a^L} \frac{\partial a^L}{\partial z^L} = \nabla_aC \odot \sigma^{'}(z^L) δL=∂aL∂C∂zL∂aL=∇aC⊙σ′(zL) -
反向传播误差:
δ l = ( ( w l + 1 ) T σ l + 1 ) ⊙ σ ′ ( z l ) \delta^l = ((w^{l+1})^T \sigma^{l+1}) \odot \sigma^{'}(z^l) δl=((wl+1)Tσl+1)⊙σ′(zl) -
使用梯度下降, 训练参数
w l ⟶ w l − η m ∑ x δ x , l ( a x , l − 1 ) T w^l \longrightarrow w^l - \frac{\eta}{m} \sum_x \delta^{x, l}(a^{x, l-1})^T wl⟶wl−mηx∑δx,l(ax,l−1)Tb l = b l − η m ∑ x δ x , l b^l = b^l - \frac{\eta}{m}\sum_x \delta^{x, l} bl=bl−mηx∑δx,l