ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

拉格朗日对偶从放弃到入门:从约束优化到SVM的完整推导与理解

拉格朗日对偶从放弃到入门:从约束优化到SVM的完整推导与理解 搞机器学习的朋友十个里有八个会在拉格朗日对偶这块卡住剩下两个是假装没卡过。我当年第一次学它是在读研啃 SVM 推导的时候公式抄得下来书也翻烂了但合上本子一想这东西到底在干嘛为什么要把一个好好的求最小问题换成另一个求最大问题对偶函数那个 inf 到底为什么非取不可最后直接战略性放弃。后来工作了因为要给团队讲 SVM 和约束优化硬着头皮从头推第二遍才算真正想明白。这次再入门我发现问题不在推导难而在大多数人第一步就理解偏了——大家都急着教你怎么推没人讲清楚每一步设计背后的动机。这篇我就把我自己从放弃到再入门过程中理清的完整推导思路写下来包括拉格朗日函数为什么要这样构造、对偶函数为什么非取 inf 不可、弱对偶和强对偶分别成立在哪里以及我踩过的几个坑希望能帮正在这里挣扎的人少走弯路。1. 我当初是怎么被拉格朗日对偶搞到放弃的1.1 从拉格朗日乘子法说起它到底解决了什么问题想搞懂拉格朗日对偶绕不开中学就接触过的拉格朗日乘子法。先看最经典的情形等式约束下的极值问题。假设要最小化 f(x)同时满足约束 h(x)0其中 x 是向量。拉格朗日乘子法的核心思路是在约束曲面 h(x)0 上目标函数 f 取得极值的点必须满足等高线与约束曲面“相切”。用数学语言说就是 f 的梯度与 h 的梯度在该点平行。于是构造拉格朗日函数L(x, ν) f(x) ν h(x)对 x 求梯度并令其为零∇f(x*) ν ∇h(x*) 0再加上约束 h(x*)0就能解出最优解 x* 和乘子 ν。注意这里的 ν 是实数没有符号限制因为等式约束没有“方向”的概念约束本身就是两侧都成立的。举个具体例子。求 x₁² x₂² 在约束 x₁ x₂ 1 下的最小值。直观上解是 (0.5, 0.5)我们用乘子法验证L x₁²x₂²ν(x₁x₂-1)对 x₁,x₂ 求偏导得到 2x₁ν0、2x₂ν0所以 x₁x₂-ν/2代入约束得 -ν-10ν-1于是 x₁x₂0.5。整个过程中乘子 ν 其实衡量的是“约束对目标函数的边际影响”。理解这个基础很关键。因为拉格朗日对偶本质上就是把乘子法推广到不等式约束和多个约束的场景。但真正让我第一次放弃的也是这个推广过程——等式约束那一套方法没法直接套到不等式约束上我当时没想清楚差异在哪。1.2 为什么等式约束方法处理不了不等式约束等式约束要求解必须落在 h(x)0 这个曲面上乘子法强制满足约束方程。但现实优化问题里大量出现的是不等式约束比如“预算不超过一百块”“误差不能大于某个阈值”这些都是形如 g(x) ≤ 0 的条件。不等式约束和等式约束有一个本质区别最优解可能落在约束边界上也可能落在约束内部。比如约束 x ≤ 1最优解可能正好在 x1 处取得也可能在 x0.6 处取得此时约束根本没起到作用。你提前不知道约束是不是“活跃”的也就没法像等式约束那样直接把约束当作方程代入求解。当时我看到这个问题第一反应是人肉枚举所有活跃约束的组合每个组合都当作等式约束解一遍然后取可行且最小的解。理论上可行但约束数量一多组合爆炸。而且实际工程问题里约束动不动几十上百个这条路根本走不通。拉格朗日对偶解决这个问题的思路很巧妙与其去判断哪个约束活跃不如把约束本身“软化”成一个惩罚项放进目标函数。如果某个约束被违反惩罚就为正目标函数变差如果约束满足惩罚为负或零目标函数变好。惩罚的力度由乘子 λ 控制。这样一来你只需要对带惩罚的目标函数求无条件极小就能得到一个关于原问题最优值的下界。后面所有推导都建立在这个设计之上。2. 把约束“塞进”目标函数拉格朗日函数是怎么设计出来的2.1 不等式约束为什么需要非负乘子先写出优化问题的原始形式。考虑一般约束优化问题min f(x) s.t. g_i(x) ≤ 0, i 1, 2, ..., m h_j(x) 0, j 1, 2, ..., p定义广义拉格朗日函数L(x, λ, ν) f(x) Σ λ_i g_i(x) Σ ν_j h_j(x)这里 λ_i 和 ν_j 就是拉格朗日乘子。但是在不等式约束这一项里必须要求 λ_i ≥ 0。这个符号限制是整个对偶理论的命门很多推导错误就是因为顺手写成了无约束的 λ。为什么 λ_i 必须非负因为对任意满足原始约束的可行点 x有 g_i(x) ≤ 0。如果 λ_i ≥ 0那么 λ_i g_i(x) ≤ 0也就是说拉格朗日函数值不会超过 f(x)L(x, λ, ν) ≤ f(x)这个简单的不等式是整个弱对偶性证明的第一块基石。如果允许 λ_i 0那么对于一个不可行点比如 g_i(x) 0乘上负的 λ_i 反而会“奖励”它让拉格朗日函数值更低这样你就没法保证 L 是 f 的下界了。打个比方λ_i 就像一个记分监督员专门记录约束被违反的情况。记分规则必须是对违规者扣分也就是 λ_i ≥ 0 时违规越大惩罚越重如果记分员对违规者加分那整个评价体系就崩了。读到这里建议你先自己算一个例子确认一下设 f(x)x²约束 x ≤ 1写成 g(x)x-1 ≤ 0试试 λ 取正数和负数时 L(x,λ) 和 f(x) 的大小关系马上就能体会这个符号限制的意义。2.2 等式约束的乘子为什么没有符号限制等式约束 h_j(x)0 对应的乘子 ν_j 则没有符号限制原因更简单在可行点上h_j(x) 严格等于 0所以无论 ν_j 取正取负ν_j h_j(x) 这一项在可行点上都恒等于零不会影响拉格朗日函数值与 f(x) 的大小关系。这背后有一个更深层的直觉等式约束是“双向”的x 必须同时满足上下两个方向的条件而不等式约束是“单向”的它只限制了一侧。这种非对称性反映在乘子上就是一个有符号限制、一个没有。当时我在这里卡了很久总想着把等式乘子也套上非负限制结果推导出来的对偶问题完全不对。后来记住一个口诀不等式约束的乘子非负等式约束的乘子自由。遇到具体问题时先检查自己的 λ 有没有带符号要求。2.3 构造拉格朗日函数的通用步骤构造广义拉格朗日函数可以按三步走。第一步把原始问题里所有不等式写成 g_i(x) ≤ 0 的标准形式所有等式写成 h_j(x) 0 的标准形式。注意不等号一定要统一成 ≤因为后续推导中的所有符号判断都基于这个形式。第二步为每个不等式约束配一个 λ_i要求 λ_i ≥ 0为每个等式约束配一个 ν_j无符号限制。第三步把这些项全部加到目标函数上写成 f(x) 加两类惩罚项的形式。以最典型的 SVM 原始问题为例硬间隔支持向量机的优化目标是min (1/2)||w||² s.t. y_i (w·x_i b) ≥ 1, i 1, 2, ..., n先把不等式转换成标准形式g_i(w, b) 1 - y_i (w·x_i b) ≤ 0然后写出拉格朗日函数L(w, b, α) (1/2)||w||² Σ α_i (1 - y_i(w·x_i b))其中 α_i ≥ 0。这个结果在 SVM 相关教材里见得多了但很多人忽略了这里的 α ≥ 0 正是由不等式约束带来的它的非负性会直接影响后面 KKT 条件里的互补松弛项。3. 对偶函数与对偶问题一步步把原始问题变成它的“镜像”3.1 对偶函数的定义为什么要对 x 取极小有了拉格朗日函数 L(x, λ, ν) 之后下一步动作是固定 λ 和 ν把 x 看作变量对 x 求极小值。这个函数称为拉格朗日对偶函数g(λ, ν) inf_x L(x, λ, ν)这个“取极小”的操作我第一次学的时候完全不能理解觉得把 x 这个真正要优化的变量直接消掉问题不是变了吗后来才明白这正是对偶理论最核心的一步因为我们需要的是一个只依赖乘子 λ、ν 的函数用它来给原始问题最优值 p* 做下界估计。为什么 g(λ, ν) 能给 p* 提供下界回忆上一节的关键不等式对任意可行点 x~L(x~, λ, ν) ≤ f(x~)。现在对 x~ 这一类可行点挨个看即使取所有 x 中的最小值也一定不超过这些可行点上的函数值。所以g(λ, ν) inf_x L(x, λ, ν) ≤ f(x*)其中 x* 是原始问题最优解。也就是说对任何满足 λ ≥ 0 的乘子g(λ, ν) 都是原始最优值 p* 的一个下界。一个函数能对另一个未知的最优值给出下界这本身就是极有价值的信息——哪怕目前还不知道 p* 是多少。注意一个细节g(λ, ν) 完全可能等于 -∞。比如某个 L 随着 x 趋向无穷而趋于负无穷那么对偶函数在这个点就没有意义。所有使 g(λ, ν) -∞ 的 (λ, ν) 组成对偶函数的定义域。这个细节是初学者最容易忽略的坑后边专门说。3.2 弱对偶性的推导过程现在把散落的不等式串起来得到拉格朗日对偶理论的第一个重要结论弱对偶性。设原始问题最优值为 p*。设 λ ≥ 0 且对偶函数 g(λ, ν) 有定义那么对于任意原始可行点 x~有L(x~, λ, ν) f(x~) Σ λ_i g_i(x~) Σ ν_j h_j(x~) ≤ f(x~)这里的非等式来自三项λ_i ≥ 0g_i(x~) ≤ 0h_j(x~)0。接着对左边取所有 x 的下确界g(λ, ν) inf_x L(x, λ, ν) ≤ L(x~, λ, ν) ≤ f(x~)因为上式对任意可行 x~ 都成立所以对右边取极小得到g(λ, ν) ≤ p*最后既然任意可行乘子给出的对偶函数值都是 p* 的下界那所有下界里最大者自然也是最接近 p* 的这就是对偶问题的来源。3.3 对偶问题、对偶可行域与对偶间隙对偶问题是这么定义的max g(λ, ν) s.t. λ ≥ 0注意这里没有任何关于 x 的约束x 已经在求下确界时被消掉了。对偶问题的最优值记为 d*。由弱对偶性可知 d* ≤ p*两者之差 p* - d* 称为对偶间隙。弱对偶性不需要任何凸性假设只要原始问题有意义对偶间隙就一定非负。这一点很重要意味着无论原始问题多么复杂只要能算出对偶函数就能得到一个有效的下界。用一个小例子把完整流程走一遍。考虑问题min -x s.t. x ≤ 1标准形式下 f(x)-xg(x)x-1 ≤ 0。写拉格朗日函数L(x, λ) -x λ(x - 1) (λ - 1)x - λ对 x 取下确界。当 λ 1 时L 与 x 无关恒等于 -1当 λ ≠ 1 时L 关于 x 的斜率非零x 可以趋向 ±∞L 趋于 -∞。所以对偶函数为g(1) -1其余 λ 处 g(λ) -∞对偶问题是在 λ ≥ 0 上最大化 g(λ)得到 d* -1。原始问题里 x ≤ 1所以 f(x)-x 的最小值是当 x1 时取到p*-1。这里 d* p*对偶间隙为零强对偶成立。虽然是个极端例子但完整展示了从原始问题到拉格朗日函数再到对偶问题的整个推导链路。我当时第一次完整推完这个小例子心里踏实了很多。因为它验证了整个框架是自洽的而且步骤可复现写拉格朗日函数、对 x 求极值、得到对偶函数、解对偶问题、检查对偶间隙。4. 什么时候对偶真的等价强对偶、Slater 与 KKT4.1 凸问题和 Slater 条件弱对偶性永远成立但真正让对偶理论在优化里大放异彩的是强对偶性——也就是对偶间隙为零d* p*。强对偶不是平白无故成立的它需要额外条件。最常见的充分条件是原始问题为凸优化问题并且满足 Slater 条件。这里简单说下凸优化问题目标函数 f 是凸函数所有不等式约束 g_i 是凸函数等式约束要求是仿射函数也就是形如 a^Tx b 0 的线性等式。在这个前提下如果存在一个可行点 x_rel使得所有不等式约束都严格成立即 g_i(x_rel) 0那么强对偶成立。为什么需要“严格”小于 0用几何直觉理解只有可行域内部非空我们才能在那个最优边界上找到一张真正“托住”目标函数的超平面。如果可行域本身就塌缩成一个边界上的点或者约束退化成等式支撑超平面就可能不存在。Slater 条件本质上就是在说可行域要有足够多的内部点给强对偶成立留出空间。有个常见放宽如果某个不等式约束是线性的即 g_i(x)a^T x - b那么 Slater 条件对这个约束可以放宽成普通可行即可因为线性约束天然不会破坏强对偶。我最初的一个误区是以为只要问题凸强对偶就一定成立。后来才意识到凸只是基础Slater 条件才是保证。好在多数实际建模的问题SVM、Lasso、线性回归的带约束形式都天然满足 Slater 条件所以很多人没遇到反例也就忽略了这一点。真到了处理非凸或者约束严格可行的场景这个区分能救命。4.2 KKT 条件的四件套当强对偶成立并且原始、对偶问题都达到最优解时任何一对最优解 x* 和 (λ*, ν*) 都必须满足 KKT 条件。KKT 是 Karush-Kuhn-Tucker 的缩写它其实是拉格朗日乘子法在不等式约束下的完整推广。一个完整的 KKT 系统由四部分组成。第一是原始可行性g_i(x*) ≤ 0, h_j(x*) 0这保证了 x* 确实在原始可行域里。第二是对偶可行性λ* ≥ 0这保证了对偶变量来自合法的乘子集合。第三是互补松弛λ_i* g_i(x*) 0, i 1, 2, ..., m这条最漂亮它说明如果某个不等式约束在最优解处没有被激活g_i(x*) 0那它对应的乘子一定是零反过来如果乘子大于零约束一定被激活g_i(x*) 0。也就是说KKT 自动帮我们识别出哪些约束是真正起作用的。这就是 SVM 里“支持向量”概念的数学来源。第四是平稳性∇f(x*) Σ λ_i* ∇g_i(x*) Σ ν_j* ∇h_j(x*) 0这说明 x* 是拉格朗日函数关于 x 的一个驻点可以理解为把约束的影响折算进目标函数之后梯度达到平衡。4.3 从强对偶链推导 KKT 的思路很多人背 KKT 条件怎么都背不住其实它根本不需要背。从一条强对偶等式链就能完整推出来。设 x* 是原始最优解(λ*, ν*) 是对偶最优解。由于强对偶成立f(x*) g(λ*, ν*)于是f(x*) inf_x L(x, λ*, ν*) ≤ L(x*, λ*, ν*) ≤ f(x*)注意两端都是 f(x*)所以中间两个不等号必须全部取等号。先看中间那个小于等于号变成等号意味着 L(x*, λ*, ν*) f(x*)。把它展开f(x*) Σ λ_i* g_i(x*) Σ ν_j* h_j(x*) f(x*)由于 x* 原始可行h_j(x*)0所以上式等价于Σ λ_i* g_i(x*) 0而每一项 λ_i* g_i(x*) 都非正λ_i* ≥ 0 且 g_i(x*) ≤ 0和为 0 只能说明每一项都是 0这就推出了互补松弛。再看第一个不等号变成等号意味着 x* 使 L(x, λ*, ν*) 达到全局极小。在可微条件下极小点的梯度为零平稳性条件随之而来。我当时把这个链条亲手写了两遍KKT 条件就再也不需要背了。建议你也这么做不要直接看答案自己从 f(x*) g(λ*, ν*) 出发一步步推到四组条件。这个过程比任何记忆技巧都管用。5. 用几何直觉重新看一遍推导5.1 一个简单问题在数轴上的样子抽象的符号推导容易让人迷失几何直觉是很好的救生圈。看一个简单例子min x² s.t. x ≥ 1标准形式是 g(x) 1 - x ≤ 0。原始最优解显然在 x1 处p*1。构造拉格朗日函数L(x, λ) x² λ(1 - x), λ ≥ 0对 x 求极小。这是一个开口向上的二次函数极值点满足 2x - λ 0即 x λ/2。代入得到对偶函数g(λ) (λ/2)² λ(1 - λ/2) λ - λ²/4对偶问题是最大化 g(λ)λ ≥ 0。对 λ 求导等于零得到 λ2此时 g(2) 1d*1强对偶成立。现在画一下图像x² 是一条抛物线约束 x≥1 限制了只取右侧部分。g(λ)λ - λ²/4 这条曲线可以理解为对所有 λ ≥ 0它对应一族以 (1, λ) 为法方向的支撑直线的截距。λ2 时直线恰好同时经过可行域里的最优点 (1,1)并且从下方托住了目标函数图像。强对偶成立本质就是能找到一条支撑直线刚好切在最优点处。这个例子虽然一维但足以说明对偶函数“找下界”的本质对每个 λ算的是一个倾斜直线在曲线下方的最大可能高度对偶问题就是在所有可能的斜率里挑一个最高的支撑高度。5.2 高维下的支撑超平面与对偶间隙来源把视角从一维扩展到一般情形。构造一个辅助集合 GG { (f(x), g_1(x), ..., g_m(x), h_1(x), ..., h_p(x)) : x ∈ R^n }这个集合把每个 x 对应的目标值和约束值打包成一个高维点。原始问题的最优值 p* 对应的是在这个集合中第一个坐标尽可能小同时后几个坐标落在“可行区域”内的那个点。对偶函数在这个视角下的含义非常直观它是寻找一个以方向 (1, λ, ν) 为法向量的支撑超平面使得整个集合 G 都落在超平面的一侧然后看这个超平面在第一个坐标轴上的截距是多少。如果 G 本身是凸集或者其凸包在最优边界上提供了有效的支撑点那么支撑超平面可以精确地“切”到最优值所在的位置强对偶成立。如果 G 非凸比如可行集是离散的、断裂的多块区域那么支撑超平面最多只能撑在集合凸包的外壳上触及不到内部的真实最优值这时候对偶间隙就出现了。这个几何视角解释了很多直觉问题。比如为什么强对偶在凸优化里几乎总是成立因为凸优化对应的集合 G 在经过适当处理后是凸的支撑超平面想切哪里就切哪里。又比如为什么非凸问题里对偶间隙是常态不规则的集合形状无法被一张平整的超平面完美贴合单靠线性支撑就总会漏掉一些“凹陷”处的最优信息。我后来在工作中看非凸问题的论文凡是涉及到先求对偶、再分析间隙的脑子里都会自动浮现这个支撑超平面的图像。这个直觉比死记定理有用得多。6. 实际应用与推导时最容易踩的坑6.1 用拉格朗日对偶推导 SVM 对偶形态拉格朗日对偶最经典的应用之一就是把 SVM 的原始优化问题转换成对偶问题从而引出核函数。这里完整走一遍推导也顺便展示前面所有概念是怎么串起来的。硬间隔 SVM 的原始问题min (1/2)||w||² s.t. y_i (w·x_i b) ≥ 1, i 1, 2, ..., n把不等式转成标准形式后拉格朗日函数为L(w, b, α) (1/2)||w||² Σ_{i1}^{n} α_i [1 - y_i(w·x_i b)]其中 α_i ≥ 0。对偶函数需要对 w 和 b 一起取极小所以先求梯度零点的条件∂L/∂w 0 w Σ α_i y_i x_i ∂L/∂b 0 Σ α_i y_i 0把这两个条件代回 L得到对偶函数g(α) - (1/2) Σ_{i1}^{n} Σ_{j1}^{n} α_i α_j y_i y_j x_iᵀ x_j Σ_{i1}^{n} α_i对偶问题就是最大化这个关于 α 的目标函数同时满足 α_i ≥ 0 和 Σ α_i y_i 0。这个推导最震撼的地方在于原始问题里需要计算的 w 和 b在对偶形式中完全消失了只剩下样本之间的内积 x_iᵀ x_j。这意味着我们根本不需要知道样本向量的具体表示只要知道两两之间的内积就够了而用核函数替换内积就是水到渠成的事。这就是“核技巧”的数学基础也是无数人学拉格朗日对偶的根本原因。6.2 常见问题排查速查表在实际动手推导时我总结过一份高频错误清单这里按现象、原因、对策列出来。典型现象背后原因解决办法对偶函数在某些点直接等于 -∞拉格朗日函数关于 x 无下界乘子不在对偶定义域内检查乘子约束是否完整缩小 λ、ν 取值范围对偶间隙不为 0原始问题非凸或 Slater 条件不满足验证凸性和约束内部点存在性必要时改用其他方法按 KKT 求出的点不是最优解可能错误地把 KKT 当充分条件用于非凸问题凸问题里 KKT 足够非凸问题必须另做全局性分析推导中 λ 出现负值忘记了不等式乘子非负这个硬前提回到拉格朗日函数定义检查符号限制对偶目标里少了一项代入 w、b 时漏算了交叉项或常数项把代换过程完整写下逐项核对系数这个表是我第二次推导时反复用来自我检查的。很多时候公式推不下去不是不会算而是前面某个乘子符号写错了或者对偶函数定义域没看好。先排查这两个问题能省掉大量时间。6.3 一个验证对偶推导的通用套路如果手上有一个新的约束优化问题想快速验证自己的对偶推导是否正确我建议按下面这个套路走一遍。先取一个极端情形把所有不等式约束当成等式约束或者把约束缩放成非常宽松观察对偶函数和原始最优值是否趋于一致。再取一个所有约束都不起作用的点比如把问题放到无约束条件下看 λ 是否趋于 0。最后用一个小规模数值例子直接在程序里枚举 x 的若干取值比较原始最优值和对偶最优值。比如前面那个 min -x, s.t. x≤1 的例子写成程序枚举 x 从 -10 到 10很容易验证 p*-1、d*-1。这种数值验证方式成本很低但能立刻暴露推导错误。我在学习阶段几乎每个推导都这样检查一遍比自己干瞪眼高效得多。6.4 推导时容易被忽略的三个细节第一个细节对偶函数定义域非常容易被忽视。很多人写出 g(λ, ν) 后直接开始求最大值完全没考虑 g 可能是 -∞ 的区域。实际上对偶问题必须限定在 g(λ, ν) -∞ 的定义域上讨论否则 max 根本没有意义。第二个细节互补松弛条件只在强对偶成立时有意义。如果弱对偶情况下你硬套 λ_i g_i(x) 0很可能得到一个并不存在的“最优解”。最简单的反例就是非凸问题它满足某些形式的驻点条件但不满足全局最优所要求的全部条件。第三个细节对偶变量并不总是有实际意义除非你给约束赋予了“资源价格”这类解释。比如在线性规划里对偶变量是影子价格表示约束右侧单位变化对目标值的影响但在 SVM 里α 更像是一个样本重要性的权重而不是直观的“市场价格”。理解每个应用场景下对偶变量的含义能帮你更好地判断推导是否合理。说到这我想起自己第二次推导 SVM 时的一个小习惯在纸上把原始问题写在左边把对偶问题写在右边中间用箭头标出每一步的转化依据尤其是“哪一步用了 λ≥0”“哪一步用了互补松弛”。等这张图完整串起来整个拉格朗日对偶的框架才算真正长在自己身上了。这个习惯也推荐给你它不需要什么技巧但确实是我从放弃到再入门之间最关键的转折点。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进