![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=1738941827-GeNcFRX0N62AwJMXNgxkomqPGHyS3YLS-0-b06f2fe23d127017bf300cf4d801a501)
图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=1738941827-8XSs5nku4kbnklpw4Kf9J6RXsQnVf4TX-0-99079c760fac9015237796f326acc87c)
图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=1738941827-Kh1eodN1zi3MACmojS0K7BSw64wi5uQt-0-9beb4285b47a56550865a39c5f8c4b5e)
我们如果直接使用链式法则进行求导就会遇到一个问题,当路径数量增加时,式(2.5)中的子项目数会呈指数增长,所以这时我们需要把上式右侧部分进行合并,合并后,我们只需要进行一次乘法就可以获得所需要的结果,这样大幅度提升了模型的运算效率,合并后的式子如下:
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/521.jpg?sign=1738941827-IUWQEFlwZwCqepJhDkwPnyA6qb3BkqRo-0-7cbc5297d46e72a4055e82b293c5ee6d)
接下来,我们解决式(2.6)的实现问题。根据计算方向的不同,可以分为正向微分与反向微分。我们先看针对图2-16的正向微分算法,如图2-17所示。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/524.jpg?sign=1738941827-G1wUE6VB1AlGRy4OH2fOkK0mgOHyS3Je-0-b563b29d9b69f67b6db9f31cb81333d0)
图2-17 正向微分算法
可以看到,正向微分算法根据路径的传播方向,依次计算路径中的各结点对输入X的偏导数,结果中保留了输入对各结点的影响。
下面,我们看一下反向微分算法(见图2-18)。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/525.jpg?sign=1738941827-o43AJE8KwG3hK4lYK38nOXnQOAbxvfIc-0-077debb73e04332a53148bc1245da54d)
图2-18 反向微分算法
可以看到,该算法从后向前进行计算,结果中保留了路径中各结点对输出的影响。
这里就有一个问题了,既然正向反向都可以实现式(2.6)的计算,那么我们应该选择哪个算法来实现呢?答案是反向微分算法,理由如下:
首先我们看一个计算式子e=(a+b)∗(b+1)的图模型(见图2-19)。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/526.jpg?sign=1738941827-7CFNtAWeJhrbYhqkQ0Ncypv783u9fjXo-0-e5777695cd66f629e9e89cdc8032b995)
图2-19 图模型计算示例
其中,c,d表示中间结果,边的方向表示一个结点是另一个结点的输入。
假设输入变量a=2、b=1,图2-19中各结点的偏导计算结果如图2-20所示。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/527.jpg?sign=1738941827-22mFDCb2LmDVZAhRunfZ2VhwcreknTrz-0-339674593c50bd7eb56476925de36afd)
图2-20 利用正向微分算法得到各结点的偏导计算结果
利用正向微分算法,我们得到关于变量b的偏导计算结果如图2-21所示。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/528.jpg?sign=1738941827-bhF9gLZniHaNVUo5lvKytsayuLBmaxql-0-e36d2946b546b23884d4f4044efacb29)
图2-21 利用正向微分算法得到变量b的偏导计算结果
利用反向微分算法,我们得到的偏导计算结果如图2-22所示。
![](https://epubservercos.yuewen.com/57267A/15056703005210806/epubprivate/OEBPS/Images/529.jpg?sign=1738941827-xJFQ0sh9MSLIOjccc7Ns7YIQuvisdUct-0-42512da8f223a4585c71a27b72de1e0e)
图2-22 利用反向微分算法得到的偏导计算结果
由此可见,反向微分算法保留了所有变量(包括中间变量)对结果e的影响。若e为误差函数,则对图进行一次计算,可以得出所有结点对e的影响,也就是梯度值,下一步就可以利用这些梯度值来更新边的权重值了;而正向微分算法得到的结果是只保留了一个输入变量对误差e的影响,显然,想要获得多个变量对e的影响,我们就需要进行多次计算。所以正向微分算法在效率上明显不如反向微分,这也是我们选择反向微分算法的原因。