【 凸优化】第六讲:求解器与支持向量机

一、二次规划的对偶与凸性的判定

KKT 条件停在四组式子上:稳定性、原问题可行、对偶问题可行、互补松弛。四组凑齐,点就是最优解。真正拿到一个题目,这四组式子要落到算上。先看形状最规整的一类:

min⁡ 12xTQx−rTxs.t. Ax⪰b(1-1)\min\ \dfrac{1}{2}x^{T}Qx - r^{T}x \quad \mathrm{s.t.}\ Ax \succeq b \tag{1-1}min 21xTQx−rTxs.t. Ax⪰b(1-1)

x∈Rnx \in \mathbb{R}^{n}x∈Rn,QQQ 对称正定,A∈Rm×nA \in \mathbb{R}^{m \times n}A∈Rm×n。目标二次且严格凸,约束仿射,这是一个凸二次规划。

求对偶,先把约束摆成标准方向,Ax⪰bAx \succeq bAx⪰b 两边乘负号:

b−Ax⪯0(1-2)b - Ax \preceq 0 \tag{1-2}b−Ax⪯0(1-2)

再写拉格朗日函数,把约束乘以非负乘子加进目标:

L(x,λ)=12xTQx−rTx+λT(b−Ax)(1-3)L(x, \lambda) = \dfrac{1}{2}x^{T}Qx - r^{T}x + \lambda^{T}\left(b - Ax\right) \tag{1-3}L(x,λ)=21xTQx−rTx+λT(b−Ax)(1-3)

其中 λ⪰0\lambda \succeq 0λ⪰0。转对偶有两条路。讨论法把含 xxx 的项按系数归拢,系数不为零时下确界掉到 −∞-\infty−∞,为零时留下有限值。目标里有二次项,含 xxx 的部分配不成一个一次式,讨论法在这里不好使。走第二条路,直接求梯度。

∇xL=Qx−r−ATλ(1-4)\nabla_{x}L = Qx - r - A^{T}\lambda \tag{1-4}∇xL=Qx−r−ATλ(1-4)

让这个梯度等于零:

Qx−r−ATλ=0⇒x=Q−1(r+ATλ)(1-5)Qx - r - A^{T}\lambda = 0 \quad \Rightarrow \quad x = Q^{-1}\left(r + A^{T}\lambda\right) \tag{1-5}Qx−r−ATλ=0⇒x=Q−1(r+ATλ)(1-5)

能写成闭式,靠的是 QQQ 正定、可逆。QQQ 只半正定时 Q−1Q^{-1}Q−1 不存在,代回这一步要改用伪逆,或者干脆把 xxx 留在原处,对偶函数按下确界写。

把式(1-5)代回 LLL,用 r+ATλ=Qxr + A^{T}\lambda = Qxr+ATλ=Qx 合并两个一次项:

g(λ)=12xTQx−xTQx+bTλ=−12xTQx+bTλ(1-6)g(\lambda) = \dfrac{1}{2}x^{T}Qx - x^{T}Qx + b^{T}\lambda = -\dfrac{1}{2}x^{T}Qx + b^{T}\lambda \tag{1-6}g(λ)=21xTQx−xTQx+bTλ=−21xTQx+bTλ(1-6)

再把 xxx 换掉,得到一个只含 λ\lambdaλ 的凹二次函数:

g(λ)=−12(r+ATλ)TQ−1(r+ATλ)+bTλ(1-7)g(\lambda) = -\dfrac{1}{2}\left(r + A^{T}\lambda\right)^{T}Q^{-1}\left(r + A^{T}\lambda\right) + b^{T}\lambda \tag{1-7}g(λ)=−21(r+ATλ)TQ−1(r+ATλ)+bTλ(1-7)

对偶问题是对它求最大:

max⁡λ −12(r+ATλ)TQ−1(r+ATλ)+bTλs.t. λ⪰0(1-8)\max_{\lambda}\ -\dfrac{1}{2}\left(r + A^{T}\lambda\right)^{T}Q^{-1}\left(r + A^{T}\lambda\right) + b^{T}\lambda \quad \mathrm{s.t.}\ \lambda \succeq 0 \tag{1-8}λmax −21(r+ATλ)TQ−1(r+ATλ)+bTλs.t. λ⪰0(1-8)

形状很清楚:Q−1Q^{-1}Q−1 正定,目标关于 λ\lambdaλ 是凹二次,约束是非负象限。二次规划的对偶还是二次规划。

强对偶的判定只要两句。目标严格凸,约束仿射,可行域非空。仿射不等式不要求严格小于零,取等号也算数,Slater 条件自动成立,于是强对偶成立,两个最优值相等。仿射约束比一般凸约束好用,就在这里,不必再去凑一个严格内点。

带数字的版本顺着 KKT 走。把 QQQ、AAA、bbb、rrr 的数字代进去,未知量是 xxx 与 λ\lambdaλ,方程三条:梯度为零、约束可行、互补松弛。紧约束的乘子为正,松约束的乘子为零,一组组试过去,试出来的就是答案。二维题目画图更快,等值线是同心椭圆,约束是直线,最优点在椭圆与直线相切处,或者落在两条约束的交点上。

换一类问题,给的是具体表达式,没有矩阵形式,第一步是凑。把它整理成

f(x)=12xTQx+cTx+d(1-9)f(x) = \dfrac{1}{2}x^{T}Qx + c^{T}x + d \tag{1-9}f(x)=21xTQx+cTx+d(1-9)

对照系数读 QQQ:平方项系数乘二放对角,交叉项系数的一半放非对角,两个非对角元相同,因为 QQQ 必须对称。拿一个二次型试一遍,二次部分取 x12+2x1x2+x22x_{1}^{2} + 2x_{1}x_{2} + x_{2}^{2}x12+2x1x2+x22,一次部分取 3x13x_{1}3x1:

