一步一步计算反向传播

反向传播(Backpropagation) 是训练神经网络的一种常见手段。在 神经网络基础 这一节里,咱们提到,肯定好每一个神经节点的权重(weight)与误差(bias)以后,就能经过前馈(feedforward)肯定神经网络的输出,但这只是输出预测值。咱们还须要根据预测值,来 反推 各个权重与误差须要如何调整,以使得预测值和指望值偏差更小。这就是反向传播所作的事情。网络

要弄明白反向传播是如何工做的,以一个具体例子计算是最简单直接的。假设现有一个 3 层的神经网络以下:函数

假设现有同样本,输入为 0.一、0.5,指望输出为 0.九、0.1。咱们初始权重、初始误差如图所示:post

接下来咱们经过这个样本的训练,来调整初始权重。学习

前馈

首先咱们经过前馈来肯定神经网络的输出,也就是预测值。回顾一下神经节点的输入输出,它的输入是上一层各个节点经过权重与误差计算的结果,咱们记为 z;它的输出是 z 通过 激活函数(activation functions)产生的输出,记为 a。通式以下:cdn

z^{l}_j = 
\sum_k w^{l}_{jk} a^{l-1}_k + b^l_j
a^{l}_j = \sigma(z^{l}_j)

其中,激活函数定义为blog

\sigma(x) = \frac{1}{1 + e^{-x}}

先不用过于纠结公式的各个字符的含义,暂时只须要知道计算方法便可。get

带入得:it

z_{h1} = 0.1 * 0.1 + 0.5 * 0.2 + 0.1 = 0.21
a_{h1} = \sigma(z_{h1}) = 0.549833997
z_{h2} = 0.1 * 0.3 + 0.5 * 0.4 + 0.2 = 0.43
a_{h2} = \sigma(z_{h2}) = 0.605873668

同理算出输出层:io

z_{o1} = 0.549833997 * 0.5 + 0.605873668 * 0.6 + 0.3 = 0.938441199
a_{o1} = \sigma(z_{o1}) = 0.718784679
z_{o2} = 0.549833997 * 0.7 + 0.605873668 * 0.8 + 0.4 = 1.269582732
a_{o2} = \sigma(z_{o2}) = 0.780671310

这样咱们完成了一次前馈的计算,获得了神经网络的两个预测值(output),但这和样本的指望值(target)有必定的偏差。咱们使用 平方偏差函数(squared error function)计算偏差 C,通式为:function

C = \frac{1}{2n} \sum_{x} \|target-a^L(x)\|^2

带入值为:

C_{o1} = \frac{1}{2} * (0.9 - 0.718784679)^2 = 0.016419496
C_{o2} = \frac{1}{2} * (0.1 - 0.780671310)^2 = 0.231656716
C = C_{o1} + C_{o2} = 0.016419496 + 0.231656716 = 0.248076212

也就是说,神经网络的预测值与实际值有 0.248076212 偏差,咱们的目标就是经过调节权重和误差,让这个偏差更小。

反向传播

反向传播实际上就是一个求导的过程。若是咱们要知道如何经过改变 w_5,使得总偏差能变小,这其实就是求总偏差 C 对 w_5 求偏导。根据链式法则

\frac{\partial{C}}{\partial{w_{5}}} = \frac{\partial{C}}{\partial{a_{o1}}} * \frac{\partial{a_{o1}}}{\partial{z_{o1}}} * \frac{\partial{z_{o1}}}{\partial{w_{5}}}

这个公式的含义实际上就是 w_5 的改变能对 C 形成的影响,接下来分别求等式右边的三个部分。

首先由于

C = C_{o1} + C_{o2} = \frac{1}{2} * (0.9 - a_{o1})^2 + C_{o2}

其中 C_{o2}a_{o1} 无关,因此 C 对 a_{o1} 求偏导为

\frac{\partial{C}}{\partial{a_{o1}}} = -(0.9 - a_{o1}) = -0.181215321

接下来求 \frac{\partial{a_{o1}}}{\partial{z_{o1}}},而

a_{o1} = \sigma(z_{o1})

因此

\frac{\partial{a_{o1}}}{\partial{z_{o1}}} = \sigma'(z_{o1})

\sigma'(x) = \sigma(x) * (1 - \sigma(x))

因此带入可得

\frac{\partial{a_{o1}}}{\partial{z_{o1}}} = a_{o1} * (1 - a_{o1}) = 0.202133264

最后,咱们再看 \frac{\partial{z_{o1}}}{\partial{w_{5}}},由于

z_{o1} = w_5 * a_{h1} + w_6 * a_{h2} + b_3

因此

\frac{\partial{z_{o1}}}{\partial{w_{5}}} = a_{h1} = 0.21

综上,

\frac{\partial{C}}{\partial{w_{5}}} = \frac{\partial{C}}{\partial{a_{o1}}} * \frac{\partial{a_{o1}}}{\partial{z_{o1}}} * \frac{\partial{z_{o1}}}{\partial{w_{5}}}
= -0.181215321 * 0.202133264 * 0.21
= -0.007692225

为了使偏差更小,咱们使用 w_5 减去这个数,这里引入一个较小的 学习速率(learning rate),用来控制梯度降低的速度,这里取 0.5,则:

w_5 = w_5 - \eta * \frac{\partial{C}}{\partial{w_{5}}} = 0.5 - (-0.007692225) = 0.507692225

另外,计算误差也是同样的道理,以 b3 举例

\frac{\partial{C}}{\partial{b_{3}}} = 
\frac{\partial{C}}{\partial{a_{o1}}} * \frac{\partial{a_{o1}}}{\partial{z_{o1}}} * \frac{\partial{z_{o1}}}{\partial{b_{3}}}

z_{o1} = w_5 * a_{h1} + w_6 * a_{h2} + b_3

因此

\frac{\partial{z_{o1}}}{\partial{b_{3}}} = 1

\frac{\partial{C}}{\partial{b_{3}}} = \frac{\partial{C}}{\partial{a_{o1}}} * \frac{\partial{a_{o1}}}{\partial{z_{o1}}} * \frac{\partial{z_{o1}}}{\partial{w_{5}}}
= -0.181215321 * 0.202133264 * 1
= -0.036629644

因此

b_3 = b_3 - \eta * \frac{\partial{C}}{\partial{b_{3}}} = 0.3 - (-0.036629644) = 0.336629644

同理,咱们能够计算出新的 w_6w_7w_8w_9b_4,再根据公式计算出新的 w_1w_2w_3w_4b_1b_2。这样,咱们就完成了一次反向传播。

相关文章
相关标签/搜索