前几课我们从概率与信息论里把损失函数"推"了出来:最大似然给了我们交叉熵,MAP 给了我们带正则的目标。可一旦写下 \(L(\theta)\),真正的问题才开始——怎么把它最小化?这一课讲优化的几何:什么样的地形好走(凸性),为什么沿负梯度走最快,以及为什么有的"碗"明明是凸的却走得慢得让人抓狂(病态曲率)。
读完这一课,你将能够
- 用"弦在曲线上方"和"Hessian 半正定"两套语言判断一个函数是否凸,并解释凸为什么意味着"局部最优即全局最优"。
- 说清为什么负梯度是最速下降方向,并解释学习率 \(\eta\) 太大/太小各会怎样。
- 用条件数(Hessian 最大/最小特征值之比)解释梯度下降为什么在狭长山谷里走"之"字形、收敛慢。
- 用维度直觉解释为什么高维参数空间里临界点几乎都是鞍点、而非坏的局部极小。
- 纠正"非凸=训不了"的误解,说出深度学习里真正的拦路虎是鞍点、病态曲率、坏初始化与学习率。
- 在 \(f=\tfrac12(x^2+\gamma y^2)\) 上手算梯度下降,并用 numpy 改条件数观察收敛快慢。
训练,就是优化
把前几课的成果收个口:无论是回归、分类还是生成模型,训练最终都落到一个统一的形式
\[ \min_{\theta}\; L(\theta), \]其中 \(\theta\) 是模型的所有参数(可能是几个数,也可能是几十亿个数),\(L\) 是损失。"学习"这个浪漫的词,在数学上就是"在 \(\theta\) 的高维空间里找一个让 \(L\) 尽量小的点"。剩下的全是细节:地形长什么样,从哪儿出发,每步迈多大。
直觉。把 \(L(\theta)\) 想象成一片地形,\(\theta\) 是你站的位置,海拔就是损失。你被蒙住眼睛,只能用脚感受脚下的坡度(梯度),想走到最低的谷底。这一课就是研究:什么样的地形容易走到底,什么样的地形会把你困住。
凸集与凸函数:什么是"好地形"
先别急着背定义。我们想要的"好地形"直觉上是:一个碗。不管从哪儿放一颗球,它都会滚到同一个最低点。数学家把这种性质拆成两层:底面的形状(凸集)和碗壁的形状(凸函数)。
凸集:连两点的线段不会"出界"
一个集合 \(C\) 是凸集(convex set),如果对里面任意两点 \(x,y\),连接它们的整条线段也都在 \(C\) 里:
\[ x,y\in C \;\Rightarrow\; \lambda x+(1-\lambda)y\in C,\quad \forall\,\lambda\in[0,1]. \]约定好一个贯穿全课的读法:\(\lambda\) 是"\(x\) 的份额"——\(\lambda=1\) 时整点落在 \(x\),\(\lambda=0\) 时落在 \(y\),中间按比例滑动。圆盘、实心椭圆、整个 \(\mathbb{R}^n\) 都是凸的;一个月牙形、一个甜甜圈就不是——你能找到两点,它们的连线穿出了集合外面。
凸函数:弦永远在曲线上方
有了凸的"地基",再看碗壁。一个函数 \(f\) 是凸函数(convex function),如果它图像上任意两点之间的弦(割线)都在函数图像的上方或重合:
\[ f\big(\lambda x+(1-\lambda)y\big)\;\le\;\lambda f(x)+(1-\lambda)f(y),\quad \forall\,\lambda\in[0,1]. \]左边是"先取平均位置,再看函数值";右边是"先取两端函数值,再平均"。凸 = 实际曲线 ≤ 直线插值。注意左右两边的 \(\lambda\) 配的始终是同一个点——\(\lambda\) 越大,无论是位置还是函数值都更靠近 \(x\) 这一端,两边永远对齐,不会错位。抛物线 \(x^2\)、指数 \(e^x\)、绝对值 \(|x|\) 都满足;而 \(\sin x\) 或者有两个谷的函数就不满足——某些弦会钻到曲线下面去。
直觉。"弦在上方"为什么重要?因为它排除了"中间凹下去一块"的可能。如果中间能凹下去,那块凹陷就可能形成第二个谷——一个会困住球的坑。凸函数从定义上就杜绝了这种坑,所以它最多只有一个谷。
二阶判据:Hessian 半正定(呼应 M1 第7课)
"弦在上方"很直观,但拿到一个具体函数怎么快速判断?这就要请出我们在模块1学过的 Hessian 矩阵 \(H\)(二阶偏导构成的对称矩阵,记录了曲面在每个方向上的弯曲程度)。一维情形大家熟悉:\(f''(x)\ge 0\)(处处不向下弯)就凸。多维的推广是:
\[ f \text{ 凸} \quad\Longleftrightarrow\quad H(\theta)\succeq 0\ \text{处处成立(Hessian 半正定)}. \]"半正定 \(\succeq 0\)"在模块1第4/5课讲过:等价于 \(H\) 的所有特征值都 \(\ge 0\)。几何上,特征值是各主方向的"弯曲强度"。全部 \(\ge 0\),意味着无论朝哪个方向看,曲面都不向下弯——这正是"碗"的样子。如果某个特征值是负的,那个方向就是向下弯的,曲面在该方向像个鞍——不再是碗。
例题:用 Hessian 判断二次函数是否凸
判断 \(f(x,y)=2x^2+3y^2-2xy\) 是否凸。
解。先求一阶偏导:\(\partial_x f = 4x-2y\),\(\partial_y f = 6y-2x\)。再求二阶:
\[ H=\begin{bmatrix} \partial_{xx} & \partial_{xy}\\ \partial_{yx} & \partial_{yy}\end{bmatrix} =\begin{bmatrix} 4 & -2\\ -2 & 6\end{bmatrix}. \]判正定有个不必算特征值的捷径——顺序主子式法(顺序主子式全为正即正定):左上角 \(4>0\);整个行列式 \(\det H = 4\cdot 6-(-2)(-2)=24-4=20>0\)。两个顺序主子式都为正 ⇒ \(H\) 正定 ⇒ 特征值都 \(>0\)(实际为 \(2.76\) 与 \(7.24\))⇒ \(f\) 严格凸。
注意 Hessian 是常数矩阵(二次函数的二阶导不含变量),所以"处处正定"一次就验完——这正是二次函数好分析的原因。
两点小提醒(看完即可放过)。其一,顺序主子式全为正只能判正定;要判"半正定"(特征值 \(\ge 0\) 而非 \(>0\))则需用所有主子式或直接看特征值,顺序主子式那套对半正定不成立。其二,我们这里只用到"正定 ⇒ 严格凸"这一个方向;反过来不一定成立——比如 \(x^4\) 是严格凸的,但它在原点的二阶导恰好为 \(0\)(并非处处正定)。
关键结论:凸的最大好处——局部最优即全局最优
凸函数最值钱的性质是:任何局部最优都是全局最优。直觉证明:假设 \(\theta^\star\) 是个局部最低点,但别处有个更低的点 \(\theta'\)(\(L(\theta')
负梯度 = 最速下降方向(呼应 M1 第6课)
知道了好地形长什么样,现在问:站在地形上某点,往哪个方向迈一步下降最快?答案是负梯度方向 \(-\nabla L\)。回忆模块1第6课的一阶展开,朝单位方向 \(u\) 走一小步 \(\epsilon\):
\[ L(\theta+\epsilon u)\approx L(\theta)+\epsilon\,\nabla L(\theta)^\top u. \]下降量由 \(\nabla L^\top u\)(梯度与方向的内积)决定。要让函数下降最多,就要让这个内积最负。内积 \(=\|\nabla L\|\,\|u\|\cos\angle\),在 \(\|u\|=1\) 下,当 \(u\) 与 \(\nabla L\) 方向正好相反(\(\cos=-1\))时最负。所以最速下降方向就是 \(u=-\nabla L/\|\nabla L\|\)。梯度指向上坡最陡的方向,取个负号就是下坡最陡的方向。
把这个想法变成迭代算法,就是梯度下降(gradient descent):
\[ \boxed{\;\theta \leftarrow \theta-\eta\,\nabla L(\theta)\;} \]每一步朝当前最陡的下坡方向迈一步,步长由学习率(learning rate)\(\eta\) 控制。注意"最速下降"只是局部最优方向——它只看脚下这一小步,不保证是通往谷底的全局捷径(下面的"之"字形就是这个局部性付出的代价)。
学习率 \(\eta\):太大震荡/发散,太小太慢
\(\eta\) 是这一课最需要手感的旋钮。它控制每步迈多远,而"多远算合适"取决于地形的弯曲程度。
- \(\eta\) 太小:太慢。每步挪一点点,要迈成千上万步才到谷底。安全但磨蹭。
- \(\eta\) 太大:震荡甚至发散。步子迈过了头,从谷的一侧蹦到另一侧,甚至越蹦越高飞出去。这正是模块1第6课提过的"之"字形/反弹现象在一维上的极端版。
对二次碗 \(f=\tfrac12 a\theta^2\)(曲率 \(a\)),一步更新是 \(\theta\leftarrow\theta-\eta a\theta=(1-\eta a)\theta\)。要收敛必须 \(|1-\eta a|<1\),即 \(0<\eta<2/a\)。曲率越大(碗越陡),可用的学习率上限越低。记住这个 \(2/a\)——在多维里,\(a\) 就是某个方向上的曲率,也就是 Hessian 的一个特征值;最严格的红线由最大特征值决定,所以下面会写成 \(\eta<2/\lambda_{\max}\)。它马上要解释病态问题。
易错。很多人把"loss 没降下来"一律归咎于"模型不行/数据不行",其实头号嫌疑往往是 \(\eta\)。\(\eta\) 太大时 loss 会上下剧烈跳动甚至变成 NaN;太小时 loss 平滑但几乎不动。看 loss 曲线的形状,就能反推 \(\eta\) 调高还是调低——这是最便宜的诊断。
病态与条件数:凸碗也能很难走(呼应 M1 第4/5课)
这里是全课最关键的洞察。我们刚说凸问题"好优化",但"好"指的是"不会卡在假谷底",不等于"走得快"。即使地形是个完美的凸碗,如果这碗又长又窄,梯度下降照样会走得很惨。
条件数:碗有多"歪"
衡量碗"歪不歪"的量叫条件数(condition number),定义为 Hessian 的最大与最小特征值之比:
\[ \kappa=\frac{\lambda_{\max}(H)}{\lambda_{\min}(H)}. \]回忆模块1:特征值是各主方向的曲率。\(\kappa=1\) 意味着各方向曲率一样——等高线是正圆,碗很"圆正"。\(\kappa\) 很大意味着某方向陡得多、某方向缓得多——等高线是狭长的椭圆,一条又深又窄的山谷。这种碗叫病态(ill-conditioned)。
狭长山谷里的"之"字形
为什么病态会拖慢梯度下降?因为负梯度方向通常并不指向谷底。在狭长椭圆里,梯度主要垂直于山谷长轴(朝陡的方向),只有很小一点分量沿长轴(朝谷底)。结果是:你大步横跨山谷、在两侧壁来回反弹(之字形),却只极慢地沿着谷底往前蹭。
更糟的是学习率被"卡死":为了在陡方向不发散,\(\eta\) 必须 \(<2/\lambda_{\max}\);可这么小的 \(\eta\) 在缓方向上每步只挪 \(\eta\lambda_{\min}\) 那么一丁点。收敛步数大致正比于 \(\kappa\):条件数翻倍,要走的步数也大致翻倍。
例题:在病态二次型上手算两步梯度下降
取 \(f(x,y)=\tfrac12(x^2+\gamma y^2)\),\(\gamma=10\)(于是 \(H=\mathrm{diag}(1,10)\),\(\kappa=10\))。梯度 \(\nabla f=(x,\;\gamma y)\)。从 \((1,1)\) 出发,取 \(\eta=0.18\),手算两步:
第 1 步. 当前 \((1,1)\),梯度 \((1,\;10\cdot 1)=(1,10)\)。更新:
\[ (x,y)\leftarrow(1,1)-0.18\,(1,10)=(0.82,\,-0.80). \]注意 \(y\) 从 \(+1\) 一下被甩到 \(-0.80\)——跨过了谷底(\(y=0\))跳到对面。这就是之字形的一步。
第 2 步. 当前 \((0.82,-0.80)\),梯度 \((0.82,\;10\cdot(-0.80))=(0.82,\,-8.0)\)。更新:
\[ (x,y)\leftarrow(0.82,-0.80)-0.18\,(0.82,-8.0)=(0.6724,\,0.64). \]\(y\) 又从 \(-0.80\) 弹回 \(+0.64\)——在山谷两侧来回横跳。对比 \(x\) 方向:\(1\to0.82\to0.6724\),老老实实单调下降,但慢吞吞。陡方向(\(y\))剧烈震荡、缓方向(\(x\))龟速前进,这就是病态的全部痛苦。
(若把 \(\eta\) 调到 \(0.2=2/\lambda_{\max}\),\(y\) 方向会变成 \(1\to-1\to1\) 永远反弹不收敛;再大就发散。这印证了 \(\eta<2/\lambda_{\max}\) 的红线。)
ML 和 ML 的联系
病态不是教科书里的人造怪物,它在真实训练里无处不在:不同参数的尺度天差地别、特征没归一化、深层网络里梯度在层间被反复缩放——都会让损失曲面变成狭长山谷。这正是下一课要讲的自适应优化器(动量、RMSProp、Adam)存在的根本理由:它们本质上都是在"偷偷估计曲率、给每个方向配不同的有效学习率",从而抹平病态、把之字形掰直。所以"为什么需要 Adam"这个问题,答案就藏在条件数 \(\kappa\) 里。
深度学习是非凸的——但敌人不是非凸本身
坏消息先说:神经网络的损失 \(L(\theta)\) 几乎从不凸。激活函数的非线性、层层复合,让损失曲面布满起伏。按"凸才好优化"的逻辑,深度学习似乎根本没法训。可它偏偏训得很好。为什么?
关键在于高维空间的几何反直觉。我们的恐惧来自低维想象:非凸 = 一堆坑,球会卡在某个不够深的坑(坏的局部极小)里出不来。但在百万维参数空间里,这个图像是错的。
一个临界点(梯度为零处)是"坏局部极小",要求 Hessian 在所有方向都向上弯(全部特征值 \(>0\))。而它是鞍点(saddle point),只要存在一个向上弯、一个向下弯的方向(特征值有正有负)。在 \(d\) 维空间里,"每个方向都恰好向上弯"就像连抛 \(d\) 次硬币全是正面——维度越高越罕见(这只是个抓直觉的类比,背后"各方向曲率符号近似独立"的严格分布属于随机矩阵理论,留到 skip)。所以高维里临界点压倒性地是鞍点,而不是坏的局部极小。另外,在很多实际网络里还观察到:越深的(损失越高的)局部极小越稀少,大多数局部极小的损失都彼此接近、且接近全局最优——卡在一个"差很多的谷"里的概率其实很低(这是经验规律,成立与否依赖具体模型与假设,并非铁律,边界留到 skip)。
例题:一个最简单的鞍点
看 \(f(x,y)=x^2-y^2\),临界点在原点。Hessian \(H=\mathrm{diag}(2,-2)\),特征值 \(+2\)(\(x\) 方向向上弯,是个谷)和 \(-2\)(\(y\) 方向向下弯,是个脊)。有正有负 ⇒ 鞍点。沿 \(x\) 轴它是最小值,沿 \(y\) 轴它是最大值——像马鞍。
逃离有多快?在这个标准(非退化)鞍点上,下弯方向 \(y\) 的更新是 \(y\leftarrow(1+2\eta)y\),乘的是一个大于 \(1\) 的因子,是指数放大——只要初始 \(y\) 不恰好为零,迟早会被迅速甩离原点(练习3 正是演示这一点)。所以纯二次鞍点其实逃得挺快。真正让训练"磨蹭很久"的,是另一类:Hessian 在多个方向特征值都 \(\approx 0\) 的平坦/退化鞍点与平台区——那里下弯方向的曲率极小,指数放大的因子非常接近 \(1\),前期看上去几乎停滞,要积累很多步才动起来。换句话说,逃离速度取决于负曲率的强度和初始扰动的大小:曲率越平、扰动越小,看似卡得越久。
关键结论:真正的难点是什么
请把"非凸 = 训不了"这个恐惧删掉。深度学习能成立的经验事实是:非凸本身不可怕,可怕的是——①鞍点(高维里远比坏局部极小常见;标准鞍点逃得快,但平坦/退化的鞍点与平台会让训练长期磨蹭);②病态曲率(之字形,前面那套条件数的故事在非凸地形里照样成立);③坏初始化(出发点决定你掉进哪片地形);④学习率(永远的头号旋钮)。下一课的优化器、和后面要学的初始化/归一化技巧,全都是冲着这四个敌人去的——而没有一个是冲着"消灭非凸"去的。
两个必须记住的凸例子
虽然深度模型非凸,但机器学习的两个基石问题是凸的,它们是理解一切的脚手架:
- 最小二乘(线性回归):\(L(\theta)=\tfrac12\|X\theta-y\|^2\)。Hessian 是 \(H=X^\top X\),它永远半正定(对任意 \(v\),\(v^\top X^\top X v=\|Xv\|^2\ge 0\))。所以最小二乘是凸的,甚至有闭式解 \(\theta=(X^\top X)^{-1}X^\top y\)。而它的条件数正是 \(X^\top X\) 的条件数——特征尺度不一致就病态,这就是为什么要做特征标准化。
- 逻辑回归:用交叉熵(上一课从最大似然推出来的那个)做损失时,\(L(\theta)\) 关于 \(\theta\) 是凸的。它没有闭式解,但凸性保证没有坏的局部极小,梯度下降不会被假谷底困住,会一路朝全局最优走。逻辑回归是"凸但需迭代"的典范,是从线性模型走向神经网络的最后一站平地。
调一调,观察现象
下面用 numpy 在 \(f=\tfrac12(x^2+\gamma y^2)\) 上跑梯度下降。改三个旋钮,亲眼看到上面讲的每个结论。每段都能几秒跑完,只 import numpy、只用 print。
任务 1:调条件数 \(\gamma\),看收敛步数
改什么 → 把 \(\gamma\) 从 1 改到 10 再到 50(用各自安全的 \(\eta=1/\gamma\))。预期看到 → 到达 \(\|\theta\|<10^{-3}\) 所需步数随 \(\gamma\) 暴涨:\(\gamma=1\) 约 1 步、\(\gamma=10\) 约 66 步、\(\gamma=50\) 约 342 步。注意 → \(\gamma=1\) 那个"1 步"是个退化巧合:此时 \(\eta=1/\gamma=1\) 恰好等于 \(1/\lambda\),更新变成 \(\theta\leftarrow(1-1)\theta=0\),一步精确落到原点,并不代表"\(\kappa=1\) 所以快"。真正体现"步数 ≈ 正比于 \(\kappa\)"的是 \(\gamma=10\) 与 \(50\) 这两点(\(66\) 与 \(342\),比值约 \(1:5\),正好对上 \(\kappa\) 的 \(10:50\))。为什么 → 条件数 \(\kappa=\gamma\),收敛步数大致正比于 \(\kappa\),病态直接拖慢全局。
import numpy as np
def run(gamma, eta, x0=(1.0, 1.0), tol=1e-3, max_steps=10000):
x = np.array(x0, dtype=float)
for k in range(1, max_steps + 1):
grad = np.array([x[0], gamma * x[1]]) # 梯度 (x, gamma*y)
x = x - eta * grad # theta <- theta - eta * grad
if np.linalg.norm(x) < tol:
return k
return max_steps
for gamma in [1.0, 10.0, 50.0]:
eta = 1.0 / gamma # 安全步长,约 1/lambda_max
print(f"gamma={gamma:5} cond={gamma:.0f} steps={run(gamma, eta)}")
任务 2:打印轨迹,亲眼看"之"字形
改什么 → 固定 \(\gamma=10,\ \eta=0.18\),从 \((1,1)\) 出发,打印前几步的 \((x,y)\)。预期看到 → \(y\) 列正负来回横跳(\(1\to-0.80\to0.64\to\dots\)),\(x\) 列单调缓降(\(1\to0.82\to0.6724\to\dots\))。为什么 → 陡方向 \(y\) 跨过谷底来回反弹,缓方向 \(x\) 龟速前进——这就是病态的"之"字形,和例题手算完全一致。
import numpy as np
gamma, eta = 10.0, 0.18
x = np.array([1.0, 1.0])
print("step x y")
for k in range(6):
print(f"{k:3} {x[0]: .4f} {x[1]: .4f}")
grad = np.array([x[0], gamma * x[1]])
x = x - eta * grad
任务 3:把 \(\eta\) 推过红线,看震荡与发散
改什么 → 固定 \(\gamma=10\)(\(\lambda_{\max}=10\),红线 \(\eta=2/10=0.2\))。依次试 \(\eta=0.15\)(收敛)、\(\eta=0.2\)(恰好反弹不收敛)、\(\eta=0.21\)(发散)。预期看到 → 看的是"降 / 不降 / 爆"这三种定性形态,不是绝对到零:\(\eta=0.15\) 时范数单调缩小、40 步降到约 \(1.5\times10^{-3}\) 量级(还没到极小,因为这点收敛本就要 60 多步);\(\eta=0.2\) 时 \(y\) 在 \(\pm1\) 间永远反弹、范数卡在 \(1.0\) 不降;\(\eta=0.21\) 时范数爆炸到约 \(4.5\times10^{1}\)。为什么 → 收敛要求 \(|1-\eta\lambda_{\max}|<1\),即 \(\eta<2/\lambda_{\max}=0.2\),跨过就停止收敛、再大就发散。
import numpy as np
gamma = 10.0
for eta in [0.15, 0.20, 0.21]:
x = np.array([1.0, 1.0])
for _ in range(40):
x = x - eta * np.array([x[0], gamma * x[1]])
print(f"eta={eta:.2f} final ||theta||={np.linalg.norm(x):.3e}")
动手练习
- 手验凸性。对 \(f(x,y)=x^2+4y^2+xy\),手算 Hessian,用顺序主子式判断是否(严格)凸(提示:左上 \(2>0\),\(\det=2\cdot8-1=15>0\),故正定),再用 numpy 的
np.linalg.eigvalsh验证特征值都为正。 - 测量条件数与步数的正比关系。基于任务 1 的
run,对 \(\gamma\in\{2,5,10,20,40\}\) 各用 \(\eta=1/\gamma\) 跑一遍,打印(gamma, steps),观察 steps 是否大致随 \(\gamma\) 线性增长。(提示:别把 \(\gamma=1\) 那个 1 步的退化点混进来比,它是 \(\eta\) 恰好等于精确解步长的特例;从 \(\gamma=2\) 起看线性趋势才靠谱。) - 逃离鞍点。在 \(f(x,y)=x^2-y^2\)(梯度 \((2x,-2y)\))上从 \((0.5,\,10^{-6})\) 出发跑梯度下降,打印 \(y\) 随步数的变化。\(y\) 会按 \((1+2\eta)\) 的因子被指数放大、最终逃离原点——体会"沿下弯方向被指数推开"的过程(初始 \(y\) 越小,前期看似停滞越久,一旦起来就很快)。把初始 \(y\) 设成精确的 \(0\) 会怎样?为什么?
- 归一化能治病态。构造 \(f=\tfrac12(x^2+100y^2)\)(\(\kappa=100\))。先直接跑,记下步数;再做变量替换 \(y'=10y\)(即在 \(y\) 方向把尺度缩小 10 倍),让新问题变成 \(\tfrac12(x^2+y'^2)\)(\(\kappa=1\)),再跑,对比步数。这就是特征标准化的威力。
掌握自检
- 我能用"弦在曲线上方"和"Hessian 半正定(特征值 \(\ge 0\))"两种方式说明同一件事:凸;并知道"顺序主子式全为正"判的是正定(⇒ 严格凸),而"严格凸"反过来不一定正定(如 \(x^4\))。
- 我能解释凸为什么保证"局部最优即全局最优",以及这为什么让凸问题"好优化"。
- 我能推出负梯度是最速下降方向,并说出 \(\eta\) 太大/太小的后果与收敛红线 \(\eta<2/\lambda_{\max}\)(一维里就是 \(2/a\))。
- 我能用条件数 \(\kappa=\lambda_{\max}/\lambda_{\min}\) 解释之字形和收敛慢,并说出这如何引出下一课的自适应优化器。
- 我能用维度直觉解释为什么高维里临界点几乎都是鞍点、而非坏局部极小,并区分"标准鞍点逃得快"与"平坦/退化鞍点会磨蹭"。
- 我能反驳"非凸=训不了",并列出真正的四个敌人:鞍点、病态曲率、坏初始化、学习率。
- 我能各举一个凸的机器学习例子(最小二乘 / 逻辑回归)并说明其凸性来源。
下一课我们就把这一课的诊断变成药方:实战优化器——SGD、动量、Adam 与学习率调度。你会看到动量如何借惯性穿过之字形,Adam 如何给每个方向配自适应步长来对抗病态——这一课埋下的每个 \(\kappa\)、每个红线 \(2/\lambda_{\max}\),都会在那里得到回应。
可以先放过的点
- 凸性的严格证明(比如"局部即全局"的 \(\epsilon\)-\(\delta\) 论证、各种凸函数运算的封闭性、半正定与严格凸的精确等价条件)。现在记住几何直觉就够,等你以后读凸优化教材(如 Boyd)再回来补严谨。
- 鞍点几何的随机矩阵理论(为什么高维里特征值符号近似独立、损失随临界点高度的分布,以及"局部极小质量分布"这条经验规律到底在什么假设下成立)。现在只需接受"高维里鞍点远多于坏局部极小"这个结论,等深入研究优化理论时再深挖。
- 逻辑回归在可分数据上的细节:当数据完全线性可分时,交叉熵的最优参数会跑到无穷大(loss\(\to0\) 但 \(\theta\) 无界),梯度下降不会停在有限点上——这也是为什么逻辑回归实践中常配 L2 正则(既埋下正则动机,又不破坏本课节奏)。
- 条件数对收敛速度的精确界(如梯度下降的 \(\frac{\kappa-1}{\kappa+1}\) 收缩率、动量法把它改善到 \(\sqrt{\kappa}\) 的推导)。现在记住"步数大致正比于 \(\kappa\)",下一课讲动量时再看为什么能开根号。