12x1x22222x1x2+30x1x2(1-10)\dfrac{1}{2}\begin{bmatrix} x_{1} & x_{2} \end{bmatrix}\begin{bmatrix} 2 & 2 \cr 2 & 2 \end{bmatrix}\begin{bmatrix} x_{1} \cr x_{2} \end{bmatrix} + \begin{bmatrix} 3 & 0 \end{bmatrix}\begin{bmatrix} x_{1} \cr x_{2} \end{bmatrix} \tag{1-10}21x1x22222x1x2+30x1x2(1-10)

两个特征根是 444 与 000。半正定,目标凸,但不正定,严格凸性没有,最优解可能是一整条线段,沿 x1+x2x_{1} + x_{2}x1+x2 为常数的方向目标不变。把交叉项系数改成 333,两个非对角元都变成 333,特征根 555 与 −1-1−1,目标非凸,问题落到凸优化管不到的地方。

判据只看二次项。一次项与常数项加多少都不改变弯曲方向,这就是判凸性时可以不看它们的理由。

约束按同一套处理。每条不等式写成 gi(x)≤0g_{i}(x) \le 0gi(x)≤0,看 gig_{i}gi 的二次项矩阵半正定与否。仿射约束的二次项矩阵是零矩阵,天然满足。目标凸、每条约束凸、等式约束仿射,三条凑齐,问题就是凸的。

二维的问题先画图。可行域画出来,等值线画出来,最优解在哪一眼能看到:边界相切处,或者多边形的顶点。猜出位置再代 KKT 验证,比从头解方程快。

二维画一遍就够,三维以上只能靠软件。

二、CVX:把问题写成几句话

手算只对二维、三维有效。几十个变量的问题,解要靠软件。

CVX 是 Grant 与 Boyd 写的建模系统,想法来自 Löfberg 的 YALMIP 与 Dahl、Vandenberghe 的 CVXOPT。它本身不求解任何问题,作用是把受纪律约束的凸规划翻译成求解器认得的形状,二阶锥规划与半正定规划,再交给 SeDuMi 或 SDPT3 这类数值包。

一句话划清它的边界:CVX 接受你的问题,那它一定是凸的;但 CVX 不是用来检验凸性的工具。它按一套保凸运算的规则逐个函数核对,认不出的写法直接拒收。被拒收的问题也可能确实凸,只是写法不合它的规矩。

支持的四类问题:线性规划、二次规划、二阶锥规划、半定规划。适合几十到几千个变量的规模,几百个变量的原型验证最舒服。几万、几十万变量的正经计算要换专用求解器。

安装三步。解压到任意目录,不要放进 MATLAB 自带的 toolbox 里;在命令行 cd 到该目录;运行 cvx_setup。十几秒到二十几秒配完,最后一行提示安装成功。

用法是给一段代码划界。cvx_begin 与 cvx_end 之间是模型,外面是普通 MATLAB 语句。最小二乘的写法如下。

复制代码
m = 16; n = 8;
A = randn(m, n); b = randn(m, 1);

cvx_begin
    variable x(n)
    minimize( norm(A*x - b) )
cvx_end

模型只有三句:声明变量、给目标、收尾。同样的解用反斜杠也能得,两种写法逐位一致,这是检验安装是否正常最快的办法,跑一遍对一下数就知道有没有配错。

图 1 是运行后的输出。三个数一样:反斜杠解的残差范数、CVX 解的残差范数、cvx_optval,都是 2.0354,状态是 Solved;再往下是两组 xxx 的逐位对照,八个数每一位都相同。

图 1:两种写法给出同一个解

图源:《凸优化理论与应用》Topic 5。

变量在 cvx_end 之前是符号对象,求解完才被数值覆盖。模型段里不能拿 xxx 去做数值判断,此刻它不是数;反过来,cvx_end 之后它也不再是符号,重新声明一遍才能再进下一个模型。

带上下界的版本只多两行:

复制代码
cvx_begin
    variable x(n)
    minimize( norm(A*x - b) )
    subject to
        x >= l;
        x <= u;
cvx_end

约束直接写成向量不等式,不必拆成一行行的 aiTx≤bia_{i}^{T}x \le b_{i}aiTx≤bi 再拼矩阵。这是建模语言真正省事的地方:数据从文件读进来,逻辑在 cvx 段里写,两者分开。

目标必须凸或仿射,约束函数必须凸或仿射。diag 与 trace 是仿射的矩阵函数,可以放心用。CVX 用延拓值处理定义域,凸函数出界取 +∞+\infty+∞,凹函数出界取 −∞-\infty−∞,所以 log、sqrt 写在约束里不会算出复数。

半定规划的写法是把矩阵变量按矩阵声明:

复制代码
cvx_begin sdp
    variable X(n+1, n+1) symmetric
    minimize( trace(L*X) )
    subject to
        diag(X) == ones(n+1, 1);
        X == semidefinite(n+1);
cvx_end

semidefinite(n) 这一句表明 XXX 对称半正定,不必摊成向量,也不必自己写二次型。

自定义函数也简单。新建一个 deadzone.m,里面写 y = max(abs(x) - 1, 0)。max 与 abs 都在保凸运算表里,CVX 认出它是凸的,此后它既能当目标,也能进约束。

对偶变量可以直接要。声明一句 dual variable y,再在约束前面加一个 y 加冒号的前缀,写成 y : x >= 0,yyy 的维数由那条约束自动定,不用自己声明。求解完 yyy 就是那条约束的乘子。约束有多条,就 y1、y2 分别对应,一次求解把原问题与对偶问题的解一起给出来。

两个控制命令值得记住。cvx_quiet(true) 关掉中间输出,默认可能刷满屏;cvx_precision 调精度,一般双精度够用。

