凸优化基础,本科生能看得懂的极限水平

此篇学习笔记大多数为网络搬运+自己的理解,笔者学历不高,水平有限,就是给的多。此文所需的数学知识已经达到了笔者浅薄的认知极限。

1. 判定凸集,以及凸函数

凸集定义[1][2]

Convex set

俗话定义:例如立方体、球体和圆形这样的没有凹痕和中空的集合就是凸集,月牙形不是凸集。

具体定义:在欧式空间中,凸集是对于集合内的每一对点,连接该对点的直线段上的每个点也都在该集合内。

抽象定义:凸集是在凸组合下闭合的仿射空间的子集。

数学定义:凸集,实数 RR 上(或复数 CC 上)的向量空间中,如果集合 SS 中,任意两点的连线上的点都在 SS 内,则称集合 SS 为凸集。

凸函数定义[3]

在区间上的凸函数

凸函数是指具有如下特性的一个定义在某个向量空间的凸子集 CC (区间)上的实值函数 ff:对其定义域 CC 上的任意两点 x1x1, x2x2 ,总有

f(x1+x22)f(x1)+f(x2)2f(\frac{x_1+x_2}2)\leqslant\frac{f(x_1)+f(x_2)}2

对实数集上的函数,可通过求解二阶导数来判别:

  • 若二阶导数在区间上非负,则称为凸函数
  • 若二阶导数在区间上恒大于0,则称严格凸函数

2. 线性规划与二次规划

线性规划[4]

线性规划(Linear Programming,简称LP)为高中教材包含的内容,不再赘述,直接上例子唤醒回忆。

假设一个农夫有一块 AA 平方千米的农地,打算种植小麦或大麦,或是两者依某一比例混合种植。该农夫只可以使用有限数量的肥料 FF 和农药 PP,而单位面积的小麦和大麦都需要不同数量的肥料和农药,小麦以 (F1,P1)(F_{1},P_{1}) 表示,大麦以 (F2,P2)(F_{2},P_{2}) 表示。设小麦和大麦的售出价格分别为 S1S_1S2S_2,则小麦与大麦的种植面积问题可以表示为以下的线性规划问题:

maxZS1x1+S2x2(最大化利润:目标函数)s.t.x1+x2A(种植面积的限制)F1x1+F2x2F(肥料数量的限制)P1x1+P2x2P(农药数量的限制)x10,x20(不可以栽种负数的面积)\begin{matrix} \begin{aligned} \max Z &S_{1}x_{1}+S_{2}x_{2}&(\text{最大化利润:目标函数})\\ s.t. & x_1+x_2\leqslant A &(\text{种植面积的限制})\\ & F_1 x_1 + F_2 x_2 \leqslant F &(\text{肥料数量的限制})\\ & P_1 x_1 + P_2 x_2 \leqslant P & (\text{农药数量的限制})\\ & x_1 \geqslant 0,\, x_2 \geqslant 0 &(\text{不可以栽种负数的面积})\\ \end{aligned} \end{matrix}

几何上,线性约束条件的集合相当于一个凸包或凸集,叫做可行域。因为目标函数亦是线性的,所以其极值点会自动成为最值点。线性目标函数亦暗示其最优解只会出现在其可行域的边界点中。

二次规划[5]

是一种典型的优化问题,包括凸二次规划和非凸二次规划,在此类问题中,目标函数是变量的二次函数,约束条件是变量的线性不等式。

假定变量的个数为 dd,约束条件的个数为 mm,则标准的二次规划问题形如:

minx12xTQx+cTxs.t.Axb\begin{matrix} \min_{x} &\frac{1}{2}x^TQx+c^Tx\\ s.t.&Ax \leqslant b \end{matrix}

其中 xxdd 维向量,为实 QRd×dQ\in \mathbb{R^{d\times d }} 对称矩阵,ARm×dA\in \mathbb{R^{m \times d }} 为实矩阵,bRmb\in \mathbb{R^m}cRdc\in \mathbb{R^d} 为实向量,AxbAx \leqslant b 的每一行对应一个约束。

QQ 为半正定矩阵,则上面的目标函数是凸函数,相应的二次规划为凸二次规划问题;此时若约束条件定义的可行域不为空,且目标函数在此可行域有下界,则该问题有全局最小值。

QQ 为正定矩阵,则该问题有唯一的全局最小值。

QQ 为非正定矩阵,则目标函数是有多个平稳点和局部极小点的NP难问题。

常用的二次规划问题求解方法有:

  • 椭球法
  • 内点法
  • 增广拉格朗日法
  • 梯度投影法等

QQ 为正定矩阵,则相应的二次规划问题可由椭球法在多项式时间内求解。

矩阵的正定及半正定[5:1]

正定矩阵是一种实对称矩阵。正定二次型 f(x1x2xn)=XTAXf(x_1,x_2,…,x_n)=X^TAX 的矩阵 AA (或 AA 的转置)称为正定矩阵。

当考虑矩阵的特征值时:

  • 若所有特征值均不小于零,则称为半正定。
  • 若所有特征值均大于零,则称为正定。

从几何的角度看的话:正定、半正定矩阵的直觉代表一个向量经过它的变化后的向量与其本身的夹角小于等于90度。

3. 拉格朗日与对偶函数[6]

在支持向量机和最大熵模型中都会用到拉格朗日对偶性,主要为解决约束最优化问题,通过将原始问题转换为对偶问题求解。

原始问题

先从最简单的求函数最小值开始说起:

minxRnf(x)\min_{\boldsymbol{x} \in \mathbf{R}^n}f(\boldsymbol{x})

f(x)f(x) 的最小值时 xx 的取值,f(x)f(x)RnR^n 上连续可微。这时候我们对 f(x)f(x) 求导令导数为 0 就能取到极值了。若此时加入约束如下:

minxRnf(x)\min_{\boldsymbol{x} \in \mathbf{R}^n}f(\boldsymbol{x})

s.t.ci(x)0,i=1,2,,khj(x)=0,j=1,2,,l\begin{aligned}\mathbb{s.t.}\quad &c_i(\boldsymbol{x}) \le 0,\quad i=1,2,\cdots,k\\&h_j(\boldsymbol{x})=0,\quad j=1,2,\cdots,l\end{aligned}

其中 f(x),ci(x),hj(x)Rnf(x),c_i(x),h_j(x)在R^n 上连续可微我们称此约束最优化为原始问题,也是拉格朗日对偶性需要解决的问题。

此时我们直接求导是无法解决了,要是可以将约束条件转换为未知变量或许就可以找到答案了。

拉格朗日函数

为了求解原始问题,我们首先引入广义拉格朗日函数 (generalized Lagrange function):

L(x,α,β)=f(x)+i=1kαici(x)+j=1lβjhj(x)L(\boldsymbol{x},\boldsymbol{\alpha},\boldsymbol{\beta})=f(\boldsymbol{x})+\sum_{i=1}^k \alpha_ic_i(\boldsymbol{x}) + \sum_{j=1}^l\beta_jh_j(\boldsymbol{x})

其中 x=(x1,x2,,xn)TRn\boldsymbol{x}=(x_1,x_2,\cdots,x_n)^T \in \mathbf{R}^nαi\alpha_iβj\beta _j 是拉格朗日乘子且 αi0\alpha_i \ge 0

拉格朗日函数虽然一眼看去十分复杂,但是其实它是将所有的限定条件加上新引入的变量(拉格朗日乘子)构成了一个新的函数,这样就将限定条件转换为了未知变量。

此时我们考虑 xx 的函数:

