最受欢迎的算法之一:反向传播训练

反向传播是训练神经网络的最常用方法之一。Rumelhart、Hinton和Williams(1986)引入了反向传播,该方法到今天仍然很流行。程序员经常使用反向传播训练深层神经网络,因为在图形处理单元上运行时,它的伸缩性很好。要了解这种用于神经网络的算法,我们必须探讨如何训练它,以及它如何处理模式。

经典的反向传播已得到扩展和修改,产生了许多不同的训练算法。本章中将讨论神经网络最常用的训练算法。我们从经典的反向传播开始,然后以随机梯度下降结束本章。

6.1 理解梯度

反向传播是梯度下降的一种,许多教科书中通常互换使用这两个术语。梯度下降是指针对每个训练元素,在神经网络中的每个权重上计算一个梯度。由于神经网络不会输出训练元素的期望值,因此每个权重的梯度将为你提示如何修改权重以实现期望输出。如果神经网络确实输出了预期的结果,则每个权重的梯度将为0,这表明无需修改权重。

梯度是权重当前值下误差函数的导数。误差函数用于测量神经网络输出与预期输出的差距。实际上,我们可以使用梯度下降,在该过程中,每个权重的梯度可以让误差函数达到更低值。

梯度实质上是误差函数对神经网络中每个权重的偏导数。每个权重都有一个梯度,即误差函数的斜率。权重是两个神经元之间的连接。计算误差函数的梯度可以确定训练算法应增加,还是减小权重。反过来,这种确定将减小神经网络的误差。误差是神经网络的预期输出和实际输出之间的差异。许多不同的名为“传播训练算法”的训练算法都利用了梯度。总的来说,梯度告诉神经网络以下信息:

  • 零梯度——权重不会导致神经网络的误差;
  • 负梯度——应该增加权重以减小误差;
  • 正梯度——应当减小权重以减小误差。

由于许多算法都依赖于梯度计算,因此我们从分析这个过程开始。

 6.1.1 什么是梯度

首先,让我们探讨一下梯度。本质上,训练是对权重集的搜索,这将使神经网络对于训练集具有最小的误差。如果我们拥有无限的计算资源,那么只需尝试各种可能的权重组合,来确定在训练期间提供最小误差的权重。

因为我们没有无限的计算资源,所以必须使用某种快捷方式,以避免需要检查每种可能的权重组合。这些训练算法利用了巧妙的技术,从而避免对所有权重进行蛮力搜索。但这种类型的穷举搜索将是不可能的,因为即使小型网络也具有无限数量的权重组合。

请考虑一幅图像,它展示每个可能权重的神经网络误差。图6-1展示了单个权重的误差。

最受欢迎的算法之一:反向传播训练_第1张图片

 

图6-1 单个权重的误差

从图6-1中很容易看到,最佳权重是曲线的

 

(

 

)值最低的位置。问题是我们只看到当前权重的误差;我们看不到整幅图像,因为该过程需要穷尽的搜索。但是,我们可以确定特定权重下误差曲线的斜率。在图6-1中,我们看到误差曲线在

 

=1.5处的斜率。与误差曲线相切(在

 

=1.5处)的直线给出了斜率。在这个例子中,斜率或梯度为−0.562 2。负斜率表示增大权重会降低误差。

梯度是指在特定权重下误差函数的瞬时斜率。误差曲线在该点的导数给出了梯度。这条线的倾斜程度告诉我们特定权重下误差函数的陡峭程度。

导数是微积分中最基本的概念之一。对于本书,你只需要了解导数在特定点处提供函数的斜率即可。训练技巧和该斜率可以为你提供信息,用于调整权重,从而降低误差。现在,利用梯度的实用定义,我们将展示如何计算它。

 6.1.2 计算梯度

我们将为每个权重单独计算一个梯度。我们不仅关注方程,也关注梯度在具有真实数值的实际神经网络中的应用。图6-2展示了我们将使用的神经网络——XOR神经网络。

最受欢迎的算法之一:反向传播训练_第2张图片

 

图6-2 XOR神经网络

此外,本书线上资源(见引言)的几个示例中使用了相同的神经网络。在本章中,我们将展示一些计算,说明神经网络的训练。我们必须使用相同的起始权重,让这些计算保持一致。但是,上述权重没有什么特征,是由该程序随机生成的。

