![TensorFlow与自然语言处理应用](https://wfqqreader-1252317822.image.myqcloud.com/cover/741/26542741/b_26542741.jpg)
2.9 反向传播
理解反向传播(Backpropagation)算法可能需要一些时间,读者也可以跳过本节内容,因为很多软件库都具有自动区分和执行整个训练过程的能力。但是,理解这个算法肯定会让你深入了解与深度学习相关的问题(学习问题、缓慢学习、梯度爆炸、梯度下降)。
让我们首先看一张典型的神经网络结构图,如图2-15所示。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/522.jpg?sign=1738846869-ysobC2H88LX51l28pAlaFpolctxNp2jR-0-fc0d60c38110741ff8e7bd81693adabb)
图2-15 神经网络结构图
图2-15是一个包含了输入层L1、隐藏层L2和输出层L3的简单神经网络,它的处理流程为根据输入层的input以及相应的权重值和配置(图中黑色带箭头的边),通过隐藏层的加工,最终将结果映射到输出层得到结果的输出。模型可以抽象表示为y=f(x),x,y分别表示输入和输出向量。
根据神经网络的处理流程,我们如果要得到输出y,就必须知道图2-15中每条边的参数值,这也是神经网络中最重要的部分。在神经网络中是通过迭代的方法来计算这些参数的,具体来讲就是,首先初始化这些参数,通过神经网络的前向传导过程来计算得到输出y,但这些值与真实值存在着误差,我们假设累计误差函数为err(x),然后利用梯度方法极小化err(x)来更新参数,直至误差值达到符合要求而停止计算。在更新参数这一过程中,我们就用到了著名的反向传播算法。
为了更好地去说明神经网络的传播算法,我们这里取图2-15中的一条路径来做说明,但这不失一般性,假设路径如图2-16所示。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/523.jpg?sign=1738846869-qT7GXParxwP0kbxGW55gyhrTVgoXeB48-0-273ac336a8bb73f8cd124c1768978505)
图2-16 神经网络传播路径示例
图2-16中的边表示偏导数,如α=(∂Y⁄∂X)。
想要知道输入X对输出Z的影响,我们可以用偏导数(∂Z⁄∂X)=(∂Z⁄∂Y)⋅(∂Y⁄∂X),即:
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/520.jpg?sign=1738846869-zVqJLHz88Zy6quIgxWg1a3Bg7XxOO1fu-0-fe80462916511cb2a771e2e0a91167ce)
我们如果直接使用链式法则进行求导就会遇到一个问题,当路径数量增加时,式(2.5)中的子项目数会呈指数增长,所以这时我们需要把上式右侧部分进行合并,合并后,我们只需要进行一次乘法就可以获得所需要的结果,这样大幅度提升了模型的运算效率,合并后的式子如下:
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/521.jpg?sign=1738846869-0hwuQMZglZxISOorh7jFxRFYYyUr21Wl-0-ecf51b2ad2e031b00d974fa661e5ece1)
接下来,我们解决式(2.6)的实现问题。根据计算方向的不同,可以分为正向微分与反向微分。我们先看针对图2-16的正向微分算法,如图2-17所示。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/524.jpg?sign=1738846869-do9coG9Z49nKF8cQTUvseXpdgZTzbAcL-0-aa4592fd11d1bf39a379eeb892c37c81)
图2-17 正向微分算法
可以看到,正向微分算法根据路径的传播方向,依次计算路径中的各结点对输入X的偏导数,结果中保留了输入对各结点的影响。
下面,我们看一下反向微分算法(见图2-18)。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/525.jpg?sign=1738846869-pL3J9HHzJRFngHo0QSWFdaPrwbIrKRKW-0-74847431d58fef5a95525b3aa13dd727)
图2-18 反向微分算法
可以看到,该算法从后向前进行计算,结果中保留了路径中各结点对输出的影响。
这里就有一个问题了,既然正向反向都可以实现式(2.6)的计算,那么我们应该选择哪个算法来实现呢?答案是反向微分算法,理由如下:
首先我们看一个计算式子e=(a+b)∗(b+1)的图模型(见图2-19)。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/526.jpg?sign=1738846869-tppPAj3GzRSLnPbtpapHkrdAc6Gcwa1R-0-e16cc6c29b62d34aaa73af8db898cd62)
图2-19 图模型计算示例
其中,c,d表示中间结果,边的方向表示一个结点是另一个结点的输入。
假设输入变量a=2、b=1,图2-19中各结点的偏导计算结果如图2-20所示。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/527.jpg?sign=1738846869-EkLPJmW3MnYo7rs1HdyJQk4tatHb3Eeb-0-b2cb2f04a157909f1b99a5cccfd321f9)
图2-20 利用正向微分算法得到各结点的偏导计算结果
利用正向微分算法,我们得到关于变量b的偏导计算结果如图2-21所示。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/528.jpg?sign=1738846869-xkePQceigaGUbgItoxJ8SRLq290KzEOt-0-d7a20510819106511fda8c0e269bc7ae)
图2-21 利用正向微分算法得到变量b的偏导计算结果
利用反向微分算法,我们得到的偏导计算结果如图2-22所示。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/529.jpg?sign=1738846869-DkE6XtzxdGuNytt6kjMndwlN668C2diu-0-0bff67b6914d86be63d2c85593505c59)
图2-22 利用反向微分算法得到的偏导计算结果
由此可见,反向微分算法保留了所有变量(包括中间变量)对结果e的影响。若e为误差函数,则对图进行一次计算,可以得出所有结点对e的影响,也就是梯度值,下一步就可以利用这些梯度值来更新边的权重值了;而正向微分算法得到的结果是只保留了一个输入变量对误差e的影响,显然,想要获得多个变量对e的影响,我们就需要进行多次计算。所以正向微分算法在效率上明显不如反向微分,这也是我们选择反向微分算法的原因。