由于导师要求自己从头到尾自己实现卷积神经网络,所以最近看了关于神经网络的反向传播内容。内容大部分都是从博客和书上摘录下来。整理完后方便自己以后复习!不喜勿喷。看完真的是清爽明朗!!!知道算法后写程序就简单多啦哈哈。
梯度下降法
我们训练神经网络的目的是找到能最小化代价函数 C ( w , b ) C(w, b) C(w,b)的权重和偏置。
假设我们要最小化某些函数,
C
(
v
)
C(v)
C(v)。它可以是任意的多元实值函数,
v
=
v
1
,
v
2
,
…
v=v_{1}, v_{2}, \dots
v=v1,v2,…。
为了最小化
C
(
v
)
C(v)
C(v),我们先想象
C
C
C是一个只有两个变量
v
1
v_{1}
v1和
v
2
v_{2}
v2的函数。
为了更精确地描述这个问题,让我们思考一下,当我们在
v
1
v_{1}
v1和
v
2
v_{2}
v2方向分别移动一个很小的量,即
Δ
v
1
\Delta v_{1}
Δv1和
Δ
v
2
\Delta v_{2}
Δv2时,
C
(
v
)
C(v)
C(v)将会发生什么情况。微积分告诉我们
C
C
C将会有如下变化:
Δ
C
≈
∂
C
∂
v
1
Δ
v
1
+
∂
C
∂
v
2
Δ
v
2
.
.
.
.
.
.
(
1
)
\Delta C \approx \frac{\partial C}{\partial v_{1}} \Delta v_{1}+\frac{\partial C}{\partial v_{2}} \Delta v_{2} ......(1)
ΔC≈∂v1∂CΔv1+∂v2∂CΔv2......(1)
我们要寻找一种选择 Δ v 1 \Delta v_{1} Δv1和 Δ v 2 \Delta v_{2} Δv2的方法使得 Δ C \Delta C ΔC为负。为了弄明白如何选择,需要定义 Δ v \Delta v Δv为 v v v变化的向量, Δ v ≡ ( Δ v 1 , Δ v 2 ) T \Delta v \equiv\left(\Delta v_{1}, \Delta v_{2}\right)^{T} Δv≡(Δv1,Δv2)T, T T T是转置符号。
我们也定义
C
C
C的梯度为偏导数的向量,
(
∂
C
∂
v
1
,
∂
C
∂
v
2
)
T
\left(\frac{\partial C}{\partial v_{1}}, \frac{\partial C}{\partial v_{2}}\right)^{T}
(∂v1∂C,∂v2∂C)T。我们用
∇
C
\nabla C
∇C来表示梯度向量,即:
∇
C
≡
(
∂
C
∂
v
1
,
∂
C
∂
v
2
)
T
\nabla C \equiv\left(\frac{\partial C}{\partial v_{1}}, \frac{\partial C}{\partial v_{2}}\right)^{T}
∇C≡(∂v1∂C,∂v2∂C)T
有了这些定义,(1)的表达式可以被重写为:
Δ
C
≈
∇
C
⋅
Δ
v
.
.
.
.
.
.
(
2
)
\Delta C \approx \nabla C \cdot \Delta v ......(2)
ΔC≈∇C⋅Δv......(2)
这个方程真正让我们兴奋的是它让我们看到了如何选取
Δ
v
\Delta v
Δv 才能让
Δ
C
\Delta C
ΔC为负数。假设我们选取:
Δ
v
=
−
η
∇
C
.
.
.
.
.
.
(
3
)
\Delta v=-\eta \nabla C......(3)
Δv=−η∇C......(3)
其中的
η
\eta
η是个很小的正数(称为学习率)。方程(2)告诉我们
Δ
C
≈
−
η
∇
C
⋅
∇
C
=
−
η
∥
∇
C
∥
2
\Delta C \approx-\eta \nabla C \cdot \nabla C=-\eta\|\nabla C\|^{2}
ΔC≈−η∇C⋅∇C=−η∥∇C∥2。由于
∥
∇
C
∥
2
≥
0
\|\nabla C\|^{2} \geq 0
∥∇C∥2≥0,这保证了
Δ
C
≤
0
\Delta C \leq 0
ΔC≤0,即,如果我们按照方程(3)的规则去改变
v
v
v,那么
C
C
C 会一直减小,不会增加。
我们用方程(3)计算
Δ
v
\Delta v
Δv,来移动位置
v
v
v:
v
→
v
′
=
v
−
η
∇
C
v \rightarrow v^{\prime}=v-\eta \nabla C
v→v′=v−η∇C
然后我们用它再次更新规则来计算下一次移动。如果我们反复持续这样做,我们将持续减小 C C C —— 获得一个全局的最小值。
总结一下,梯度下降算法工作的方式就是重复计算梯度 ∇ C \nabla C ∇C,然后沿着相反的方向移动。
为了使梯度下降能够正确地运行,我们需要选择足够小的学习速率 η \eta η使得方程(2) 能得到很好的近似。如果不这样,我们会以 Δ C > 0 \Delta C>0 ΔC>0结束,这显然不好。同时,我们也不想 η \eta η 太小,因为这会使 Δ v \Delta v Δv的变化极小,梯度下降算法就会运行得非常缓慢。在真正的实现中, η \eta η 通常是变化的,以至方程(2) 能保持很好的近似度,但算法又不会太慢。
前面已经解释了具有两个变量的函数
C
C
C的梯度下降。但事实上,即使
C
C
C是一个具有更多变量的函数也能很好地工作。我们假设
C
C
C是一个有
m
m
m个变量
v
1
,
…
,
v
m
v_{1}, \dots, v_{m}
v1,…,vm的多元函数。那么对
C
C
C 中自变量的变化
Δ
v
=
(
Δ
v
1
,
…
,
Δ
v
m
)
T
\Delta v=\left(\Delta v_{1}, \ldots, \Delta v_{m}\right)^{T}
Δv=(Δv1,…,Δvm)T,
Δ
C
\Delta C
ΔC将会变为:
Δ
C
≈
∇
C
⋅
Δ
v
\Delta C \approx \nabla C \cdot \Delta v
ΔC≈∇C⋅Δv这里的梯度
∇
C
\nabla C
∇C是向量
∇
C
≡
(
∂
C
∂
v
1
,
…
,
∂
C
∂
v
m
)
T
\nabla C \equiv\left(\frac{\partial C}{\partial v_{1}}, \ldots, \frac{\partial C}{\partial v_{m}}\right)^{T}
∇C≡(∂v1∂C,…,∂vm∂C)T
正如两个变量的情况,我们可以选取
Δ
v
=
−
η
∇
C
\Delta v=-\eta \nabla C
Δv=−η∇C
而且
Δ
C
\Delta C
ΔC的(近似)表达式(2)保证是负数。这给了我们一种方式从梯度中去取得最小值,即使
C
C
C是任意的多元函数,我们也能重复运用更新规则
v
→
v
′
=
v
−
η
∇
C
v \rightarrow v^{\prime}=v-\eta \nabla C
v→v′=v−η∇C
可以把这个更新规则看做定义梯度下降算法。这给我们提供了一种方式去通过重复改变 v v v来找到函数 C C C的最小值。这个规则并不总是有效的 —— 有一件事能导致错误,让我们无法从梯度下降来求得函数 C C C的全局最小值。但在实践中,梯度下降算法通常工作地非常好,在神经网络中这是一种非常有效的方式去求代价函数的最小值,进而促进网络自身的学习。
我们怎么在神经网络中用梯度下降算法去学习呢?其思想就是利用梯度下降算法去寻找能使得代价函数代价取得最小值的权重
w
k
w_{k}
wk和偏置
b
l
b_{l}
bl。为了清楚这是如何工作的,我们将用权重和偏置代替变量
v
j
v_{j}
vj。也就是说,现在“位置”变量有两个分量组成:
w
k
w_{k}
wk和
b
l
b_{l}
bl,而梯度向量
∇
C
\nabla C
∇C 则有相应的分量
∂
C
/
∂
w
k
\partial C / \partial w_{k}
∂C/∂wk和
∂
C
/
∂
b
l
\partial C / \partial b_{l}
∂C/∂bl。 用这些分量来写梯度下降的更新规则,我们得到:
w
k
→
w
k
′
=
w
k
−
η
∂
C
∂
w
k
b
l
→
b
l
′
=
b
l
−
η
∂
C
∂
b
l
\begin{aligned} w_{k} \rightarrow w_{k}^{\prime} &=w_{k}-\eta \frac{\partial C}{\partial w_{k}} \\ b_{l} \rightarrow b_{l}^{\prime} &=b_{l}-\eta \frac{\partial C}{\partial b_{l}} \end{aligned}
wk→wk′bl→bl′=wk−η∂wk∂C=bl−η∂bl∂C
通过重复应用这一更新规则我们就能有望能找到代价函数的最小值。换句话说,这是一个能让神经网络学习的规则。
回顾二次代价函数。注意这个代价函数有着这样的形式 C = 1 n ∑ x C x C=\frac{1}{n} \sum_{x} C_{x} C=n1∑xCx即,它是遍及每个训练样本代价 C x ≡ ∥ y ( x ) − a ∥ 2 2 C_{x} \equiv \frac{\|y(x)-a\|^{2}}{2} Cx≡2∥y(x)−a∥2的平均值。在实践中,为了计算梯度 ∇ C \nabla C ∇C,我们需要为每个训练输入 x x x单独地计算梯度值 ∇ C x \nabla C_{x} ∇Cx,然后求平均值, ∇ C = 1 n ∑ x ∇ C x \nabla C=\frac{1}{n} \sum_{x} \nabla C_{x} ∇C=n1∑x∇Cx。不幸的是,当训练输入的数量过多时会花费很多时间,这样会使学习变得相当缓慢。
有种叫做\textbf{随机梯度下降}的算法能够加速学习。其思想就是通过随机选取少量训练输入样本来计算 ∇ C x \nabla C_{x} ∇Cx,进行估算梯度 ∇ C \nabla C ∇C。通过计算少量样本的平均值我们可以快速得到一个对于实际梯度 ∇ C \nabla C ∇C的很好的估算,这有助于加速梯度下降,进而加速学习过程。
更准确地说,随机梯度下降通过随机选取少量的
m
m
m个训练输入来工作。我们将这些随机的训练输入标记为
X
1
,
X
2
,
…
,
X
m
X_{1}, X_{2}, \ldots, X_{m}
X1,X2,…,Xm,并把它们称为一个小批量数据(mini-batch)。假设样本数量
m
m
m 足够大,我们期望
∇
C
X
j
\nabla C_{X_{j}}
∇CXj的平均值大致相等于整个
∇
C
X
\nabla C_{X}
∇CX的平均值,即,
∑
j
=
1
m
∇
C
X
j
m
≈
∑
x
∇
C
x
n
=
∇
C
\frac{\sum_{j=1}^{m} \nabla C_{X_{j}}}{m} \approx \frac{\sum_{x} \nabla C_{x}}{n}=\nabla C
m∑j=1m∇CXj≈n∑x∇Cx=∇C
这里的第二个求和符号是在整个训练数据上进行的。交换两边我们得到
∇
C
≈
1
m
∑
j
=
1
m
∇
C
X
j
\nabla C \approx \frac{1}{m} \sum_{j=1}^{m} \nabla C_{X_{j}}
∇C≈m1j=1∑m∇CXj
证实了我们可以通过仅仅计算随机选取的小批量数据的梯度来估算整体的梯度。
为了将其明确地和神经网络的学习联系起来,假设
w
k
w_{k}
wk和
b
l
b_{l}
bl表示我们神经网络中权重和偏置。随机梯度下降通过随机地选取并训练输入的小批量数据来工作,
w
k
→
w
k
′
=
w
k
−
η
m
∑
j
∂
C
X
j
∂
w
k
w_{k} \rightarrow w_{k}^{\prime}=w_{k}-\frac{\eta}{m} \sum_{j} \frac{\partial C_{X_{j}}}{\partial w_{k}}
wk→wk′=wk−mηj∑∂wk∂CXj
b l → b l ′ = b l − η m ∑ j ∂ C X j ∂ b l b_{l} \rightarrow b_{l}^{\prime}=b_{l}-\frac{\eta}{m} \sum_{j} \frac{\partial C_{X_{j}}}{\partial b_{l}} bl→bl′=bl−mηj∑∂bl∂CXj
其中两个求和符号是在当前小批量数据中的所有训练样本 X j X_{j} Xj上进行的。然后我们再挑选另一随机选定的小批量数据去训练。直到我们用完了所有的训练输入,这被称为完成了一个训练迭代期(epoch)。然后我们就会开始一个新的训练迭代期。
神经网络的反向传播
反向传播算法最初在 1970 年代被提及,但是人们直到 David Rumelhart、Geoffrey Hinton 和Ronald Williams 的著名的 1986 年的论文中才认识到这个算法的重要性。这篇论文描述了对一些神经网络反向传播要比传统的方法更快,这使得使用神经网络来解决之前无法完成的问题变得可行。现在,反向传播算法已经是神经网络学习的重要组成部分。
反向传播预热知识
在讨论反向传播前,我们先熟悉一下基于矩阵的算法来计算网络的输出。
我们首先给出网络中权重的清晰定义。我们使用
w
j
k
l
w_{j k}^{l}
wjkl表示从
(
l
−
1
)
t
h
(l-1)^{\mathrm{th}}
(l−1)th层的
k
t
h
k^{\mathrm{th}}
kth个神经元到
l
t
h
l^{\mathrm{th}}
lth层的
j
t
h
j^{\mathrm{th}}
jth 个神经元的链接上的\textbf{权重}。
我们对网络的偏置和激活值也会使用类似的表示。显式地,我们使用
b
j
l
b_{j}^{l}
bjl表示在
l
t
h
l^{\mathrm{th}}
lth层第
j
t
h
j^{\mathrm{th}}
jth个神经元的偏置,使用
a
j
l
a_{j}^{l}
ajl表示
l
t
h
l^{\mathrm{th}}
lth层第
j
t
h
j^{\mathrm{th}}
jth个神经元的激活值。
有了这些表示
l
t
h
l^{\mathrm{th}}
lth层的第
j
t
h
j^{\mathrm{th}}
jth个神经元的激活值
a
j
l
a_{j}^{l}
ajl就和
(
l
−
1
)
t
h
(l-1)^{\mathrm{th}}
(l−1)th层的激活值通过方程关联起来了:
a
j
l
=
σ
(
∑
k
w
j
k
l
a
k
l
−
1
+
b
j
l
)
.
.
.
.
.
.
(
4
)
a_{j}^{l}=\sigma\left(\sum_{k} w_{j k}^{l} a_{k}^{l-1}+b_{j}^{l}\right)......(4)
ajl=σ(k∑wjklakl−1+bjl)......(4)
其中求和是在
(
l
−
1
)
th
(l-1)^{\text { th }}
(l−1) th 层的所有
k
k
k个神经元上进行的。为了用矩阵的形式重写这个表达式,我们对每一层
l
l
l都定义一个权重矩阵
w
l
w^{l}
wl
j
t
h
j^{\mathrm{th}}
jth 在第
k
t
h
k^{\mathrm{th}}
kth 列的元素是
w
j
k
l
w_{j k}^{l}
wjkl。类似的,对每一层
l
l
l,定义一个偏置向量
b
l
b^{l}
bl。偏置向量的每个元素其实就是前面给出的
b
j
l
b_{j}^{l}
bjl,每个元素对应于
l
t
h
l^{\mathrm{th}}
lth层的每个神经元。最后,我们定义激活向量
a
l
a^{l}
al,其元素是那些激活值
a
j
l
a_{j}^{l}
ajl。
最后我们需要引入向量化函数(如
σ
\sigma
σ)来按照矩阵形式重写公式(4})。其含义就是作用函数(如
σ
\sigma
σ)到向量
v
v
v中的每个元素。我们使用
σ
(
v
)
\sigma(v)
σ(v)表示这种按元素进行的函数作用。所以,
σ
(
v
)
\sigma(v)
σ(v)的每个元素其实满足
σ
(
v
)
j
=
σ
(
v
j
)
\sigma(v)_{j}=\sigma\left(v_{j}\right)
σ(v)j=σ(vj)。
了解了这些表示,方程(4)就可以写成下面这种简洁的向量形式:
a
l
=
σ
(
w
l
a
l
−
1
+
b
l
)
a^{l}=\sigma\left(w^{l} a^{l-1}+b^{l}\right)
al=σ(wlal−1+bl)
在使用上述方程计算 a l a^{l} al的过程中,我们计算了中间量 z l ≡ w l a l − 1 + b l z^{l} \equiv w^{l} a^{l-1}+b^{l} zl≡wlal−1+bl。 这个量其实是非常有用的:我们称 z l z^{l} zl 为 l l l层神经元的带权输入。 z l z^{l} zl 的每个元素是 z j l = ∑ k w j k l a k l − 1 + b j l z_{j}^{l}=\sum_{k} w_{j k}^{l} a_{k}^{l-1}+b_{j}^{l} zjl=∑kwjklakl−1+bjl,其实 z j l z_{j}^{l} zjl就是第 l l l层第 j j j 个神经元的激活函数的带权输入。
反向传播算法基于常规的线性代数运算 —— 诸如向量加法,向量矩阵乘法等。但是有一个运算不大常见。特别地,假设 s s s和 t t t是两个同样维度的向量。那么我们使用 s ⊙ t s \odot t s⊙t来表示按元素的乘积。所以 s ⊙ t s \odot t s⊙t的元素就是 ( s ⊙ t ) j = s j t j (s \odot t)_{j}=s_{j} t_{j} (s⊙t)j=sjtj。这种类型的按元素乘法有时候被称为 Hadamard 乘积,或者 Schur 乘积。
反向传播的四个基本方程
反向传播其实是对权重和偏置变化影响代价函数过程的理解。最终极的含义其实就是计算偏导数 ∂ C / ∂ w j k l \partial C / \partial w_{j k}^{l} ∂C/∂wjkl和 ∂ C / ∂ b j l \partial C / \partial b_{j}^{l} ∂C/∂bjl。但是为了计算这些值,我们首先引入一个中间量, δ j l \delta_{j}^{l} δjl,这个我们称为在 l t h l^{\mathrm{th}} lth层第 j t h j^{\mathrm{th}} jth个神经元上的误差。
反向传播将给出计算误差 δ j l \delta_{j}^{l} δjl的流程,然后将其关联到计算 ∂ C / ∂ w j k l \partial C / \partial w_{j k}^{l} ∂C/∂wjkl和 ∂ C / ∂ b j l \partial C / \partial b_{j}^{l} ∂C/∂bjl。
我们定义
l
l
l层的第
j
t
h
j^{\mathrm{th}}
jth个神经元上的误差
δ
j
l
\delta_{j}^{l}
δjl:
δ
j
l
≡
∂
C
∂
z
j
l
\delta_{j}^{l} \equiv \frac{\partial C}{\partial z_{j}^{l}}
δjl≡∂zjl∂C
∂ C ∂ z j l \frac{\partial C}{\partial z_{j}^{l}} ∂zjl∂C是神经元的误差的度量。我们使用 δ l \delta^{l} δl表示关联于 l l l层的误差向量。反向传播会提供给我们一种计算每层的 δ l \delta^{l} δl的方法,然后将这些误差和最终我们需要的量 ∂ C / ∂ w j k l \partial C / \partial w_{j k}^{l} ∂C/∂wjkl和 ∂ C / ∂ b j l \partial C / \partial b_{j}^{l} ∂C/∂bjl联系起来。
输出层误差的方程,
δ
L
\delta^{L}
δL:每个元素的定义如下:
δ
j
L
=
∂
C
∂
a
j
L
σ
′
(
z
j
L
)
.
.
.
.
.
.
(
B
P
1
)
\delta_{j}^{L}=\frac{\partial C}{\partial a_{j}^{L}} \sigma^{\prime}\left(z_{j}^{L}\right) ......(BP1)
δjL=∂ajL∂Cσ′(zjL)......(BP1)
右式第一个项 ∂ C / ∂ a j L \partial C / \partial a_{j}^{L} ∂C/∂ajL表示代价随着 j t h j^{\mathrm{th}} jth输出激活值的变化而变化的速度。假如 C C C不太依赖一个特定的输出神经元 j j j,那么 δ j L \delta_{j}^{L} δjL就会很小,这也是我们想要的效果。右式第二项 σ ′ ( z j L ) \sigma^{\prime}\left(z_{j}^{L}\right) σ′(zjL)刻画了在 z j L z_{j}^{L} zjL处激活函数 σ \sigma σ变化的速度。
在 (BP1) 中的每个部分都是很好计算的。其中 ∂ C / ∂ a j L \partial C / \partial a_{j}^{L} ∂C/∂ajL依赖于代价函数的形式。如果我们使用二次函数,那么 C = 1 2 ∑ j ( y j − a j ) 2 C=\frac{1}{2}\sum_{j}\left(y_{j}-a_{j}\right)^{2} C=21∑j(yj−aj)2,则 ∂ C / ∂ a j L = ( a j − y j ) \partial C / \partial a_{j}^{L}=\left(a_{j}-y_{j}\right) ∂C/∂ajL=(aj−yj)。
方程 (BP1) 对
δ
L
\delta^{L}
δL来说是个按分量构成的表达式。以矩阵形式重写方程如下:
δ
L
=
∇
a
C
⊙
σ
′
(
z
L
)
\delta^{L}=\nabla_{a} C \odot \sigma^{\prime}\left(z^{L}\right)
δL=∇aC⊙σ′(zL)
这里
∇
a
C
\nabla_{a} C
∇aC被定义成一个向量,其元素是偏导数
∂
C
/
∂
a
j
L
\partial C / \partial a_{j}^{L}
∂C/∂ajL。 在二次代价函数时,我们有
∇
a
C
=
(
a
L
−
y
)
\nabla_{a} C=\left(a^{L}-y\right)
∇aC=(aL−y),所以 (BP1) 的整个矩阵形式就变成
δ
L
=
(
a
L
−
y
)
⊙
σ
′
(
z
L
)
\delta^{L}=\left(a^{L}-y\right) \odot \sigma^{\prime}\left(z^{L}\right)
δL=(aL−y)⊙σ′(zL)
使用下一层的误差
δ
l
+
1
\delta^{l+1}
δl+1来表示当前层的误差
δ
l
\delta^{l}
δl: 特别地,
δ
l
=
(
(
w
l
+
1
)
T
δ
l
+
1
)
⊙
σ
′
(
z
l
)
.
.
.
.
.
.
(
B
P
2
)
\delta^{l}=\left(\left(w^{l+1}\right)^{T} \delta^{l+1}\right) \odot \sigma^{\prime}\left(z^{l}\right) ......(BP2)
δl=((wl+1)Tδl+1)⊙σ′(zl)......(BP2)
其中 ( w l + 1 ) T \left(w^{l+1}\right)^{T} (wl+1)T是 ( l + 1 ) t h (l+1)^{\mathrm{th}} (l+1)th层权重矩阵 w l + 1 w^{l+1} wl+1 的转置。假设我们知道 l + 1 t h l+1^{\mathrm{th}} l+1th层的误差 δ l + 1 \delta^{l+1} δl+1。当我们应用转置的权重矩阵 ( w l + 1 ) T \left(w^{l+1}\right)^{T} (wl+1)T,我们可以凭直觉地把它看作是在沿着网络反向移动误差,给了我们度量在 l t h l^{\mathrm{th}} lth层输出的误差方法。然后,我们进行 Hadamard 乘积运算 ⊙ σ ′ ( z l ) \odot \sigma^{\prime}\left(z^{l}\right) ⊙σ′(zl)。这会让误差通过 l l l层的激活函数反向传递回来并给出在第 l l l 层的带权输入的误差 δ \delta δ。
通过组合 (BP1) 和 (BP2),我们可以计算任何层的误差 δ l \delta^{l} δl。首先使用 (BP1) 计算 δ L \delta^{L} δL,然后应用方程 (BP2) 来计算 δ L − 1 \delta^{L-1} δL−1,然后再次用方程 (BP2) 来计算 δ L − 2 \delta^{L-2} δL−2,如此一步一步地反向传播完整个网络。
代价函数关于网络中任意偏置的改变率: 就是
∂
C
∂
b
j
l
=
δ
j
l
.
.
.
.
.
.
(
B
P
3
)
\frac{\partial C}{\partial b_{j}^{l}}=\delta_{j}^{l}......(BP3)
∂bjl∂C=δjl......(BP3)
这其实是,误差
δ
j
l
\delta_{j}^{l}
δjl和偏导数值
∂
C
/
∂
b
j
l
\partial C / \partial b_{j}^{l}
∂C/∂bjl完全一致。这是很好的性质,因为 (BP1) 和 (BP2) 已经告诉我们如何计算
δ
j
l
\delta_{j}^{l}
δjl。所以就可以将(BP3) 简记为
∂
C
∂
b
=
δ
\frac{\partial C}{\partial b}=\delta
∂b∂C=δ
其中 δ \delta δ和偏置 b b b都是针对同一个神经元。
代价函数关于任何一个权重的改变率:特别地,
∂
C
∂
w
j
k
l
=
a
k
l
−
1
δ
j
l
.
.
.
.
.
.
(
B
P
4
)
\frac{\partial C}{\partial w_{j k}^{l}}=a_{k}^{l-1} \delta_{j}^{l}......(BP4)
∂wjkl∂C=akl−1δjl......(BP4)
这告诉我们如何计算偏导数
∂
C
/
∂
w
j
k
l
\partial C / \partial w_{j k}^{l}
∂C/∂wjkl,其中
δ
l
\delta^{l}
δl和
a
l
−
1
a^{l-1}
al−1这些量我们都已经知道如何计算了。方程也可以写成下面用更少下标的表示:
∂
C
∂
w
=
a
i
n
δ
o
u
t
\frac{\partial C}{\partial w}=a_{\mathrm{in}} \delta_{\mathrm{out}}
∂w∂C=ainδout
其中
a
i
n
a_{\mathrm{in}}
ain是输入给权重
w
w
w的神经元的激活值,
δ
out
\delta_{\text { out }}
δ out 是输出自权重
w
w
w的神经元的误差。
四个基本方程的证明
我们现在证明这四个基本的方程 (BP1)–(BP4)。所有这些都是多元微积分的链式法则的推论。
从方程 (BP1) 开始,它给出了输出误差
δ
L
\delta^{L}
δL的表达式:
δ
j
L
=
∂
C
∂
z
j
L
\delta_{j}^{L}=\frac{\partial C}{\partial z_{j}^{L}}
δjL=∂zjL∂C
应用链式法则,我们可以就输出激活值的偏导数的形式重新表示上面的偏导数:
δ
j
L
=
∑
k
∂
C
∂
a
k
L
∂
a
k
L
∂
z
j
L
\delta_{j}^{L}=\sum_{k} \frac{\partial C}{\partial a_{k}^{L}} \frac{\partial a_{k}^{L}}{\partial z_{j}^{L}}
δjL=k∑∂akL∂C∂zjL∂akL
这里求和是在输出层的所有神经元
k
k
k上运行的。当然,第
k
th
k^{\text { th }}
k th 个神经元的输出激活值
a
k
L
a_{k}^{L}
akL只依赖于当
k
=
j
k=j
k=j时第
j
th
j^{\text { th }}
j th 个神经元的输入权重
z
j
L
z_{j}^{L}
zjL。所以当
k
≠
j
k \neq j
k̸=j时
∂
a
k
L
/
∂
z
j
L
\partial a_{k}^{L} / \partial z_{j}^{L}
∂akL/∂zjL消失了。结果我们可以简化上一个方程为:
δ
j
L
=
∂
C
∂
a
j
L
∂
a
j
L
∂
z
j
L
\delta_{j}^{L}=\frac{\partial C}{\partial a_{j}^{L}} \frac{\partial a_{j}^{L}}{\partial z_{j}^{L}}
δjL=∂ajL∂C∂zjL∂ajL
又因为
a
j
L
=
σ
(
z
j
L
)
a_{j}^{L}=\sigma\left(z_{j}^{L}\right)
ajL=σ(zjL),右边的第二项可以写为
σ
′
(
z
j
L
)
\sigma^{\prime}\left(z_{j}^{L}\right)
σ′(zjL),方程变成:
δ
j
L
=
∂
C
∂
a
j
L
σ
′
(
z
j
L
)
\delta_{j}^{L}=\frac{\partial C}{\partial a_{j}^{L}} \sigma^{\prime}\left(z_{j}^{L}\right)
δjL=∂ajL∂Cσ′(zjL)
这正是分量形式的 (BP1)。
下一步,我们将证明 (BP2),它给出了以下一层误差
δ
l
+
1
\delta^{l+1}
δl+1的形式表示误差
δ
l
\delta^{l}
δl。为此,我们想要以
δ
k
l
+
1
=
∂
C
/
∂
z
k
l
+
1
\delta_{k}^{l+1}=\partial C / \partial z_{k}^{l+1}
δkl+1=∂C/∂zkl+1的形式重写
δ
j
l
=
∂
C
/
∂
z
j
l
\delta_{j}^{l}=\partial C / \partial z_{j}^{l}
δjl=∂C/∂zjl。我们可以用链式法则:
δ
j
l
=
∂
C
∂
z
j
l
=
∑
k
∂
C
∂
z
k
l
+
1
∂
z
k
l
+
1
∂
z
j
l
=
∑
k
∂
z
k
l
+
1
∂
z
j
l
δ
k
l
+
1
\begin{aligned} \delta_{j}^{l} &=\frac{\partial C}{\partial z_{j}^{l}} \\ &=\sum_{k} \frac{\partial C}{\partial z_{k}^{l+1}} \frac{\partial z_{k}^{l+1}}{\partial z_{j}^{l}} \\ &=\sum_{k} \frac{\partial z_{k}^{l+1}}{\partial z_{j}^{l}} \delta_{k}^{l+1} \end{aligned}
δjl=∂zjl∂C=k∑∂zkl+1∂C∂zjl∂zkl+1=k∑∂zjl∂zkl+1δkl+1
这里最后一行我们交换了右边的两项,并用
δ
k
l
+
1
\delta_{k}^{l+1}
δkl+1的定义代入。为了对最后一行的第一项求值,注意:
z
k
l
+
1
=
∑
j
w
k
j
l
+
1
a
j
l
+
b
k
l
+
1
=
∑
j
w
k
j
l
+
1
σ
(
z
j
l
)
+
b
k
l
+
1
z_{k}^{l+1}=\sum_{j} w_{k j}^{l+1} a_{j}^{l}+b_{k}^{l+1}=\sum_{j} w_{k j}^{l+1} \sigma\left(z_{j}^{l}\right)+b_{k}^{l+1}
zkl+1=j∑wkjl+1ajl+bkl+1=j∑wkjl+1σ(zjl)+bkl+1
做微分,我们得到
∂
z
k
l
+
1
∂
z
j
l
=
w
k
j
l
+
1
σ
′
(
z
j
l
)
\frac{\partial z_{k}^{l+1}}{\partial z_{j}^{l}}=w_{k j}^{l+1} \sigma^{\prime}\left(z_{j}^{l}\right)
∂zjl∂zkl+1=wkjl+1σ′(zjl)
把它代入 (42) 我们得到
δ
j
l
=
∑
k
w
k
j
l
+
1
δ
k
l
+
1
σ
′
(
z
j
l
)
\delta_{j}^{l}=\sum_{k} w_{k j}^{l+1} \delta_{k}^{l+1} \sigma^{\prime}\left(z_{j}^{l}\right)
δjl=k∑wkjl+1δkl+1σ′(zjl)
这正是以分量形式写的 (BP2)。
最后两个方程(BP3) 和 (BP4)的证明它们同样遵循链式法则,和前面两个方程的证明相似。
反向传播算法
反向传播方程给出了一种计算代价函数梯度的方法。让我们显式地用算法描述出来:
-
输入 x x x: 为输入层设置对应的激活值 a 1 a^{1} a1
-
前向传播: 对每个 l = 2 , 3 , … , L l=2,3, \dots, L l=2,3,…,L计算相应的 z l = w l a l − 1 + b l z^{l}=w^{l} a^{l-1}+b^{l} zl=wlal−1+bl 和 a l = σ ( z l ) a^{l}=\sigma\left(z^{l}\right) al=σ(zl)
-
输出层误差 δ L \delta^{L} δL: 计算向量 δ L = ∇ a C ⊙ σ ′ ( z L ) \delta^{L}=\nabla_{a} C \odot \sigma^{\prime}\left(z^{L}\right) δL=∇aC⊙σ′(zL)
-
反向误差传播: 对每个 l = L − 1 , L − 2 , … , 2 l=L-1, L-2, \ldots, 2 l=L−1,L−2,…,2,计算 δ l = ( ( w l + 1 ) T δ l + 1 ) ⊙ σ ′ ( z l ) \delta^{l}=\left(\left(w^{l+1}\right)^{T} \delta^{l+1}\right) \odot \sigma^{\prime}\left(z^{l}\right) δl=((wl+1)Tδl+1)⊙σ′(zl)
-
输出: 代价函数的梯度由 ∂ C ∂ w j k l = a k l − 1 δ j l \frac{\partial C}{\partial w_{j k}^{l}}=a_{k}^{l-1} \delta_{j}^{l} ∂wjkl∂C=akl−1δjl和 ∂ C ∂ b j l = δ j l \frac{\partial C}{\partial b_{j}^{l}}=\delta_{j}^{l} ∂bjl∂C=δjl得出
卷积神经网络的反向传播
由于CNN的运算过程与DNN不一样,所以CNN的反向传播过程也有所不同。
1.池化层在前向传播的时候,对输入进行了压缩,那么我们现在需要向前反向推导
δ
l
−
1
\delta^{l-1}
δl−1,这个推导方法和DNN完全不同。
2.卷积层是通过张量卷积,或者说若干个矩阵卷积求和而得的当前层的输出,这和DNN很不相同,DNN的全连接层是直接进行矩阵乘法得到当前层的输出。这样在卷积层反向传播的时候,上一层的 δ l − 1 \delta^{l-1} δl−1 递推计算方法肯定有所不同。
3.对于卷积层,由于 W W W使用的运算是卷积,那么从推导出该层的所有卷积核的 W W W, b b b的梯度方式也不同。
对于这三个问题,我们一个一个来解决。
已知池化层的 δ l \delta^{l} δl推导上一层的 δ l − 1 \delta^{l-1} δl−1,这个过程一般称为upsample。
假设池化的size为2*2,
δ
l
\delta^{l}
δl:
δ
l
=
[
2
3
4
5
]
\delta^{l}=\left[ \begin{array}{ll}{2} & {3} \\ {4} & {5}\end{array}\right]
δl=[2435]
由于池化size为2*2,首先将size还原:
[
0
0
0
0
0
2
3
0
0
4
5
0
0
0
0
0
]
\left[ \begin{array}{llll}{0} & {0} & {0} & {0} \\ {0} & {2} & {3} & {0} \\ {0} & {4} & {5} & {0} \\ {0} & {0} & {0} & {0}\end{array}\right]
⎣⎢⎢⎡0000024003500000⎦⎥⎥⎤
假设是最大池化,并且之前记录的最大值的位置为左上,右下,右上,左下。那么
δ
l
−
1
\delta ^{l-1}
δl−1:
δ
l
−
1
=
[
2
0
0
0
0
0
0
3
0
4
0
0
0
0
5
0
]
\delta^{l-1}=\left[ \begin{array}{llll}{2} & {0} & {0} & {0} \\ {0} & {0} & {0} & {3} \\ {0} & {4} & {0} & {0} \\ {0} & {0} & {5} & {0}\end{array}\right]
δl−1=⎣⎢⎢⎡2000004000050300⎦⎥⎥⎤
解释下为什么要这么做,在正向传播的时候,池化之前的四个最大值位置左上,右下,右上,左下,都以比例为1的系数传递到下一层。而其他位置对输出的贡献都为0,也就是说对池化输出没有影响,因此比例系数可以理解为0。所以在正向传播的过程中,最大值所在位置可以理解为通过函数 f ( x ) = x f(x)=x f(x)=x传递到下一层,而其他位置则通过 f ( x ) = 0 f(x)=0 f(x)=0传递到下一层,并且把这些值相加构成下一层的输出,虽然 f ( x ) = 0 f(x)=0 f(x)=0并没有作用,但这样也就不难理解反向传播时,把的各个值移到最大值所在位置,而其他位置为0了。因为由 f ( x ) = x f(x)=x f(x)=x,最大值位置的偏导数为1,而 f ( x ) = 0 f(x)=0 f(x)=0的偏导数为0。
如果是平均池化,那么
δ
l
−
1
\delta ^{l-1}
δl−1:
δ
l
−
1
=
[
0.5
0.5
0.75
0.75
0.5
0.5
0.75
0.75
1
1
1.25
1.25
1
1
1.25
1.25
]
\delta^{l-1}=\left[ \begin{array}{cccc}{0.5} & {0.5} & {0.75} & {0.75} \\ {0.5} & {0.5} & {0.75} & {0.75} \\ {1} & {1} & {1.25} & {1.25} \\ {1} & {1} & {1.25} & {1.25}\end{array}\right]
δl−1=⎣⎢⎢⎡0.50.5110.50.5110.750.751.251.250.750.751.251.25⎦⎥⎥⎤
平均池化的话,池化操作的四个位置传递到下一层的作用可以等价为 f ( x ) = x / 4 f(x)=x/4 f(x)=x/4,所以在方向传播过程中就相当于把 δ l \delta ^{l} δl每一个位置的值乘1/4再还原回去。
所以由
δ
l
\delta ^{l}
δl推导
δ
l
−
1
\delta ^{l-1}
δl−1可以总结为:
δ
l
−
1
=
u
p
s
a
m
p
l
e
(
δ
l
)
⊙
σ
′
(
z
l
−
1
)
\delta^{l-1}=u p s a m p l e\left(\delta^{l}\right) \odot \sigma^{\prime}\left(z^{l-1}\right)
δl−1=upsample(δl)⊙σ′(zl−1)
等式右边第一项表示上采样,第二项是激活函数的导数,在池化中可以理解为常数1(因为池化过程的正向传播过程中没有激活函数)。
已知卷积层的
δ
l
\delta ^{l}
δl推导上一层的
δ
l
−
1
\delta ^{l-1}
δl−1:
δ
l
−
1
=
δ
l
∂
z
l
∂
z
l
−
1
=
δ
l
∗
r
o
t
180
(
W
l
)
⊙
σ
′
(
z
l
−
1
)
\delta^{l-1}=\delta^{l} \frac{\partial z^{l}}{\partial z^{l-1}}=\delta^{l} * r o t 180\left(W^{l}\right) \odot \sigma^{\prime}\left(z^{l-1}\right)
δl−1=δl∂zl−1∂zl=δl∗rot180(Wl)⊙σ′(zl−1)
首先由链式法则:
δ
l
−
1
=
∂
C
∂
z
l
∂
z
l
∂
a
l
−
1
⊙
σ
′
(
z
l
−
1
)
\delta^{l-1}=\frac{\partial C}{\partial z^{l}} \frac{\partial z^{l}}{\partial a^{l-1}} \odot \sigma^{\prime}\left(z^{l-1}\right)
δl−1=∂zl∂C∂al−1∂zl⊙σ′(zl−1)
r o t 180 ( w l ) rot180({w^{l}}) rot180(wl)代表对卷积核进行翻转180°的操作, σ ′ ( z l − 1 ) {\sigma }'(z^{l-1}) σ′(zl−1)为激活函数的导数。这里比较难理解的是为什么要对卷积核进行180°的翻转。
假设我们
l
−
1
l-1
l−1层的输出
a
l
−
1
a^{l-1}
al−1是一个3x3矩阵,第l层的卷积核
W
W
W是一个2x2矩阵,采用1像素的步幅,则输出
z
l
z^{l}
zl是一个2x2的矩阵。这里暂时不考虑偏置项
b
b
b的影响。
那么可得:
a
l
−
1
∗
W
l
=
z
l
a^{l-1} * W^{l}=z^{l}
al−1∗Wl=zl
即:
(
a
11
a
12
a
13
a
21
a
22
a
23
a
31
a
32
a
33
)
∗
(
w
11
w
12
w
21
w
22
)
=
(
z
11
z
12
z
21
z
22
)
\left( \begin{array}{lll}{a_{11}} & {a_{12}} & {a_{13}} \\ {a_{21}} & {a_{22}} & {a_{23}} \\ {a_{31}} & {a_{32}} & {a_{33}}\end{array}\right) * \left( \begin{array}{ll}{w_{11}} & {w_{12}} \\ {w_{21}} & {w_{22}}\end{array}\right)=\left( \begin{array}{ll}{z_{11}} & {z_{12}} \\ {z_{21}} & {z_{22}}\end{array}\right)
⎝⎛a11a21a31a12a22a32a13a23a33⎠⎞∗(w11w21w12w22)=(z11z21z12z22)
展开后得到:
z
11
=
a
11
w
11
+
a
12
w
12
+
a
21
w
21
+
a
22
w
22
z
12
=
a
12
w
11
+
a
13
w
12
+
a
22
w
21
+
a
23
w
22
z
21
=
a
21
w
11
+
a
22
w
12
+
a
31
w
21
+
a
32
w
22
z
22
=
a
22
w
11
+
a
23
w
12
+
a
32
w
21
+
a
33
w
22
\begin{array}{l}{z_{11}=a_{11} w_{11}+a_{12} w_{12}+a_{21} w_{21}+a_{22} w_{22}} \\ {z_{12}=a_{12} w_{11}+a_{13} w_{12}+a_{22} w_{21}+a_{23} w_{22}} \\ {z_{21}=a_{21} w_{11}+a_{22} w_{12}+a_{31} w_{21}+a_{32} w_{22}} \\ {z_{22}=a_{22} w_{11}+a_{23} w_{12}+a_{32} w_{21}+a_{33} w_{22}}\end{array}
z11=a11w11+a12w12+a21w21+a22w22z12=a12w11+a13w12+a22w21+a23w22z21=a21w11+a22w12+a31w21+a32w22z22=a22w11+a23w12+a32w21+a33w22
求
a
l
a^{l}
al的梯度:
∇
a
l
−
1
=
∂
J
(
W
,
b
)
∂
a
l
−
1
=
∂
J
(
W
,
b
)
∂
z
l
∂
z
l
∂
a
l
−
1
=
δ
l
∂
z
l
∂
a
l
−
1
\nabla a^{l-1}=\frac{\partial J(W, b)}{\partial a^{l-1}}=\frac{\partial J(W, b)}{\partial z^{l}} \frac{\partial z^{l}}{\partial a^{l-1}}=\delta^{l} \frac{\partial z^{l}}{\partial a^{l-1}}
∇al−1=∂al−1∂J(W,b)=∂zl∂J(W,b)∂al−1∂zl=δl∂al−1∂zl
又由展开式可知:
a
11
a_{11}
a11只与
z
11
z_{11}
z11有关,并且系数为
w
11
w_{11}
w11,所以有:
∇
a
11
=
δ
11
w
11
\nabla a_{11}=\delta_{11} w_{11}
∇a11=δ11w11
a
12
a_{12}
a12只与
z
11
z_{11}
z11和
z
12
z_{12}
z12有关,并且系数分别为
w
11
w_{11}
w11,
w
12
w_{12}
w12所以:
∇
a
12
=
δ
11
w
12
+
δ
12
w
11
\nabla a_{12}=\delta_{11} w_{12}+\delta_{12} w_{11}
∇a12=δ11w12+δ12w11
同理可以得到:
∇
a
13
=
δ
12
w
12
∇
a
21
=
δ
11
w
21
+
δ
21
w
11
∇
a
22
=
δ
11
w
22
+
δ
12
w
21
+
δ
21
w
12
+
δ
22
w
11
∇
a
23
=
δ
12
w
22
+
δ
22
w
12
∇
a
31
=
δ
21
w
21
∇
a
32
=
δ
21
w
22
+
δ
22
w
21
∇
a
33
=
δ
22
w
22
\begin{array}{c}{\nabla a_{13}=\delta_{12} w_{12}} \\ {\nabla a_{21}=\delta_{11} w_{21}+\delta_{21} w_{11}} \\ {\nabla a_{22}=\delta_{11} w_{22}+\delta_{12} w_{21}+\delta_{21} w_{12}+\delta_{22} w_{11}} \\ {\nabla a_{23}=\delta_{12} w_{22}+\delta_{22} w_{12}} \\ {\nabla a_{31}=\delta_{21} w_{21}} \\ {\nabla a_{32}=\delta_{21} w_{22}+\delta_{22} w_{21}} \\ {\nabla a_{33}=\delta_{22} w_{22}}\end{array}
∇a13=δ12w12∇a21=δ11w21+δ21w11∇a22=δ11w22+δ12w21+δ21w12+δ22w11∇a23=δ12w22+δ22w12∇a31=δ21w21∇a32=δ21w22+δ22w21∇a33=δ22w22
使用矩阵形式表示就是:
(
0
0
0
0
0
δ
11
δ
12
0
0
δ
21
δ
22
0
0
0
0
0
)
∗
(
w
22
w
21
w
12
w
11
)
=
(
∇
a
11
∇
a
12
∇
a
13
∇
a
21
∇
a
22
∇
a
23
∇
a
31
∇
a
32
∇
a
33
)
\left( \begin{array}{cccc}{0} & {0} & {0} & {0} \\ {0} & {\delta_{11}} & {\delta_{12}} & {0} \\ {0} & {\delta_{21}} & {\delta_{22}} & {0} \\ {0} & {0} & {0} & {0}\end{array}\right) * \left( \begin{array}{cc}{w_{22}} & {w_{21}} \\ {w_{12}} & {w_{11}}\end{array}\right)=\left( \begin{array}{ccc}{\nabla a_{11}} & {\nabla a_{12}} & {\nabla a_{13}} \\ {\nabla a_{21}} & {\nabla a_{22}} & {\nabla a_{23}} \\ {\nabla a_{31}} & {\nabla a_{32}} & {\nabla a_{33}}\end{array}\right)
⎝⎜⎜⎛00000δ11δ2100δ12δ2200000⎠⎟⎟⎞∗(w22w12w21w11)=⎝⎛∇a11∇a21∇a31∇a12∇a22∇a32∇a13∇a23∇a33⎠⎞
这就解释了为什么在反向传播时需要将卷积核进行180°的翻转操作了。
已知卷积层的 δ l \delta ^{l} δl推导 w w w, b b b的梯度:
全连接层中的 w w w, b b b的梯度与DNN中的推导一致,池化层没有 w w w, b b b参数,所以不用进行 w w w, b b b 梯度的推导。
对于卷积层正向传播过程:
z
l
=
a
l
−
1
∗
W
l
+
b
z^{l}=a^{l-1} * W^{l}+b
zl=al−1∗Wl+b
所以参数
w
w
w的梯度:
∂
J
(
W
,
b
)
∂
W
l
=
∂
J
(
W
,
b
)
∂
z
l
∂
z
l
∂
W
l
=
a
l
−
1
∗
δ
l
\frac{\partial J(W, b)}{\partial W^{l}}=\frac{\partial J(W, b)}{\partial z^{l}} \frac{\partial z^{l}}{\partial W^{l}}=a^{l-1} * \delta^{l}
∂Wl∂J(W,b)=∂zl∂J(W,b)∂Wl∂zl=al−1∗δl
注意到这里我们并没有使用翻转180°的操作。因为由之前的展开式:
z
11
=
a
11
w
11
+
a
12
w
12
+
a
21
w
21
+
a
22
w
22
z
12
=
a
12
w
11
+
a
13
w
12
+
a
22
w
21
+
a
23
w
22
z
21
=
a
21
w
11
+
a
22
w
12
+
a
31
w
21
+
a
32
w
22
z
22
=
a
22
w
11
+
a
23
w
12
+
a
32
w
21
+
a
33
w
22
\begin{array}{l}{z_{11}=a_{11} w_{11}+a_{12} w_{12}+a_{21} w_{21}+a_{22} w_{22}} \\ {z_{12}=a_{12} w_{11}+a_{13} w_{12}+a_{22} w_{21}+a_{23} w_{22}} \\ {z_{21}=a_{21} w_{11}+a_{22} w_{12}+a_{31} w_{21}+a_{32} w_{22}} \\ {z_{22}=a_{22} w_{11}+a_{23} w_{12}+a_{32} w_{21}+a_{33} w_{22}}\end{array}
z11=a11w11+a12w12+a21w21+a22w22z12=a12w11+a13w12+a22w21+a23w22z21=a21w11+a22w12+a31w21+a32w22z22=a22w11+a23w12+a32w21+a33w22
∂ J ( W , b ) ∂ W 11 l = a 11 δ 11 + a 12 δ 12 + a 21 δ 21 + a 22 δ 22 ∂ J ( W , b ) ∂ W 12 l = a 12 δ 11 + a 13 δ 12 + a 22 δ 21 + a 23 δ 22 ∂ J ( W , b ) ∂ W 21 l = a 13 δ 11 + a 14 δ 12 + a 23 δ 21 + a 24 δ 22 ∂ J ( W , b ) ∂ W 22 l = a 21 δ 11 + a 22 δ 12 + a 31 δ 21 + a 32 δ 22 \begin{array}{l}{\frac{\partial J(W, b)}{\partial W_{11}^{l}}=a_{11} \delta_{11}+a_{12} \delta_{12}+a_{21} \delta_{21}+a_{22} \delta_{22}} \\ {\frac{\partial J(W, b)}{\partial W_{12}^{l}}=a_{12} \delta_{11}+a_{13} \delta_{12}+a_{22} \delta_{21}+a_{23} \delta_{22}} \\ {\frac{\partial J(W, b)}{\partial W_{21}^{l}}=a_{13} \delta_{11}+a_{14} \delta_{12}+a_{23} \delta_{21}+a_{24} \delta_{22}} \\ {\frac{\partial J(W, b)}{\partial W_{22}^{l}}=a_{21} \delta_{11}+a_{22} \delta_{12}+a_{31} \delta_{21}+a_{32} \delta_{22}}\end{array} ∂W11l∂J(W,b)=a11δ11+a12δ12+a21δ21+a22δ22∂W12l∂J(W,b)=a12δ11+a13δ12+a22δ21+a23δ22∂W21l∂J(W,b)=a13δ11+a14δ12+a23δ21+a24δ22∂W22l∂J(W,b)=a21δ11+a22δ12+a31δ21+a32δ22
所以
w
w
w的梯度:
∂
J
(
W
,
b
)
∂
W
l
=
(
a
11
a
12
a
13
a
14
a
21
a
22
a
23
a
24
a
31
a
32
a
33
a
34
a
41
a
42
a
43
a
44
)
∗
(
δ
11
δ
12
δ
21
δ
22
)
\frac{\partial J(W, b)}{\partial W^{l}}=\left( \begin{array}{llll}{a_{11}} & {a_{12}} & {a_{13}} & {a_{14}} \\ {a_{21}} & {a_{22}} & {a_{23}} & {a_{24}} \\ {a_{31}} & {a_{32}} & {a_{33}} & {a_{34}} \\ {a_{41}} & {a_{42}} & {a_{43}} & {a_{44}}\end{array}\right) * \left( \begin{array}{cc}{\delta_{11}} & {\delta_{12}} \\ {\delta_{21}} & {\delta_{22}}\end{array}\right)
∂Wl∂J(W,b)=⎝⎜⎜⎛a11a21a31a41a12a22a32a42a13a23a33a43a14a24a34a44⎠⎟⎟⎞∗(δ11δ21δ12δ22)
这也就是没有进行翻转的原因。
b b b的梯度:
这里假设
w
=
0
w=0
w=0,那么
z
=
b
z=b
z=b,梯度
δ
l
\delta ^{^{l}}
δl是三维张量,而
b
b
b只是一个向量,不能像普通网络中那样直接和
δ
l
\delta ^{^{l}}
δl相等。通常的做法是将误差
δ
\delta
δ的各个子矩阵的项分别求和,得到一个误差向量所以这里
b
b
b的梯度就是
δ
l
\delta ^{^{l}}
δl 的各个通道对应位置求和:
∂
J
(
W
,
b
)
∂
b
l
=
∑
u
,
v
(
δ
l
)
u
,
v
\frac{\partial J(W, b)}{\partial b^{l}}=\sum_{u, v}\left(\delta^{l}\right)_{u, v}
∂bl∂J(W,b)=u,v∑(δl)u,v
得到的是一个误差向量。
总结一下CNN的反向传播过程:
1 池化层的误差反向传播:
δ
l
−
1
=
u
p
s
a
m
p
l
e
(
δ
l
)
⊙
σ
′
(
z
l
−
1
)
\delta^{l-1}=u p s a m p l e\left(\delta^{l}\right) \odot \sigma^{\prime}\left(z^{l-1}\right)
δl−1=upsample(δl)⊙σ′(zl−1)
2 卷积层的误差反向传播:
δ
l
−
1
=
δ
l
∂
z
l
∂
z
l
−
1
=
δ
l
∗
rot
180
(
W
l
)
⊙
σ
′
(
z
l
−
1
)
\delta^{l-1}=\delta^{l} \frac{\partial z^{l}}{\partial z^{l-1}}=\delta^{l} * \operatorname{rot} 180\left(W^{l}\right) \odot \sigma^{\prime}\left(z^{l-1}\right)
δl−1=δl∂zl−1∂zl=δl∗rot180(Wl)⊙σ′(zl−1)
3 参数更新:
∂
J
(
W
,
b
)
∂
W
l
=
∂
J
(
W
,
b
)
∂
z
l
∂
z
l
∂
W
l
=
a
l
−
1
∗
δ
l
\frac{\partial J(W, b)}{\partial W^{l}}=\frac{\partial J(W, b)}{\partial z^{l}} \frac{\partial z^{l}}{\partial W^{l}}=a^{l-1} * \delta^{l}
∂Wl∂J(W,b)=∂zl∂J(W,b)∂Wl∂zl=al−1∗δl
∂ J ( W , b ) ∂ b l = ∑ u , v ( δ l ) u , v \frac{\partial J(W, b)}{\partial b^{l}}=\sum_{u, v}\left(\delta^{l}\right)_{u, v} ∂bl∂J(W,b)=u,v∑(δl)u,v
参考文献
[1]https://blog.csdn.net/u013093426/article/details/81086396 (手把手教你搭建卷积神经网络(CNN))
[2]https://www.cnblogs.com/charlotte77/p/7783261.htm (【深度学习系列】卷积神经网络详解(二)——自己手写一个卷积神经网络)
[3]https://www.cnblogs.com/pinard/p/6494810.htm (卷积神经网络(CNN)反向传播算法)
[4]https://www.jianshu.com/p/8ad58a170fd (反向传播算法推导-卷积神经)
[5]https://blog.csdn.net/weixin_40446651/article/details/81516944 (深层神经网络和卷积神经网络的反向传播过程推导)
[6]神经网络与深度学习中文版