前言
众所周知,深度神经网络的一大精髓在于BP算法。每个Batch的前馈计算完成后,采用BP算法可以很方便地求得梯度,或者说,损失函数 E E E对于任一个权重 w i , j w_{i, j} wi,j的偏导 ∂ E ∂ w i , j \frac{\partial E}{\partial w_{i, j}} ∂wi,j∂E都是可知的。下一步,便可以很自然地才用梯度下降算法对权重更新,以向最小值点前进。
四个基本方程
BP算法的核心是如下的4个基本方程,不论什么形式的误差函数,都能够通过这4个基本方程逐层求解,最终就能够得到我们需要的梯度。
其中,
δ
j
l
\delta_{j}^{l}
δjl被定义为第
l
l
l层的误差,其中输出层误差如下:
δ
j
L
=
∂
C
∂
a
j
L
σ
′
(
z
j
L
)
\delta^{L}_{j} = \frac{ \partial C}{ \partial a^{L}_{j} } \sigma_{'}(z^{L}_{j})
δjL=∂ajL∂Cσ′(zjL)
而这4个方程中,最能够体现“反向传播”的思想的莫过于BP2,其本质是使用 l + 1 l+1 l+1层的误差 δ l + 1 \delta^{l+1} δl+1来表示第 l l l层的误差 δ i l \delta_{i}^{l} δil,这样就能够实现从后一层到前一层的反向推进过程。而因为全连接层每一个神经元都和上一层的所有神经元相连,会导致链式法则运用起来比较复杂,接下来我们就详细讨论这一过程。
链式法则
大家在学高数的时候都学过,复合函数求导要使用链式法则。随便举一个经典的例子:
f
(
u
,
v
)
=
u
+
7
v
,
u
(
x
,
y
)
=
3
x
+
2
y
,
v
(
x
,
y
)
=
x
y
f(u,v)=u+7v, u(x, y)=3x+2y,v(x,y)=xy
f(u,v)=u+7v,u(x,y)=3x+2y,v(x,y)=xy
容易得到:
d
f
d
x
=
∂
f
∂
u
∂
u
∂
x
+
∂
f
∂
v
∂
v
∂
x
=
3
+
7
y
\frac{df}{dx}=\frac{\partial f }{\partial u}\frac{\partial u }{\partial x} + \frac{\partial f }{\partial v}\frac{\partial v }{\partial x}=3+7y
dxdf=∂u∂f∂x∂u+∂v∂f∂x∂v=3+7y
但是实际上我们是默认了一些东西的,为了后面研究全连接层众多参数的情况下更加清晰明朗,在这里有必要不厌其烦的追究一下:
- 如何知道中间变量只有 u u u和 v v v?
- 如何知道 x x x对于 y y y没有影响,即 ∂ y ∂ x \frac{\partial y }{\partial x} ∂x∂y为零?
一、完备表达
对于第一个问题,或许我们可以直接说:“这是由于
f
(
u
,
v
)
f(u,v)
f(u,v)的括号内只有
u
u
u和
v
v
v,倘若给出的形式是
f
(
u
,
v
,
w
)
f(u, v, w)
f(u,v,w),大可以写成:
d
f
d
x
=
∂
f
∂
u
∂
u
∂
x
+
∂
f
∂
v
∂
v
∂
x
+
∂
f
∂
w
∂
w
∂
x
\frac{df}{dx}=\frac{\partial f }{\partial u}\frac{\partial u }{\partial x} + \frac{\partial f }{\partial v}\frac{\partial v }{\partial x}+ \frac{\partial f }{\partial w}\frac{\partial w }{\partial x}
dxdf=∂u∂f∂x∂u+∂v∂f∂x∂v+∂w∂f∂x∂w。”
看起来这是一个很trivial的问题,然而在面临误差函数 E E E这样的函数,我们很难知道他到底有哪些中间变量。事实上,直觉上我们会感到,对于任意一层 l l l它都可以写成 E ( w i , j ; a 1 l , . . . , a n l l ) E(w_{i,j};a_{1}^{l}, ...,a_{n_{l}}^{l}) E(wi,j;a1l,...,anll)的形式(并非完全严谨,后面会说明这里权重的指代)。
严谨地说呢,当一个函数用某几个变量就能够全部表达时,我们就可以在括号里面只填入这几个参数。我把这样的一组参数称为能够完备表达函数 f f f的参数,比如:
- e x 2 + 3 y + s i n z + x y z e^{x^{2}+3y+sinz+xyz} ex2+3y+sinz+xyz就能够记为 f ( x , y , z ) f(x,y,z) f(x,y,z)。就算再有 h = x y z h=xyz h=xyz,也不需要记为 f ( x , y , z , h ) f(x,y,z,h) f(x,y,z,h)。
回到实际问题,当我们要分析 E E E对于中间变量 a 1 l , . . . , a n l l a_{1}^{l}, ...,a_{n_{l}}^{l} a1l,...,anll这种情况,我们其实把 E E E表为这一层的全部输出(和一些权重)的函数,但是实际上一层一层地求不太现实。
一个简单的等价表达是:
- 对于给定序列 a 1 l , . . . , a n l l a_{1}^{l}, ...,a_{n_{l}}^{l} a1l,...,anll,如果 f f f的值是唯一确定的,即可认为 f f f可由 a 1 l , . . . , a n l l a_{1}^{l}, ...,a_{n_{l}}^{l} a1l,...,anll完备表达,记为: f ( a 1 l , . . . , a n l l ) f(a_{1}^{l}, ...,a_{n_{l}}^{l}) f(a1l,...,anll)
不难发现,给定某一层的参数和该层往后的所有连接权重,即可得到确定的损失函数值,于是可以表达为:
E
(
W
;
a
1
l
,
.
.
.
,
a
n
l
l
)
E(W;a_{1}^{l}, ...,a_{n_{l}}^{l})
E(W;a1l,...,anll),其中
W
W
W即代表第
l
l
l层往后的所有权重。链式求导时,只需要考虑表中的这些参数,比如:
∂
E
∂
w
i
,
j
=
∑
j
∂
E
∂
a
j
l
∂
a
j
l
∂
w
i
,
j
(1)
\frac{\partial E}{\partial w_{i,j}}=\sum_{j}\frac{\partial E}{\partial a_{j}^{l}}\frac{\partial a^{l}_{j}}{\partial w_{i,j}} \tag{1}
∂wi,j∂E=j∑∂ajl∂E∂wi,j∂ajl(1)
而不需再考虑诸如
∂
E
∂
a
i
l
−
1
∂
a
i
l
−
1
∂
a
j
l
\frac{\partial E}{\partial a_{i}^{l-1}}\frac{\partial a_{i}^{l-1}}{\partial a_{j}^{l}}
∂ail−1∂E∂ajl∂ail−1一项的影响,尽管此项可能非零(后一层输出必定受到前一层输出的影响)。
二、影响传递
如何判断一个变量对另一个变量的偏导 ∂ y ∂ x \frac{\partial y }{\partial x} ∂x∂y是不是零呢?我们在直角坐标系中通常认为这是trivial的,因为 x x x和 y y y之间没有直观的联系(除非给出约束)。对于神经网络,我们也可以直观得将偏导数理解为一种贡献率,或者显著性,即一个参数的变化引起另一个参数变化的敏感程度。(于是自然有人利用这个来做剪枝,这里可以参见我的另一篇博客。)
基于神经网络的前馈计算过程,给出以下几条容易得到的假设:
- 前馈计算中,前一层的参数对后一层的输出一般有影响,反之,后一层的参数一般对前一层的输出没有直观影响;
- 如果不是本身变化,一般认为权重 w i , j w_{i,j} wi,j、偏置 b l b_{l} bl等等都是常数,对别的参数有贡献率 ∂ a k l ∂ w i , j \frac{\partial a_{k}^{l} }{\partial w_{i,j}} ∂wi,j∂akl,但是反之 ∂ w i , j ∂ x \frac{\partial w_{i,j} }{\partial x} ∂x∂wi,j一般都为零。
具体的计算,主要使用这个式子:
a
j
l
=
σ
(
∑
i
w
j
,
i
a
i
l
−
1
+
b
l
)
a_{j}^{l}=\sigma(\sum_{i}w_{j,i}a_{i}^{l-1}+b^{l})
ajl=σ(i∑wj,iail−1+bl)
一个细节
有了上面两个部分的铺垫,反过来可以注意到一件事,即一般情况下上面的式(1)应该写成:
∂
E
∂
w
m
,
n
=
∑
j
∂
E
∂
a
j
l
∂
a
j
l
∂
w
i
,
j
+
∑
k
,
h
∂
E
∂
w
k
,
h
∂
w
k
,
h
∂
w
m
,
n
(2)
\frac{\partial E}{\partial w_{m,n}}=\sum_{j}\frac{\partial E}{\partial a_{j}^{l}}\frac{\partial a^{l}_{j}}{\partial w_{i,j}}+\sum_{k,h}\frac{\partial E}{\partial w_{k,h}}\frac{\partial w_{k,h}}{\partial w_{m,n}} \tag{2}
∂wm,n∂E=j∑∂ajl∂E∂wi,j∂ajl+k,h∑∂wk,h∂E∂wm,n∂wk,h(2)
假设
w
m
,
n
w_{m,n}
wm,n是第
l
0
l_{0}
l0层的参数,而
a
j
l
a^{l}_{j}
ajl是第
l
l
l层的输出。
若取 l > l 0 l>l_{0} l>l0,显然后排的输出会受到前排权重的影响,即 ∀ j , ∂ a j l ∂ w m , n ≠ 0 \forall j,\frac{\partial a^{l}_{j}}{\partial w_{m,n}}\neq0 ∀j,∂wm,n∂ajl=0,并且此时 ( k , h ) (k,h) (k,h)将不能取到 ( m , n ) (m,n) (m,n),即右边第二项求和为零,上式退化为先前的情况;
而取
l
≤
l
0
l \leq l_{0}
l≤l0,显然前排的输出与后排的权重没什么联系,即
∀
j
,
∂
a
j
l
∂
w
m
,
n
=
0
\forall j,\frac{\partial a^{l}_{j}}{\partial w_{m,n}}=0
∀j,∂wm,n∂ajl=0,所以右边的第一项求和为零,而第二项只有在取
(
k
,
h
)
=
(
m
,
n
)
(k,h)=(m,n)
(k,h)=(m,n)时非零,上式退化为:
∂
E
∂
w
m
,
n
=
∂
E
∂
w
m
,
n
∂
w
m
,
n
∂
w
m
,
n
=
∂
E
∂
w
m
,
n
\frac{\partial E}{\partial w_{m,n}}=\frac{\partial E}{\partial w_{m,n}}\frac{\partial w_{m,n}}{\partial w_{m,n}}=\frac{\partial E}{\partial w_{m,n}}
∂wm,n∂E=∂wm,n∂E∂wm,n∂wm,n=∂wm,n∂E
表明这种情况没有分析价值。但是这仍然是成立的,这充分说明了这种分析方法的严谨性。
参考文献
[1] Michael Nielsen, Netural Networks and Deep Learning, 2017.
[2] LeCun, Denker, Solla, Optimal Brain Damage, 1989.