如何直观地、形象地理解反向传播?经常有人这么问。言下之意是,不看数学公式如何理解反向传播?我的答案是,即使可以“形象地”理解反向传播,也是似懂非懂,根基不牢。数学推导才是正道,只要会求偏导数,理解反向传播其实不难。

复合函数角度

首先从复合函数的角度推导。材料来自南京大学吴建鑫教授的Introduction to Convolutional Neural Networks。任何深度神经网络都可以抽象成一系列复合函数。记第一层的输入是$x^{1}$,输出是$x^{2}$(也是第二层的输入),参数是$w^{1}$。以此类推,最后一层(最外面的函数)的输入是$x^{L}$,输出是$z$,参数是$w^{L}$。最后一层是计算损失的层,$z$是损失。

参数通过随机梯度下降更新:

也就是说,对每个参数的更新,都要知道损失对该参数的偏导数。反向传播就是干这个的。

假设我们想求 $\frac{\partial z}{\partial w^{i}}$,我们要把它跟第$i+1$层联系起来:

这是一个简单的链式法则。其中 $\frac{\partial x^{i+1}}{\partial w^{i}}$ 是第$i$层的输出对该层参数的偏导,如果知道 $x^{i+1}$ 就可以直接计算,这就要求我们存储每一层的输出。然后我们要计算 $\frac{\partial z}{\partial x^{i+1}}$ ,如果 $x^{i+1}$ 是最后一层的输入,那么 $\frac{\partial z}{\partial x^{i+1}}$ 可以直接计算。如果 $x^{i+1}$ 不是最后一层的输入怎么办呢?这就要求我们存储损失对每一层输入的偏导。所以我们还需要另一个式子:

这里 $\frac{\partial z}{\partial x^{i+1}}$ 是之前计算好的已经存储起来,$\frac{\partial x^{i+1}}{\partial x^{i}}$ 可以直接计算。

梳理一遍:从最后一层开始,计算损失对该层参数的偏导和对该层输入的偏导并存储起来。对于每层的两个偏导计算,都需要上一层的计算结果。这个过程一直进行到第一层,它是”反向”的,偏导一直向第一层“传播”。

神经网络角度

复合函数角度是宏观,神经网络角度是微观。复合函数角度是道,神经网络角度是术。材料来自南京大学周志华教授的《机器学习》。假设我们训练多层前馈神经网络,有$d$个输入神经元,$l$个输出神经元,$q$个隐层神经元。隐层和输出层都用Sigmoid ($\sigma$) 作为激活函数。训练集 $D = { (x^1,y^1),(x^2,y^2),…,(x^m,y^m)}$。如下图所示:

BP

变量符号如下:

  • $\theta_j$:输出层第$j$个神经元的阈值。
  • $\gamma_h$:隐层第$h$个神经元的阈值。
  • $v_{ih}$: 输入层第$i$个神经元与隐层第$h$个神经元之间的连接权。
  • $w_{hj}$: 隐层第$h$个神经元与输出层第$j$个神经元之间的连接权。
  • $\alpha_h = \sum_{i=1}^{d}v_{ih}x_i$:隐层第$h$个神经元接收到的输入。
  • $b_h$:隐层第$h$个神经元的输出。
  • $\beta_j = \sum_{h=1}^{q}w_{hj}b_h$:输出层第$j$个神经元接收到的输入。

对训练样例 $(x_k,y_k)$,假定神经网络的输出为 $\hat y_k = (\hat y_1^k,\hat y_2^k,..,\hat y_l^k)$,即

则均方误差为:

同样,要用随机梯度下降更新参数,我们就需要知道误差对所有$w,\theta,v,\gamma$的偏导数。下面依次计算。

计算 $\frac{\partial E_k}{\partial w^{hj}}$ :

其中,对于特定的$w_{hj}$:

Sigmoid函数有一个很好的性质:

根据(1)(2),有:

由(3)(4)(5)(6),得:

计算 $\frac{\partial E_k}{\partial \theta_{j}}$ :

类似(6):

由(7)(5)(8)可得:

计算 $\frac{\partial E_k}{\partial v_{ih}}$ :

$v_{jh}$ 先影响到第$h$个隐层神经元的输入 $\alpha_h$,再影响该神经元的输出$b_h$,再影响到所有输出层神经元的输入,最后影响到$E_k$。有:

由(5)(6)得:

对于特定的$j$:

类似(6):

类似(4):

由(9)abcd得:

计算 $\frac{\partial E_k}{\partial \gamma_h}$ :

类似(8):

由eabf得:

总结

到这里所有的计算都完成了。借用复合函数角度的概念,第$L$层是损失层,不需要计算偏导数。$w^{L-1}$ 就是 $w$ 和 $\theta$,$x^{L-1}$ 就是 $\beta$ 。神经网络的例子里直接往前计算了两层,可以发现有的结果重复使用,就像复合函数角度里那样。如果网络更深,可以想象像(9)和(e)这样的式子会更长,好在程序实现的时候可以重复使用之前的结果,不必每次都计算超长的算式。反向传播的精髓除了链式法则,还有计算足迹储存以备重复使用,这一点像递归,也像动态规划。