θP(x)=maxα,β:αi0L(x,α,β)\theta_P(\boldsymbol{x})=\max_{\boldsymbol{\alpha,\beta}:\alpha_i\ge0}L(\boldsymbol{x},\boldsymbol{\alpha},\boldsymbol{\beta})

下标 p 代表原始问题。

可以证明,如果 xx 满足原始问题中约束,那么 θ(x)=f(x)\theta(\boldsymbol{x})=f(\boldsymbol{x})

如果 xx 不满足原始问题中的约束(ci(x)0;hj(x)=0c_i(x)\le 0;h_j(x)=0),那么 θ(x)=+\theta(\boldsymbol{x})=+\infty,即:

θP(x)={f(x),x满足原始问题约束+,其他\theta_P(\boldsymbol{x})=\begin{cases}f(\boldsymbol{x}),&\boldsymbol{x} \text{满足原始问题约束}\\+\infty,&\text{其他}\end{cases} %]]>

所以如果考虑极小化问题:

minxθP(x)=minxmaxα,β:αi0L(x,α,β)\min_{\boldsymbol{x}}\theta_P(\boldsymbol{x})=\min_{\boldsymbol{x}}\max_{\boldsymbol{\alpha,\beta}:\alpha_i\ge0}L(\boldsymbol{x},\boldsymbol{\alpha},\boldsymbol{\beta})

就会发现它是与原始最优化问题等价的,即它们有相同的解。

minxmaxα,β:αi0L(x,α,β)\min_{\boldsymbol{x}}\max_{\boldsymbol{\alpha,\beta}:\alpha_i\ge0}L(\boldsymbol{x},\boldsymbol{\alpha},\boldsymbol{\beta}) 称为广义拉格朗日函数的极小极大问题。这样一来,就把原始最优化问题表示为广义拉格朗日函数的极小极大问题。我们定义原始问题最优解:

p=minxθP(x)p^*=\min_{x}\theta_P(x)

总结一下原始问题和拉格朗日函数:从原始问题开始,通过拉格朗日函数重新定义一个无约束问题,这个无约束问题等价于原来的约束优化问题,从而将约束问题无约束化。也就是将d个变量和k个约束条件的最优化问题转换为d+k个变量的最优化问题。到此我们还是无法求解,我们需要将原始问题转换成对偶问题来求解。

对偶问题

我们再定义:

θD(α,β)=minxL(x,α,β)\theta_D(\alpha,\beta)=\min_x L(x,\alpha,\beta)

并极大化 θD\theta_D,即:

maxα,βθD(α,β)=maxα,βminxL(x,α,β)\max_{\alpha,\beta}\theta_D(\alpha,\beta)=\max_{\boldsymbol{\alpha,\beta}}\min_{\boldsymbol{x}}L(\boldsymbol{x},\boldsymbol{\alpha},\boldsymbol{\beta})

maxα,βminxL(x,α,β)\max_{\boldsymbol{\alpha,\beta}}\min_{\boldsymbol{x}}L(\boldsymbol{x},\boldsymbol{\alpha},\boldsymbol{\beta}) 为广义拉格朗日函数的极大极小问题(上一节的是极小极大问题)。这样可以将广义拉格朗日函数的极大极小问题进一步表示为约束最优化问题:

maxα,βθD(α,β)=maxα,βminxL(x,α,β)s.t.αi0,i=1,2,,k\begin{aligned} \max_{\alpha,\beta}\theta_D(\alpha,\beta)= \max_{\boldsymbol{\alpha,\beta}}\min_{\boldsymbol{x}}L(\boldsymbol{x},\boldsymbol{\alpha},\boldsymbol{\beta}) \\ \mathbb{s.t.}\quad\alpha_i\ge0,\quad i=1,2,\cdots,k \end{aligned}

我们将上面的问题称为原始问题的对偶问题。定义对偶问题的最优值

d=maxα,βθD(α,β)d^* = \max_{\alpha,\beta}\theta_D(\alpha,\beta)

对比原始问题,对偶问题是先固定 αα, ββ,求最优化 xx 的解,再确定参数 αα, ββ

原始问题是先固定 xx,求最优化 αα, ββ的解,再确定 xx

原始问题和对偶问题的关系

若原始问题和对偶问题都有最优值,那么

d=maxα,βminxL(x,α,β)minxmaxα,β:αi0L(x,α,β)=pd^*=\max_{\boldsymbol{\alpha,\beta}}\min_{\boldsymbol{x}}L(\boldsymbol{x},\boldsymbol{\alpha},\boldsymbol{\beta})\le\min_{\boldsymbol{x}}\max_{\boldsymbol{\alpha,\beta}:\alpha_i\ge0}L(\boldsymbol{x},\boldsymbol{\alpha},\boldsymbol{\beta})=p^*

也就是说原始问题的最优值不小于对偶问题的最优值,但是我们要通过对偶问题来求解原始问题,就必须使得原始问题的最优值与对偶问题的最优值相等,于是可以得出下面的推论:

xx^∗αα^∗, ββ^∗ 分别是原始问题和对偶问题的可行解并且 d=pd^∗=p^∗xx^∗αα^∗, ββ^∗ 分别是原始问题和对偶问题的最优解。

对偶问题跟原始问题可以看成本来是两个问题,因为优化的顺序不同而会得出两个不一定相关的值(但是 minxmaxyf(x,y)maxymaxxf(x,y)\mathop{min}_{x}\mathop{max}_{y}f(x,y) \geq \mathop{max}_{y}\mathop{max}_{x}f(x,y)) 还是成立的,直观理解的话高中经常用的二次函数就可以了)。

两者的差值就是 duality gap,描述了我用另一种方式刻画问题的时候所造成的误差,强对偶的情况下最优值没有差别。

在最优点处将会满足KKT 条件,但是KKT条件本身并不需要问题满足强对偶。关于KKT条件什么时候不满足,有一种另外的理解是他要求各个函数的梯度张成足够大的空间(因为KKT的最后一条本质上是一个 Ax=0Ax=0 的问题)。

所以,当原始问题和对偶问题的最优值相等:d=pd^∗ =p^*时,可以用求解对偶问题来求解原始问题(当然是对偶问题求解比直接求解原始问题简单的情况下),但是到底满足什么样的条件才能使d=pd^∗=p^∗呢,这就是下面要阐述的 KKT 条件。

4. strong duality 和 KKT 条件

强对偶性

若原始问题(对偶问题)有一个确定的最优解,那么对偶问题(原始问题)也有一个确定的最优解,而且这两个最优解所对应的目标函数值相等,这就是强对偶性。[7]

KKT条件[6:1]

对原始问题和对偶问题,假设函数 f(x)f(x)ci(x)c_i(x) 是凸函数, hj(x)h_j(x) 为仿射函数,并且不等式约束 ci(x)c_i(x) 是严格可行的,则 xx^∗αα^∗, ββ^∗ 分别是原始问题和对偶问题的解的充要条件是 xx^∗αα^∗, ββ^∗ 满足下面的Karush-Kuhn-Tucker(KKT)条件:

