本文是 Machine Learning and Optimization 系列的第一篇。我会尝试介绍一些机器学习中的常用的优化算法和相关的基本理论,并结合具体的机器学习模型的例子进行简单分析和示例。系列相关的示例代码会全部放在 github/MLOpt.jl 上。此外由于我挖了太多的“系列”坑了连自己都记不住了,于是专门做了一个 Series 页面将这些坑搜集起来,并且每个系列做一个自己的简要页面并列出系列里的文章,方便索引。此外每篇文章如果属于某一个系列,在文章右边会有系列链接。Optimization 一直是 Machine Learning 里的一个重要部分,关于试图写本系列的介绍文章的 motivation,详见 Machine Learning and Optimization 的系列主页,下面直接进入正文。

首先考虑最简单的无约束的光滑函数的优化问题,最小化 ,并假设 是可导的。此时如果 的一个 minimizer 的话,必须要满足什么样的条件呢?但凡是学过微积分的同学应该都会想到导数等于零这个条件。如若不然,假设 ,考虑 处的一阶近似:

,当正数 足够小时,

因此 不能是(局部)minimizer。当 是 convex 的时候,这个条件也能保证 是 global minimizer。但是 general 的情况下这只是一个必要条件, 有可能只是一个局部 minimizer 而非全局最优,或者是一个 local maximizer 或者甚至什么都不是。但是在实际问题中有时候就是会碰到非 convex 又没有太多其他结构可以利用的情况,没有办法有效地找到全局最优解,所以只能找一个 local minimizer 或者只是一个 的点,通常称为 stationary point。例如 处就是一个 stationary point。

寻找 的 stationary point 其实就是找方程 的解的问题,所以 optimization 的问题和解方程的问题经常都可以互相转化。一个最基本的算法就是 gradient descent,它是一个迭代的算法,通过依次地生成点 逐渐接近 stationary point 。它的迭代公式是

其中 是一个正定矩阵,根据 的取法不同会产生出各种各样的变种算法。首先可以注意到的一点是,该算法如其名,根据当前的 gradient 来决定一个 descent 的方向进行移动。根据 处的一阶近似,如果步长 足够小的话,我们可以保证每一步迭代 的值是减小的,而到达 stationary point 的时候迭代将会停止。

下有界的时候,单调递减的迭代可以保证收敛到一个极限,但是这样还不能保证找到 stationary point:首先收敛的极限可能并不是我们所期望的那一个,其次函数值 的收敛也并不一定保证 的收敛。

如果想要保证收敛性,我们必须对 做一些进一步的假设或限制,针对不同的 的取法也会有不同的结论。注意到 是迭代公式 (eq: 1) 的一个不动点:

简单起见,我们考虑 ,以及固定 为常数的情况,假设 二阶可导并且其 Hessian 满足 ,其中 。此时我们有

其中 是根据中值定理中存在的一点。只要 ,亦即 ,就能保证

此时我们能得到所谓的 Q-线性收敛。当然这个算法实际中比较难严格地应用,一方面要估计合理的 可能会比较困难,另一方面可能要优化的函数本身并不满足这里的 assumption。实际上,我们这里的 assumption 还是很强的,首先 实际上说 Hessian 是正定的,因此我们已经能保证 是 convex 的了,更确切地说,它保证了 的 strong convexity,此时 stationary point 如果存在的话,就一定是 global minimizer。此外, 的条件可以理解为在说 gradient 的 Lipschitz 连续性。

1

定义 1(Strongly Convex Functions). 当 满足 时,称 -strongly convex 函数,其中参数 。当 时退回到普通的 convex 函数的定义。