前面提到的神经网络是典型的三层前馈神经网络,就像我们之前研究的那样,圆圈表示神经元,连接圆圈的线表示权重,连接线中间的矩形给出每个连接的权重。

我们现在面临的问题是,计算神经网络中每个权重的偏导数。当一个方程具有多个变量时,我们使用偏导数。每个权重均被视为变量,因为这些权重将随着神经网络的变化而独立变化。每个权重的偏导数仅显示每个权重对误差函数的独立影响。该偏导数就是梯度。

可以用微积分的链式规则来计算每个偏导数。我们从一个训练集元素开始。对于图6-2,我们提供[1,0]作为输入,并期望输出是1。你可以看到我们将输入应用于图6-2。第一个输入神经元的输入为1.0,第二个输入神经元的输入为0.0。

该输入通过神经网络馈送,并最终产生输出。第4章“前馈神经网络”介绍了计算输出与总和的确切过程。反向传播既有前向,也有反向。计算神经网络的输出时,就会发生前向传播。我们仅针对训练集中的这个数据项计算梯度,训练集中的其他数据项将具有不同的梯度。在后文,我们将讨论如何结合各个训练集元素的梯度。

现在我们准备计算梯度。下面总结了计算每个权重的梯度的步骤:

  • 根据训练集的理想值计算误差;
  • 计算输出节点(神经元)的增量;
  • 计算内部神经元节点的增量;
  • 计算单个梯度。

我们将在随后的内容中讨论这些步骤。

6.2 计算输出节点增量

为神经网络中的每个节点(神经元)计算一个常数值。我们将从输出节点开始,然后逐步通过神经网络反向传播。“反向传播”一词就来自这个过程。我们最初计算输出神经元的误差,然后通过神经网络向后传播这些误差。

节点增量是我们将为每个节点计算的值。层增量也描述了该值,因为我们可以一次计算一层的增量。在计算输出节点或内部节点时,确定节点增量的方法可能会有所不同。首先计算输出节点,并考虑神经网络的误差函数。在本书中,我们将研究二次误差函数和交叉熵误差函数。

 6.2.1 二次误差函数

神经网络的程序员经常使用二次误差函数。实际上,你可以在网络上找到许多使用二次误差函数的示例。如果你正在阅读一个示例程序,但未提及具体的误差函数,那么该程序可能使用了二次误差函数,也称为MSE函数,我们在第5章“训练和评估”中讨论过。公式6-1展示了MSE函数:

 

(6-1)

公式6-1将神经网络的实际输出(

 

)与预期输出(

 

)进行了比较。变量

 

为训练元素的数量乘以输出神经元的数量。MSE将多个输出神经元处理为单个输出神经元的情况。公式6-2展示了使用二次误差函数的节点增量:

 

(6-2)

二次误差函数非常简单,因为它取了神经网络的预期输出与实际输出之间的差。

 

′表示激活函数的导数。

 6.2.2 交叉熵误差函数

二次误差函数有时可能需要很长时间才能正确调整权重。公式6-3展示了交叉熵误差(Cross-entropy Error,CE)函数:

 

(6-3)

如公式6-4所示,采用交叉熵误差函数的节点增量计算要比采用MSE函数简单得多。

 

(6-4)

交叉熵误差函数通常会比二次误差函数结果更好,因为二次误差函数会为误差创建一个陡峭的梯度。我们推荐采用交叉熵误差函数。

6.3 计算剩余节点增量

既然已经根据适当的误差函数计算了输出节点的增量,我们就可以计算内部节点的增量,如公式6-5所示:

 

(6-5)

我们将为所有隐藏和无偏置神经元计算节点增量,但无须为输入和偏置神经元计算节点增量。即使我们可以使用公式6-5轻松计算输入和偏置神经元的节点增量,梯度计算也不需要这些值。你很快会看到,权重的梯度计算仅考虑权重所连接的神经元。偏置和输入神经元只是连接的起点,它们从来不是终点。

如果你希望看到梯度计算过程,有几个JavaScript示例显示了这些计算过程。这些示例可以在以下URL中找到:

http://www.heatonresearch.com/aifh/vol3/

6.4 激活函数的导数

