如何使用优化器让训练网络更快——神经网络的奥秘
摘要: 本文介绍了创建神经网络时使用的多种优化器,并讲述了如何使用优化器让训练网络更快。
通过使用Numpy来创建神经网络,让我意识到有哪些因素影响着神经网络的性能。架构、超参数值、参数初始化,仅是其中的一部分,而这次我们将致力于对学习过程的速度有巨大影响的决策,以及所获得的预测的准确性—对优化策略的选择。我们会研究很多流行的优化器,研究它们的工作原理,并进行对比。
你在GitHub上可以找到所有代码:
机器学习算法的优化
优化是搜索用于最小化或最大化函数参数的过程。当我们训练机器学习模型的时候,通常使用间接优化。我们选择某种度量,如精确度或回调,来指示模型如何很好地解决给定问题。然而,我们正在优化一个不同的代价函数J(θ),并且希望把它最小化以提高我们关心的度量。当然,代价函数的选择通常与我们要解决的具体问题有关。本质上,它表明了我们离理想的解决方案有多远。
陷阱
结果证明,通常要找到最小的非凸代价函数并不容易,我们必须使用先进的优化策略来找到它们。如果你已经学过了微分,就一定知道局部最小值的概念,这些是我们的优化器可能陷入的最大陷阱。对于那些还没有接触过这个数学概念的人,我只能说这些是在给定的区域内函数取最小值的点,如上图左侧所示。
克服所谓的鞍点(saddle points)通常被认为更具有挑战性。这些是稳定状态,其中代价函数的值几乎是不变的。这种情况显示在上图的右侧。在这些点上,梯度几乎在所有方向上都被归零,使得无法逃离。
有时候,特别是在多层网络的情况下,我们可能必须处理代价函数中非常陡峭的区域。在这些地方,梯度的值急剧地增加,引起梯度爆炸,这会致使采取一些极大的步骤长度,并经常破坏之前的整个优化工作。然而,通过梯度裁剪,就是定义允许的最大梯度值,就可以很容易地避免这个问题。
梯度下降法(Gradient descent)
在我们了解更好的算法之前,先看看一些基本的策略方法。可能一个最简单的方法就是简单地沿着与梯度相反的方向移动,这个方法可以用下面的等式来表示:
其中,α是一个称为学习率的超参数,它会转换为我们将在每次迭代中采取的步骤长度。它的值在一定程度上表示了一种折中选择,是学习的速度和可以获得结果的准确性之间的。选择太小的步骤长度会导致我们冗长的计算和执行更多的迭代。另一方面,无论如何,选择过大的步骤长度可以有效地阻止我们找到最小值。在图2中表示了这种情况,我们可以看到,在随后的迭代中,如何振动,而不能保持稳定。在此期间,定义了适当步骤的模型几乎立即就被发现了。
此外,这个算法容易受到前面描述的鞍点问题的影响。由于在随后的迭代过程中执行校正的大小与计算的梯度成正比,我们将无法摆脱平稳期。
最后,为了达到这一目的,该算法是无效的,它要求在每次迭代中使用整个训练集。这意味着,在每一个时期,我们必须查看所有的例子,以便执行下一步的优化。当训练集包含数千个例子的时候,这可能不是问题,但是正如我在之前提到的,当有数百万条记录可供使用时,神经网络工作的效果最好,但在这种情况下,很难想象在每次迭代中我们都使用整个集合,这会浪费时间和计算机资源。
小批量梯度下降法(Mini-bach Gradient descent)
让我们来解决上节中提到的最后一个问题——低效。虽然向量化允许我们可以加速计算,但是要一次性处理太多的训练实例,并且当数据集具有数百万条记录时,整个处理过程仍然需要很长时间才能完成。让我们试着使用一个相当简单的解决方法,将整个数据集分成更小的部分,在随后的迭代中进行训练。假设左边的图形表示我们想要优化的代价函数。可以看到,由于我们需要处理的数据量要小得多,新算法就会使得决策更快。让我们来看下比较模型移动中的对比。梯度下降会采取罕见的、相对大的步骤,几乎没有噪音。另一方面,批量梯度下降更频繁地执行步骤,但是由于被分析的数据集中可能存在多样性,则会有更多的噪音。甚至在一次迭代中,我们会朝着与预期相反的方向移动。然而,平均而言,我们会朝着最小值的方向移动。
那么按照什么尺寸拆呢?在深度学习中的通常情况下,答案是不确定的,取决于具体情况。如果整个数据集就是一批,那么我们基本上就是处理一个普通的梯度下降。另一方面,如果大小是1,那么在每次迭代中,我们只使用数据集中的一个实例,因此失去了向量化的好处。这种方法有时是合理的,被称为随机梯度下降。在实际环境中,我们通常会选择从64到512个例子的范围里选择一个中间值。
指数加权平均法(exponentially weighted averges,EWA)
这一思想被广泛应用于统计学、经济学、深度学习等领域。许多高级的神经网络优化算法使用了这个思想,因为它允许我们持续优化,即使在给定点所计算的梯度是零的情况下。让我们来了解一下这个算法,我们将使用最大的一家科技公司的股票作为例子。
EWA实质上是对许多得到的值计算平均数,以便不受局部波动的影响而关注整体趋势。EWA的值是使用上面的递推公式计算的,其中β是用于控制要计算平均值的数的范围。在随后的迭代中,我们考虑了1 /(1 -β)的例子。对于较大的β值,得到的曲线更平滑,因为我们平均了许多记录。另一方面,曲线越来越向右移动,因为当我们把很长一段时间内的值进行平均的时候,EWA对新的趋势适应的比较慢。这在图5中可以看到,其中我们说明了股票在收盘时的实际价格,显示了给不同的β参数计算的指数加权平均值。
动量梯度下降法(Gradient descent with momentum)
该方法利用指数加权平均法来避免代价函数的梯度接近于零的点。简单来说就是,我们允许算法获得动量,因此即使局部梯度为零,我们仍然可以依靠之前计算的值向前移动。由于这个原因,它一直是一个比纯梯度下降更好的选择。
通常我们给网络的每一层使用反向传播来计算dW和db的值。这次,我们首先计算VdW和Vdb的中间值,而不是直接使用计算出来的梯度来更新神经网络参数的值,这些值实际上是关于单个参数的代价函数导数的EWA。最后,我们将在梯度下降中使用VdW和Vdb。整个过程可用上述方程表示。值得注意的是,这种方法的实现需要在迭代之间存储EWA的值。
现在我们尝试开发一个关于EWA影响模型行为的直觉能力。再次想象上面的轮廓象征着我们优化的代价函数。上图显示标准梯度下降和动量梯度下降的比较。我们可以看到,代价函数图表的形状推动一种非常缓慢的优化方法。正如股票市场价格的例子一样,使用指数加权平均法允许我们关注主要的趋势而不是噪声。指示最小值的分量被扩大,并且承担波动的分量被慢慢消除。更重要的是,如果我们在后续的更新中获得的梯度指向一个相似的方向,那么学习率将会提高。这将导致更快的收敛和减少振荡。然而,这种方法有一个缺点—当你接近最小值的时候,动量值会增大,并且可能变得相当大,以至于算法不能在正确的地方停止。
RMSProp算法
另一种提高梯度下降性能的方法是使用RMSProp方法—均方根传播(Root Mean Squared Propagation)。它是有适应能力的,允许为模型每个参数的学习率单个调整。随后的参数值是基于之前为特定参数计算的梯度值。
使用图6的例子和上面的方程,让我们考虑这个方法背后的逻辑。根据名称,在每次迭代中,我们计算相应参数的代价函数导数的每个元素的平方。此外,我们使用EWA来计算在最近迭代中获得的值的平均数。最后,在更新网络参数值之前,将相应的梯度分量除以平方和的平方根。这意味着对于梯度大的参数,学习率降低得更快;反之,对于梯度小的参数,学习率降低得则更慢。以这种方式,我们的算法会减少波动,并防止噪音影响信号。为了避免零作除数(数值稳定性),我们要向分母添加一个非常小的值,在公式中标记为ɛ。
在写本文的时候,我对所分析优化器的质量飞跃感到非常惊讶。第一个是当我看到标准梯度下降和小批量梯度下降之间的训练时间上的差异时;第二,比较RMSprop与迄今为止我们看到的一切。然而,这种方法有其缺点。随着上述方程的分母在每次迭代中增大,学习率会越来越小。因此,这可能会导致模型完全停止运行。
Adam
最后,让我说一下Adam(自适应矩估计)。这是一种算法,和RMSProp一样,在大量的应用中效果不错。它利用了RMSProp的最大优点,将应用与动量优化的思想结合起来。结果就会得到一种允许快速且有效的优化策略。上图显示了讨论过的优化器如何处理函数复杂部分的优化。可以看到Adam在这种情况下做得很好。
遗憾的是,随着我们的方法有效性的提高,计算的复杂度也增大了。以上我写了十个矩阵方程来描述优化过程的单次迭代。对于那些不太熟悉数学的人,别担心,没有新的东西,这些是之前为动量和RMSProp 优化器所写的方程。我们将简单地使用这两种想法。
总结
我希望能以一种由浅入深的方式来解释这些复杂的问题。本文的相关工作使我能够理解选择正确的优化器是多么的重要。对这些算法的理解会让我们有意识地使用它们,了解个体超参数的变化如何影响整个模型的性能。
本文为云栖社区原创内容,未经允许不得转载。