查看全课大纲(第 43 / 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 回传
拉格朗日乘子法(1):从无约束到等式约束
约 23 分钟
小象实战讲义 · 机器学习算法精讲
接下来这两节,讲的是通往 SVM 最大间隔的数学准备——拉格朗日乘子法和里面的 KKT 条件。原计划是先讲 SVM 的最大 margin、再讲里边的优化,但讲师在开场特意换了顺序:先把优化讲完,之后再学 SVM 就可能更容易些。理由也说得很直白:今天学机器学习的人,多多少少都看过 SVM、看过 maximum margin,但一到里边的数学推导就有些不清楚——也许最重要的部分,恰恰就是怎么去做这个拉格朗日乘子和优化。不止一位同学说过:关键的就在这个部分。
💡 核心导读
- 优化的两种形态:无约束( 随便取,求导置零 / 梯度下降)与有约束(加
s.t.限制条件,分等式 与不等式 )。 - 几何路线:本节全程用几何的方式、不用代数的方式——等高线(iso-contour)+ 可行域(feasible region)。
- 两个移动条件:在约束曲面上每走一小步 ,既要仍然在曲面上,又要让目标函数变小。
- 点积判方向: 与负梯度的点积大于零(锐角)⟺ 这一步让 下降——本节一路推到的核心条件。
优化:我们已经在做什么
先回顾已经会的东西。学过的线性算法里,很重要的一个部分就是构造一个 cost function , 是需要调整的参数,然后在这个大的空间里面去做优化。我们已经知道的做法是梯度下降:从某个起点出发,一步一步走到最好的那个点 。优化对整个机器学习非常重要。
今天要讲的优化稍微复杂一些:有约束条件的优化。
先看一般的形式。整个问题叫 optimization——构造一个函数之后,找到里面的最优解,尤其当它是高维空间的函数时,这件事显得尤其重要。比如我们想求 的最小值:如果 属于 (或者 ),没有任何附加限制,这叫无约束优化(unconstrained optimization);如果加了限制条件,一般写成 subject to,缩写 s.t.——比如要求 ,合起来就是”在保证 的条件下优化 “,这叫有约束优化。
约束条件往往不止一个。等式可以有多个:、,比如 是一个, 又是一个。还有一种不等式约束 ,比如 。有同学问:为什么没有大于等于 0 的写法?——因为总可以通过加负号变换出来:想让它 ,两边乘 不就变成 了。习惯上统一写成 。一般地,等式约束编号 ,不等式约束编号 。
本节的路线就是讲师说的那句话:从无条件的优化,到等式的优化,再到不等式的优化,一步步详细讲。
无约束优化:一分钟回顾
想求 , 没有任何约束条件、。比如 ,怎么做?大家都记得:求导,令 ,推出 ——这一点就是最优值,我们叫它 。高维也一样,只是此时 是向量,要求它的每一个分量的偏导都等于 0(,)。这是已经会的东西,不再多说。
等式约束:先把它画出来
现在看最简单的有约束情况——等式约束 。讲师给了一个经典例子:
给了这个限制条件之后怎么求?用几何的方式,不用代数的方式。
先画目标函数 。 在 、 两个坐标轴构成的平面上, 是一条过原点的直线;往上、往右平移,、 是一组平行的直线;往下、往左,、……当然不止这几条—— 等于几都行,等于 1.5、等于 3.6 也各有一条直线,任何一个点上都有一条直线穿过,我们只是取了几条关键的。这族直线叫 iso-contour:iso 是”等高”,contour 是”等高线”——它们是 的等高线。
再画约束 。 是一个圆:圆心在原点 ,半径 。圆周上的任何一点都满足 ,也就是 ——整个圆都是合理的取值范围。这就叫约束条件: 必须等于 0,满足条件的所有 都落在这条(红色的)圆上,这个圆往后有个名字叫 feasible region(可行域)——feasible 就是”可行的”,region 是”区域”:任何落在这里边的点都是可行的;一旦离开这个圆,约束就被破坏了。
于是优化问题变成了一个纯几何问题:在这条红圆上找一个最合适的点,使它的横、纵坐标相加(也就是 )最小。把圆上的 值实际扫一遍:
# ---- 在约束圆 x1^2 + x2^2 = 2 上扫描 f = x1 + x2 的取值 ----
import math
r = math.sqrt(2)
def h(x1, x2):
return x1 * x1 + x2 * x2 - 2
def f(x1, x2):
return x1 + x2
print("约束圆: x1^2 + x2^2 = 2 (半径 sqrt(2)), 目标 f = x1 + x2")
print("圆上 8 个关键点 (每 45 度) 的 f 值与约束检查:")
for deg in (0, 45, 90, 135, 180, 225, 270, 315):
t = math.radians(deg)
x1, x2 = r * math.cos(t), r * math.sin(t)
print(f" {deg:3d} 度: ({x1:+.4f}, {x2:+.4f}) f = {f(x1, x2):+.4f} h = {h(x1, x2):+.1e}")
print("\n细扫 (1 度步长, 360 个点):")
fmin = fmax = None
cnt_min = cnt_max = 0
for deg in range(360):
t = math.radians(deg)
x1, x2 = r * math.cos(t), r * math.sin(t)
v = f(x1, x2)
if fmin is None or v < fmin - 1e-12:
fmin, pmin, cnt_min = v, (x1, x2), 1
elif abs(v - fmin) < 1e-9:
cnt_min += 1
if fmax is None or v > fmax + 1e-12:
fmax, pmax, cnt_max = v, (x1, x2), 1
elif abs(v - fmax) < 1e-9:
cnt_max += 1
print(f" f 最小 = {fmin:.4f}, 只出现在 ({pmin[0]:+.4f}, {pmin[1]:+.4f}), 共 {cnt_min} 个点")
print(f" f 最大 = {fmax:.4f}, 只出现在 ({pmax[0]:+.4f}, {pmax[1]:+.4f}), 共 {cnt_max} 个点")
print(f" 检算: 该点 h = {h(pmin[0], pmin[1]):+.1e}, 1^2 + 1^2 = 2 <- 在圆上")约束圆: x1^2 + x2^2 = 2 (半径 sqrt(2)), 目标 f = x1 + x2
圆上 8 个关键点 (每 45 度) 的 f 值与约束检查:
0 度: (+1.4142, +0.0000) f = +1.4142 h = +4.4e-16
45 度: (+1.0000, +1.0000) f = +2.0000 h = +8.9e-16
90 度: (+0.0000, +1.4142) f = +1.4142 h = +4.4e-16
135 度: (-1.0000, +1.0000) f = +0.0000 h = +4.4e-16
180 度: (-1.4142, +0.0000) f = -1.4142 h = +4.4e-16
225 度: (-1.0000, -1.0000) f = -2.0000 h = +4.4e-16
270 度: (-0.0000, -1.4142) f = -1.4142 h = +4.4e-16
315 度: (+1.0000, -1.0000) f = -0.0000 h = +0.0e+00
细扫 (1 度步长, 360 个点):
f 最小 = -2.0000, 只出现在 (-1.0000, -1.0000), 共 1 个点
f 最大 = 2.0000, 只出现在 (+1.0000, +1.0000), 共 1 个点
检算: 该点 h = +4.4e-16, 1^2 + 1^2 = 2 <- 在圆上读这张表。圆上全是可行点:每一点的 都是 量级的浮点毛边(数学上精确为 0)。两个特殊点: 处 是圆上最大, 处 是圆上最小——检算 ,这两点确实在圆上。“相切”的数值含义:细扫 360 个点, 在整个圆上只出现一次——也就是说等高线 与圆只碰 这一个点、碰一下就分开,这正是”相切”:想再往左下挪一点点等高线,它就与圆无交点了(约束不允许 更小);往右上挪,与圆交成两个点(还有更小的取值)。上侧的 同理,是等高线 与圆的切点。问题从”带约束的优化”变成了”在圆上找相切的那条等高线”——纯几何。
在圆上走:每一步要满足什么
图画完了,接下来要构造稍微复杂一点的数学。设想我们站在圆上的某一点(记作 ),想沿圆移动一小步。这一步写成 :
- 是一个无穷小的移动单位——比如 这种量级,趋于无穷小;
- 是一个缩放常数,代表每次移动多少个 ——跟以前学的梯度下降里的步长一个角色。
这一步移动要满足两个条件。
条件一(可行性):移动完了之后,这个点仍然在圆上——。一旦离开圆,约束条件就被破坏了,后面的讨论全部作废。
条件二(优化性):移动完了之后,目标函数要比出发点更小——。我们求的是最小值,所以每一次移动都应该让 变小,这才是我们期望的移动方向。
于是整个过程可以想象成:在圆上从一个点出发,沿着某一个方向不断地移动,每次移动都比上一次的 值小,一路移动到再也找不到这样的方向为止——那当然就是最好的结果了。
要判断”哪个方向能让 变小”,就需要 的梯度。 有两个维度,分别求偏导:对 求偏导等于 1,对 求偏导也等于 1,写成列向量
而我们更关心的是它的负梯度 。原因大家记得:梯度下降的更新式 ,前面是一个减号——我们沿着负梯度方向走,函数值才下降。
点积定符号:锐角、直角、钝角
那么移动方向 与负梯度方向应该有什么样的关系?这是一个特别重要的点。先看两个任意向量 、 的点积与夹角的关系(点积等于模长乘夹角的余弦——讲师现场两次口误说成 sin,此处按正确口径写):
- 夹角小于 90 度(锐角):——两向量大致往一个方向走,一个在另一个上的投影是正的;
- 夹角等于 90 度(垂直):——两个方向没有任何关系、没有 correlation(第 5.2 节余弦相似度里的老结论);
- 夹角大于 90 度(钝角):——方向相反。
把它落到我们的问题上: 乘上负梯度大于 0,就是核心条件——
从圆上一点实际试三个方向:
# ---- 点积三分支: Delta x 与负梯度的夹角如何决定 f 的升降 ----
import math
grad_f = (1, 1)
neg_grad = (-1, -1)
def dot(a, b):
return a[0] * b[0] + a[1] * b[1]
def cos_angle(a, b):
return dot(a, b) / math.sqrt(dot(a, a) * dot(b, b))
x0 = (0.0, math.sqrt(2)) # 圆上 90 度处的点
f0 = x0[0] + x0[1]
eps = 0.001
print(f"梯度 grad f = (1, 1), 负梯度 = (-1, -1) (梯度下降: theta := theta - alpha*grad)")
print(f"从圆上一点 ({x0[0]:.4f}, {x0[1]:.4f}) 出发, 试探三个方向 (e = {eps}):")
print()
moves = [
("锐角方向 (-1, -1)", (-1, -1)),
("垂直方向 (-1, 1)", (-1, 1)),
("钝角方向 ( 1, 1)", (1, 1)),
]
for name, d in moves:
p = dot(d, neg_grad)
x_new = (x0[0] + eps * d[0], x0[1] + eps * d[1])
f_new = x_new[0] + x_new[1]
print(f"{name}: delta_x · (-grad) = {p:+.0f} (cos 夹角 = {cos_angle(d, neg_grad):+.1f})")
print(f" f: {f0:.4f} -> {f_new:.4f} (变化 {f_new - f0:+.4f})")梯度 grad f = (1, 1), 负梯度 = (-1, -1) (梯度下降: theta := theta - alpha*grad)
从圆上一点 (0.0000, 1.4142) 出发, 试探三个方向 (e = 0.001):
锐角方向 (-1, -1): delta_x · (-grad) = +2 (cos 夹角 = +1.0)
f: 1.4142 -> 1.4122 (变化 -0.0020)
垂直方向 (-1, 1): delta_x · (-grad) = +0 (cos 夹角 = +0.0)
f: 1.4142 -> 1.4142 (变化 +0.0000)
钝角方向 ( 1, 1): delta_x · (-grad) = -2 (cos 夹角 = -1.0)
f: 1.4142 -> 1.4162 (变化 +0.0020)三个方向、三种命运:点积 (锐角)的那一步让 从 1.4142 降到 1.4122;点积 (垂直)的一步 纹丝不动;点积 (钝角)的一步反而升到 1.4162。这就是”沿哪个方向走才不断优化”的判据:每一步的 与负梯度的点积要大于零。
一句诚实的注:这三个试探方向只用来演示点积符号与 升降的对应关系;真正在圆上走的时候, 还必须同时满足条件一(走出这一步还在圆上)——既要在圆上、又要让 降,两个条件拧在一起才是完整的题目。另外,约束函数 自己也是一个函数,它也有梯度—— 的梯度长什么样、指向哪里,跟我们这张图怎么接上,正是下一节开场要做的事。(本节视频就在这里收尾。)
📝 动手练一练
- 两个条件:在约束曲面上寻找最优解时,每一步移动 必须满足哪两个条件?分别保证什么?如果只满足其中一个会发生什么?
👉 点击查看参考答案
- 条件一(可行性):——移动后仍然在约束曲面(圆)上。它保证每一步都是合法解:一旦离开圆,,问题给定的约束就被破坏了,走得再” downhill “也不算数。
- 条件二(优化性):——等价于 ,移动方向与负梯度成锐角。它保证每一步都在进步, 单调下降。
- 只满足条件一:在圆上打转, 不降(白走);只满足条件二:一路往负梯度方向冲,但很快冲出圆外(违约)。最优解的处境正是:同时满足两个条件的方向不存在了——沿圆的任何方向走, 都不再变小。
- 点积手算:仍取圆上 90 度处的点 。写出 与 ;对三个试探方向 、、,分别计算它们与负梯度的点积符号,判断沿该方向 升还是降;最后指出——如果要求不离开圆(条件一),哪个方向是可走的、它让 升还是降?
👉 点击查看参考答案
,负梯度 。
- :钝角, 升;
- :锐角, 降;
- :锐角, 也降——但注意它是径向指向圆心的方向,走一小步就脱离圆(条件一不满足)。
不离开圆的走法只有切线方向:在 处,圆的切向恰好是水平的 。沿 (点积 、锐角)走, 下降且仍在圆上(一阶意义下)——这就是从 90 度位置出发的”好方向”;沿 走 反升。而 提醒我们:锐角只是条件二,还得回头检查条件一。
本章小结
- 定位:讲 SVM 最大 margin 之前的数学准备——先学优化(拉格朗日乘子、KKT 条件),再学 SVM 更容易;很多同学卡壳就卡在这部分的数学推导上。
- 形式化:无约束(求导置零 / 梯度下降)vs 有约束(s.t.);等式约束 ()与不等式约束 (; 乘负号即得)。
- 几何工具: 的等高线族(iso-contour)+ 约束圆 (可行域 feasible region);优化变成”在圆上找使 最小的点”,答案是等高线与圆的切点(,,细扫确认圆上仅此一点取到)。
- 移动条件: 中 无穷小、 是缩放常数;条件一 (不出圆),条件二 (要变小)。
- 点积判据:、更关心负梯度(梯度下降的减号); ⟺ 锐角 ⟺ 下降(数值验证 三分支与 升降严格对应;垂直 = 没有 correlation)。
- 悬念: 自己的梯度长什么样、两个条件怎么合到一张图上——下一节继续。
📋 行动清单
- 自己画出 五条等高线与半径 的圆,标出两个切点并检算
- 跑代码一:把约束换成 (半径 ),重跑扫描,观察最小值点与对应等高线怎么变
- 在圆上另取一点(如 ),手算该点处三个试探方向与负梯度的点积符号
- 用一句话说清 feasible region 的含义,以及”离开它一步”意味着什么
- 预习下一节《拉格朗日乘子法(2)》—— 的梯度与法线方向
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。