反向传播算法

反向传播等式为我们提供了一个计算代价函数梯度的方法。下面让我们明确地写出该算法:

  • 输入 x:计算输入层相应的激活函数值a^1。
  • 正向传播:对每个l=2,3,\ldots,L,计算z^l=w^la^{l-1}+b^l和a^l=\sigma(z^l)。
  • 输出误差 \delta^L:计算向量\delta^L=\nabla_a C \odot \sigma'(z^L)。
  • 将误差反向传播:对每个l=L-1,L-2,\ldots,2计算\delta^{l}=((w^{l+1})^T \delta^{l+1}) \odot \sigma'(z^{l})
  • 输出:代价函数的梯度为\frac{\partial C}{\partial w^l_{jk}} = a^{l-1}_k \delta^l_j和\frac{\partial C}{\partial b^l_j} = \delta^l_j
    通过以上算法就能看出它为什么叫反向传播算法。我们从最后一层开始,反向计算错误向量。在神经网络中反向计算误差可能看起来比较奇怪。但如果回忆反向传播的证明过程,会发现反向传播的过程起因于代价函数是关于神经网络输出值的函数。为了了解代价函数是如何随着前面的权重和偏置改变的,我们必须不断重复应用链式法则,通过反向的计算得到有用的表达式。

练习

  • 修改一个神经元后的反向传播

    假设我们修改了正向传播网络中的一个神经元,使得该神经元的输出为f(\sum_j w_j x_j + b),其中f是一个非sigmoid函数的函数。在这种情况下我们应该怎样修改反向传播算法?

  • 线性神经元的反向传播

    假设我们在整个神经网络中用\sigma(z) = z代替常用的非线性方程\sigma。重新写出这种情况下的反向传播算法。

正如我在上文中已经说过的,反向传播算法对每个训练样本计算代价函数的梯度。在实际情况中,经常将反向传播算法与诸如随机梯度下降的学习算法共同使用,在随机梯度下降算法中,我们需要计算一批训练样本的梯度。给定一小批(mini-batch)个训练样本,下面的算法给出了基于这些训练样本的梯度下降学习步骤:

  • 输入一组训练样本
  • 对每个训练样本 x:设定相应的输入激活值a^{x,1}并执行以下步骤:
    • 正向传播:对于每个l=2,3,\ldots,L,计算z^{x,l} = w^l a^{x,l-1}+b^l和a^{x,l} = \sigma(z^{x,l})。
    • 输出误差\delta^{x,L}:计算向量\delta^{x,L} =\nabla_a C_x \odot \sigma'(z^{x,L})。
    • 将误差反向传播:对每个l=L-1,L-2,\ldots,2,计算\delta^{x,l} = ((w^{l+1})^T \delta^{x,l+1}) \odot \sigma'(z^{x,l})。
  • 梯度下降:对每个l = L, L-1, \ldots, 2,分别根据法则w^l \rightarrow w^l-\frac{\eta}{m} \sum_x \delta^{x,l} (a^{x,l-1})^T和b^l \rightarrow b^l-\frac{\eta}{m} \sum_x \delta^{x,l}更新权重和偏置。
    当然,为了在实际应用时实现随机梯度下降,你还需要一个用于生成小批(mini-batches)训练样本的外部循环和一个用于逐步计算每一轮迭代的外部循环。为了简洁,这些都被省略了。

原文: https://hit-scir.gitbooks.io/neural-networks-and-deep-learning-zh_cn/content/chap2/c2s6.html