上篇说的,仅仅基于梯度的优化算法称为 一阶优化算法(first-order optimization algorithms)
, 比如最典型的 梯度下降法;很多时候,仅仅使用一阶的梯度信息效果是不够优良的,还需要考虑梯度的梯度, 也就是 二阶优化算法(second-order optimization algorithms)
, 二阶优化算法基于的是 Hessian 矩阵, 比较典型的方法如 牛顿法。
先来回顾一下 梯度,Jacobian 矩阵 和 Hessian 矩阵 的关系。开始!
二阶导数(second derivative)
,即导数的导数,表达的是一阶导数如何随着输入的变化而变化。一阶导数,表征的是曲线的斜率
, 同理我们可以认为二阶导数,表征的是曲线(或曲面)的曲率
. 借助物理来理解,就是函数表征的是位移和时间的对应关系,一阶导数就是速度,二阶导数就是加速度。
- 对于一个一次函数而言,比如 , 其一阶导数就是常数 , 而二阶导数就是 , 或者说匀速直线运动,速度恒定,没有加速度。
- 对于一个二次函数而言,比如自由落体运动 , 其一阶导数就是 , 二阶导数就是常数 , 也就是说有随 变化的斜率和固定的曲率,或者说有固定的加速度然后有随时间变化的速度。
回到优化算法中,我们之前使用的梯度下降法,相当于以当前的速度匀速直线前进一个 时间,作为估计的 , 当然这个和真实的 肯定是有差距的。二阶导数信息就可以用来预知这个差距的大小:
- 如果
二阶导数/曲率
为 , 也就是没有加速度,匀速直线运动,那么我们用梯度进行预测就是很准确的。 - 如果
二阶导数/曲率
为负, 也就是减速运动,那么我们用梯度进行预测的值就会比真实值大。 - 如果
二阶导数/曲率
为正, 也就是加速运动, 那么我们用梯度进行预测的值就会比真实值小。
对于多元函数,二阶函数有很多,我们将这些导数合并成为 Hessian 矩阵。由于微分算子在任何二阶偏导连续的点处都可以交换,因此 Hessian 矩阵在这些点上是对称的。在深度学习背景中,我们遇到的大多数的 Hessian 矩阵基本都是对称的。而由于Hessian 矩阵是实对称的,我们可以将其分解为一组实特征值和一组特征向量的正交基。那么在特定方向 上的 二阶导数就可以写成 。 当 是 的一个特征向量时,这个方向的二阶导数就是对应的特征值。对于其他的方向 , 方向二阶导数就是所有特征值的加权平均,权重 ,且与 夹角越小的特征向量的权重越大。最大特征值确定最大二阶导数,最小特征值确定最小二阶导数。
下面我们定量的来看一下,通过二阶导数如何衡量一个梯度下降步骤表现的有多好。我们在当前点
处做函数
的近似二阶泰勒展开
其中有三项,
- 函数的原始值
- 函数斜率导致的预期改善
- 函数曲率导致的校正
当最后一项太大时,函数值是可能向上移动的。
- 当 为 0 或者负数时候,近似的泰勒级数增加表明增加 将永远使 下降。在理论上,这种情况下我们应该把步长尽量调大,然而在实践中,泰勒级数不会在 很大的时候依然保持准确,因此在这个情况下我们必须采取更具启发式的选择。
- 当
为正数时,通过计算可得,使得近似泰勒级数下降最多的最优步长是
最坏的情况下, 与 的最大特征值 对应的特征向量对齐,则最优步长是 . 当我们要最小化的函数能用二次函数很好地近似的情况下, Hessian 的特征值决定了学习率的量级。
二阶导数还可以用来确定一个临界点是否是局部极大点,局部极小点 或者 鞍点。
- 当 时, 是一个局部极小值点
- 当 时, 是一个局部极大值点
- 当 时,很遗憾,不能确定唯一情况。 可能是一个鞍点或可能是一个平坦区域的一部分。
对于已知
, 进而求得二阶导数以更加具体的判断, 这就是所谓的 二阶导数测试(second derivative test)
.
在多维的情况下,我们需要检测函数的所有二阶导数。利用 Hessian 矩阵的特征值分解,我们可以将二阶导数测试扩展到多维情况。在临界点处 , 我们通过检测 Hessian 的特征值来判断该临界点是一个局部极大点,局部极小点 还是鞍点。
- 当 Hessian 是正定的,即所有特征值都是正的, 则该临界点是局部极小点。类似于山脚下的小泉眼,往四面山上走都是上坡路,水从四面山上流进来。
- 当 Hessian 是负定的,即所有特征值都是负的, 则该临界点是局部极大点。类似于山顶的火山喷发,往四面山上走都是下坡路,岩浆从山顶向四处流下。
- 当 Hessian 的特征值,有正有负有零的时候,就不能准确判断了,但是也能提供一定的信息
- 如果Hessian 的特征值中至少一个是正的,一个是负的,那么我们可以肯定 是 某个横截面的局部极大值,确是另一个横截面的局部极小点,这就很有可能是鞍点了。
- 当所有的非零特征值是同号的且至少有一个特征值是 时,这个检测就是不确定的。因为单变量的二阶导数测试在零特征值对应的横截面上是不确定的。
在多维情况下,单个点处每个方向上的二阶导数是不同的。 Hessian 的条件数衡量这些二阶导数的变化范围。当 Hessian的条件数很差时,梯度下降法也会表现的很差。因为此时,一个方向上的导数增加得很快,而在另外一个方向上增加得很慢。梯度下降法不会知道这层信息,所以它不知道应该优先搜索导数长期为负的反向。病态条件也导致很难选择合适的步长。步长必须足够小,以免冲过最小而向具有较强正曲率的方向上升。而通常这也意味着在其他较小的曲率上进展不明显。
我们可以利用 Hessian的信息来指导搜索,以解决这个问题。其中最简单的方法是牛顿法(Newton's method)
。另起一篇,单独介绍。
最后,总结一下,
上面提到的优化算法适用于各种各样的函数,但几乎都没有理论保证。因为深度学习中使用的函数族是非常复杂的,所以深度学习算法往往缺少理论保证。在许多其他领域,优化的主要方法是为有限的函数族设计优化算法。
在深度学习的背景下,限制函数满足 Lipschitz连续(Lipschitz continuous)
或者其导数 Lipschitz连续可以获得一些保证。Lipschitez 连续函数的变化速度以 Lipschitz 常数(Lipschitz constant)
为界 :
这个属性允许我们量化自己的假设: 梯度下降等算法导致的输入的微小变化将使输出只产生微小变化, 因此是很有用的。Lipschitz 连续性也是相当弱的约束, 并且深度学习中很多优化问题经过相对较小的修改后就能变得 Lipschitz连续。
最成功的特定优化领域或许是凸优化(Convex optimization)
. 凸优化通过更强的限制提供更多的保证。凸优化算法只对凸函数使用,即 Hessian 矩阵 处处半正定的函数。因为这些函数没有鞍点而且其所有局部极小点必然是全局最小点,所以表现良好。然而,深度学习中的大多数问题都不能表示成凸优化的形式。凸优化仅用作一些深度学习算法的子程序。凸优化中的分析思路岁证明深度学习算法的收敛性非常有用,然而一般来说,深度学习背景下凸函数的重要性大大减少。