Backpropagation
神经网络中,我们利用梯度下降法来对损失函数进行优化,这在神经元数量不多的时候很有效。但是深层神经网络中,有上百万的参数需要调整,单纯使用梯度下降法可以算,但几乎不可能算完。因此我们需要更有效的方法来优化损失函数,这也就引出了反向传播(backpropagation)
链式法则
下图是多层神经网络的一个模型,现在我们要对损失函数L进行优化,即对其中每个参数求偏导。以图中三角部分为例,展开:
假设该部分的模型函数如下:
z
=
w
1
x
1
+
w
2
x
2
+
b
z=w_1x_1+w_2x_2+b
z=w1?x1?+w2?x2?+b
z是即将输入给激活函数的值,
w
1
w_1
w1?是
x
1
x_1
x1?的权重,
w
2
w_2
w2?是
x
2
x_2
x2?的权重,b是偏置值,如下:
根据链式法则,我们将损失函数(这里的C是整个损失函数中的某一个加项)对某一个
w
w
w的偏导,拆成了上图中的形式。
前/后向传播
就像上图中标出的那样,我们把
?
z
?
w
\frac{\partial z}{\partial w}
?w?z?,称为前向传播项;把
?
C
?
z
\frac{\partial C}{\partial z}
?z?C?,称为后向传播项。
1、前向传播
之所以
?
z
?
w
\frac{\partial z}{\partial w}
?w?z?称为前向传播,是因为它的值只和与参数直接相连的输入有关。例如在上图中,
?
z
?
w
1
=
x
1
\frac{\partial z}{\partial w_1} = x_1
?w1??z?=x1?,
?
z
?
w
2
=
x
2
\frac{\partial z}{\partial w_2} = x_2
?w2??z?=x2?
2、反向传播
?
C
?
z
\frac{\partial C}{\partial z}
?z?C?是很复杂的,因为C和z并不直接相关,我们用链式法则对其可以继续分解(假设经过激活函数后的输出可表示为
a
=
σ
(
z
)
a=\sigma(z)
a=σ(z)):
?
C
?
z
=
?
a
?
z
?
C
?
a
\frac{\partial C}{\partial z}=\frac{\partial a}{\partial z}\frac{\partial C}{\partial a}
?z?C?=?z?a??a?C?
其中
?
a
?
z
\frac{\partial a}{\partial z}
?z?a?就是激活函数在z处的值,可以简单的表示为
σ
′
(
z
)
\sigma^{'}(z)
σ′(z)。而
?
C
?
a
\frac{\partial C}{\partial a}
?a?C?又要求我们继续进行链式展开:
?
C
?
a
=
?
z
′
?
a
?
C
?
z
′
+
?
z
′
′
?
a
?
C
?
z
′
′
\frac{\partial C}{\partial a}=\frac{\partial z^{'}}{\partial a}\frac{\partial C}{\partial z^{'}}+\frac{\partial z^{''}}{\partial a}\frac{\partial C}{\partial z^{''}}
?a?C?=?a?z′??z′?C?+?a?z′′??z′′?C?
很容易发现这是一个迭代的过程,因为我们总需要继续求解下一层的偏导数。这里我们先假设
?
C
?
z
′
\frac{\partial C}{\partial z^{'}}
?z′?C?和
?
C
?
z
′
′
\frac{\partial C}{\partial z^{''}}
?z′′?C?已知,那么可以把最初的式子改写为:
?
C
?
z
=
σ
′
(
z
)
[
w
3
?
C
?
z
′
+
w
4
?
C
?
z
′
′
]
\frac{\partial C}{\partial z}=\sigma^{'}(z)\left[w_3 \frac{\partial C}{\partial z^{'}} + w_4 \frac{\partial C}{\partial z^{''}} \right]
?z?C?=σ′(z)[w3??z′?C?+w4??z′′?C?]
下面这张图能够让你更好的理解,为什么它被称为“反向”传播。
如何继续计算
1、单隐层
如果,上图中红色的就是output层,那么我们上面给出的假设已知是成立的,因为此时:
?
C
?
z
′
=
?
y
1
?
z
′
?
C
?
y
1
\frac{\partial C}{\partial z^{'}}=\frac{\partial y_1}{\partial z^{'}}\frac{\partial C}{\partial y_1}
?z′?C?=?z′?y1???y1??C?
?
C
?
z
′
′
=
?
y
2
?
z
′
′
?
C
?
y
2
\frac{\partial C}{\partial z^{''}}=\frac{\partial y_2}{\partial z^{''}}\frac{\partial C}{\partial y_2}
?z′′?C?=?z′′?y2???y2??C?
y与z之间的关系,由激活函数得出;而C与y之间的关系,正是你定义的损失函数,这些偏导都是已知的。
2、多隐层
那如果红色的之后还有很多层,我们其实只需要继续迭代,直到达到output层即可。我们可以想象成有一个逆向的神经网络,其优化过程如下:
总结
BP算法分为三个步骤(对某一个参数):
- forward pass。正向求取各个
?
z
?
w
=
a
\frac{\partial z}{\partial w}=a
?w?z?=a
- backward pass。反向求取各个
?
C
?
z
\frac{\partial C}{\partial z}
?z?C?
- combine。
a
×
?
C
?
z
=
?
C
?
w
a \times \frac{\partial C}{\partial z} = \frac{\partial C}{\partial w}
a×?z?C?=?w?C?
|