BP算法(反向传播算法)
反向传播算法的核心是偏微分表达式$\partial C / \partial w$,也就是计算网络中损失函数C对任意权重$w$(或者是偏移$b$)的偏微分。这个表达式告诉我们当我们改变权重$w$和偏移$b$的时候,损失函数的变化有多快。尽管这个表达式有点复杂,但是它也有优点。其中每个元素都有一个神经元,有直观的解释。它实际上帮助我们洞察了当权重和偏移变化的时候整个网络是如何变化的。因此值得深究。
两个假设 反向传播算法的目标是计算两个偏微分:
\partial C /\partial w
\partial C /\partial b
要使得反向传播算法有效,我们必须对损失函数的形式有两个假设。假设损失函数的形式如下:
C = \frac{1}{2n} \sum_x||y(x)-a^L(x)||^2
其中,$n$是训练集的数量,$y=y(x)$是相应的期望的输出(实际输出),L表示神经网络的层数,$a^L=a^L(x)$是$x$为输入的时候神经网络的输出。
对于该损失函数的第一个假设是成本函数可以写成一个求平均的格式:
C=\frac{1}{n}\sum_xC_x
这是一个二次损失函数的例子,对于单个训练集的损失函数为:
C_x = \frac{1}{2} ||y-a^L||^2
需要这个假设的意义在于反向传播算法实际上计算的是对于单个训练集的偏微分,即$\partial C_x/\partial w$和$\partial C_x / \partial b$。记住一点,在计算反向传播的时候,y和x都是已知的,我们的目的是计算在当前训练集和输出的情况下,偏微分量结果。 第二个假设是Hadamard乘积。
反向传播算法的四个基本公式
反向传播算法的目标是为了计算偏微分,这里我们引入一个中间变量$\delta_j^l$,它表示第$l$层的第$j$个神经元的误差:
\delta_j^l = \frac{\partial C}{ \partial z_j^l}
这里的$z_j^l$就是第$l$层的第$j$个神经元的前向传播的值,即:
z_j^l = w^l * a^{l-1} + b^l
其中,$a^{l-1}$是第$l-1$层的激活函数的结果。我们使用$\delta^l$表示第$l$层的误差向量。它的含义就是,第$l$层第$j$个神经元的输出变化的时候,损失函数如何变化。
接下来我们看一下输出层(第$L$层)的例子:
\begin{aligned}
\delta^L &= \frac{\partial C}{\sigma(z^L)} \sigma'(z^L) \\
&\\
&= \frac{\partial C}{a^L}\sigma'(z^L)
\end{aligned}
一般情况下,我们定义的损失函数是:
C = \frac{1}{2} (y-a^L)^2
因此:
\frac{\partial C}{\partial a^L} = -(y-a^L)
那么,因此有:
\delta^L = (a^L-y) \odot \sigma'(z^L)
当$C$不是很依赖输出神经元$j$的时候,$\delta_j^L$就比较小,这也是我们期望的。右边第二个项$\sigma`(z_j^L)$,表明的是激活函数$\sigma$在$z_j^L$这一点的变化有多快。
现在我们考虑某个中间层的$\delta^l$变量。
\delta^l = \frac{\partial C}{\partial z^l}
注意到$a^l = g(z^l)$,$z^l=w^la^{l-1}+b^l$,因此这里有:
\begin{aligned}
\frac{\partial{C}}{\partial{z^l}} &= \frac{\partial{C}}{a^L} \frac{\partial{a^L}}{\partial{z^{L}}} \cdot
\frac{\partial{z^L}}{\partial{a^{(L-1)}}} \frac{\partial{a^{L-1}}}{\partial{z^{L-1}}}
\cdots
\frac{\partial{z^{l+1}}}{\partial{a^{l}}} \frac{\partial{a^{l}}}{\partial{z^{l}}} \\
&\\
&= \frac{\partial C}{\partial{z^{l+1}}} \cdot \frac{\partial{z^{l+1}}}{\partial{a^{l}}} \frac{\partial{a^{l}}}{\partial{z^{l}}}
\end{aligned}
注意到:
z^{l+1} = w^{l+1} a^l +b ^l
a^{l} = \sigma(z^l)
因此有:
\frac{\partial{z^{l+1}}}{\partial{a^{l}}} = w^{l+1}
\frac{\partial{a^{l}}}{\partial{z^{l}}} = \sigma'(z^l)
继续上式推导:
\begin{aligned}
\frac{\partial{C}}{\partial{z^l}} &= \frac{\partial C}{\partial{z^{l+1}}} \cdot w^{l+1} \cdot \sigma'(z^l)
\end{aligned}
至此,我们有一个新的公式:
\delta^l = \delta^{l-1}\cdot w^{l+1}\cdot \sigma'(z^l)
假设我们知道第$l+1$层的误差$\delta^{l+1}$,当我们使用权重矩阵的转置乘以这个误差的时候,我们可以认为是把错误向后传递。它提供了一种方式可以度量第$l$层输出的误差。
由于:
\begin{aligned}
z^l &= w^l * a^{l-1}+b^l \\
&\\
\frac{dz^l}{dw^l} &= a ^{l-1} \\
&\\
\frac{\partial{C}}{\partial w^l} &= \frac{\partial C}{z^l} \cdot \frac{\partial z^l}{\partial w^l} \\
&\\
&= \delta^l \cdot a^{l-1}
\end{aligned}