xL(x,α,β)=0αL(x,α,β)=0βL(x,α,β)=0αici(x)=0,i=1,2,,kci(x)0,i=1,2,,kαi0,i=1,2,,khj(x)=0,j=1,2,,l\begin{aligned} \nabla_\boldsymbol{x}L(\boldsymbol{x}^*,\boldsymbol{\alpha}^*,\boldsymbol{\beta}^*)=0 \\ \nabla_\boldsymbol{\alpha}L(\boldsymbol{x}^*,\boldsymbol{\alpha}^*,\boldsymbol{\beta}^*)=0 \\ \nabla_\boldsymbol{\beta}L(\boldsymbol{x}^*,\boldsymbol{\alpha}^*,\boldsymbol{\beta}^*)=0 \\ \alpha_i^*c_i(\boldsymbol{x}^*)=0,\quad i=1,2,\cdots,k\\ c_i(\boldsymbol{x}^*)\le0,\quad i=1,2,\cdots,k\\ \alpha_i^*\ge0,\quad i=1,2,\cdots,k\\ h_j(\boldsymbol{x}^*)=0,\quad j=1,2,\cdots,l \end{aligned}

关于KKT 条件的理解:前面三个条件是对于各个变量的偏导数为0(这就解释了一开始为什么假设三个函数连续可微,如果不连续可微的话,这里的偏导数存不存在就不能保证),后面四个条件就是原始问题的约束条件以及拉格朗日乘子需要满足的约束。

仿射函数[6:2]

f(x)=Ax+bf(\boldsymbol{x})=\boldsymbol{A}\boldsymbol{x}+b

仿射函数就是一个线性函数,其输入是n维向量,参数 A可以是常数,也可以是m×n的矩阵,b可以是常数,也可以是m维的列向量,输出是一个m维的列向量。在几何上,仿射函数是一个线性空间到另一个线性空间的变换。

5. 非凸优化问题[8]

凸优化-相对简单

凸优化有个非常重要的定理,即任何局部最优解即为全局最优解。由于这个性质,只要设计一个较为简单的局部算法,例如贪婪算法(Greedy Algorithm)或梯度下降法(Gradient Decent),收敛求得的局部最优解即为全局最优。因此求解凸优化问题相对来说是比较高效的。这也是为什么机器学习中凸优化的模型非常多,毕竟机器学习处理大数据,需要高效的算法。

非凸优化-非常困难

而非凸优化问题被认为是非常难求解的,因为可行域集合可能存在无数个局部最优点,通常求解全局最优的算法复杂度是指数级的(NP难)。最经典的算法要算蒙特卡罗投点法了,大概思想便是随便投个点,然后在附近区域(可以假设convex)得到局部最优值。然后随机再投个点,再找到局部最优点。如此反复,直到满足终止条件。

非凸优化为何重要,开始受到重视?

因为现实生活中,几乎所有问题的本质是非凸的。

科学的本质便是由简到难,先把简单问题研究透彻,然后把复杂问题简化为求解一个个简单问题。例如上面提到的投点法,就是在求解一个个的凸优化问题。假设需要求解 1w 个凸优化问题可以找到非凸优化的全局最优点,那么凸优化被研究透彻了,会加速凸优化问题的求解时间,例如0.001秒。这样求解非凸优化问题=求解1w个凸优化问题=10秒,还是可以接受的。

运筹学中线性规划与凸优化的关系

线性规划是运筹学最基础的课程,其可行域(可行解的集合)是多面体(polyhedron),具有着比普通的凸集更好的性质。因此是比较容易求解的(多项式时间可解)。

深度学习为何非凸

深度学习里的损失函数,是一个高度复合的函数。例如 h(x)=f(g(x))h(x)=f(g(x)) 就是 ffgg 复合函数。

ffgg 都是线性的时候,hh 是线性的。但在深度学习里用到的函数,Logistic, ReLU等等,都是非线性 ,并且非常多。把他们复合起来形成的函数 hh, 便是非凸的。

求解这个非凸函数的最优解,类似于求凸优化中某点的梯度,然后按照梯度最陡的方向搜索。不同的是,复合函数无法求梯度,于是这里使用 Back Propagation 求解一个类似梯度的东西,反馈能量,然后更新。

深度学习中的优化问题,虽然目标函数非常复杂,但是它没有约束。运筹学由目标函数和约束条件组成,而约束条件,是使得运筹学的优化问题难以求解的重要因素。

6. NP-Hard 问题与松弛化处理

P、NP

  • P问题:在多项式时间内可以被解决的问题
  • NP问题:在多项式时间内可以被验证其正确性的问题

售货员旅行问题 (traveling salesman problem),是最具有代表性的NP问题之一。假设一个推销员需要从香港出发,经过广州,北京,上海,…,等 n 个城市, 最后返回香港。 任意两个城市之间都有飞机直达,但票价不等。现在假设公司只给报销 C 块钱,问是否存在一个行程安排,使得他能遍历所有城市,而且总的路费小于 C?

推销员旅行问题显然是 NP 的。因为如果你任意给出一个行程安排,可以很容易算出旅行总开销。但是,要想知道一条总路费小于 C 的行程是否存在,在最坏情况下,必须检查所有可能的旅行安排! 这将是个天文数字。

这个天文数字到底有多大?目前的方法接近一个一个的排着试,还没有找到更好可以寻得最短路径的方法。对七个城而言,共有 6!=7206!=720 个排法,还比较简单;但若有 20 个城,则排法就有 19!19! 种。在排列组合里 n!n! 写起来轻松。但 1.21×10171.21 \times 10^{17} 是一个大得不得了的数字。若每秒钟排一次,要排 3.84×1093.84 \times 10^9 年(一年约为 3.15×1073.15 \times 10^7 秒),即使使用计算器,每秒排一百万次(不容易做到)也得重做三千年才能找到答案。「生也有涯,知也无涯」,想不到区区二十个城,要三十个世纪才能找到答案。[9]

NP 困难

  • NPC(Non-deterministic Polynomial Complete) Problem: 满足两个条件 (1)是一个NP问题 (2) 所有的NP问题都可以约化到它
  • NP-Hard Problem: 满足NPC问题的第二条,但不一定要满足第一条[9:1]

NP困难(NP-hardness, non-deterministic polynomial-time hardness)问题是计算复杂性理论中最重要的复杂性类之一。如果所有NP问题都可以多项式时间归约到某个问题,则称该问题为NP困难。

因为NP困难问题未必可以在多项式时间内验证一个解的正确性(即不一定是NP问题),因此即使NP完全问题有多项式时间的解(P=NP),NP困难问题依然可能没有多项式时间的解。因此NP困难问题“至少与NP完全问题一样难”。[10]

松弛化处理

线性规划的松弛[11]

在数学中,0-1整数规划的线性规划的松弛是这样的问题:把每个变量必须为0或1的约束,替换为较弱的每个变量属于区间[0,1]的约束。

也就是说,对于原整数规划的每个下列形式的约束:x{0,1}x \in \{0, 1\}

我们转而使用一对线性约束来代替:0xi10 \le x_i \le 1

这样产生的松弛是线性规划,因此得名线性规划的松弛。这种松弛技术把NP难的最优化问题(整数规划)转化为一个相关的多项式时间可解的问题(线性规划)。我们可以用松弛后的线性规划的解来获得关于原整数规划的解的信息。

拉格朗日松弛[12]

拉格朗日松弛技术是一个非常简单而漂亮地转化方法。

首先,拉格朗日松弛技术是用在优化问题里面(假设是最小化问题),而且一定是有约束条件的优化问题。

假设我们已经知道没有约束条件的优化问题怎么解了。然后对于有约束条件的优化问题,我们想懒一点的话,就可以想想办法怎么把它转化成没有约束条件的优化问题。

于是有人就想到

  1. 直接去掉约束条件

    那显然定义域变大了,那得到的最小值肯定不比原来的大。那怎么办?

  2. 那就如果不满足某些约束条件,我们就来点惩罚

    这个惩罚表现在目标函数上。我们在目标函数上多加一项,如果某些约束条件没有满足,那目标函数就会变大。