直观来讲,convex 性质是指函数曲线位于该点处的切线,也就是线性近似之上,而 strongly convex 则进一步要求位于该处的一个二次函数上方,也就是说要求函数不要太“平坦”而是可以保证有一定的“向上弯曲”的趋势。当然这是一个很强的 assumption,但是同时也是非常重要的 assumption。比如我们都知道如果函数 是 convex 的,那么我们可以保证 的点将是一个 global minimizer,但是在实际的数值计算中,我们很少能直接求解 这个方程,而是需要通过一些迭代的算法来得到一个近似的估计,比如得到一个 使得 ,但是仅仅靠 convex 性质并不能保证在这种情况下得到的点 会是一个比较好的 global minimizer 的近似点。比如 在 global minimizer 周围是非常平坦的情况的话,我们有可能会找到一个很远的点但是起 gradient 的 norm 非常小。此时如果我们有 strongly convexity 的话,就能对情况做一些控制,考虑 strongly convex function 的定义式,令 是 global minimizer,而 为我们得到的近似解,于是

由于 ,所以

得到

也就是说通过求方程 的更好的 近似,我们可以保证得到原优化问题的更好的近似。当然,这个 bound 的好坏也要取决于 strongly convex 性质中的常数 的大小。

再回到迭代优化算法上,除了我们这里提到固定 为常数的情况外,另外一种比较常见的算法是用 line search 来找最优的 :就是在确定了前进方向 之后,令 ,然后通过最小化一元函数 来得到 ,因为是沿着确定的方向最小化,所以又叫做 line search。通常即使原来的函数 比较复杂,对应的 可能会变得很简单或者甚至有 closed form minimizer。直观上来看这种算法要更加 aggressive 一点,不过从收敛性的角度来说,并没有比固定 的算法有本质上的区别,在 是 Lipschitz 连续的情况下可以证明收敛性,但是如果要保证收敛速度,必须像上面那样做进一步的假设,可以得到类似的线性收敛速度。具体证明可以参考例如 (Gilbert & Lemarechal, 2006) 的第 2.5 小节或者 (Boyd & Vandenberghe, 2004) 的 9.3.1 节。

这里我们不妨做一个小结:刚才我们所提到的迭代优化算法,在每一次的迭代中通过将原优化问题分解为两个较为简单的优化问题来逐步逼近最优解:

  1. 寻找局部最优方向,由于是在局部操作,根据函数的光滑性或者其他一些预先知道的结构信息,我们可以对函数进行局部近似,从而将问题简化。最常用的近似就是泰勒展开,其中各种 gradient descent 方法中主要用一阶泰勒展开,而使用二阶展开则可以得到牛顿法,还有最近机器学习中比较多见的 Proximal Method 则是将目标函数分解成简单的和复杂的部分,简单的部分保持原样而只对复杂的部分进行泰勒展开近似。 处的一阶展开为 ,此时寻找局部最优移动方向则对应优化问题 其中 是用于将搜索限制在一个局部邻域里的,因为泰勒展开近似只能保证在局部有效。而上面这个问题中的目标函数关于 是线性的,所以非常容易优化。如果 中的 norm 是 Euclidean norm,那么我们立即得到最优解为 ,也就是 gradient 的反方向。如果我们取 -norm,那么最优解将会对于 这个向量的绝对值最大的那个坐标轴的方向(或其反方向),如果最大绝对值的方向不唯一的话可以任取一个,这可以看成是 Coordinate Descent 算法的一种解释。
  2. 寻找最优步长,在 exact line search 中我们是将问题化简到了最小化 这个一元函数的问题上。如果 的形式简单通常可以做 exact line search;复杂的情况则通常可以通过进一步的数值迭代算法来得到一个近似的步长,叫做 inexact line search,这样通常会让这一步计算量变得很大,因此也有许多其他算法来寻找一个“合理”的步长,而不一定要找到(近似)最优的步长,常见有诸如 Wolfe’s Condition、Armijo Rule 之类的。

下面我们来看两个机器学习中的例子,一个是 Linear Regression,另一个是 Logistic Regression。在 Linear Regression 中,我们得到训练数据 ,目标函数如下 (简单起见我们假设 的其中一个维度是常数,这样就不用显式地写成带 bias 的 的形式了。)

写成矩阵的形式( 为列向量, 矩阵的行对应数据点)是