反向传播过程需要激活函数的导数,它们通常确定反向传播过程将如何执行。大多数现代深度神经网络都使用线性、Softmax和ReLU激活函数。我们还会探讨S型和双曲正切激活函数的导数,以便理解ReLU激活函数为何表现如此出色。

 6.4.1 线性激活函数的导数

线性激活函数被认为不是激活函数,因为它只是返回给定的任何值。因此,线性激活函数有时称为一致激活函数。该激活函数的导数为1,如公式6-6所示:

 

(6-6)

如前文所述,希腊字母

 

表示激活函数,在

 

右上方的撇号表示我们正在使用激活函数的导数。这是导数的几种数学表示形式之一。

 6.4.2 Softmax激活函数的导数

在本书中,Softmax激活函数和线性激活函数仅在神经网络的输出层上使用。如第1章“神经网络基础”所述,Softmax激活函数与其他激活函数的不同之处在于,其值还取决于其他输出神经元,而不仅仅取决于当前正在计算的输出神经元。方便起见,公式6-7再次展示了Softmax激活函数:

 

(6-7)

 

向量代表所有输出神经元的输出。公式6-8展示了该激活函数的导数:

 

(6-8)

对于上述导数,我们使用了稍微不同的符号。带有草书风格的符号的比率表示偏导数,当你对具有多个变量的方程进行微分时会使用这个符号。要取偏导数,可以将方程对一个变量微分,而将所有其他变量保持不变。上部的指出要微分的函数。在这个例子中,要微分的函数是激活函数

 

。下部的表示偏导数的分别微分。在这个例子中,我们正在计算神经元的输出,所有其他变量均视为常量。微分是瞬时变化率:一次只有一个变量能变化。

如果使用交叉熵误差函数,就不会使用线性或Softmax激活函数的导数来计算神经网络的梯度。通常你只在神经网络的输出层使用线性和Softmax激活函数。因此,我们无须担心它们对于内部节点的导数。对于使用交叉熵误差函数的输出节点,线性和Softmax激活函数的导数始终为1。因此,你几乎不会对内部节点使用线性或Softmax激活函数的导数。

 6.4.3 S型激活函数的导数

公式6-9展示了S型激活函数的导数:

 

(6-9)

机器学习经常利用公式6-9中表示的S型激活函数。我们通过对S型函数的导数进行代数运算来导出该公式,以便在其自身的导数计算中使用S型激活函数。为了提高计算效率,上述激活函数中的希腊字母

 

表示S型激活函数。在前馈过程中,我们计算了S型激活函数的值。保留S型激活函数的值使S型激活函数的导数易于计算。如果你对如何得到公式6-9感兴趣,可以参考以下网址:

http://www.heatonresearch.com/aifh/vol3/deriv_sigmoid.html

 6.4.4 双曲正切激活函数的导数

公式6-10给出了双曲正切激活函数的导数:

 

(6-10)

在本书中,我们建议使用双曲正切激活函数,而不是S型激活函数。

 6.4.5 ReLU激活函数的导数

公式6-11展示了ReLU激活函数的导数:

 

(6-11)

严格来说,ReLU激活函数在0处没有导数,但是,由于约定,当

 

为0时,0处的梯度被替换。具有S型和双曲正切激活函数的深层神经网络可能难以通过反向传播进行训练。造成这一困难的因素很多,梯度消失问题是最常见的原因之一。图6-3展示了双曲正切激活函数及其梯度/导数。

最受欢迎的算法之一:反向传播训练_第3张图片

 

图6-3 双曲正切激活函数及其梯度/导数

图6-3表明,当双曲正切激活函数(实线)接近−1和1时,双曲正切激活(虚线)的导数消失为0。S型和双曲正切激活函数都有这个问题,但ReLU激活函数没有。图6-4展示了S型激活函数及其消失的导数。

最受欢迎的算法之一:反向传播训练_第4张图片

 

图6-4 S型激活函数及其消失的导数

6.5 应用反向传播

反向传播是一种简单的训练算法,可以利用计算出的梯度来调整神经网络的权重。该方法是梯度下降的一种形式,因为我们将梯度降到较低的值。随着程序调整这些权重,神经网络将产生更理想的输出。神经网络的整体误差应随着训练而下降。在探讨反向传播权重的更新过程之前,我们必须先探讨更新权重的两种不同方式。

 6.5.1 批量训练和在线训练