另外我们也多了拉格朗日乘子,它也是我们可以动的变量。这时候最优的结果当然会满足所有约束条件,不然就被罚惨了。

这就是所谓的拉格朗日松弛技术,是把有约束优化问题转化成无约束优化问题的好方法。

我们知道拉格朗日乘子法在保留原函数的基础上引入了一个线性项,那么这个线性项有什么作用呢?它保证了在获得最优乘子的情况下,原目标函数的解和拉格朗日函数的解是一致的。具体是怎么做的呢?

我们假设当前点偏离了等式约束,并且我们已知偏离等式约束的这个点对应的原函数的值要比满足等式约束值的原函数的最优值要小。那么拉格朗日引入了这个线性项之后,两者相加,大于那个最优值。那么这样实际上最优值还是在等式约束满足的情况下得到。

因此拉格朗日函数就起到了对偏离等式约束的惩罚作用,保证了原目标函数和拉格朗日函数解的一致性。

虽然说拉格朗日乘子法的线性项只是对原目标函数的一个线性逼近,也就是说两者之间不是等价的,但是拉格朗日乘子法,能够保证在取得最优乘子的情况下两者解的一致性,那么很显然通过求解拉格朗日函数的最优解来求得原目标函数的最优解是一种更实际,更方便的做法。

比如要解如下问题:

minx2+y2s.t.   x+y=1\begin{aligned} \min x^2+y^2\\ s.t.\space \space \space x+y=1 \end{aligned}

我们可以用拉格朗日乘子 pp 转换这个问题为:

minL(x,y,p)=x2+y2+p(1xy)\min L(x,y,p)=x^2+y^2+p(1-x-y)

令:Lx=0,Ly=0\frac{\partial L}{\partial x}=0,\frac{\partial L}{\partial y}=0

可得:x=y=p2x=y=\frac{p}2

x+y=1\because x+y=1

x=y=0.5,p=1\therefore x=y=0.5,p=1

pp 即惩罚

7. 离散优化

  1. 连续优化(continuous optimization)

    连续优化是求解在连续变量的问题,其一般地是求一组实数,或者一个函数。

  2. 离散优化(discrete optimization)

    连续优化是求解离散变量的问题,是从一个无限集或者可数无限集里寻找一个对象,典型地是一个整数,一个集合,一个排列,或者一个图。

  3. 组合优化(combinatorial optimization)

    组合优化问题的目标是从组合问题的可行解集中求出最优解,通常可描述为:令 Ω={s1s2sn}Ω=\{s1,s2,…,sn\} 为所有状态构成的解空间,C(si)C(s_i) 为状态 sis_i 对应的目标函数值,要求寻找最优解 ss,使得对于所有的 siΩs_i \in Ω,有 C(s)=minC(si)C(s^*)=\min C(s_i)。组合优化往往涉及排序、分类、筛选等问题,它是运筹学的一个重要分支。

    典型的组合优化问题有旅行商问题、加工调度问题、0-1背包问题、装箱问题、图着色问题、聚类问题等。这些问题描述非常简单,并且有很强的工程代表性,但最优化求解很困难,其主要原因是求解这些问题的算法需要极长的运行时间与极大的存储空间,以致根本不可能在现有计算机上实现,即所谓的“组合爆炸”。正是这些问题的代表性和复杂性激起了人们对组合优化理论与算法的研究兴趣。

8. 梯度下降、随机梯度下降、Adam和Adagrad

梯度下降[13]

微分

梯度下降法的基本思想可以类比为下山的过程。假设这样一个场景:一个人被困在山上,需要从山上下来(i.e. 找到山的最低点,也就是山谷)。但此时山上的浓雾很大,导致可视度很低。因此,下山的路径就无法确定,他必须利用自己周围的信息去找到下山的路径。这个时候,他就可以利用梯度下降算法来帮助自己下山。具体来说就是,以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着山的高度下降的地方走,同理,如果我们的目标是上山,也就是爬到山顶,那么此时应该是朝着最陡峭的方向往上走。然后每走一段距离,都反复采用同一个方法,最后就能成功的抵达山谷。

单变量函数的微分:

f(x)=x2f(x)=2x\begin{aligned} f(x)=x^2 \\ f'(x)=2x \end{aligned}

多变量函数的微分:

f(x,y)=x2y2fx=2xy2,fy=x22y\begin{aligned} f(x,y)=x^2y^2\\ \frac{\partial{f}}{\partial{x}}=2xy^2,\frac{\partial{f}}{\partial{y}}=x^22y \end{aligned}

以上这些内容都很好理解,单变量函数微分对那一个变量求导数即可,多变量函数微分,对每一个变量求偏导数即可。

而后者,就是梯度。

梯度

假设有:

J(θ)=0.55(5θ1+2θ212θ3)J(\theta)=0.55-(5\theta_1+2\theta_2-12\theta_3)

所以其梯度可写作如下:

J(θ)=Jθ1,Jθ2,Jθ3=5,2,12\nabla{J(\theta)}=\lang{\frac{\partial{J}}{\partial{\theta_1}},\frac{\partial{J}}{\partial{\theta_2}},\frac{\partial{J}}{\partial{\theta_3}}}\rang=\lang{-5,-2,12}\rang

我们可以看到,梯度就是分别对每个变量进行微分,然后用逗号分割开,梯度是用<>包括起来,说明梯度其实是向量。

  • 在单变量的函数中,梯度其实就是函数的微分,代表着函数在某个给定点的切线的斜率
  • 在多变量函数中,梯度是向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向

我们需要到达山底,就需要在每一步观测到此时最陡峭的地方,梯度就恰巧告诉了我们这个方向。梯度的方向是函数在给定点上升最快的方向,那么梯度的反方向就是函数在给定点下降最快的方向,这正是我们所需要的。所以我们只要沿着梯度的方向一直走,就能走到局部的最低点。

梯度下降

梯度下降公式:

Θ1=Θ0αJ(Θ)\Theta^1=\Theta^0-\alpha{\nabla{J(\Theta)}}

此公式是一个程序算法迭代的公式,等式右边的计算结果会赋值到等式左边。我们当前所处的位置为 Θ0\Theta^0 点,要从这个点走到 JJ 的最小值点,也就是山底。首先我们先确定前进的方向,也就是梯度的反向,然后走一段距离的步长,也就是 α\alpha,走完这个段步长,就到达了 Θ1\Theta^1 这个点。

α\alpha 在梯度下降算法中被称作为学习率或者步长,一般是 (0,1](0,1] 的数,意味着我们可以通过 α\alpha 来控制每一步走的距离,不要走太快,错过了最低点。

一个例子

假设有单变量的函数:

J(θ)=θ2J(\theta)=\theta^2

其微分:

J(θ)=2θJ'(\theta)=2\theta

随便选取初始点 θ0=1,α=0.4\theta^0=1,\alpha=0.4,根据 Θ1=Θ0αJ(Θ)\Theta^1=\Theta^0-\alpha{\nabla{J(\Theta)}} 公式,可计算梯度下降迭代过程:

θ0=1θ1=θ0α×J(θ0)=10.4×2=0.2θ2=θ1α×J(θ1)=0.04θ3=0.008θ4=0.0016\begin{aligned} \theta^0&=1\\ \theta^1&=\theta^0-\alpha\times{J'(\theta^0)}\\ &=1-0.4\times{2}\\ &=0.2\\ \theta^2&=\theta^1-\alpha\times{J'(\theta^1)}\\ &=0.04\\ \theta^3&=0.008\\ \theta^4&=0.0016 \end{aligned}