有一个坑:自定义的函数名不能与 CVX 内部函数重名,重名会被静默覆盖,报错信息很难看懂。

早年在工作站上写优化程序,屏幕四十行字符,只有最后一行显示正在编辑的那一句,其余行全是中间结果。程序只能记在脑子里,用上下键翻着确认上一行写了什么。数据一个个手工敲,与逻辑代码混在一处,查错只能一行行盯。现在数据和代码分开了,AAA、bbb 从文件读进来,剩下的只管写模型。

三、求解器的版图

这些名字看着杂,分工其实清楚。建模层把数学式子翻译成规范形式,CVX、CVXPY、YALMIP、JuMP 都在这一层,输出的不是解,而是一个二阶锥或半定锥形式的中间表示。真正算的是求解层,SeDuMi、SDPT3、CPLEX、Gurobi 属于这一层。再往下是稀疏矩阵分解与迭代法,规模一大,瓶颈全落在后面这一层。

Python 一侧有三个常用件。CVXPY 是 Python 风格的建模语言,写法和数学式子接近:声明 cp.Variable(n),目标写 cp.sum_squares,套进 cp.Problem 再调 solve。CVXOPT 不是建模语言,它本身就是求解器,按矩阵传参,linprog 一类的接口要求把 ccc、GGG、hhh、AAA、bbb 按固定次序摆好,顺序写反是最常见的错。CVXGEN 做的是另一件事,把小型二次规划生成定制的 C 代码,约束与目标里的系数总数在两千上下最合适,再大就不灵。

MATLAB 一侧还有 YALMIP,Julia 一侧有 JuMP,思路都一样,把模型与求解器隔开。

CPLEX 的名字来自 C 语言实现的单纯形法。Bixby 在 1987 年参与创办 CPLEX Optimization,1988 年开始商业销售,1997 年被 ILOG 收购,2009 年 1 月 ILOG 又被 IBM 收购。它专攻大规模线性规划、二次规划、带二次约束的二次规划、二阶锥规划,以及对应的混合整数版本。学术版免费,变量数不设上限,用学校邮箱申请,一两天就能下来。运筹圈里它是事实上的基准:比较两种算法谁快,先固定求解器,再换算法。

IBM 收购之后,原来的开发团队基本散了,软件这些年基本停在原地。这是开源工具能追上来的一个原因,也是运筹圈近十年格局变化的一个原因。

Gurobi 出自同一批人。Bixby 在 2008 年与 Ed Rothberg、Zonghao Gu 一起创办,求解大规模线性与二次问题,混合整数部分尤其强。接口齐全,C++、Java、Python、.NET、MATLAB、R 都有,内存占用小,一般问题免费。2019 年的 9.0 版向非凸走了一步:目标里允许双线性项,二次约束不再要求半正定;另加一类广义函数约束,把高阶多项式、对数、指数、三角函数自动分段线性化,精度与速度用参数平衡。

软件好不好用,要拿标准题验收。贝尔实验室、田纳西大学与橡树岭国家实验室几家共同维护的 NETLIB 收集了一批线性规划标准数据与标准答案,网址在 netlib.org 的 lp/data 下。数据是运筹圈的老格式,没有现成的转换器,得自己写一个读进来。把题跑一遍对答案,问题就暴露了:CVX 配 SDPT3 在个别标准题上找不到正确解。建模层与求解层是两件事,这一条在这里露了底。

国产的有两家。杉数的 COPT 把单纯形法与内点法都实现了,支持主流 64 位系统与 ARM64,接口有 Python、PuLP、Pyomo、C、C++、C#、Java、AMPL、GAMS。线性规划上与国外顶尖持平,整数规划还在迭代,分支变量的选择、预处理里的那些小技巧要年头积累。工程上已经用在水电调度、船舶设计这类几万个变量的整数规划里。达摩院的 MindOpt 支持单纯形、内点、并发三种解法,有 C++ 与 Python 接口。

哪家快,有公开的榜。亚利桑那州立大学的 Mittelmann 在 plato.asu.edu 上维护基准表,各家用同一批问题比时间,更新得挺勤。

榜单上的差距,最近几年在缩小。

还有一条支线是把凸优化程序编译下去。CVXGEN 之外,也有工具把模型转成 C 或汇编,直接烧进嵌入式设备,很小的计算设备也能解一个规模不大的二次规划。个人电脑上跑的东西,缩到单片机上,这条路是通的。

四、最大间隔:从分离超平面到二次规划

分类问题是这样一件事:给一堆点,每个点带一个标签,二分类就是非此即彼。点的坐标是属性向量,身高体重、像素灰度、基因表达量都行。目标是找一条规则,把两类分开,新来的点按这条规则判。

凸集分离定理给了现成的工具:两个不相交的凸集,存在超平面把它们分开。两类点各自的凸包不交,就存在超平面严格分开。超平面写成 wTx+b=0w^{T}x + b = 0wTx+b=0,www 是法向量,bbb 是偏置。分开的意思是

wTxi+b>0,i=1,...,N;wTxj+b<0,j=1,...,M(4-1)w^{T}x_{i} + b > 0,\quad i = 1, \dots, N; \qquad w^{T}x_{j} + b < 0,\quad j = 1, \dots, M \tag{4-1}wTxi+b>0,i=1,...,N;wTxj+b<0,j=1,...,M(4-1)

有多少个点就有多少条约束。

这样的超平面一般不唯一。www 与 bbb 同时放大,wTx+bw^{T}x + bwTx+b 的符号不变,超平面不动,系数变了;整体平移一点、稍微转一点,只要还夹在两类中间,也都可行。哪一条最好,要另立判据。

判据是间隔,也就是超平面到最近点的距离。新样本落在超平面附近的最容易判错,把超平面推到两类之间最空的地方,能容忍的扰动最大。