我们已经展示了如何为单个训练集元素计算梯度。在本章的前面,我们对神经网络输入[1,0]并期望输出1的情况计算了梯度。对于单个训练集元素,这个结果是可以接受的,但是,大多数训练集都有很多元素。因此,我们可以通过两种方式来处理多个训练集元素,即在线训练和批量训练。

在线训练意味着你需要在每个训练集元素之后修改权重。利用在第一个训练集元素中获得的梯度,你可以计算权重并对它们进行更改。训练进行到下一个训练集元素时,也会计算并更新神经网络。训练将继续进行,直到你用完每个训练集元素为止。至此,训练的一个迭代或一轮(epoch)已经完成。

批量训练也利用了所有训练集元素,但是,我们不着急更新所有权重。作为替代,我们对每个训练集元素的梯度求和。一旦我们完成了对训练集元素梯度的求和,就可以更新神经网络权重。至此,迭代完成。

有时,我们可以设置批量的大小。如你的训练集可能有10 000个元素,此时可选择每1 000个元素更新一次神经网络的权重,从而使神经网络权重在训练迭代期间更新10次。

在线训练是反向传播的最初方式。如果要查看该程序批处理版本的计算,请参考以下在线示例:

http://www.heatonresearch.com/aifh/vol3/xor_batch.html

 6.5.2 随机梯度下降

批量训练和在线训练不是反向传播的仅有选择。随机梯度下降(SGD)是反向传播算法中最受欢迎的算法。SGD可以用批量或在线训练模式工作。在线SGD简单地随机选择训练集元素,然后计算梯度并执行权重更新。该过程一直持续到误差达到可接受的水平为止。与每次迭代遍历整个训练集相比,选择随机训练集元素通常会更快收敛到可接受的权重。

批量SGD可通过选择批量大小来实现。对于每次迭代,随机选择数量不应超过所选批量大小的训练集元素,因此选择小批量。更新时像常规反向传播批量处理更新一样,将小批量处理中的梯度相加。这种更新与常规批量处理更新非常相似,不同之处在于,每次需要批量时都会随机选择小批量。迭代通常以SGD处理单个批量。批量大小通常比整个训练集小得多。批量大小的常见选择是600。

 6.5.3 反向传播权重更新

现在,我们准备更新权重。如前所述,我们将权重和梯度视为一维数组。给定这两个数组,我们准备为反向传播训练的迭代计算权重更新。公式6-12给出了为反向传播更新权重的公式:

 

(6-12)

公式6-12计算权重数组中每个元素的权重变化。你也会注意到,公式6-12要求对来自上一次迭代的权重进行改变。你必须将这些值保存在另一个数组中。如前所述,权重更新的方向与梯度的符号相反:正梯度会导致权重减小,反之负梯度会导致权重增大。由于这种相反关系,公式6-12以负号开始。

公式6-12将权重增量计算为梯度与学习率(以ε表示)的乘积。此外,我们将之前的权重变化与动量值(以α表示)的乘积相加。学习率和动量是我们必须提供给反向传播算法的两个参数。选择学习率和动量的值对训练的表现非常重要。不幸的是,确定学习率和动量主要是通过反复试验实现的。

学习率对梯度进行缩放,可能减慢或加快学习速度。低于1.0的学习率会减慢学习速度。如学习率为0.5会使每个梯度减少50%;高于1.0的学习率将加速训练。实际上,学习率几乎总是低于1。

选择过高的学习率会导致你的神经网络无法收敛,并且会产生较高的全局误差,而不会收敛到较低值。选择过低的学习率将导致神经网络花费大量时间实现收敛。

和学习率一样,动量也是一个缩放因子。尽管是可选的,但动量确定了上一次迭代的权重变化中有百分之多少应该应用于这次迭代。如果你不想使用动量,只需将它的值指定为0。

动量是用于反向传播的一项技术,可帮助训练逃避局部最小值,这些最小值是误差图上的低点所标识的值,而不是真正的全局最小值。反向传播倾向于找到局部最小值,而不能再次跳出来。这个过程导致训练收敛误差较高,这不是我们期望的。动量可在神经网络当前变化的方向上对它施加一些力,让它突破局部最小值。

 6.5.4 选择学习率和动量

动量和学习率有助于训练的成功,但实际上它们并不是神经网络的一部分。一旦训练完成,训练后的权重将保持不变,不再使用动量或学习率。它们本质上是一种临时的“脚手架”,用于创建训练好的神经网络。选择正确的动量和学习率会影响训练的效果。