随机梯度下降

在上一篇种我们讨论了,「以当前的所处的位置为基准,寻找这个位置最陡峭的地方」,实际上在机器学习种,使用大量样本来学习时,就会导致样本集中的每一个样本都要计算一下梯度,损失函数的维度越高,计算所花费的时间成本就越高。

比如有如下损失函数,目标函数的损失函数通常取各个样本损失函数的平均:

J(x)=1ni=1nJ(xi)J(x)=\frac{1}{n}\sum_{i=1}^{n}{J(x_i)}

其中 J(xi)J(x_i) 是第 xix_i 个样本的目标函数,那么目标函数在 xx 处的梯度为:

J(x)=1ni=1nJ(xi)\nabla{J(x)}=\frac{1}{n}\nabla\sum_{i=1}^{n}{J(x_i)}

如果使用梯度下降法(批量梯度下降法),那么每次迭代过程中都要对 nn 个样本进行求梯度,所以开销非常大,随机梯度下降的思想就是随机采样一个样本 J(xi)J(x_i) 来更新参数,那么计算开销就从 O(n)O(n) 下降到 O(1)O(1)[14]

随机梯度下降的缺点:

  • 选择合适的 learning rate 比较困难 - 对所有的参数更新使用同样的 learning rate。对于稀疏数据或者特征,有时我们可能想更新快一些对于不经常出现的特征,对于常出现的特征更新慢一些,这时候SGD就不太能满足要求了
  • SGD容易收敛到局部最优,并且在某些情况下可能被困在鞍点。[15]

为了解决以上确定,引入下面两个主题。

动量法[16]

如果说随机梯度下降或小批量随机梯度下降的收敛情况如下图:

那么,加上动量,让他震荡不那么极端的剧烈,就是类似下图的收敛情况:

上文中曾经提到过 Θn=Θn1αJ(Θn)\Theta_n=\Theta_{n-1}-\alpha{\nabla{J(\Theta_n)}} 梯度下降的公式,加入动量限制:

mn=γmn1+αJ(Θn)Θn=Θn1mn\begin{aligned} m_n&=\gamma{m_{n-1}}+\alpha{\nabla{J(\Theta_n)}}\\ \Theta_n&=\Theta_{n-1}-m_n \end{aligned}

其中,nn 代表本轮,n1n-1 代表上一轮,动量超参数 γγ 满足 0γ<10≤γ<1 。当 γ=0γ=0 时,动量法等价于小批量随机梯度下降。

在超参数设置合适的情况下,还能达到更加好的在竖直方向上的移动更加平滑,且在水平方向上更快逼近最优解的收敛效果:

数学原理

假设当前时间步 tt 的变量 yty_t 是上一时间步 t1t−1 的变量 yt1y_{t−1} 和当前时间步另一变量 xtx_t 的线性组合:

yt=γyt1+(1γ)xt.y_t = \gamma y_{t-1} + (1-\gamma) x_t.

展开可得无穷级数形式:

yt=(1γ)xt+γyt1=(1γ)xt+(1γ)γxt1+γ2yt2=(1γ)xt+(1γ)γxt1+(1γ)γ2xt2+γ3yt3\begin{aligned} y_t &= (1-\gamma) x_t + \gamma y_{t-1}\\ &= (1-\gamma)x_t + (1-\gamma) \cdot \gamma x_{t-1} + \gamma^2y_{t-2}\\ &= (1-\gamma)x_t + (1-\gamma) \cdot \gamma x_{t-1} + (1-\gamma) \cdot \gamma^2x_{t-2} + \gamma^3y_{t-3}\\ &\ldots \end{aligned}

其中重复出现的部分是:(1γ)×γnxtn(1-\gamma)\times{\gamma^{n}x_{t-n}}

其中最重要的部分 γn\gamma^n ,由于 γ\gamma 取值范围是 (0,1](0,1],当 γn\gamma^n 是一个很小的数时,无穷小项后面可以忽略不计,比如当其小于 exp(1)0.3679exp(-1)\approx 0.3679 时。

limn(11n)n=exp(1)0.3679\lim_{n \rightarrow \infty} \left(1-\frac{1}{n}\right)^n = \exp(-1) \approx 0.3679

所以,当 γ1\gamma \rightarrow 1 时, γ1/(1γ)=exp(1)\gamma^{1/(1-\gamma)}=\exp(-1)

所以,上面的 γn\gamma^n 中的 nn 可取 11γ\frac{1}{1-\gamma}

比如,γ=0.95\gamma =0.95 时,yt0.05i=0190.95ixtiy_t \approx 0.05 \sum_{i=0}^{19} 0.95^i x_{t-i}yty_t 可以被看作对最近 20 个时间步的 xtx_t 值的加权平均;当 γ=0.9γ=0.9 时, yty_t 可以看作是对最近 10 个时间步的 xtx_t 值的加权平均。而且,离当前时间步 tt 越近的 xtx_t 值获得的权重越大(越接近1)。

缺点

当自变量 x1x_1x2x_2 的梯度值有较大差别时,需要选择足够小的学习率使得自变量在梯度值较大的维度上不发散。但这样会导致自变量在梯度值较小的维度上迭代过慢。动量法依赖指数加权移动平均使得自变量的更新方向更加一致,从而降低发散的可能。

由此引入下一个话题,它根据自变量在每个维度的梯度值的大小来调整各个维度上的学习率,从而避免统一的学习率难以适应所有维度的问题。

AdaGrad[17]

AdaGrad 算法会使用一个小批量随机梯度 gt\boldsymbol{g}_t 按元素平方的累加变量 st\boldsymbol{s}_t 。在时间步0,AdaGrad 将 s0\boldsymbol{s}_0 中每个元素初始化为0。在时间步 tt ,首先将小批量随机梯度 gt\boldsymbol{g}_t 按元素平方后累加到变量 st\boldsymbol{s}_t ,其中 \odot 是按元素相乘。接着,我们将目标函数自变量中每个元素的学习率通过按元素运算重新调整一下:

st=st1+gtgt,Θt=Θt1αst+ϵgt\begin{aligned} \boldsymbol{s_t}&=\boldsymbol{s}_{t-1}+\boldsymbol{g}_t \odot \boldsymbol{g}_t,\\ \Theta_t&=\Theta_{t-1}-\frac{\alpha}{\sqrt{\boldsymbol{s}_t + \epsilon}} \odot \boldsymbol{g}_t \end{aligned}

其中 α\alpha 是学习率, ϵ\epsilon 是为了维持数值稳定性而添加的常数,如 10610^{−6} 。这里开方、除法和乘法的运算都是按元素运算的。这些按元素运算使得目标函数自变量中每个元素都分别拥有自己的学习率。

需要强调的是,小批量随机梯度按元素平方的累加变量 st\boldsymbol{s}_t 出现在学习率的分母项中。因此,如果目标函数有关自变量中某个元素的偏导数一直都较大,那么该元素的学习率将下降较快;反之,如果目标函数有关自变量中某个元素的偏导数一直都较小,那么该元素的学习率将下降较慢。然而,由于 st\boldsymbol{s}_t 一直在累加按元素平方的梯度,自变量中每个元素的学习率在迭代过程中一直在降低(或不变)。所以,当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad 算法在迭代后期由于学习率过小,可能较难找到一个有用的解。