把这件事写成优化问题:

max⁡w,b min⁡i ∣wTxi+b∣∥w∥(4-2)\max_{w,b}\ \min_{i}\ \dfrac{|w^{T}x_{i} + b|}{\lVert w \rVert} \tag{4-2}w,bmax imin ∥w∥∣wTxi+b∣(4-2)

内层对每个点算投影距离取最小,外层把这个最小距离推到最大。这个式子没法解:内层的 min 不可微,外面套着绝对值与范数,整体非凸。

两步转化。第一步,www 与 bbb 的整体缩放不改变超平面,于是不妨把最近点的函数值定成 111,让所有点满足 ∣wTxi+b∣≥1|w^{T}x_{i} + b| \ge 1∣wTxi+b∣≥1。第二步,把点到超平面的距离,换成两条平行超平面之间的距离:把 wTx+b=0w^{T}x + b = 0wTx+b=0 向两侧平移,各推到撞上最近的点为止,得到 wTx+b=1w^{T}x + b = 1wTx+b=1 与 wTx+b=−1w^{T}x + b = -1wTx+b=−1。

两条平行线之间的距离是这么算的。取 z1z_{1}z1 在 wTz+b=1w^{T}z + b = 1wTz+b=1 上,z2z_{2}z2 在 wTz+b=−1w^{T}z + b = -1wTz+b=−1 上,两式相减得 wT(z1−z2)=2w^{T}(z_{1} - z_{2}) = 2wT(z1−z2)=2。z1−z2z_{1} - z_{2}z1−z2 在法向上的投影就是两条线的距离:

wT(z1−z2)∥w∥=2∥w∥(4-3)\dfrac{w^{T}\left(z_{1} - z_{2}\right)}{\lVert w \rVert} = \dfrac{2}{\lVert w \rVert} \tag{4-3}∥w∥wT(z1−z2)=∥w∥2(4-3)

把两条约束合成一条,问题变成

max⁡w,b 2∥w∥s.t. yi(wTxi+b)≥1(4-4)\max_{w,b}\ \dfrac{2}{\lVert w \rVert} \quad \mathrm{s.t.}\ y_{i}\left(w^{T}x_{i} + b\right) \ge 1 \tag{4-4}w,bmax ∥w∥2s.t. yi(wTxi+b)≥1(4-4)

yiy_{i}yi 是标签,正类取 +1+1+1,负类取 −1-1−1。靠着这个符号,两条约束合成一条,约束数量减半。

目标求最大,2/∥w∥2/\lVert w \rVert2/∥w∥ 不是凹函数,问题还不是凸的。上下颠倒:

min⁡w,b 12∥w∥2s.t. yi(wTxi+b)≥1(4-5)\min_{w,b}\ \dfrac{1}{2}\lVert w \rVert^{2} \quad \mathrm{s.t.}\ y_{i}\left(w^{T}x_{i} + b\right) \ge 1 \tag{4-5}w,bmin 21∥w∥2s.t. yi(wTxi+b)≥1(4-5)

颠倒的依据是单调性:2/∥w∥2/\lVert w \rVert2/∥w∥ 最大与 ∥w∥\lVert w \rVert∥w∥ 最小同解,与 ∥w∥2/2\lVert w \rVert^{2}/2∥w∥2/2 最小也同解。平方与乘正常数都不移动最优点的位置,乘 1/21/21/2 是为了求导后系数干净。

这是标准的二次规划。目标二次且正定,约束仿射,凸的,可以交给第二节那套工具。

图 2:间隔宽度为 2/‖w‖,压在两条边界上的点决定超平面

图源:《凸优化理论与应用》Topic 6。

判决函数是 f(x)=sgn(wTx+b)f(x) = \mathrm{sgn}(w^{T}x + b)f(x)=sgn(wTx+b),符号就是类别。图 2 里两类点各有几个,压在两条边界上的却只有各自的一个,其余的离边界还有余量。超平面的位置由这几个贴边的点钉住,多一个干扰点也不动。这件事这一节还没法解释,要到对偶里才看得出来。

五、对偶问题与支撑向量

维度是个麻烦。www 的维数等于特征维数,基因数据一万维,直接解原问题就要在一万维空间里做一个二次规划。

对偶的变量个数等于样本个数。

先写拉格朗日函数:

L(w,b,α)=12∥w∥2−∑i=1lαiyi(wTxi+b)−1(5-1)L(w, b, \alpha) = \dfrac{1}{2}\lVert w \rVert^{2} - \sum_{i=1}^{l}\alpha_{i}\lefty_{i}\\left(w\^{T}x_{i} + b\\right) - 1\\right \tag{5-1}L(w,b,α)=21∥w∥2−i=1∑lαiyi(wTxi+b)−1(5-1)

αi≥0\alpha_{i} \ge 0αi≥0,共 lll 个乘子。对 www 与 bbb 求偏导,各令其为零:

∂L∂w=w−∑iαiyixi=0⇒w=∑iαiyixi(5-2)\dfrac{\partial L}{\partial w} = w - \sum_{i}\alpha_{i}y_{i}x_{i} = 0 \quad \Rightarrow \quad w = \sum_{i}\alpha_{i}y_{i}x_{i} \tag{5-2}∂w∂L=w−i∑αiyixi=0⇒w=i∑αiyixi(5-2)

∂L∂b=−∑iαiyi=0⇒∑iαiyi=0(5-3)\dfrac{\partial L}{\partial b} = -\sum_{i}\alpha_{i}y_{i} = 0 \quad \Rightarrow \quad \sum_{i}\alpha_{i}y_{i} = 0 \tag{5-3}∂b∂L=−i∑αiyi=0⇒i∑αiyi=0(5-3)

bbb 在式(5-3)里被消掉,这是等式约束的一个用处:它把 bbb 从式子里整个拿掉,代回时那一项化为零。