学习率会影响神经网络训练的速度,降低学习率会使训练更加细致。较高的学习率可能会跳过最佳权重设置,较低的学习率总是会产生更好的结果,但是,降低训练速度会大大增加运行时间。在神经网络训练中降低学习率可能是一种有效的技术。

你可以用动量来对抗局部最小值。如果你发现神经网络停滞不前,则较高的动量值可能会使训练超出其遇到的局部最小值。归根结底,为动量和学习率选择好的值是一个反复试验的过程。你可以根据训练的进度进行调整。动量通常设置为0.9,学习率通常设置为0.1或更低。

 6.5.5 Nesterov动量

由于小批量引入的随机性,SGD算法有时可能产生错误的结果。权重可能会在一次迭代中获得非常有益的更新,但是训练元素的选择不当会使其在下一个小批量中被撤销。因此,动量是一种资源丰富的工具,可以减轻这种不稳定的训练结果。

Nesterov动量是Yu Nesterov在1983年发明的一种较新的技术应用,该技术在他的Introductory Lectures on Convex Optimization: A Basic Course一书中得到了更新[1]。有时将该技术称为Nesterov的加速梯度下降。尽管对Nesterov动量的完整数学解释超出了本书的范围,但我们将针对权重进行详细介绍,以便你可以实现它。本书的示例(包括在线JavaScript的示例)包含Nesterov动量的实现。此外,本书的线上资源包含一些针对Nesterov动量权重更新的JavaScript示例程序。

公式6-13基于学习率(ε)和动量(α)计算部分权重更新:

 

(6-13)

当前迭代用

 

表示,前一次迭代用

 

−1表示。这种部分权重更新称为

 

,最初从0开始。部分权重更新的后续计算基于部分权重更新的先前值。公式6-13中的偏导数是当前权重下误差函数的梯度。公式6-14展示了Nesterov动量更新,它代替了公式6-12中展示的标准反向传播权重更新:

 

(6-14)

上面的权重更新的计算,是部分权重更新的放大。公式6-14中显示增量权重已添加到当前权重中。具有Nesterov动量的SGD是深度学习最有效的训练算法之一。

6.6 本章小结

本章介绍了经典的反向传播和SGD。这些方法都基于梯度下降。换言之,它们用导数优化了单个权重。对于给定的权重,导数向程序提供误差函数的斜率。斜率允许程序确定如何更新权重。每个训练算法对斜率或梯度的解释不同。

尽管反向传播是最古老的训练算法之一,但它仍然是最受欢迎的算法之一。反向传播就是将梯度添加到权重中,负梯度将增大权重,正梯度将减小权重。我们通过学习率来缩放权重,防止权重变化过快。0.5的学习率意味着将权重增加一半的梯度,而2.0的学习率意味着将权重增加2倍的梯度。

反向传播算法有多种变体,其中一些变体(如弹性传播)颇受欢迎。第7章将介绍一些反向传播的变体。尽管了解这些变体很有用,但是SGD仍然是最常见的深度学习训练算法之一。

本文摘自《人工智能算法(卷3):深度学习和神经网络》

最受欢迎的算法之一:反向传播训练_第5张图片

 

本书是介绍AI的系列图书中的卷3。AI是一个涵盖许多子学科的、研究广泛的领域。对没有读过本系列图书卷1或卷2的读者,本书简介将提供一些背景信息。读者无须在阅读本书之前先阅读卷1或卷2。下文介绍了可从卷1和卷2中获取的信息。

自人工智能的早期阶段以来,神经网络就扮演着至关重要的角色。现在,令人兴奋的新技术,例如深度学习和卷积,正在将神经网络带向一个全新的方向。本书结合各种现实世界任务中的神经网络应用,例如图像识别和数据科学,介绍了当前的神经网络技术,包括ReLU激活、随机梯度下降、交叉熵、正则化、Dropout和可视化。

本书的目标读者是那些对人工智能感兴趣,但苦于没有良好的数学基础的人。读者只需要对大学代数课程有基本了解即可。本书为读者提供配套的示例程序代码,目前已有Java、C#和Python版本。

你可能感兴趣的:(反向传播训练,梯度下降,算法,人工智能,神经网络)