其中带 系数的那一项是 regularizer,这种带 -norm 的 regularizer 的 linear regression 通常也被称为 ridge regression。从 Learning Theory 的角度来说,regularizer 是用于帮助提升模型的 generalization 能力。从数值计算的角度来说,加 regularizer 有助于处理 condition number 不好的情况下矩阵求逆很困难的问题:因为目标函数是 quadratic 的,所以实际上是有解析解的,求导并令导数等于零即可得到最优解为:

要 evaluate 这个解,我们通常并不直接求矩阵的逆,而是通过解线性方程组的方式(例如高斯消元法)来计算。考虑没有 regularizer 也就是 的情况,如果矩阵 的 condition number 很大的话,解线性方程组就会在数值上相当不稳定,而这个 regularizer 的引入则可以改善 condition number。

既然可以直接通过解线性方程的方式来得到最优解为什么还要用麻烦的 gradient descent 来优化呢?因为剧本就是这么写的啊其实反过来看通过 gradient descent 或者其他的迭代优化算法来求解对应的 quadratic 目标函数也是另一种解线性方程组的算法:不同的算法有不同的特点,有的时候在特殊的场合下会很有优势。例如如果数据矩阵是非常稀疏的时候,也许高斯消元法中的行的加减操作会产生一些比较 dense 的中间矩阵造成存储和计算困难,但是迭代优化由于只会用稀疏矩阵来进行乘法操作,所以开销可能会相对较小一些。

当然使用迭代优化的算法,condition number 太大仍然会导致问题:它会拖慢迭代的收敛速度,而 regularizer 从优化的角度来看,实际上是将目标函数变成 -strongly convex 的了。首先让我们来看看目标函数对参数 的 gradient:

我们考虑沿着 gradient 的反方向移动的情况,由于我们可以直接计算出 的 Hessian 为 ,我们可以直接套用本文一开始的分析方法选择一个固定的 来得到 Q-线性收敛。不过这里由于 quadratic function 形式简单我们可以直接用 exact line search。方便起见,我们记 , , ,则

注意到 是关于 的一个二次函数,对 求导得到

于是最优解为

带入 gradient descent 的迭代公式,我们可以计算出

根据 Kantorovich 不等式,可以得到

其中 是矩阵 的最小和最大的特征值。根据 condition number 的定义 ,我们可以进一步得到

右边是 gradient descent 的目标函数收敛速率的一个上界,可以看到 的 condition number 越小,上界就越小,也就是收敛速度会越快。注意到 ,通过特征值的定义即可简单验证,假设 的 condition number 是 的话,加上 regularizer 之后它的 condition number 变为 ,会变小,从而改善收敛速度。

虽然这只是收敛速度的一个 upper bound,但是 condition number 对实际的收敛速度影响还是蛮大的,图 (fig: 1) 给出了两个不同的 condition number 的情况。

1
图 1
condition number 200。 迭代 60 次收敛
condition number 2。 迭代 5 次收敛

为了让图好看一点,我给图中的横纵坐标用了不同的比例,所以不太看得出来 exact line search 下 gradient descent 的一个性质:前后两次迭代的移动方向是正交的。注意到第 次迭代是沿着 的方向移动 使得 最小,因此

所以如果横纵坐标轴的比例一样的话,收敛路径应该看起来是正交的 zig-zag 形状。实际中如果 比较复杂不能直接优化的话,由于是一元函数,可以用一个通用的二分查找法来寻找 的点。

上面是针对一个 quadratic 函数来进行的具体分析,对于我们刚才讨论过的 general 的函数 并且其 Hessian 满足 时, 作为其 Hessian 的 condition number 的一个上界同样会以类似的方式影响 gradient descent 的收敛速度。例如可以参考 (Boyd & Vandenberghe, 2004) 里的 9.3.1 节。

接下来我们再来看一个复杂一点的 Logistic Regression (LR) 的例子。LR 是 machine learning 中的一个经典的分类算法,虽然挂着“Regression”的名号,但是确实如假包换的 classification 算法。LR 的基本假设是数据类别间是由一个线性的 decision boundary 隔开的,换句话说