把式(5-2)、式(5-3)代回 LLL,逐项合:

L=12∥w∥2−wTw+∑iαi(5-4)L = \dfrac{1}{2}\lVert w \rVert^{2} - w^{T}w + \sum_{i}\alpha_{i} \tag{5-4}L=21∥w∥2−wTw+i∑αi(5-4)

第一项与第二项合成 −∥w∥2/2-\lVert w \rVert^{2}/2−∥w∥2/2,再把式(5-2)代入:

max⁡α ∑iαi−12∑i∑jαiαjyiyjxiTxjs.t. α⪰0, ∑iαiyi=0(5-5)\max_{\alpha}\ \sum_{i}\alpha_{i} - \dfrac{1}{2}\sum_{i}\sum_{j}\alpha_{i}\alpha_{j}y_{i}y_{j}x_{i}^{T}x_{j} \quad \mathrm{s.t.}\ \alpha \succeq 0,\ \sum_{i}\alpha_{i}y_{i} = 0 \tag{5-5}αmax i∑αi−21i∑j∑αiαjyiyjxiTxjs.t. α⪰0, i∑αiyi=0(5-5)

仍然是二次规划:目标关于 α\alphaα 是凹二次,约束是一个仿射等式加非负象限。

互补松弛在这里给出一个结论:

αiyi(wTxi+b)−1=0(5-6)\alpha_{i}\lefty_{i}\\left(w\^{T}x_{i} + b\\right) - 1\\right = 0 \tag{5-6}αiyi(wTxi+b)−1=0(5-6)

方括号里是点到间隔边界的余量。余量为正,点在边界之外(分类正确、不在边界上),乘子必须为零;乘子不为零,点就必须正好落在边界上。

图 2 上贴边的那几个点说的就是这件事。解完之后回看,绝大多数 α\alphaα 是零,只有少数几个非零,对应的点正落在边界上。超平面由这几个点决定,其余的挪走、删掉,解不变。名字里的 support 就是这个意思:这几个点支撑着整个模型。

乘子还可以当价格读。第 iii 条约束被放松一点,目标最多改善 αi\alpha_{i}αi;αi\alpha_{i}αi 为正说明这条约束在最优解处是紧的,模型确实受它限制。αi\alpha_{i}αi 为零的那些点,约束本来就没起作用,删掉不影响解。

偏置 bbb 由支撑向量反算。支撑向量上 yi(wTxi+b)=1y_{i}(w^{T}x_{i} + b) = 1yi(wTxi+b)=1,于是

b=yi−wTxi(5-7)b = y_{i} - w^{T}x_{i} \tag{5-7}b=yi−wTxi(5-7)

数值上取所有支撑向量的结果求平均,避免个别点的舍入误差把 bbb 带偏。

判决函数也不必显式求 www:

f(x)=sgn(∑iαiyixiTx+b)(5-8)f(x) = \mathrm{sgn}\left(\sum_{i}\alpha_{i}y_{i}x_{i}^{T}x + b\right) \tag{5-8}f(x)=sgn(i∑αiyixiTx+b)(5-8)

只有 α\alphaα 非零的项要算,求和项数等于支撑向量的个数,与样本总量无关。

偏置 bbb 能不能不要?去掉它,超平面必须过原点,对偶里那条 ∑iαiyi=0\sum_{i}\alpha_{i}y_{i} = 0∑iαiyi=0 也跟着消失,问题少一个等式约束。代价是自由度被砍掉一截:两类点都在第一象限时,过原点的直线怎么转都分不开它们。补救办法很简单,先把数据减掉均值挪到原点附近,等于把这个平移自由度还回去。少一个等式约束还有数值上的好处,迭代时每次只动一个乘子就够,不必成对地动。

问题凸、约束仿射、数据可分时可行域不空,强对偶成立,两个问题的最优值相同。既然值一样,选哪一边解就看哪一边省事,理由有几层。约束上,对偶只剩一个等式与非负象限,用投影梯度、坐标下降这类方法好处理;原问题的约束有 lll 条,一条都不能漏。解的结构上,α\alphaα 大部分为零,算力花在少数点上。更要紧的一层在内积上:目标与判决函数里出现的只有 xiTxjx_{i}^{T}x_{j}xiTxj 这种内积,数据不再以坐标形式出现。这一层要等到第七节才看出用处。

六、软间隔与惩罚函数的选型

前面所有推导都建立在一条假设上:两类点能被超平面完全分开。实际数据经常不是这样。两类点各自形成一个凸包,两个凸包相交,超平面就插不进去。

这时原问题无解,可行域是空的。对偶问题倒是可行,α=0\alpha = 0α=0 就是一个可行点,目标值为零。但最优值没有上界,沿着把两个凸包的交点分开的方向把 α\alphaα 放大,目标一路升上去。无解对无界,与上一讲那张四种组合的表对得上。

1995 年 Cortes 与 Vapnik 给了一个改法,叫软间隔。思路是允许少量点越界,越界要付代价。给每个点配一个松弛变量 ξi≥0\xi_{i} \ge 0ξi≥0,约束放宽为

yi(wTxi+b)≥1−ξi,ξi≥0(6-1)y_{i}\left(w^{T}x_{i} + b\right) \ge 1 - \xi_{i},\qquad \xi_{i} \ge 0 \tag{6-1}yi(wTxi+b)≥1−ξi,ξi≥0(6-1)

ξi\xi_{i}ξi 是该点被允许侵入间隔的深度。ξi=0\xi_{i} = 0ξi=0 不越界;0<ξi<10 < \xi_{i} < 10<ξi<1 进了间隔但还在超平面这一侧,判对;ξi>1\xi_{i} > 1ξi>1 越过超平面,判错。目标里给越界加一笔罚款:

min⁡w,b,ξ 12∥w∥2+C∑iξis.t. yi(wTxi+b)≥1−ξi, ξi≥0(6-2)\min_{w,b,\xi}\ \dfrac{1}{2}\lVert w \rVert^{2} + C\sum_{i}\xi_{i} \quad \mathrm{s.t.}\ y_{i}\left(w^{T}x_{i} + b\right) \ge 1 - \xi_{i},\ \xi_{i} \ge 0 \tag{6-2}w,b,ξmin 21∥w∥2+Ci∑ξis.t. yi(wTxi+b)≥1−ξi, ξi≥0(6-2)

CCC 是事先选定的参数,控制两件事的轻重:间隔要宽,错分要少。

图 3:松弛变量度量每个点侵入间隔的深度

图源:《凸优化理论与应用》Topic 6。

图 3 里,落在间隔内侧的红点各带一个 ξ\xiξ,越过错平面越远的,ξ\xiξ 越大。目标是把这些深度加起来压小,同时把两条虚线尽量拉开。

对偶推一遍。拉格朗日函数多一项,ξ\xiξ 的约束也配乘子 βi≥0\beta_{i} \ge 0βi≥0:

L=12∥w∥2+C∑iξi−∑iαiyi(wTxi+b)−1+ξi−∑iβiξi(6-3)L = \dfrac{1}{2}\lVert w \rVert^{2} + C\sum_{i}\xi_{i} - \sum_{i}\alpha_{i}\lefty_{i}\\left(w\^{T}x_{i} + b\\right) - 1 + \\xi_{i}\\right - \sum_{i}\beta_{i}\xi_{i} \tag{6-3}L=21∥w∥2+Ci∑ξi−i∑αiyi(wTxi+b)−1+ξi−i∑βiξi(6-3)

先对松弛变量求偏导:

∂L∂ξi=C−αi−βi=0⇒αi+βi=C(6-4)\dfrac{\partial L}{\partial \xi_{i}} = C - \alpha_{i} - \beta_{i} = 0 \quad \Rightarrow \quad \alpha_{i} + \beta_{i} = C \tag{6-4}∂ξi∂L=C−αi−βi=0⇒αi+βi=C(6-4)

两个乘子都非负,于是 0≤αi≤C0 \le \alpha_{i} \le C0≤αi≤C。β\betaβ 从此不再出现,被这两个条件顶掉了。

代回之后,目标函数一个字都没变,只是 α\alphaα 多了一个上界:

max⁡α ∑iαi−12∑i∑jαiαjyiyjxiTxjs.t. 0≤αi≤C, ∑iαiyi=0(6-5)\max_{\alpha}\ \sum_{i}\alpha_{i} - \dfrac{1}{2}\sum_{i}\sum_{j}\alpha_{i}\alpha_{j}y_{i}y_{j}x_{i}^{T}x_{j} \quad \mathrm{s.t.}\ 0 \le \alpha_{i} \le C,\ \sum_{i}\alpha_{i}y_{i} = 0 \tag{6-5}αmax i∑αi−21i∑j∑αiαjyiyjxiTxjs.t. 0≤αi≤C, i∑αiyi=0(6-5)

硬间隔的对偶加一个盒约束,就是软间隔的对偶。松弛变量在拉格朗日里被乘子吞掉,只剩 CCC 作为上界,这个结果简单得有点意外,Cortes 与 Vapnik 因为这一条拿了 2008 年 ACM 的 Paris Kanellakis 奖。

CCC 的作用可以从式(6-4)读。CCC 大,罚款重,模型宁可把间隔压窄也要少错分,容易过拟合;CCC 小,错分便宜,间隔宽,欠拟合。还有一个数值上的连带效应:CCC 太小时所有 α\alphaα 都被压在很小的范围,www 的长度长不过 111,于是找不到落在边界上的支撑向量,bbb 算不出来。程序报无解,先试把 CCC 调大。

目标里那两项目前各有分工。∥w∥2/2\lVert w \rVert^{2}/2∥w∥2/2 管模型的复杂度,C∑ξiC\sum\xi_{i}C∑ξi 管训练误差,两者的相对权重由 CCC 定。后一项起的是缰绳的作用:参数自由度大的模型不加它,解会跑到没有意义的地方去。深度学习里几亿个参数,靠的也是这根缰绳。

惩罚函数不一定取线性。把 C∑ξiC\sum\xi_{i}C∑ξi 换成 C∑G(ξi)C\sum G(\xi_{i})C∑G(ξi),只要 GGG 是凸的、单调不减、G(0)=0G(0) = 0G(0)=0,整个问题仍然是凸的,对偶的推法也照旧。选哪个 GGG,取决于想对什么样的错误宽容。

图 4:四种惩罚函数:二次、绝对值、Huber、不敏感

图源:《凸优化理论与应用》Topic 6。

图 4 的四条曲线值得逐个看。

二次惩罚在近处光滑,远处按平方增长。一个离得很远的错分点会把超平面整个拉过去,图上看就是虚线被拽歪。数据里常有这种点,多半是记录错了。

绝对值惩罚是线性的,远处也只按一次增长,远点的影响力有限。近处有个折点,导数不连续,用次梯度处理。

Huber 惩罚把两者的好处接起来:∣ξ∣≤1|\xi| \le 1∣ξ∣≤1 时按二次走,超过之后按一次走,接缝处的导数正好连续。近处光滑,远处不敏感。

不敏感惩罚在 ∣ξ∣≤ε|\xi| \le \varepsilon∣ξ∣≤ε 之内直接取零,小误差不罚。这一条来自死区函数,y=max⁡(∣x∣−1,0)y = \max(|x| - 1, 0)y=max(∣x∣−1,0) 画出来就是一马平川再接两条斜线,落在死区里的误差不计。

