深度学习与目标检测
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.4 后向传递

后向传递的核心思路是:从目标函数值开始,从输出层回溯到输入层,根据不同参数的影响更新神经网络的参数值,最终实现误差值最小化。这里的参数就是2.3节中提到的权重和偏移量。此时,这个问题就被转换为优化问题——如何计算不同参数对模型的影响,以及怎样尽可能降低它们的影响?一个常用的方法是将求导与梯度下降算法相结合。

梯度下降算法每次都在当前的梯度计算参数,然后让参数向着梯度的反方向前进一段距离,不断重复,直到梯度接近0时停止。此时,所有的参数恰好使损失函数达到极小值的状态。

2.4.1 后向传递的流程

后向传递算法可以理解为:梯度的计算顺序是从后往前的。它利用深度神经网络的结构进行计算,并不是一次计算所有参数的梯度,而是从后往前进行计算,首先计算输出层的梯度,接着计算第二个权重组的梯度,然后计算中间层的梯度,再计算第一个权重组的梯度,最后计算输入层的梯度。各层的计算结束后,就可以求出需要的路径的梯度了。这个过程相当于对链式求导法则求导。要想知道损失值对某个神经元的梯度,就看看有几条路径通向这个神经元,然后将这些路径的梯度累加即可。

2.4.2 梯度下降

梯度是指量场中某一点的梯度指向在这一点的标量场中增长最快的方向,它是一个矢量。梯度下降法是最常用的神经网络模型训练优化算法。深度学习模型大都采用梯度下降算法进行优化训练。下面通过一个实例简要介绍梯度下降。

我们以对一个简单的一元函数fx)=x2+5求极值问题为例。由于不知道该函数的极值,我们先随机取一个点,假如这个点是(5,30),显然我们可以判断这个点不是我们想要的极值点。然后,采取分别向该点两边取点的方法,即判断哪边的函数值更小,往值更小的那一边取点。假如我们取了x1=4和x2=6两个点,函数值分别为21和41,显然,应该向x1=4的方向继续取值。

但是,每次向两边取多少个值才合适呢?总不能每次取相同的跨度吧(这样做会有永远取不到极值的可能)。这时,我们应该灵活地改变取值的跨度,使用下式来更新取值。

在这里,η是学习率,也可以理解为步长。该值越大,每次移动的“步子”就越大;该值越小,每次移动的“步子”就越小。学习率是一个重要的参数,在网络训练中控制着通过对权值的更新使得误差降到最低的速度。大多数的优化算法都会使用学习率。为了提升梯度下降算法的性能,我们需要把学习率的值设定在合适的范围内,这是因为学习率过大或过小都对整个网络不利。如果学习率过大,很可能会跳过最优值;如果学习率过小,网络优化的时间会非常长,效率也会非常低,导致长时间无法收敛。

然而,在我们根据损失函数和训练的整体需求选择合适的学习率之后,就一定不会出问题了吗?答案是否定的。在实际训练过程中很可能出现这样的情况:训练集的损失下降到一定程度就不再下降了,有可能在两个值之间振荡。此时,很多人会想到要降低学习率,但学习率的降低势必会使训练时间变长。在这里提出一个可以平衡两者矛盾的解决方案——学习率衰减(learning rate decay)。它的基本思想是让学习率随训练的进行而衰减,有两种基本实现方法,分别是线性衰减和指数衰减。

介绍了学习率之后,继续解释之前的更新公式。这也是一个迭代的过程。

是函数在该点的导数,在靠近极值时,导数值会变小,因此更新的差值也会变小。扩展到二元乃至多元函数,更新的维度变多了,不止有一个方向会对极值点的选取产生影响。以二元函数fxy)为例,更新公式就变成了两个:

在这里,为函数fxy)关于x的偏导数,分别求不同方向的切线的斜率。类比一元函数的例子我们应该可以理解:任取一个初始值,然后从两个方向同时进行更新,直至fxy)收敛到极值。

如果有多个变量,就更容易理解了。假设某函数有kw变量,分别对每个w进行更新,wn代表第nw变量,ii+1表示更新的次数,更新后的公式为

不难发现,求梯度就是对每个自变量求偏导数,然后将其偏导数作为自变量方向的坐标。

梯度下降法是一种迭代算法,经常用于求凸函数的极小值。由于其计算效率高,在机器学习中经常使用。与其对应的有用于求极大值的梯度上升(gradient ascent)法。这两种方法的原理一样,只是计算过程中的正负号不同。

在神经网络训练过程中运用梯度下降法时,只要结合高等数学中的链式求导法则,分别对训练模型中的每个参数求偏导数,不断地更新参数(参数的更新过程会在2.4.3节具体说明),就能得到一组参数,使模型的损失降到最小。

2.4.3 参数修正

本节以一个三层神经网络来具体说明后向传递算法中参数的更新过程[2]

表示第l层的第j个神经元的输入,表示第l层的第j个神经元的输出,表示第l-1层的第k个神经元指向第l层的第j个神经元的权值,表示第l层的第j个神经元的偏移量,激活函数为σ,损失函数为C。在同一层的输入与输出之间,存在如下关系。

在后向传递算法中,我们需要求出损失函数对每个参数的偏导数。但是,我们并不是直接求偏导数的,而是定义一个损失来代表第l层的第j个神经元产生的误差,先逐层向后传播,得到每层神经元节点的损失,再通过每个节点的损失求该节点的参数的偏导数的。

首先,求出最后一层神经元产生的损失。将其向量化后,公式为

从后往前计算每一层神经元产生的损失,公式为

在这一步,中对k的求和符号的含义是进一步推导公式。同时,添加了第l层全部神经元的输入值,即k在这里只代表其中的一个神经元,但是我们需要考虑第l层的所有神经元。

因为,所以。在这里要说明一下为什么求导之后就没有求和符号了。虽然第l-1层的每个输出神经元对第l层的第k个神经元的输入值都有影响,但是我们目前只关心第l-1层的第j个神经元对第l层各个神经元的输入值产生了多大的影响,所以,对求导之后,就不需要求和符号了。化简后,得到下式。

将其向量化后,公式为

l-1为l,则上式中的l变为l+1后得到公式

接下来,求权值和偏置值的梯度。

求权值的梯度,公式如下。

求偏置值的梯度,公式如下。

综上所述,深度神经网络的参数修正流程如下。

①对样本进行前向传递,得到预测的输出值。

xl=wlyl-1+bl

yl=σ(xl)

②计算最后的输出层产生的误差。

③进行后向传递,得到每一层产生的误差。

④根据产生的误差,得到相应的梯度,进而进行参数的修正。