查看全课大纲(第 44 / 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 回传
拉格朗日乘子法(2):等式约束下的平行条件与拉格朗日函数
约 27 分钟
小象实战讲义 · 机器学习算法精讲
上一节把图画到了一半:等高线、约束圆、移动方向的两个条件、点积判符号——都摆在了台面上,视频停在”接下来要求 的梯度”。这一节接着走:把 的梯度画出来,看它和 的梯度之间是什么关系——这条线索一路走到头,就是拉格朗日函数。
💡 核心导读
- 的梯度:,方向永远是圆的法线方向;约束写成 还是 ,圆不变、但梯度反向——别调错方向。
- 平行条件:最优时,可行的移动方向(切向)里再也找不到让 下降的——这当口 与 必然平行,两者只差一个常数 。
- 拉格朗日函数:——对 求偏导恰好回收平行条件,对 求偏导恰好回收约束本身,两件事并成一件事。
- 手算全流程:经典例子 、 一路推到底,最大值点与最小值点各领一个解。
先把 的梯度画出来
还是上一节那张图:几条等高线(关于 的),加一个圆( 的可行域)。 自己也是一个函数,它的梯度怎么求?——去求导呗。
,对 求导是 ,对 求导是 ,写成向量:
就是把该点的坐标各乘上 2。比如圆上取点 ,它的梯度就是 ;取点 (按比例在圆外延的方向上取值),梯度就是 。把这些箭头画在圆上,会看得很清楚: 的梯度方向,永远是沿着圆的切线的垂直方向——也就是法线方向。
这里有一个值得单独强调的警告(讲师特意叮嘱”别调错方向”):约束条件写 还是 ,描述的是同一个圆——就像 完全可以写成 。但两者的梯度方向恰好相反:一个处处指向圆外、一个处处指向圆内。几何条件本身不受影响(不管向内向外,都垂直于同一条法线),但写公式、画箭头的时候,心里要清楚自己用的是哪一版。
从两个条件到”平行”
现在 的梯度和 的梯度都拿到了,可以看它们的关系了。回忆上一节的两个移动条件,在圆上从一点 挪一小步 :
- 可行性:——挪完还在圆上,也就是 要垂直于 (沿切向走);
- 优化性:——这一步要让 变小,也就是 与负梯度成锐角、。
顺着圆一路走、 一路降,直到某个点:可行的切向里,再也找不到让 下降的方向了。这个”走不动”的几何翻译是什么?切向是与 垂直的方向;“切向上没有 的下降分量”意味着 的梯度在切向上没有分量——也就是说 只能落在法线方向上。两条梯度都垂直于同一条切线,那它们彼此之间只能是平行的:
负梯度与 的梯度平行、只差一个常数 ——这就是最优时的几何相貌。把圆上每个点的两个梯度实际量一遍:
# ---- 圆上各点 grad h 与 grad f 的夹角: 平行的只有两个点 ----
import math
def angle_between(v1, v2):
d = v1[0] * v2[0] + v1[1] * v2[1]
n = math.sqrt(v1[0] ** 2 + v1[1] ** 2) * math.sqrt(v2[0] ** 2 + v2[1] ** 2)
c = max(-1.0, min(1.0, d / n))
return math.degrees(math.acos(c))
grad_f = (1.0, 1.0)
r = math.sqrt(2)
print("grad f = (1, 1) (常数); 约束圆 x1^2+x2^2=2 上各点 grad h = (2*x1, 2*x2):")
print(" 角度 | 点 (x1, x2) | grad h | grad h 与 grad 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)
gh = (2 * x1, 2 * x2)
a = angle_between(gh, grad_f)
mark = ""
if a < 1e-4:
mark = " <- 平行(同向): f 的最大值点"
elif a > 180 - 1e-4:
mark = " <- 平行(反向): f 的最小值点"
print(f" {deg:3d} 度 | ({x1:+.4f}, {x2:+.4f}) | ({gh[0]:+.4f}, {gh[1]:+.4f}) | {a:6.1f} 度{mark}")
print()
print("两个平行点的方向辨析 (负梯度 -grad f = (-1,-1)):")
for x1, x2, tag in ((-1.0, -1.0, "最小值点"), (1.0, 1.0, "最大值点")):
gh = (2 * x1, 2 * x2)
a_neg = angle_between(gh, (-1.0, -1.0))
mu = -grad_f[0] / gh[0]
print(f" ({x1:+.0f}, {x2:+.0f}) {tag}: grad h 与 -grad f 夹角 {a_neg:.0f} 度, "
f"grad f + mu*grad h = 0 要求 mu = {mu:+.2f}")grad f = (1, 1) (常数); 约束圆 x1^2+x2^2=2 上各点 grad h = (2*x1, 2*x2):
角度 | 点 (x1, x2) | grad h | grad h 与 grad f 夹角
0 度 | (+1.4142, +0.0000) | (+2.8284, +0.0000) | 45.0 度
45 度 | (+1.0000, +1.0000) | (+2.0000, +2.0000) | 0.0 度 <- 平行(同向): f 的最大值点
90 度 | (+0.0000, +1.4142) | (+0.0000, +2.8284) | 45.0 度
135 度 | (-1.0000, +1.0000) | (-2.0000, +2.0000) | 90.0 度
180 度 | (-1.4142, +0.0000) | (-2.8284, +0.0000) | 135.0 度
225 度 | (-1.0000, -1.0000) | (-2.0000, -2.0000) | 180.0 度 <- 平行(反向): f 的最小值点
270 度 | (-0.0000, -1.4142) | (-0.0000, -2.8284) | 135.0 度
315 度 | (+1.0000, -1.0000) | (+2.0000, -2.0000) | 90.0 度
两个平行点的方向辨析 (负梯度 -grad f = (-1,-1)):
(-1, -1) 最小值点: grad h 与 -grad f 夹角 0 度, grad f + mu*grad h = 0 要求 mu = +0.50
(+1, +1) 最大值点: grad h 与 -grad f 夹角 180 度, grad f + mu*grad h = 0 要求 mu = -0.50全圆 8 个采样点里,夹角 45 度、90 度、135 度的都有——平行(0 度或 180 度)只出现在两个点: 与 。这正是上一节扫描 值找到的那两个切点:一个最大值、一个最小值。“满足平行关系的点就是这两个非常特殊的点”——一个是最大值、一个是最小值, 沿圆走到那里都彻底走不动了。
拉格朗日函数:把两件事并成一件事
几何条件拿到了:。现在看它跟一个著名的构造有什么关系。回到原始问题:
拉格朗日函数是构造出来的一个关于 和 的新函数:
(Lagrange 是人名,Multiplier 是乘子——拉格朗日乘子有时特指这个 ,整个方法构造出来的 叫拉格朗日函数。)
对它求偏导,会发现一件妙事。对 求偏导并置零:
这正是刚才用几何推出来的平行条件——同一件事。对 求偏导并置零:
这正好是限制条件本身。
所以为什么要这样构造 ?讲师的原话把它讲透了:把我们想做的两件事——限制条件的等式、求最优解的等式——通过 重新构造到一起去了。优化 (对每个分量求偏导置零),就等于在满足限制条件的前提下、让梯度之间满足那个方向关系——满足这个关系的值,当然就是最优值。
手算一遍:从方程到
把经典例子从头到尾解出来。,:
三个偏导置零:
由前两个方程,。(这一步容易错:讲师在黑板上先写成了 ,当场代回去验算—— 得不到 、对不上——才自我纠正为 。值得自己推一遍,体会这个坑。)
代入第三个方程:
两支各走一路: 给出 、(最小值); 给出 、(最大值)。跑代码验证:
# ---- 拉格朗日函数完整求解: 两解、全偏导零验证 ----
# L(x1, x2, mu) = (x1 + x2) + mu*(x1^2 + x2^2 - 2)
# dL/dx1 = 1 + 2*mu*x1 = 0 -> x1 = -1/(2*mu)
# dL/dx2 = 1 + 2*mu*x2 = 0 -> x2 = -1/(2*mu)
# dL/dmu = x1^2 + x2^2 - 2 = 0 -> 2 * 1/(4*mu^2) = 2 -> mu^2 = 1/4
print("L(x1, x2, mu) = (x1 + x2) + mu*(x1^2 + x2^2 - 2)")
print("由 dL/dx1 = 0 与 dL/dx2 = 0 得: x1 = x2 = -1/(2*mu)")
print("代入 dL/dmu = 0: 2 * 1/(4*mu^2) = 2 -> mu^2 = 1/4 -> mu = +/- 0.5")
print()
for mu in (0.5, -0.5):
x1 = -1.0 / (2.0 * mu)
x2 = -1.0 / (2.0 * mu)
dL_dx1 = 1.0 + 2.0 * mu * x1
dL_dx2 = 1.0 + 2.0 * mu * x2
dL_dmu = x1 * x1 + x2 * x2 - 2.0
f = x1 + x2
print(f"mu = {mu:+.1f}: x* = ({x1:+.1f}, {x2:+.1f}), f(x*) = {f:+.1f}")
print(f" 验证: dL/dx1 = {dL_dx1:+.1e}, dL/dx2 = {dL_dx2:+.1e}, dL/dmu = {dL_dmu:+.1e} (全为零)")
print()
print("几何检查 (mu = +0.5 的解):")
gh = (-2.0, -2.0)
print(f" 在 (-1,-1): grad h = ({gh[0]:.0f}, {gh[1]:.0f}), -grad f = (-1, -1) -- 同一个方向 (mu > 0)")
print(f" grad f + 0.5*grad h = (1+0.5*({gh[0]:.0f}), 1+0.5*({gh[1]:.0f})) = ({1+0.5*gh[0]:.0f}, {1+0.5*gh[1]:.0f})")L(x1, x2, mu) = (x1 + x2) + mu*(x1^2 + x2^2 - 2)
由 dL/dx1 = 0 与 dL/dx2 = 0 得: x1 = x2 = -1/(2*mu)
代入 dL/dmu = 0: 2 * 1/(4*mu^2) = 2 -> mu^2 = 1/4 -> mu = +/- 0.5
mu = +0.5: x* = (-1.0, -1.0), f(x*) = -2.0
验证: dL/dx1 = +0.0e+00, dL/dx2 = +0.0e+00, dL/dmu = +0.0e+00 (全为零)
mu = -0.5: x* = (+1.0, +1.0), f(x*) = +2.0
验证: dL/dx1 = +0.0e+00, dL/dx2 = +0.0e+00, dL/dmu = +0.0e+00 (全为零)
几何检查 (mu = +0.5 的解):
在 (-1,-1): grad h = (-2, -2), -grad f = (-1, -1) -- 同一个方向 (mu > 0)
grad f + 0.5*grad h = (1+0.5*(-2), 1+0.5*(-2)) = (0, 0)两个解都严丝合缝:三个偏导在解处全部精确为零, 在 处正好合成 。
方向辨析(讲师在解完之后特意叮嘱”大家一定要搞清楚这件事,不要搞混了”):在最小值点 , 与负梯度 是同一个方向、;而在最大值点 , 与 恰好相反、。哪头是哪头,取决于求最大值还是求最小值:找最小值看负梯度,沿梯度方向找的是最大值。 这个点,既满足限制条件(在圆上),又沿负梯度方向走到了 最低的值——它就是我们期待的最优结果。
换到高维:一口锅、一圈圈等高线
圆和直线的例子讲清楚了,讲师又带着把图景升了一维,值得跟着想象一遍。
、 张成一个平面,而 在它们头上撑起一个三维曲面——一个光滑的空间面(可以想象一口大锅的形状)。限制条件 是底面 平面上的一条线;把这条线沿着竖直方向”投影”到锅面上,就在锅面上切出一条曲线——这条曲线才是真正的可行域(feasible region):曲线上的每一点,既满足 ,又带着一个 的高度。我们要做的,就是在这条曲线上找最优值。
把锅沿竖直方向压到平面上,就得到熟悉的等高线图:一圈套一圈的闭合曲线(contour),同一个圈上高度相等。限制条件还是平面上那条线——于是一切都回到上一节的画面:在线能碰到的范围里,找离最优点”垂直方向最近”的那个接触点,等高线与约束线在那里相切、两条法线(两个梯度)在那里平行。二维图里画的圆和直线,只是这个高维图景的截面。
这就是拉格朗日乘子法背后的真正道理:把需要优化的函数乘上一个拉格朗日乘子加进来,构造出 ,对它求偏导置零——等价于在满足约束的前提下找到了梯度之间的方向关系。满足这个关系的值,就是最优值。
到这里,等式约束的优化就讲完了。还差最后一块:不等式约束的优化—— 的情形。那正是我们做 SVM 的时候要遇到的形态:做到后来你会发现,SVM 的求解就是一个不等式的优化。下一节接着讲。
📝 动手练一练
- 为什么必须平行:在等式约束优化中,为什么极值点处 必须与 平行?请用”可行移动方向”和”函数值变化”两个角度简要解释。
👉 点击查看参考答案
在约束 (圆)上,可行的移动方向 必须沿切向,即 。在极值点处,任何可行的微小移动都不能再让 下降,即对所有切向 都有 。两条同时成立,意味着:凡是与 垂直的方向,也都与 垂直——这只有当 与 平行(共线)时才做得到。否则总能找到一个与 垂直、却与 不垂直的切向,沿着它移动 还会变,这与极值点的定义矛盾。
- 换一个目标函数:目标函数改为 ,约束仍是圆 。写出拉格朗日函数、三个偏导方程,手算出两个极值点与对应的乘子,并算出最小值。
👉 点击查看参考答案
拉格朗日函数:。
三个偏导置零:;;。
代入约束:,。
- :,——最小值;
- :,——最大值。
方向检查(与正文的方向辨析对照):最小值点处 与 同侧、;最大值点处反向、——与圆上原例子的规律一致。
本章小结
- 的梯度:,永远沿圆的法线方向; 与 描述同一个圆但梯度反向(别调错方向),几何条件不受影响。
- 平行条件:可行移动 (不出圆)+ 最优点处切向再无下降分量 ⟹ 、;数值扫描确认全圆只有 (夹角 0°、最大值)与 (夹角 180°、最小值)两点平行。
- 拉格朗日函数:; 回收平行条件、 回收约束本身——把两件事并成一件事。
- 手算全流程:(讲师黑板现场从 自我纠正的坑)、、两解 / 与 /,三个偏导在解处精确为零;最小值点 与负梯度同向()、最大值点反向()——求最小看负梯度、求最大看梯度。
- 高维图景: 是三维曲面(一口锅)、约束是平面上的一条线、投影到锅面上切出可行曲线;压扁成等高线圈(contour),最优在”垂直方向最近”的相切处。
- 下一站:等式约束讲完,不等式约束()正是 SVM 最大间隔求解时的形态。
📋 行动清单
- 在自己画的图上,把圆上 8 个点的 箭头画出来,亲眼确认只有 两点与 平行
- 跑代码一:把约束改成 (整体乘负号)重跑第一块,观察 全部反向、 变号、而 纹丝不动
- 完成练一练第 2 题()的手算后,把数值代回三个偏导方程逐项验零
- 用”一口锅 + 一圈圈等高线 + 约束线切出一条道”的画面,给自己讲一遍高维图景
- 预习下一节《拉格朗日乘子法(3)》——不等式约束,通往 SVM 的最后一块数学拼图
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。