还能不能再狠一点,让超过某个距离的错分完全不计?可以写出这样的函数,但它不凸,凹下去的那一段让整个问题失去凸性。九十年代末有一批文章专门处理这种截断惩罚,各种近似、各种松弛,后来神经网络起来,这条线就没人做了。

错分有两个来源,值得分开。一是数据本身有问题:在一片规整的点里,很远的地方冒出一个孤点,多半是录入时错了位。这类点该清洗掉,不该让模型去迁就。二是问题本身非线性可分,直线怎么摆都要错几个,这时候只能容忍,尤其当错分点紧贴决策边界时,误差本来就该被容忍。

软间隔下 bbb 的算法要改。起作用的点不止边界上的:进了间隔的、越过超平面的,α\alphaα 也可能非零。但用它们算 bbb 会把 ξ\xiξ 带进来。稳的做法是只挑 0<αi<C0 < \alpha_{i} < C0<αi<C 的点,这些点的 ξi=0\xi_{i} = 0ξi=0,正好贴在边界上,反算出来的 bbb 干净。这类点有时叫自由支撑向量。

七、核技巧:升维之后还是同一道对偶

直线分不开,还有一条路:换一个空间看。

图 5:同一批点的两种非线性分法:椭球与四次多项式曲线

图源:《凸优化理论与应用》Topic 6。

图 5 里,一类点聚在中间,一类点围在外面。直线怎么放都切不开,椭圆可以。椭圆写成

x12a2+x22b2=1(7-1)\dfrac{x_{1}^{2}}{a^{2}} + \dfrac{x_{2}^{2}}{b^{2}} = 1 \tag{7-1}a2x12+b2x22=1(7-1)

把 x12x_{1}^{2}x12、x1x2x_{1}x_{2}x1x2、x22x_{2}^{2}x22 各看成一个新变量:

Φ(x1,x2)=(x12, 2x1x2, x22)(7-2)\Phi(x_{1}, x_{2}) = \left(x_{1}^{2},\ \sqrt{2}x_{1}x_{2},\ x_{2}^{2}\right) \tag{7-2}Φ(x1,x2)=(x12, 2 x1x2, x22)(7-2)

二维的点被送到三维。原来那条椭圆在新空间里成了一个平面方程,平面就是超平面,超平面能用的办法在这里都能用。

图 6:二次映射把平面上的椭圆送成三维空间里的一张平面

图源:《凸优化理论与应用》Topic 6。

图 6 画的正是这一步,左边是平面上的椭圆,右边是三维空间里的一张平面,红点被平面托在上面,蓝点落在下面。同一个问题,换了坐标就变成线性的。

如果映射选得复杂一点,比如把点映到一个火山口形状的曲面上,内圈的点落在山口上面,外圈的点落在下面,中间插一张平面就分开了。这就是所谓墨西哥草帽。

核函数做的事,是不写出 Φ\PhiΦ 也能算内积。定义

k(xp,xq)=Φ(xp)TΦ(xq)(7-3)k(x_{p}, x_{q}) = \Phi(x_{p})^{T}\Phi(x_{q}) \tag{7-3}k(xp,xq)=Φ(xp)TΦ(xq)(7-3)

对偶问题里数据只以 xiTxjx_{i}^{T}x_{j}xiTxj 的形式出现,把这个内积换成核函数,问题形状完全不变:

max⁡α ∑iαi−12∑i∑jαiαjyiyjk(xi,xj)s.t. 0≤αi≤C, ∑iαiyi=0(7-4)\max_{\alpha}\ \sum_{i}\alpha_{i} - \dfrac{1}{2}\sum_{i}\sum_{j}\alpha_{i}\alpha_{j}y_{i}y_{j}k(x_{i}, x_{j}) \quad \mathrm{s.t.}\ 0 \le \alpha_{i} \le C,\ \sum_{i}\alpha_{i}y_{i} = 0 \tag{7-4}αmax i∑αi−21i∑j∑αiαjyiyjk(xi,xj)s.t. 0≤αi≤C, i∑αiyi=0(7-4)

判决函数同理,把内积换成核:

f(x)=sgn(∑iαiyik(xi,x)+b)(7-5)f(x) = \mathrm{sgn}\left(\sum_{i}\alpha_{i}y_{i}k(x_{i}, x) + b\right) \tag{7-5}f(x)=sgn(i∑αiyik(xi,x)+b)(7-5)

www 与 Φ\PhiΦ 都不必出现。求解时只算核矩阵 Kij=k(xi,xj)K_{ij} = k(x_{i}, x_{j})Kij=k(xi,xj),一个 n×nn \times nn×n 的对称半正定矩阵,算完就完事。

原问题一侧要留意结构。分类超曲面写成 wTΦ(x)+bw^{T}\Phi(x) + bwTΦ(x)+b,可调的是 www,Φ\PhiΦ 固定不动。非线性映射是给定的,权重是线性的。这个结构值得记住,多层网络就是把同样的结构套很多遍,每一层都套一次,映射本身也跟着参数变。

常用的核有四种。线性核 xTx′x^{T}x'xTx′;多项式核,把内积加一之后取 ddd 次幂;高斯核(也叫径向基核)

k(xp,xq)=exp⁡(−γ∥xp−xq∥2)(7-6)k(x_{p}, x_{q}) = \exp\left(-\gamma\lVert x_{p} - x_{q}\rVert^{2}\right) \tag{7-6}k(xp,xq)=exp(−γ∥xp−xq∥2)(7-6)

以及 sigmoid 核,形如双曲正切,它未必满足半正定,用的时候要当心。

高斯核值得单独说一句。式(7-2)那种映射是显式的,三项写出来就完事;高斯核按泰勒展开会得到无穷多项,对应无穷维空间里的内积,Φ\PhiΦ 根本写不出来。写成 kkk 就一行,这就是核函数省掉的东西。

