4.3 基于梯度的优化方法
大多数深度学习算法都涉及某种形式的优化。优化指的是改变x以最小化或最大化某个函数f(x)的任务。我们通常以最小化f(x)指代大多数最优化问题。最大化可经由最小化算法最小化−f(x)来实现。
我们把要最小化或最大化的函数称为目标函数(objective function)或准则(criterion)。当我们对其进行最小化时,也把它称为代价函数(cost function)、损失函数(loss function)或误差函数(error function)。虽然有些机器学习著作赋予这些名称特殊的意义,但在这本书中我们交替使用这些术语。
我们通常使用一个上标∗表示最小化或最大化函数的x值,如记x∗=arg min f(x)。
我们假设读者已经熟悉微积分,这里简要回顾微积分概念如何与优化联系。
假设有一个函数y=f(x),其中x和y是实数。这个函数的导数(derivative)记为f′(x)或。导数f′(x)代表f(x)在点x处的斜率。换句话说,它表明如何缩放输入的小变化才能在输出获得相应的变化:。
因此导数对于最小化一个函数很有用,因为它告诉我们如何更改x来略微地改善y。例如,我们知道对于足够小的来说,f(x−sign(f′(x)))是比f(x)小的。因此我们可以将x往导数的反方向移动一小步来减小f(x)。这种技术称为梯度下降(gradient descent)(Cauchy,1847)。图4.1展示了一个例子。
图4.1 梯度下降。梯度下降算法如何使用函数导数的示意图,即沿着函数的下坡方向(导数反方向)直到最小
当f′(x)=0时,导数无法提供往哪个方向移动的信息。f′(x)=0的点称为临界点(critical point)或驻点(stationary point)。一个局部极小点(local minimum)意味着这个点的f(x)小于所有邻近点,因此不可能通过移动无穷小的步长来减小f(x)。一个局部极大点(local maximum)意味着这个点的f(x)大于所有邻近点,因此不可能通过移动无穷小的步长来增大f(x)。有些临界点既不是最小点也不是最大点,这些点称为鞍点(saddle point)。见图4.2给出的各种临界点的例子。
图4.2 临界点的类型。一维情况下,3种临界点的示例。临界点是斜率为零的点。这样的点可以是:局部极小点(local minimum),其值低于相邻点;局部极大点(local maximum),其值高于相邻点;鞍点,同时存在更高和更低的相邻点
使f(x)取得绝对的最小值(相对所有其他值)的点是全局最小点(global minimum)。函数可能只有一个全局最小点或存在多个全局最小点,还可能存在不是全局最优的全局极小点。在深度学习的背景下,我们要优化的函数可能含有许多不是最优的全局极小点,或者还有很多处于非常平坦的区域内的鞍点。尤其是当输入是多维的时候,所有这些都将使优化变得困难。因此,我们通常寻找使f非常小的点,但这在任何形式意义下并不一定是最小,如图4.3所示的例子。
图4.3 近似最小化。当存在多个全局极小点或平坦区域时,优化算法可能无法找到全局最小点。在深度学习的背景下,即使找到的解不是真正最小的,但只要它们对应于代价函数显著低的值,我们通常就能接受这样的解
我们经常最小化具有多维输入的函数:。为了使“最小化”的概念有意义,输出必须是一维的(标量)。
针对具有多维输入的函数,我们需要用到偏导数(partial derivative)的概念。偏导数衡量点x处只有xi增加时f(x)如何变化。梯度(gradient)是相对一个向量求导的导数:f的导数是包含所有偏导数的向量,记为。梯度的第i个元素是f关于xi的偏导数。在多维情况下,临界点是梯度中所有元素都为零的点。
在u(单位向量)方向的方向导数(directional derivative)是函数f在u方向的斜率。换句话说,方向导数是函数关于α的导数(在α=0时取得)。使用链式法则,我们可以看到当α=0时,。
为了最小化f,我们希望找到使f下降得最快的方向。计算方向导数:
其中θ是u与梯度的夹角。将代入,并忽略与u无关的项,就能简化得到这在u与梯度方向相反时取得最小。换句话说,梯度向量指向上坡,负梯度向量指向下坡。我们在负梯度方向上移动可以减小f。这被称为最速下降法(method of steepest descent)或梯度下降(gradient descent)。
最速下降建议新的点为
其中为学习率(learning rate),是一个确定步长大小的正标量。我们可以通过几种不同的方式选择。普遍的方式是选择一个小常数。有时我们通过计算,选择使方向导数消失的步长。还有一种方法是根据几个计算,并选择其中能产生最小目标函数值的。这种策略称为线搜索。
最速下降在梯度的每一个元素为零时收敛(或在实践中,很接近零时)。在某些情况下,我们也许能够避免运行该迭代算法,并通过解方程直接跳到临界点。
虽然梯度下降被限制在连续空间中的优化问题,但不断向更好的情况移动一小步(即近似最佳的小移动)的一般概念可以推广到离散空间。递增带有离散参数的目标函数称为爬山(hill climbing)算法(Russel and Norvig,2003)。
4.3.1 梯度之上:Jacobian和Hessian矩阵
有时我们需要计算输入和输出都为向量的函数的所有偏导数。包含所有这样的偏导数的矩阵被称为Jacobian矩阵。具体来说,如果我们有一个函数,f的Jacobian矩阵定义为。
有时,我们也对导数的导数感兴趣,即二阶导数(second derivative)。例如,有一个函数,f的一阶导数(关于xj)关于xi的导数记为。在一维情况下,我们可以将。二阶导数告诉我们,一阶导数将如何随着输入的变化而改变。它表示只基于梯度信息的梯度下降步骤是否会产生如我们预期的那样大的改善,因此它是重要的。我们可以认为,二阶导数是对曲率的衡量。假设我们有一个二次函数(虽然很多实践中的函数都不是二次的,但至少在局部可以很好地用二次近似)。如果这样的函数具有零二阶导数,那就没有曲率,也就是一条完全平坦的线,仅用梯度就可以预测它的值。我们使用沿负梯度方向大小为的下降步,当该梯度是1时,代价函数将下降。如果二阶导数是负的,函数曲线向下凹陷(向上凸出),因此代价函数将下降得比多。如果二阶导数是正的,函数曲线是向上凹陷(向下凸出),因此代价函数将下降得比少。从图4.4可以看出不同形式的曲率如何影响基于梯度的预测值与真实的代价函数值的关系。
图4.4 二阶导数确定函数的曲率。这里我们展示具有各种曲率的二次函数。虚线表示我们仅根据梯度信息进行梯度下降后预期的代价函数值。对于负曲率,代价函数实际上比梯度预测下降得更快。没有曲率时,梯度正确预测下降值。对于正曲率,代价函数比预期下降得更慢,并且最终会开始增加,因此太大的步骤实际上可能会无意地增加函数值
当我们的函数具有多维输入时,二阶导数也有很多。我们可以将这些导数合并成一个矩阵,称为Hessian矩阵。Hessian矩阵定义为
Hessian等价于梯度的Jacobian矩阵。
微分算子在任何二阶偏导连续的点处可交换,也就是它们的顺序可以互换:
这意味着Hi,j=Hj,i,因此Hessian矩阵在这些点上是对称的。在深度学习背景下,我们遇到的大多数函数的Hessian几乎处处都是对称的。因为Hessian矩阵是实对称的,我们可以将其分解成一组实特征值和一组特征向量的正交基。在特定方向d上的二阶导数可以写成。当d是H的一个特征向量时,这个方向的二阶导数就是对应的特征值。对于其他的方向d,方向二阶导数是所有特征值的加权平均,权重在0和1之间,且与d夹角越小的特征向量的权重越大。最大特征值确定最大二阶导数,最小特征值确定最小二阶导数。
我们可以通过(方向)二阶导数预期一个梯度下降步骤能表现得多好。我们在当前点x(0)处做函数f(x)的近似二阶泰勒级数:
其中g是梯度,H是x(0)点的Hessian。如果我们使用学习率,那么新的点x将会是。代入上述的近似,可得
其中有3项:函数的原始值、函数斜率导致的预期改善和函数曲率导致的校正。当最后一项太大时,梯度下降实际上是可能向上移动的。当为零或负时,近似的泰勒级数表明增加将永远使f下降。在实践中,泰勒级数不会在大的时候也保持准确,因此在这种情况下我们必须采取更具启发式的选择。当为正时,通过计算可得,使近似泰勒级数下降最多的最优步长为
最坏的情况下,g与H最大特征值λmax对应的特征向量对齐,则最优步长是。当我们要最小化的函数能用二次函数很好地近似的情况下,Hessian的特征值决定了学习率的量级。
二阶导数还可以用于确定一个临界点是否是局部极大点、全局极小点或鞍点。回想一下,在临界点处f′(x)=0。而f″(x)>0意味着f′(x)会随着我们移向右边而增加,移向左边而减小,也就是f′(x-ε)<0和f′(x+ε)>0对足够小的成立。换句话说,当我们移向右边,斜率开始指向右边的上坡;当我们移向左边,斜率开始指向左边的上坡。因此我们得出结论,当f′(x)=0且f″(x)>0时,x是一个全局极小点。同理,当f′(x)=0且f″(x)<0时,x是一个局部极大点。这就是所谓的二阶导数测试(second derivative test)。不幸的是,当f″(x)=0时,测试是不确定的。在这种情况下,x可以是一个鞍点或平坦区域的一部分。
在多维情况下,我们需要检测函数的所有二阶导数。利用Hessian的特征值分解,我们可以将二阶导数测试扩展到多维情况。在临界点处,我们通过检测Hessian的特征值来判断该临界点是一个局部极大点、全局极小点还是鞍点。当Hessian是正定的(所有特征值都是正的),则该临界点是全局极小点。因为方向二阶导数在任意方向都是正的,参考单变量的二阶导数测试就能得出此结论。同样的,当Hessian是负定的(所有特征值都是负的),这个点就是局部极大点。在多维情况下,实际上我们可以找到确定该点是否为鞍点的积极迹象(某些情况下)。如果Hessian的特征值中至少一个是正的且至少一个是负的,那么x是f某个横截面的局部极大点,却是另一个横截面的全局极小点,如图4.5所示。最后,多维二阶导数测试可能像单变量版本那样是不确定的。当所有非零特征值是同号的且至少有一个特征值是0时,这个检测就是不确定的。这是因为单变量的二阶导数测试在零特征值对应的横截面上是不确定的。
图4.5 既有正曲率又有负曲率的鞍点。示例中的函数是。函数沿x1轴向上弯曲。x1轴是Hessian的一个特征向量,并且具有正特征值。函数沿x2轴向下弯曲。该方向对应于Hessian负特征值的特征向量。名称“鞍点”源自该处函数的鞍状形状。这是具有鞍点函数的典型示例。维度多于一个时,鞍点不一定要具有0特征值:仅需要同时具有正特征值和负特征值。我们可以想象这样一个鞍点(具有正负特征值)在一个横截面内是局部极大点,而在另一个横截面内是全局极小点
多维情况下,单个点处每个方向上的二阶导数是不同的。Hessian的条件数衡量这些二阶导数的变化范围。当Hessian的条件数很差时,梯度下降法也会表现得很差。这是因为一个方向上的导数增加得很快,而在另一个方向上增加得很慢。梯度下降不知道导数的这种变化,所以它不知道应该优先探索导数长期为负的方向。病态条件也导致很难选择合适的步长。步长必须足够小,以免冲过最小而向具有较强正曲率的方向上升。这通常意味着步长太小,以至于在其他较小曲率的方向上进展不明显,如图4.6所示。
我们可以使用Hessian矩阵的信息来指导搜索,以解决这个问题。其中最简单的方法是牛顿法(Newton's method)。牛顿法基于一个二阶泰勒展开来近似x(0)附近的f(x):
接着通过计算,我们可以得到这个函数的临界点:
如果f是一个正定二次函数,牛顿法只要应用一次式(4.12)就能直接跳到函数的最小点。如果f不是一个真正二次但能在局部近似为正定二次,牛顿法则需要多次迭代应用式(4.12)。迭代地更新近似函数和跳到近似函数的最小点可以比梯度下降更快地到达临界点。这在接近全局极小点时是一个特别有用的性质,但是在鞍点附近是有害的。正如本书第8.2.3节所讨论的那样,当附近的临界点是最小点(Hessian的所有特征值都是正的)时牛顿法才适用,而梯度下降不会被吸引到鞍点(除非梯度指向鞍点)。
图4.6 梯度下降无法利用包含在Hessian矩阵中的曲率信息。这里我们使用梯度下降来最小化Hessian矩阵条件数为5的二次函数f(x)。这意味着最大曲率方向具有比最小曲率方向多5倍的曲率。在这种情况下,最大曲率在方向上,最小曲率在方向上。红线表示梯度下降的路径。这个非常细长的二次函数类似一个长峡谷。梯度下降把时间浪费于在峡谷壁反复下降,因为它们是最陡峭的特征。由于步长有点大,有超过函数底部的趋势,因此需要在下一次迭代时在对面的峡谷壁下降。与指向该方向的特征向量对应的Hessian的大的正特征值表示该方向上的导数快速增加,因此基于Hessian的优化算法可以预测,在此情况下最陡峭方向实际上不是有前途的搜索方向
仅使用梯度信息的优化算法称为一阶优化算法(first-order optimization algorithms),如梯度下降。使用Hessian矩阵的优化算法称为二阶最优化算法(second-order optimization algo-rithms)(Nocedal and Wright,2006),如牛顿法。
本书大多数上下文中使用的优化算法适用于各种各样的函数,但几乎都没有理论保证。因为在深度学习中使用的函数族是相当复杂的,所以深度学习算法往往缺乏理论保证。在许多其他领域,优化的主要方法是为有限的函数族设计优化算法。
在深度学习的背景下,限制函数满足Lipschitz连续(Lipschitz continuous)或其导数Lip-schitz连续可以获得一些保证。Lipschitz连续函数的变化速度以Lipschitz常数(Lipschitz constant)为界:
这个属性允许我们量化自己的假设——梯度下降等算法导致的输入的微小变化将使输出只产生微小变化,因此是很有用的。Lipschitz连续性也是相当弱的约束,并且深度学习中很多优化问题经过相对较小的修改后就能变得Lipschitz连续。
最成功的特定优化领域或许是凸优化(Convex optimization)。凸优化通过更强的限制提供更多的保证。凸优化算法只对凸函数适用,即Hessian处处半正定的函数。因为这些函数没有鞍点而且其所有全局极小点必然是全局最小点,所以表现很好。然而,深度学习中的大多数问题都难以表示成凸优化的形式。凸优化仅用作一些深度学习算法的子程序。凸优化中的分析思路对证明深度学习算法的收敛性非常有用,然而一般来说,深度学习背景下凸优化的重要性大大减少。有关凸优化的详细信息,详见Boyd and Vandenberghe(2004)或Rockafellar(1997)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论