自变量的迭代轨迹较平滑,在迭代后期的移动幅度较小

  • AdaGrad算法在迭代过程中不断调整学习率,并让目标函数自变量中每个元素都分别拥有自己的学习率。

  • 使用AdaGrad算法时,自变量中每个元素的学习率在迭代过程中一直在降低(或不变)。

RMSProp[18]

st=γst1+(1γ)gtgt,Θt=Θt1αst+ϵgt\begin{aligned} \boldsymbol{s_t}&=\gamma\boldsymbol{s}_{t-1}+(1-\gamma)\boldsymbol{g}_t \odot \boldsymbol{g}_t,\\ \Theta_t&=\Theta_{t-1}-\frac{\alpha}{\sqrt{\boldsymbol{s}_t + \epsilon}} \odot \boldsymbol{g}_t \end{aligned}

动量法和AdaGrad的结合,同样的学习率下,RMSProp 算法可以更快逼近最优解。

Adam[19]

Adam 算法使用了动量变量 vt\boldsymbol{v}_t 和 RMSProp 算法中小批量随机梯度按元素平方的指数加权移动平均变量 st\boldsymbol{s}_t,并在时间步 0 将它们中每个元素初始化为0。给定超参数 0β1<10 \leq \beta_1 < 1(算法作者建议设为0.9),时间步 tt 的动量变量 vt\boldsymbol{v}_t 即小批量随机梯度 gt\boldsymbol{g}_t 的指数加权移动平均:

vtβ1vt1+(1β1)gt.\boldsymbol{v}_t \leftarrow \beta_1 \boldsymbol{v}_{t-1} + (1 - \beta_1) \boldsymbol{g}_t.

和 RMSProp 算法中一样,给定超参数 0β2<10 \leq \beta_2 < 1(算法作者建议设为0.999), 将小批量随机梯度按元素平方后的项 gtgt\boldsymbol{g}_t \odot \boldsymbol{g}_t 做指数加权移动平均得到 st\boldsymbol{s}_t

stβ2st1+(1β2)gtgt.\boldsymbol{s}_t \leftarrow \beta_2 \boldsymbol{s}_{t-1} + (1 - \beta_2) \boldsymbol{g}_t \odot \boldsymbol{g}_t.

由于我们将 v0\boldsymbol{v}_0s0\boldsymbol{s}_0 中的元素都初始化为 0, 在时间步 tt 我们得到 vt=(1β1)i=1tβ1tigi\boldsymbol{v}_t = (1-\beta_1) \sum_{i=1}^t \beta_1^{t-i} \boldsymbol{g}_i。将过去各时间步小批量随机梯度的权值相加,得到 (1β1)i=1tβ1ti=1β1t(1-\beta_1) \sum_{i=1}^t \beta_1^{t-i} = 1 - \beta_1^t。需要注意的是,当 tt 较小时,过去各时间步小批量随机梯度权值之和会较小。例如,当 β1=0.9\beta_1 = 0.9 时,v1=0.1g1\boldsymbol{v}_1 = 0.1\boldsymbol{g}_1。为了消除这样的影响,对于任意时间步 tt,我们可以将 vt\boldsymbol{v}_t 再除以 1β1t1 - \beta_1^t,从而使过去各时间步小批量随机梯度权值之和为 1。这也叫作偏差修正。在Adam算法中,我们对变量vtst\boldsymbol{v}_t和\boldsymbol{s}_t均作偏差修正:

v^tvt1β1t,s^tst1β2t.\hat{\boldsymbol{v}}_t \leftarrow \frac{\boldsymbol{v}_t}{1 - \beta_1^t}, \hat{\boldsymbol{s}}_t \leftarrow \frac{\boldsymbol{s}_t}{1 - \beta_2^t}.

接下来,Adam算法使用以上偏差修正后的变量 v^t\hat{\boldsymbol{v}}_ts^t\hat{\boldsymbol{s}}_t,将模型参数中每个元素的学习率通过按元素运算重新调整:

gtηv^ts^t+ϵ,\boldsymbol{g}_t' \leftarrow \frac{\eta \hat{\boldsymbol{v}}_t}{\sqrt{\hat{\boldsymbol{s}}_t} + \epsilon},

其中 η\eta 是学习率,ϵ\epsilon 是为了维持数值稳定性而添加的常数,如 10810^{-8}。和 AdaGrad 算法、RMSProp 算法一样,目标函数自变量中每个元素都分别拥有自己的学习率。最后,使用 gt\boldsymbol{g}_t' 迭代自变量:

xtxt1gt.\boldsymbol{x}_t \leftarrow \boldsymbol{x}_{t-1} - \boldsymbol{g}_t'.

Adam 算法是 RMSProp 算法与动量法的结合。

9. L-BFGS[20]

首先,L-BFGS 算法是一种拟牛顿法,是求解非线性优化问题最有效的方法之一。

考虑如下无约束的极小化问题:

minxf(x),min_\mathbf{x}f(\mathbf x),

其中 x=(x1,x2,,xN)TRN\mathbf x=(x_1,x_2,\dots,x_N)^T \in \mathbb{R}^N,假设 ff 为凸函数,且二阶连续可微,记极小问题的解为 xx^*

牛顿法

首先考虑 N=1N=1 的简单情况(此时目标函数 f(x)f(\mathbf x) 变成 f(x)f(x)),牛顿法的基本思想是:在现有极小点估计值的附近对 f(x)f(x) 做二阶泰勒展开,进而找到极小点的下一个估计值。

xkx_k 为当前的极小点估计值,则

φ(x)=f(xk)+f(xk)(xxk)+12f(xk)(xxk)2\varphi(x)=f(x_k)+f'(x_k)(x-x_k)+\frac{1}{2}f''(x_k)(x-x_k)^2

表示 f(x)f(x)xkx_k 附近的二阶泰勒展开式,由于求的是最值,由极值必要条件可知,φ(x)\varphi(x) 应满足

φ(x)=0,\varphi'(x)=0,

f(xk)+f(xk)(xxk)=0,f'(x_k)+f''(x_k)(x-x_k)=0,

从而得