什么样的函数能当核,有判据。kkk 对称,且对任意有限点集,核矩阵半正定,就存在一个希尔伯特空间与映射 Φ\PhiΦ,使 kkk 等于映射后的内积。这条叫 Mercer 条件,等价的说法是核矩阵半正定。判一个候选函数能不能用,只需拿样本算一遍核矩阵,看特征值有没有负的。

核怎么选,靠交叉验证:几组核、几组参数,各跑一遍,比验证集上的错分率。LIBSVM 这类工具包把常见核都试一遍再汇总,用起来不必自己写。

局限也在这里。核是人设计的,人能想到的核太少。手写数字识别这类任务,换着核刷,准确率停在 88% 到 89%,再往上刷不动。2012 年之后深度学习把这个数推到 94%、95%,SVM 退到二线。问题不在优化,在表示:给定一个核,模型的形状就定了,剩下的只是调权重。

八、表示能力的边界与求解的取舍

把 SVM 和深度网络摆在一起看,差别不在求解器,在模型的形状。

图 7:异或问题一条直线分不开,两层网络可以

图源:《凸优化理论与应用》Topic 6。

图 7 是 1969 年的老问题。异或的两个输入,同号输出零,异号输出一,四个点摆在平面上,一条直线最多只能分对三个。Minsky 与 Papert 在书里指出单层感知机解不了它,两层可以。书里对后半句没讲透,前半句被记住了,神经网络由此进了第一次低潮。

SVM 在这一点上与单层感知机同类。核把数据送到高维,判决仍是一个线性函数,只不过这个线性函数映回原空间之后成了曲面。形状的上限由核定死,核定不下来,上限就定不下来。

图 8:多层网络的代价曲面有多个低谷,SVM 的只有一个

图源:《凸优化理论与应用》Topic 6。

图 8 是代价曲面的对比。左边多层网络的曲面坑坑洼洼,梯度下降停在哪取决于初值;右边 SVM 的曲面是一个碗,只有一个最低点。前者不保证全局最优,后者保证。

凸的代价是表示能力受限。深层网络把非线性映射本身也参数化了,

f(x)=∑kvkσ(wkTx+βk)(8-1)f(x) = \sum_{k}v_{k}\sigma\left(w_{k}^{T}x + \beta_{k}\right) \tag{8-1}f(x)=k∑vkσ(wkTx+βk)(8-1)

单隐层就是这个形状,多层是把 σ\sigmaσ 里面的东西再套一层。函数空间比 SVM 大得多,代价曲面坑坑洼洼,找不到全局最优,但能找到一个足够低的局部最优,往往比 SVM 那个唯一的全局最优还低。深度学习取代 SVM 的根本原因在这里,不在优化做得好。

剩下的问题是解原问题还是解对偶,看两边的维数。

特征多、样本少:基因数据,一万个基因,做一次实验开销很大,最后只拿到五十个样本。原问题的变量一万维,对偶的变量五十维。解对偶,规模小两个数量级,而且五十乘五十的核矩阵随手就能算。

样本多、特征少:电商的用户行为,二十个属性,一百万条记录。对偶变量一百万维,核矩阵一百万乘一百万,什么机器都装不下。十万乘十万的矩阵已经是百亿个元素,超出内存,与用什么语言写无关。这时只能回去解原问题,或者用不显式构造核矩阵的专用算法。

核函数与软间隔可以同时用,写法就是把式(6-5)里的内积换成核,得到式(7-4)。参数于是有两个:惩罚系数 CCC,核的参数,高斯核里是带宽 γ\gammaγ(也有人写成 σ\sigmaσ)。

图 9:小带宽、大 C:边界贴着点绕,几乎不出错

图源:《凸优化理论与应用》Topic 6。

图 10:大带宽、小 C:边界最简、最光滑,错分最多

图源:《凸优化理论与应用》Topic 6。

图 9 是小带宽配大 CCC:核的作用范围窄,每个点附近都能单独弯一下,边界绕着点走,训练集上几乎不出错,形状复杂得像一团毛线。图 10 是大带宽配小 CCC:核的作用范围宽,边界只能大尺度地弯,错分多一些,形状最简最光滑。中间还有一档,大带宽配大 CCC,边界连通但仍然弯曲,错分比小带宽时多。

哪个合适,没有公式可推。参数带进去,跑出来看,比对验证集上的表现。优化问题回答的是给定参数之后最好的解长什么样,不回答参数该取多少。

这一讲停在了一个写得出来、也算得动的二次规划上。麻烦出在规模:样本一到几十万,核矩阵既装不下也分解不动,通用求解器顶不住。

下一讲处理这件事。分解法每次只解一小块,SMO 每次只动两个乘子,多分类要拆成若干个二分类再合起来。方法不一样,起点还是这一节的对偶问题。

相关推荐
专注仿真1 小时前
支持向量机(SVM)算法详解与代码实例
算法·机器学习·支持向量机
Pniubi1 小时前
力扣42接雨水(动态规划法)
算法·leetcode·职场和发展
CQU_JIAKE1 小时前
10.31[A]
算法·深度优先
zwc32104320551 小时前
Day 5:threshold与inRange阈值分割
c++·图像处理·人工智能·opencv·算法·计算机视觉
云-缩影1 小时前
实际项目中怎么选排序算法:从面试题到工程落地
java·算法·排序算法
Pniubi2 小时前
力扣46全排列(回溯(递归))
算法·leetcode·职场和发展
ZhengEnCi11 小时前
Agent 架构怎么选:从单 Agent 到多 Agent 编排的选型决策指南
算法·架构
秋天的怀念_David12 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Zzj_tju12 小时前
准确率不变,概率质量也不变吗?
人工智能·深度学习·机器学习·语言模型