Cyan's Blog

Search

Search IconIcon to open search

为什么反向传播比前向传播更高效

Last updated Unknown Edit Source

找到了一个很好的解释:

为什么说反向传播算法很高效?要回答这个问题,让我们来考虑另一种计算梯度的方式。设想现在是神经网络研究的早期阶段,大概是在上世纪50年代或60年代左右,并且你是第一个想到使用梯度下降方法来进行训练的人!但是要实现这个想法,你需要一种计算代价函数梯度的方式。你回想了你目前关于演算的知识,决定试一下是否能用链式法则来计算梯度。但是琢磨了一会之后发现,代数计算看起来非常复杂,你也因此有些失落。所以你尝试着寻找另一种方法。你决定把代价单独当做权重的函数$C=C(w)$(我们一会再来讨论偏置)。将权重写作$w1,w2,…$,并且要对某个权重计算$∂C/∂w_j$。一个很明显的计算方式是使用近似: $$\frac{\partial C}{\partial w_{j}} \approx \frac{C\left(w+\epsilon e_{j}\right)-C(w)}{\epsilon}$$ 其中$\epsilon$是一个大于零的极小数, $e_j$是第$j$个方向上的单位向量。换句话说,我们可以通过计算两个差距很小的$w_j$的代价,然后利用上面的等式来估计$∂C/∂w_j$。我们可以利用相同的思想来对偏置求偏导$∂C/∂b$。

这种方式看起来很不错。它的概念很简单,实现起来也很简单,只需要几行代码。当然了,他看起来要比使用链式法则来计算梯度靠谱多了!

然而遗憾的是,虽然这种方式看起来很美好,但当用代码实现之后就会发现,它实在是太慢了。要理解其中的原因的话,设想在我们的神经网络中有一百万个权重,对于每一个不同的权重$w_j$,为了计算$C(w+ϵe_j)$,我们需要计算$∂C/∂w_j$。这意味着为了计算梯度,我们需要计算一百万次代价函数,进而对于每一个训练样例,都需要在神经网络中前向传播一百万次。我们同样需要计算$C(w)$,因此总计需要一百万零一次前向传播。

反向传播的优点在于它仅利用一次前向传播就可以同时计算出所有的偏导$∂C/∂w_j$,随后也仅需要一次反向传播。大致来说,反向传播算法所需要的总计算量与两次前向传播的计算量基本相等(这应当是合理的,但若要下定论的话则需要更加细致的分析。合理的原因在于前向传播时主要的计算量在于权重矩阵的乘法计算,而反向传播时主要的计算量在于权重矩阵转置的乘法。很明显,它们的计算量差不多)。这与基于等式(46)的方法所需要的一百万零一次前向传播相比,虽然反向传播看起来更复杂一些,但它确实更更更更更快。

这种加速方式在1986年首次被人们所重视,极大地拓展了神经网络能够适用的范围,也导致了神经网络被大量的应用。当然了,反向传播算法也不是万能的。在80年代后期,人们终于触及到了性能瓶颈,在利用反向传播算法来训练深度神经网络(即具有很多隐含层的网络)时尤为明显。在本书后面的章节中我们将会看到现代计算机以及一些非常聪明的新想法是如何让反向传播能够用来训练深度神经网络的。

Source: 为什么说反向传播算法很高效 · 神经网络与深度学习 原文无公式, 对照 英文原文: Neural networks and deep learning添加了公式