反向传播算法
参考:http://neuralnetworksanddeeplearning.com/chap2.html
BP 算法所关注的是损失函数 C 关于神经网络每一个权重 w 和偏置 b 的偏导。BP 算法向我们展示权值和偏置对损失值的影响。BP 不仅仅是一个快速的算法,其同时为我们提供了一个视角,让我们观察权值和偏置是如何影响网络输出的。
热身:使用矩阵计算网络输出
先介绍一个网络权重和偏置值的数学表示:$w_{jk}^l$,左侧的数学表达式表示第 $l$ 层网络的第 $j$ 个元素和第 $l-1$ 层第 $k$ 个元素之间的权重。同样的,$b_j^l$ 表示第 $l$ 层第$j$个元素的偏置值,$a_j^l$ 表示 $l$ 层第 $j$ 个元素的激活函数输出。利用这种数学表示,$a_j^l$ 可以表示为:
$$
a_j^l = \sigma(\sum_k w_{jk}^l a_k^{l-1} + b_j^l) \tag{1}
$$
使用矩阵形式表示上述表达式:
$$
a^l = \sigma(w^l a^{l-1} + b^l) \tag{2}
$$
定义 $z^l = w^l a^{l-1} + b^l$ 为激活函数的输入值则可以将上面表达式$(2)$ 表示为:
$$
a^l = \sigma(z^l) \tag{3}
$$
损失函数的两个要求
BP 算法用于计算网络中所有权重 $w$ 和偏置 $b$ 关于损失函数 $C$ 的偏导数 $\frac{\partial C}{\partial w}$和$\frac{\partial C}{\partial b}$。为了使BP算法正常运行,我们需要对损失函数做两条约束。我们先给出一个常用的均方差损失函数,如下式$(4)$:
$$
C = \frac 1{2n} \sum_x \Vert y(x) - a^L(x) \Vert ^2 \tag{4}
$$
表达式 $(4)$ 中元素解释如下, $n$ 是训练网络的样本个数;$y(x)$ 是训练样本 $x$ 的期望值(也就是样本的标签);$L$ 标识着网络的层数;$a^L = a^L(x)$ 是网络在输入为 $x$ 时输出层激活函数的输出。
现在描述我们对损失函数的要求。首先,损失函数可以写成所有训练样本损失值均值的形式:$C = \frac {1}{n} \sum_x C_x$ 。
我们做上面的要求是因为训练的过程中我们常常使用批训练的方式,而不是每次只训练一个样本。批训练之后我们求当前批次样本损失值的平均数来更新权重和偏置。
其次,损失函数可以使用网络输出层作为参数:$\C = C(a^L)$,$a^L$ 是网络输出层的输出。以均方差损失函数为例,当样本为$x$时,网络的损失值为:
$$
C = \frac 1 2 \Vert y-a^L \Vert ^2 = \frac 1 2 \sum_j(y_j-a_j^L)^2 \tag{5}
$$
上式中所有元素的值都是已知的,$y$ 是标签、$a_j^L$ 是网络输出层的输出。
Hadamard 积,$s \odot t $
Hadamardd 积(哈达玛积)表示矩阵按对应元素做乘法:$(s \odot t)_j = s_j t_j$,例如:
$$
\begin{vmatrix}
1 \
2
\end{vmatrix} \odot \begin{vmatrix}
3 \
4
\end{vmatrix} = \begin{vmatrix}
13 \
24
\end{vmatrix} = \begin{vmatrix}
3 \
8
\end{vmatrix}
$$
BP 算法依赖的四个方程
BP 算法用于计算网络中权值与偏置关于损失值的偏导,也就是计算:$\frac{\partial C}{\partial w_{jk}^l}$和$\frac{\partial C}{\partial b_j^l}$ 。在给出计算方法前我们先引入一个中间变量 $\delta_j^l$,这个变量表示网络第 $l$ 层第 $j$ 个元素的值对整个网络损失的贡献。BP 算法可以帮我们计算出 $\delta_j^l$ ,然后我们就可以得到$\frac{\partial C}{\partial w_{jk}^l}$和$\frac{\partial C}{\partial b_j^l}$ 。
为了便于理解,这里我们假设网络中的某个神经元(第 $l$ 层 第$j$ 个)旁边住着一个小恶魔,它可以帮我们调整神经元的输出。小恶魔不出手时这个神经元的输入为:$ z_j^l$,小恶魔出手后,当前神经元的输入为:$ z_j^l + \Delta z_j^l$,输出为 $\delta (z_j^l + \Delta z_j^l)$。小恶魔对当前神经元的调整最终将影响整个网络的输出,小恶魔出手后对整个网络损失值的影响为:$\frac {\partial C} {\partial z_j^l} \Delta _j^l$。
如果这是一个善良的小恶魔,那么它可以帮我们调整输入一减少损失函数的值。如果$\frac {\partial C} {\partial z_j^l}$ 的值不为0,那么调整$ z_j^l = z_j^l - \eta \frac {\partial C} {\partial z_j^l} \Delta z_j^l$,将减小整个网络的损失值。如果$\frac {\partial C} {\partial z_j^l}$的值为0,那么小恶魔的调整对网络损失的贡献就非常小,除非$\Delta z_j^l$比较大。
我们定义$\delta_j^l$如下:
$$
\delta \equiv \frac {\partial C} {\partial z_j^l} \tag{6}
$$
时$(6)$的矩阵表示方法为:$\delta ^l$。BP 算法可以帮助我们计算网络中每一层的 $\delta ^l$。