查看全课大纲(第 45 / 82 节)
- 1.函数与数据泛化
- 2.向量:从几何直觉到高维空间
- 3.矩阵与张量
- 4.特征值与特征向量:矩阵变换的不动方向
- 5.凸函数:从向量求导的矩阵记号到好优化的函数形状
- 6.概率与统计:机器学习的数学基础
- 7.独立性与随机变量:贝叶斯公式与二项分布
- 8.期望、方差与协方差:随机变量的数字画像
- 9.联合概率:当一条轴不够用的时候
- 10.概率分布(一):从伯努利到伽马函数
- 11.概率分布(二):贝塔、泊松、正态与两个贝叶斯故事
- 12.机器学习的模型:找输入与输出的关系
- 13.机器学习的应用
- 14.过拟合
- 15.机器学习的分类
- 16.有监督学习:从房价预测说起
- 17.损失函数
- 18.梯度下降(上):更新规则与学习速率
- 19.梯度下降(2)
- 20.牛顿方法
- 21.KNN简介
- 22.距离测算
- 23.朴素贝叶斯
- 24.朴素贝叶斯的实际应用
- 25.信息熵:决策树构建的度量基础
- 26.信息增益与决策树的构建
- 27.ID3算法
- 28.决策树节点的划分
- 29.CART树
- 30.Bagging
- 31.Boosting:自适应提升算法
- 32.Gradient Boosting
- 33.线性模型:回归与分类的同一副骨架
- 34.最小二乘:把最优参数直接解出来
- 35.最小二乘法的几何与概率视角
- 36.极大似然:给最小二乘一个概率出身
- 37.逻辑回归(1):把线性模型接到分类上
- 38.逻辑回归(2):损失函数与多分类
- 39.---- 手造数据: 5 个样本, 2 个特征; x2 几乎 = 2*x1 (偏差手工指定, 无随机) ----
- 40.讲师例: 向量 "23014" -- 三把范数尺子量同一个向量
- 41.优化方法(1):坐标下降与前向选择
- 42.优化方法(2):前向策略与最小角回归
- 43.拉格朗日乘子法(1):从无约束到等式约束
- 44.拉格朗日乘子法(2):等式约束下的平行条件与拉格朗日函数
- 45.拉格朗日乘子法(3):不等式约束与 KKT 条件
- 46.最大间隔:把分类问题变成优化问题
- 47.拉格朗日对偶问题:把 w 和 b 全部换成 α
- 48.支持向量:边界上的少数派
- 49.SVM 计算过程:一笔到底算完,再走进核方法
- 50.贝叶斯公式:概率即信念
- 51.隐含变量和概率模型:给看不见的原因建模
- 52.EM 算法:期望与最大化的迭代
- 53.琴生不等式:EM 的数学钥匙
- 54.三个硬币问题:EM 的复盘与衔接
- 55.高斯混合模型:用隐变量解释双峰数据
- 56.隐马尔可夫模型
- 57.隐马尔可夫模型(2):前向算法与动态混合模型
- 58.隐马尔可夫模型在 NLP 中的运用
- 59.EM 算法:把「为什么收敛」推到底
- 60.HMM 在 NLP 中的运用:从分词到机器翻译
- 61.HMM 参数估计:Baum-Welch 的三块拉格朗日
- 62.高维下的高斯模型
- 63.主题模型:从词袋到隐含主题
- 64.Dirichlet 分布(1)
- 65.Dirichlet 分布(2)
- 66.统计学习内容回顾
- 67.K-means 算法
- 68.PCA 降维
- 69.SVD 降维
- 70.从聚类到流形
- 71.局部线性嵌入
- 72.随机邻域嵌入:SNE 与 t-SNE
- 73.无参模型:让数据自己说话
- 74.高斯过程:函数空间里的正态分布
- 75.高斯过程(2):噪声、正则化与核的线性组合
- 76.神经网络简介:从感知器到自编码器
- 77.反向传播:把误差一层层传回去
- 78.卷积神经网络(CNN):让特征自己学出来
- 79.循环神经网络(RNN):给网络装上记忆
- 80.深度学习回顾:静态一类,动态一类
- 81.增强学习(1):蒙特卡洛、树搜索与 Q-learning
- 82.强化学习(2):从乌鸦吃核桃到井字棋的 value 回传
拉格朗日乘子法(3):不等式约束与 KKT 条件
约 29 分钟
小象实战讲义 · 机器学习算法精讲
上一节把等式约束 的优化讲完了:拉格朗日函数 、平行条件、手算全流程。结尾还留了一块拼图——不等式约束的优化, 的情形。讲师当时说,那正是做 SVM 时要遇到的形态:SVM 的求解,最终就是一个不等式的优化。这一节把这块拼图补上:问题框架不变(),只是约束从”必须在线上”变成”可以在一片区域里”——而把两种情况统一成一组条件的那件工具,叫 KKT 条件。
💡 核心导读
- 从一条线到一个区域:等式 在二维里是一条线,不等式 是一整片可行区域(feasible region)——约束”松”了一大截。
- 两种情况:全局最优点恰好落在区域里(情况一:约束等于没有,直接按无约束解);最优点在区域外(情况二:最优解一定贴在区域边缘,不等式退化成等式,上一节的方法整个接上)。
- 判定流程:先不管限制条件求出全局最优,再看它满不满足约束——满足就完事,不满足走情况二。
- KKT 四条件:、、、—— 那一支回收情况一, 那一支回收情况二。
- 一维例子全程: 约束 ,解出 要么是 、要么是 ——两种情况被同一组条件统一。
从一条线到一个区域
还是刚才一样的这个问题:想求 ,但这回限制条件从 变成了 。给定一个不等式的时候,怎么做这个优化?讲师的路数跟上一节一样:先举一个非常简单的实际例子,把情况看清楚,再引出里边的重要概念。
设目标函数 。它的等高线长什么样,大家应该能画出来:一圈套一圈的同心圆,最小点在原点 。梯度是 ,负梯度是 ——上一节练熟的东西。
现在给定限制条件:
注意这里面的结构: 就是那个单位圆;而”“把圆内部的整个区域都划了进来。讲师在黑板上用铅笔把这个区域描了一圈(蓝色虚线区域)——这片区域内的每一个点都满足 ,都是可以取的点;要做的,就是在这片满足限制条件的区域里求 的最优值。
于是跟等式的第一个区别立刻显形: 在二维空间里是一条线; 是一个区域。在区域里满足这个条件的点都是可以的——可行域从”一条道”拓宽成了”一整片地”。
情况一:最小点就在区域里面
这个 case 非常简单。假设想求的最小点,恰好满足 这个限制条件——比如本例的全局最小点 ,代进去 ,就在区域里。那这个问题就”完完了”:直接按一个最简单的无约束问题去做——
解出来的 就是答案,没有什么问题。
这里有一个自然的疑问(讲师替大家问了):怎么知道最优点在不在限制区域之内?做法其实特别容易——先不关心限制条件,把它的全局最优解出来;然后看这个解满不满足限制条件。满足,求解完毕;不满足,再看情况二。
情况二:最小点在区域外面
我们没有每次都那么幸运——不是每次全局最优点都正好落在限制区域里边。这时候该怎么办?
把所优化的函数换一下(限制条件不动)。讲师在黑板上现场调数字:先写了带偏移的 ,改成对称一点儿的 ,再”稍微大一点点”,最终落在:
这么做的目的只有一个:让无约束最优点 明确地落在限制条件之外(它到原点的距离 ,在单位圆盘外面)。限制条件没变,变的是优化的函数——等高线还是一族同心圆,只是圆心挪到了 。
这时直觉很清楚:沿着让 下降的方向走,会一头撞到区域的边缘( 那个圆)上,再也前进不得。最优解一定落在区域的边缘——问题退化成一个等式约束的优化:
上一节的东西整个接上来,而且会出现刚才说的 和 的那种关系——最优处负梯度与法线方向共线:
(记号说明:等式约束 的乘子用 ,不等式约束 的乘子用 ——讲师特意换了字母,“为了稍微区分一下”。)
所以情况二要满足三个条件:其一,负梯度和 的梯度(法线方向)共线( 时两者同向);其二, 一定要大于零(讲师还补了一句”刚才忘说那个 是大于零”——上一节算过,求最小值的那个解 ,两头在这里接上了);其三,。这样,不等式优化就直接变成了一个等式约束的优化。
KKT 条件:把两种情况写在一起
情况一按无约束解,情况二按等式约束解——两条路各自都通了。关键是两者怎么统一:能不能把 case one 和 case two 全部写在一起?能。这就是 KKT 条件的来历。
对 s.t. ,仍然构造一样形式的拉格朗日函数(针对不等式约束的版本):
满足下面四个条件的 (连同乘子 ),就是最优解:
条件一:。对 求导就是 ,倒过来正是 ——跟上一节等式约束推出来的条件一模一样。
条件二:。刚才情况二里不是说 一定要大于零吗,为什么这里写成”大于等于”?因为还存在 的情形——那样就把 case one 也收进来了。这一改,两种情况统一。
条件三:。这是区分 case one 和 case two 的机关。两个因子相乘等于零,无非两支:
- :整个拉格朗日函数退化成 ——因为 乘 那一项压根就不算了。对 求导置零就等于对 求导置零,直接做全局优化。这正是情况一:最优点在区域里面,此时 。
- :最优解贴在边界上,——正是情况二:不等式退化成等式的优化问题。
条件四:。原始限制条件本身。 的时候,对应的就是 那一支。
这四个条件,把 case one 和 case two 所有的可能性都包含了: 等于零,代表可以直接求全局最优、全局最优就在限制区域里边; 等于零,代表最优在限制区域之外、把不等式问题变成等式问题。构造出 之后,最优解必须满足这四个条件——满足这四个条件,才是一个最优解。
这组条件是有三个人一起发现的,写了一篇文章,讲约束的这套条件就叫 Karush-Kuhn-Tucker condition,取三个人名字的首字母简称 KKT 条件(讲师口播里的”KTT 条件""KK 提条件”都是 ASR 错词,正确读法是 K-K-T)。它就是用来解决不等式约束下优化问题的工具。回头看会发现:不等式优化只有两个方向——要么变成普通的全局优化(情况一),要么变成等式的优化(情况二)——而两条路都通过构造拉格朗日函数来走。
术语对照(标准补全):教科书里这四条常被冠名为平稳性(stationarity)、原始可行性(primal feasibility)、对偶可行性(dual feasibility)、互补松弛性(complementary slackness)。本讲义按讲师的推导顺序叫它们条件一~条件四。
把开篇那个二维例子的两种情况各检一遍四条件——同一个圆盘约束,两种命运:
# ---- 二维例子: 同一个圆盘约束, 两种命运 ----
# 可行域: g(x) = x1^2 + x2^2 - 1 <= 0 (单位圆盘, 含内部与边界)
import math
def g(x1, x2):
return x1 * x1 + x2 * x2 - 1.0
print("约束区域 g(x) = x1^2 + x2^2 - 1 <= 0: 二维里不是一条线, 而是整个单位圆盘")
print()
print("=== 情况一: f(x) = x1^2 + x2^2, 全局最优点 (0,0) 就在圆盘里 ===")
print(f" 无约束解 x* = (0, 0): g(0, 0) = {g(0.0, 0.0):+.1f} <= 0 -> 满足限制条件, 约束没激活")
print(" 取 lambda* = 0, 四条件逐项检查:")
print(" 条件一: grad f(0,0) + 0*grad g = (0.0, 0.0) (grad f 在原点本身就是零向量)")
print(" 条件二: lambda* = 0 >= 0")
print(f" 条件三: lambda* * g(x*) = 0 * ({g(0.0, 0.0):.1f}) = 0.0")
print(f" 条件四: g(x*) = {g(0.0, 0.0):+.1f} < 0")
print(" -> 直接按无约束解: 2*x1 = 0, 2*x2 = 0, x1 = x2 = 0, 完事")
print()
print("=== 情况二: f(x) = (x1-1.1)^2 + (x2-1.1)^2, 最优点 (1.1,1.1) 在圆盘外 ===")
unc = (1.1, 1.1)
print(f" 无约束解 (1.1, 1.1): g = {g(*unc):+.4f} > 0 -> 不可行, 最优解只能贴在圆盘边缘")
s = 1.0 / math.sqrt(2.0)
x1s, x2s = s, s
lam = 1.1 * math.sqrt(2.0) - 1.0
gf = (2.0 * (x1s - 1.1), 2.0 * (x2s - 1.1))
gg = (2.0 * x1s, 2.0 * x2s)
stat = (gf[0] + lam * gg[0], gf[1] + lam * gg[1])
print(f" 贴边解 x* = (1/sqrt(2), 1/sqrt(2)) = ({x1s:.4f}, {x2s:.4f})")
print(f" 由条件一解出: lambda* = 1.1*sqrt(2) - 1 = {lam:.4f}")
print(f" 条件一: grad f + lambda* grad g = ({stat[0]:+.2e}, {stat[1]:+.2e}) (机器零)")
print(f" 条件二: lambda* = {lam:.4f} > 0")
print(f" 条件三: lambda* * g(x*) = {lam * g(x1s, x2s):+.2e} (g 本身是机器零)")
print(f" 条件四: g(x*) = {g(x1s, x2s):+.2e} (正好在边界上)")
print(f" 方向检查: -grad f = ({-gf[0]:.4f}, {-gf[1]:.4f}), lambda* * grad g = ({lam * gg[0]:.4f}, {lam * gg[1]:.4f})")
print(" -> 负梯度与 grad g 同向 (lambda* > 0), 不等式优化退化成 g = 0 的等式优化")约束区域 g(x) = x1^2 + x2^2 - 1 <= 0: 二维里不是一条线, 而是整个单位圆盘
=== 情况一: f(x) = x1^2 + x2^2, 全局最优点 (0,0) 就在圆盘里 ===
无约束解 x* = (0, 0): g(0, 0) = -1.0 <= 0 -> 满足限制条件, 约束没激活
取 lambda* = 0, 四条件逐项检查:
条件一: grad f(0,0) + 0*grad g = (0.0, 0.0) (grad f 在原点本身就是零向量)
条件二: lambda* = 0 >= 0
条件三: lambda* * g(x*) = 0 * (-1.0) = 0.0
条件四: g(x*) = -1.0 < 0
-> 直接按无约束解: 2*x1 = 0, 2*x2 = 0, x1 = x2 = 0, 完事
=== 情况二: f(x) = (x1-1.1)^2 + (x2-1.1)^2, 最优点 (1.1,1.1) 在圆盘外 ===
无约束解 (1.1, 1.1): g = +1.4200 > 0 -> 不可行, 最优解只能贴在圆盘边缘
贴边解 x* = (1/sqrt(2), 1/sqrt(2)) = (0.7071, 0.7071)
由条件一解出: lambda* = 1.1*sqrt(2) - 1 = 0.5556
条件一: grad f + lambda* grad g = (+0.00e+00, +0.00e+00) (机器零)
条件二: lambda* = 0.5556 > 0
条件三: lambda* * g(x*) = -1.23e-16 (g 本身是机器零)
条件四: g(x*) = -2.22e-16 (正好在边界上)
方向检查: -grad f = (0.7858, 0.7858), lambda* * grad g = (0.7858, 0.7858)
-> 负梯度与 grad g 同向 (lambda* > 0), 不等式优化退化成 g = 0 的等式优化两个细节值得看一眼:情况二里 ——数学上贴在边界上就该是 ,机器上带了符号毛边( 的平方凑整差了一丁点),条件三的 也因此是个 量级的”机器零”;条件一倒是精确的 。数学上为零、机器上有毛边,这是老朋友了。方向检查那行则把三个条件里的第一条落到了实数上: 与 逐位相同——负梯度与法线同向,。
更一般的形式:等式与不等式一起上
等式和不等式两个方向都描述完了,可以做一个更 general 的优化问题。给定 ,限制条件可能是两个系列:
第一个系列是 个等式限制条件,第二个系列是 个不等式约束。构造拉格朗日函数时,把所有项都加在一起:
每一个等式限制条件对应一个乘子 ,每一个不等式限制条件对应一个乘子 ( 和 在这里都是向量, 也是向量——在不同维度上都要求导为零)。条件清单跟着扩容:
- 对 的导数等于零(每个分量都是);
- 对 求导置零——恰好回收 ,等式约束的老办法;
- (全部 );
- (全部 );
- (全部 )。
两处需要把关的地方。其一,讲师板书时顺口把 也念成了”大于等于零”——等式约束的 没有符号限制:上一节亲手算过 两个解都成立(求最小值 、求最大值 ),这里按正确口径采信上一节的结论。其二,讲师在黑板上还把”对 求导置零”也列进了条件清单——对 那条完全正确;而对 求导置零得到 ,只在”约束被激活”的那一支成立(下面的一维例子里, 解出来的正是 那一支)。完整的不等式条件,由 、、 三件套来表达。
所以,如果构造一个特别复杂的优化函数——里面既有等式限制条件、又有不等式限制条件——就把它们都加在一起,按 KKT 条件求解,就可以得到最后的值。
一维例子:从头到尾解一遍
概念都齐了,来一个非常简单的例子走全程。优化的函数就是 ,画出来一条抛物线;限制条件是 。先把约束统一成标准形式:
(任何”大于等于”的约束,最后总会化成 的形式。)图分两种画法: 在左边(负半轴)的时候, 这个可满足的区域很大、把抛物线的全局最优点 也包了进去,全局最优点就是整个函数的最优点; 在右边(正半轴)的时候,可被允许的区域是 ,最优点就不再是 ,而是抛物线与边界的交点 。
用刚学的构造来解。拉格朗日函数:
(别忘了 。)对 求导置零:
(讲师先说成了” 等于二倍的 “,马上自我纠正为”二分之”—— 移项, 是 的一半。)对 求导置零:
两式一联立:,解出
到这里要停一下——别忘了有两种情况。最优值有可能在 允许的区域内,也有可能在允许区域外。如果在区域内(,无约束最优 可行),相当于 直接取 : 的最优值在 处直接得出来,四条件里走的是 那一支。如果在区域外(), 就是一个大于零的数,走刚才联立出来的这支,。
所以 的最优值要么是 、要么是 ;而 的最优值等于 除以二——要么是 、要么恰好就是 。(讲师收尾时先把 说到了 头上,话到一半自我纠正:那是 的最优值——写成干净的形式就是 、。)验证一下: 时,确实是 取到 、 的值才最小——两种优化到这里就都求完了。
把两个分支跑一遍,四条件逐项验:
# ---- 一维例子全程: min x^2, s.t. x >= b, 即 g(x) = b - x <= 0 ----
# L(x, lam) = x^2 + lam*(b - x)
# dL/dx = 2x - lam = 0 -> x* = lam/2
# 对 lam 求导置零 (激活支): b - x = 0 -> x = b, 联立得 lam* = 2b
def solve_1d(b):
# 先走情况一: 不管约束, 无约束最优 x = 0, 检查 g(0) = b <= 0 是否满足
if b <= 0:
return 0.0, 0.0
# 不满足 -> 情况二: 约束激活, x* 贴边界 x = b, lam* = 2b
return float(b), 2.0 * b
print("min x^2 s.t. x >= b (统一写成 g(x) = b - x <= 0)")
print("L(x, lam) = x^2 + lam*(b - x); dL/dx = 2x - lam = 0 -> x* = lam/2")
print()
print(f"{'b':>5} | {'x*':>5} | {'lam*':>5} | {'f(x*)':>6} | 四条件: 2x-lam, lam>=0, lam*g, g")
for b in (-1.0, 0.0, 0.5, 2.0):
x, lam = solve_1d(b)
dL_dx = 2.0 * x - lam
gx = b - x
print(f"{b:5.1f} | {x:5.1f} | {lam:5.1f} | {x * x:6.2f} | "
f"{dL_dx:+.1f}, {lam:.1f}, {lam * gx:+.1f}, {gx:+.1f}")
print()
print("规律: b <= 0 时无约束最优 x=0 可行, 取 0 支 (lam* = 0);")
print(" b > 0 时 x=0 不可行, 最优解贴到 x = b, 取 2b 支 (lam* = 2b)")
print("即 x* = max(0, b), lam* = max(0, 2b) —— 两种情况被一组条件统一")min x^2 s.t. x >= b (统一写成 g(x) = b - x <= 0)
L(x, lam) = x^2 + lam*(b - x); dL/dx = 2x - lam = 0 -> x* = lam/2
b | x* | lam* | f(x*) | 四条件: 2x-lam, lam>=0, lam*g, g
-1.0 | 0.0 | 0.0 | 0.00 | +0.0, 0.0, -0.0, -1.0
0.0 | 0.0 | 0.0 | 0.00 | +0.0, 0.0, +0.0, +0.0
0.5 | 0.5 | 1.0 | 0.25 | +0.0, 1.0, +0.0, +0.0
2.0 | 2.0 | 4.0 | 4.00 | +0.0, 4.0, +0.0, +0.0
规律: b <= 0 时无约束最优 x=0 可行, 取 0 支 (lam* = 0);
b > 0 时 x=0 不可行, 最优解贴到 x = b, 取 2b 支 (lam* = 2b)
即 x* = max(0, b), lam* = max(0, 2b) —— 两种情况被一组条件统一四行就是两支的全部形态: 和 走 支(), 和 走 支(),每一行的四条件全部打勾。表里那个 又是机器毛边: 乘上负数(),数学上是零、机器上带出了负号——老朋友第二次登场。
到这里,拉格朗日乘子法三节连走:等式约束(前两节)、不等式约束(本节)。讲师的收尾就一句:“拉格朗日乘子到现在为止,大家有没有什么问题?“——下一节就是真正的目的地:最大间隔。SVM 的求解就是一个不等式的优化,这一节的 KKT 条件正是为它准备的(对偶问题会在第 11 章展开)。
📝 动手练一练
- 的那一支:条件三 为什么被称为”区分两种情况的条件”?当 时,拉格朗日函数 变成了什么、优化问题变成了什么?当 时呢?
👉 点击查看参考答案
两个因子相乘为零,必居其一:
- (且 ): 里 那一项压根就不算了, 退化成 本身——对 求导置零等于对 求导置零,问题变成无约束的全局优化。对应情况一:最优解在可行域内部,约束没起作用。
- (且 ):最优解贴在可行域边界上,不等式约束退化成等式约束,按上一节等式优化的方法解。对应情况二。
四两拨千斤的一条乘积等于零,就是”把 case one 和 case two 统一到一起”的机关。
- 换一个目标函数:,约束仍是 (即 )。(1) 写出拉格朗日函数与条件一的方程;(2) 讨论 在什么范围时约束不激活、什么范围时激活,分别给出 与 ;(3) 用 和 两组数逐条验证四条件。
👉 点击查看参考答案
(1) ;条件一:,即 。
(2) 无约束最优是 ,它可行当且仅当 :
- :约束不激活,,();
- :约束激活, 贴边界 ,。
汇总:,——与正文 那题的 正好是一对镜像:一个把解往右拦、一个把解往左拦。
(3) :,。条件一 ;条件二 ;条件三 ;条件四 。全过。 :,。条件一 ;条件二 ;条件三 ;条件四 。全过(此时 )。
本章小结
- 可行域:等式 在二维里是一条线,不等式 是一整片区域;区域内所有点都满足约束。
- 情况一:全局最优满足约束()→ 直接按无约束解();判定流程:先解无约束、再验可行性。
- 情况二:全局最优在区域外 → 最优解贴边界 ,退化成等式优化;三个条件:负梯度与 共线( 时同向)、、。记号约定:等式乘子 、不等式乘子 。
- KKT 四条件:、、、; 支回收情况一( 退化为 ), 支回收情况二——两种情况统一。得名于 Karush、Kuhn、Tucker 三人。
- 一般形式: 个等式 + 个不等式,; 无符号限制( 双解先例)、、、。
- 一维例子: s.t. → 、激活支 ;干净写法 、。
📋 行动清单
- 把一维例子的两支各手推一遍(、),再取 验证:、
- 跑代码块二,盯着 从 走到 :解从 支跳到 支的瞬间,就是约束从”没激活”到”贴边界”的瞬间
- 在纸上画单位圆盘,再画圆心在原点、圆心在 的两族同心圆,标出各自最优解的位置(一个在圆心、一个贴边)
- 用自己的话讲一遍:条件三那条乘积为零,凭什么把两种情况统一
- 预习下一节《最大间隔》——SVM 的求解就是一个不等式优化,KKT 条件在那里正式上场
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。