x=xkf(xk)f(xk),x=x_k-\frac{f'(x_k)}{f''(x_k)},

于是,若给定初始值 x0x_0,则可以构造如下的迭代公式

xk+1=xkf(xk)f(xk),k=0,1,x_{k+1}=x_k-\frac{f'(x_k)}{f''(x_k)},k=0,1,\dots

产生序列 {xk}\{x_k\} 来逼近 f(x)f(x) 的极小点。在一定条件下,{xk}\{x_k\} 可以收敛到 f(x)f(x) 的极小点。

对于 N>1N > 1 的情形,二阶泰勒展开式可以做推广

φ(x)=f(xk)+f(xk)(xxk)+12(xxk)T2f(xk)(xxk)\varphi(\mathbf x)=f(\mathbf{x}_k)+\nabla f(\mathbf{x}_k)(\mathbf{x}-\mathbf{x}_k)+\frac{1}{2}(\mathbf{x}-\mathbf{x}_k)^T\nabla^2 f(\mathbf{x}_k)(\mathbf{x}-\mathbf{x}_k)

其中, f\nabla fff 的梯度向量,2f\nabla^2fff 的海森矩阵。

f=[fx1fx2fxN],2f=[2fx122fx1x22fx1xN2fx2x12fx222fx2xN2fxNx12fxNx22fxN2]N×N\begin{aligned} \nabla f=\left[\begin{array}{c} \frac{\partial f}{\partial x_{1}} \\ \frac{\partial f}{\partial x_{2}} \\ \vdots \\ \frac{\partial f}{\partial x_{N}} \end{array}\right], \quad \nabla^{2} f=\left[\begin{array}{cccc} \frac{\partial^{2} f}{\partial x_{1}^{2}} & \frac{\partial^{2} f}{\partial x_{1} \partial x_{2}} & \cdots & \frac{\partial^{2} f}{\partial x_{1} \partial x_{N}} \\ \frac{\partial^{2} f}{\partial x_{2} \partial x_{1}} & \frac{\partial^{2} f}{\partial x_{2}^{2}} & \cdots & \frac{\partial^{2} f}{\partial x_{2} \partial x_{N}} \\ & & \ddots & \\ \frac{\partial^{2} f}{\partial x_{N} \partial x_{1}} & \frac{\partial^{2} f}{\partial x_{N} \partial x_{2}} & \cdots & \frac{\partial^{2} f}{\partial x_{N}^{2}} \end{array}\right]_{N \times N} \end{aligned}

后续的方法和 N=1N=1 时类似,充满线性代数的知识,不再赘述。

g\mathbf{g}f\nabla fHH2f\nabla^2f ,若给定初始值 x0\mathbf{x}_0 ,则同样可以构造出迭代公式

xk+1=xkHk1gk,k=0,1,\mathbf{x_{k+1}}=\mathbf{x}_k-H_k^{-1}\mathbf{g}_k,k=0,1,\dots

这就是原始的牛顿迭代法,其迭代公式中的搜索方向 dk=Hk1gkd_k=-H_k^{-1}\mathbf{g}_k 称为牛顿方向。

当目标函数是二次函数时,由于二次泰勒展开函数与原目标函数不是近似而是完全相同的二次式,海森矩阵退化成一个常数矩阵,从任一初始点出发,利用迭代公式只需一步迭代即可达到 f(x)f(x) 的极小点 xx^*,因此牛顿法是一种具有二次收敛性的算法。对于非二次函数,若函数的二次性态较强,或迭代点已经进入极小点的邻域,则其收敛速度也是很快的,这是牛顿法的主要优点。

但原始牛顿法由于迭代公式中没有步长因子,对于非二次型目标函数,有时会使函数值上升,即出现 f(xk+1)>f(xk)f(\mathbf{x}_{k+1}) > f(\mathbf{x}_{k}) 的情况,这表明原始牛顿法不能保证函数值稳定的下降。

牛顿法是梯度下降法的进一步发展,梯度法利用目标函数的一阶偏导数信息、以负梯度方向作为搜索方向,只考虑目标函数在迭代点的局部性质;而牛顿法不仅使用目标函数的一阶偏导数,还进一步利用了目标函数的二阶偏导数,这样就考虑了梯度变化的趋势,因而能更全面的确定合适的搜索方向以加快收敛,它具有二阶收敛速度。但是存在以下两个确定:

  • 对目标函数有严格的要求,函数必须是具有连续的一阶、二阶偏导数,海森矩阵必须正定,
  • 计算复杂,除计算梯度外,还需要计算二阶偏导数矩阵和逆矩阵。

拟牛顿法

上节提到了牛顿法的缺点,拟牛顿法就是将牛顿法中用来计算搜索方向的海森矩阵做了近似计算。

BH,DH1B \approx H, D\approx H^{-1}

设经过 k+1k+1 次迭代后得到 xk+1\mathbf{x}_{k+1},此时将目标函数 f(x)f(x)xk+1\mathbf{x}_{k+1} 附近作泰勒展开,取二阶近似,得到

f(x)f(xk+1)+f(xk+1)(xxk+1)+12(xxk+1)T2f(xk+1)(xxk+1)f(\mathbf{x}) \approx f\left(\mathbf{x}_{k+1}\right)+\nabla f\left(\mathbf{x}_{k+1}\right) \cdot\left(\mathbf{x}-\mathbf{x}_{k+1}\right)+\frac{1}{2} \cdot\left(\mathbf{x}-\mathbf{x}_{k+1}\right)^{T} \cdot \nabla^{2} f\left(\mathbf{x}_{k+1}\right) \cdot\left(\mathbf{x}-\mathbf{x}_{k+1}\right)

两边同时求梯度,得

f(x)f(xk+1)+Hk+1(xxk+1)\nabla f(\mathbf{x}) \approx \nabla f\left(\mathbf{x}_{k+1}\right)+H_{k+1} \cdot\left(\mathbf{x}-\mathbf{x}_{k+1}\right)

x=xk\mathbf{x}=\mathbf{x}_k,得

gk+1gkHk+1(xk+1xk)\mathrm{g}_{k+1}-\mathrm{g}_{k} \approx H_{k+1} \cdot\left(\mathrm{x}_{k+1}-\mathrm{x}_{k}\right)

引入记号

sk=xk+1xk,yk=gk+1gk\mathbf{s}_{k}=\mathbf{x}_{k+1}-\mathbf{x}_{k}, \mathbf{y}_{k}=\mathbf{g}_{k+1}-\mathbf{g}_{k}

ykHk+1sk\mathbf{y}_{k} \approx H_{k+1} \cdot \mathbf{s}_{k}

skHk+11yk\mathbf{s}_{k} \approx H_{k+1}^{-1} \cdot \mathbf{y}_{k}

这就是拟牛顿条件,它对迭代过程中的海森矩阵 Hk+1H_{k+1} 作约束,因此,对 Hk+1H_{k+1} 做近似的 Bk+1B_{k+1},以及对 Hk+11H_{k+1}^{-1} 做近似的 Dk+1D_{k+1} 可以将

yk=Bk+1sk\mathbf{y}_{k}=B_{k+1} \cdot \mathbf{s}_{k}

sk=Dk+1yk\mathbf{s}_{k}=D_{k+1} \cdot \mathbf{y}_{k}

由此条件,可以推导出DFP 算法BFGS 算法,其过程比较复杂,略去不讲,这两种算法是服从上述拟牛顿条件的表述,但是其内存占用依然很高,需要用到 N×NN\times{N} 的矩阵 DkD_k,当 NN 很大时,矩阵的存储将会占用很多的计算机内存资源。

L-BFGS

所以提出 L-BFGS 算法,其基本思想是:不再存储完整的矩阵 DkD_k,而是存储计算过程中的向量序列 {si},{yi}\left\{s_{i}\right\},\left\{\mathbf{y}_{i}\right\},需要用矩阵 DkD_k 时,利用向量序列 {si},{yi}\left\{s_{i}\right\},\left\{\mathbf{y}_{i}\right\} 来计算,而且向量序列 {si},{yi}\left\{s_{i}\right\},\left\{\mathbf{y}_{i}\right\} 也不是全部存储而是固定存最新的 mm 个。这样一来,存储由原来的 O(N2)O(N^2) 降到了 O(mN)O(mN)

10. ADMM[21]

上一章说到了无约束非线性优化问题最有效的方法,牛顿法衍生出来的L-BFGS,那么关于约束问题最优化方法在机器学习中比较广泛使用的算法是 ADMM(交换方向乘子法)。

假设如下优化问题

minxf(x)s.t.Ax=b\begin{aligned} min_xf(x)\\ s.t.Ax=b \end{aligned}

ADMM通常解决的是等式约束的优化问题。

对偶方法:把minimize问题 f(x)f(x) 与约束条件 Ax=bAx=b 通过对偶变量 λ\lambda 耦合在一起,形成Lagrange函数

L(x,λ)=f(x)+λT(Axb)L(x, \lambda)=f(x)+\lambda^{T}(A x-b)

原来带约束求解 minxf(x)min_xf(x),现在求解其对偶函数 maxλminxL(x,λ)\max _{\lambda} \min _{x} L(x, \lambda),两个问题的最优解等价。

对偶上升法

step1:xk+1=argminxL(x,λk)step2:λk+1=λk+ρ(Axk+1b)\begin{array}{ll} \text {step1:} & x^{k+1}=\arg \min _{x} L\left(x, \lambda^{k}\right) \\ \text {step2:} & \lambda^{k+1}=\lambda^{k}+\rho\left(A x^{k+1}-b\right) \end{array}

实际上很好理解,就是把 maxλminxL(x,λ)\max _{\lambda} \min _{x} L(x, \lambda) 拆成了两步: maxλ(minxL(x,λ))\max _{\lambda} (\min _{x} L(x, \lambda))

对约束增加一个惩罚项,变成增广拉格朗日函数

L(x,λ)=f(x)+λT(Axb)+ρ2Axb2L(x, \lambda)=f(x)+\lambda^{T}(A x-b)+\frac{\rho}{2}\|A x-b\|^{2}

下面是两个变量的增广拉格朗日函数:

L(x,z,λ)=f(x)+g(z)+λT(Ax+Bzc)+ρ2Ax+Bzc2L(x, z, \lambda)=f(x)+g(z)+\lambda^{T}(A x+B z-c)+\frac{\rho}{2}\|A x+B z-c\|^{2}

ADMM 流程就像对偶上升法一样分别固定另外两个变量,更新其中一个变量:(也就是其名:交替方向)

step1:xk+1=argminxL(x,zk,λk)step2:zk+1=argminzL(xk+1,z,λk)step3:λk+1=λk+ρ(Axk+1+Bzk+1c)\begin{aligned} &\text {step1:} & x^{k+1}&=\arg \min _{x} L(x, z^{k}, \lambda^{k}) \\ &\text {step2:} & z^{k+1}&=\arg \min _{z} L(x^{k+1}, z, \lambda^{k}) \\ &\text {step3:}& \lambda^{k+1}&=\lambda^{k}+\rho(A x^{k+1}+B z^{k+1}-c) \end{aligned}

step1~3是大循环,求解里面的 argminL\arg\min L 是小循环,梯度下降法,牛顿法等等都可以。重复直到不怎么变化了,也就是收敛了。

参考文献


  1. 凸集[Z/OL]. https://zh.wikipedia.org/w/index.php?title=凸集&oldid=56526337. ↩︎

  2. 凸集_百度百科[EB/OL]. https://baike.baidu.com/item/凸集. ↩︎

  3. 凸函数[Z/OL]. https://zh.wikipedia.org/w/index.php?title=凸函数&oldid=54960383. ↩︎

  4. 线性规划[Z/OL]. https://zh.wikipedia.org/w/index.php?title=线性规划&oldid=59257717. ↩︎

  5. lilong117194. 二次规划_lilong117194的博客-CSDN博客_二次规划[EB/OL]. https://blog.csdn.net/lilong117194/article/details/78204994. ↩︎ ↩︎

  6. 小鹅鹅. 拉格朗日对偶性(Lagrance duality) 推导与简单理解_小鹅鹅的博客-CSDN博客_duality gap[EB/OL]. https://blog.csdn.net/asd136912/article/details/79149881. ↩︎ ↩︎ ↩︎

  7. 强对偶性_百度百科[EB/OL]. https://baike.baidu.com/item/强对偶性. ↩︎

  8. 群星纪元. 为什么 Non-Convex Optimization (非凸优化)受到了越来越大的关注? - 群星纪元的个人空间 - OSCHINA[EB/OL]. https://my.oschina.net/u/2935389/blog/2967416. ↩︎

  9. bitcarmanlee. NP-Hard问题浅谈_bitcarmanlee的博客-CSDN博客_np-hardEB/OL[2020–07–02]. https://blog.csdn.net/bitcarmanlee/article/details/51935400. ↩︎ ↩︎

  10. NP困难[Z/OL] (2020–05–24)[2020–07–02]. https://zh.wikipedia.org/w/index.php?title=NP困难&oldid=59790051. ↩︎

  11. 线性规划的松弛[Z/OL] (2014–02–26)[2020–07–02]. https://zh.wikipedia.org/w/index.php?title=线性规划的松弛&oldid=30387429. ↩︎

  12. 滴水,Richard Wei,Rapier.如何理解拉格朗日松弛技术? - 知乎[EB/OL].[2020–07–02]. https://www.zhihu.com/question/21345731. ↩︎

  13. 六尺帐篷. 深入浅出–梯度下降法及其实现EB/OL[2020–07–16]. https://www.jianshu.com/p/c7e642877b0e. ↩︎

  14. Jackpop. 如何理解随机梯度下降(stochastic gradient descent,SGD)? - 知乎EB/OL[2020–07–16]. https://www.zhihu.com/question/264189719. ↩︎

  15. 余昌黔. 深度学习最全优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)EB/OL[2020–07–16]. https://zhuanlan.zhihu.com/p/22252270. ↩︎

  16. 阿斯顿·张等. 7.4. 动量法 — 《动手学深度学习》 文档EB/OL[2020–07–16]. https://zh.d2l.ai/chapter_optimization/momentum.html. ↩︎

  17. 阿斯顿·张等. 7.5. AdaGrad算法 — 《动手学深度学习》 文档EB/OL[2020–07–17]. https://zh.d2l.ai/chapter_optimization/adagrad.html. ↩︎

  18. 阿斯顿·张等. 7.6. RMSProp算法 — 《动手学深度学习》 文档EB/OL[2020–07–17]. https://zh.d2l.ai/chapter_optimization/rmsprop.html. ↩︎

  19. 阿斯顿·张等. 7.8. Adam算法 — 《动手学深度学习》 文档EB/OL[2020–07–17]. https://zh.d2l.ai/chapter_optimization/adam.html. ↩︎

  20. 皮果提. 牛顿法与拟牛顿法学习笔记(一)牛顿法_peghoty-CSDN博客_牛顿法EB/OL[2020–07–18]. https://blog.csdn.net/itplus/article/details/21896453. ↩︎

  21. 大大大的v. 交替方向乘子法(ADMM)算法的流程和原理是怎样的? - 知乎EB/OL[2020–07–19]. https://www.zhihu.com/question/36566112. ↩︎


   转载规则


《凸优化基础,本科生能看得懂的极限水平》 Harbor Zeng 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
线性代数第一章:导学 线性代数第一章:导学
为什么学习线性代数 线性代数是高等教育中理工科学生必学的数学之一 线性代数是近现代科学发展过程中最重要的基础数学之一 初等教育中更多的是在研究一个一个的具体的数,和函数。线性代数则在研究“一组数”,即向量。 真实的世界是多维度的,单变量不足以描述真实世界的。线性代数将对数值的研究由单一纬度拓展到多维度,发展了一套数学概念和工具,使数学更加容易的解决现实中真实世界的问题。 近乎所有的理工科教材
2020-09-01
下一篇 
Scala 学习 - 函数及函数的定义 Scala 学习 - 函数及函数的定义
函数定义 值类型和返回值类型都定义在值的后面或方法名的后面,用冒号分隔开。 方法体最后一行是默认返回值,不需写 return def add(a: Int, b: Int): Int = { a + b // return a + b} 方法体如果是一个表达式,可以省略花括号: def add(a: Int, b: Int): Int = a + b 变(常)量和函数的
2020-07-04
  目录