第八部分 · 学习就是优化
凸优化:什么时候保证能到全局最优
上一课我们学会了沿着坡往下走。可一路走到底,到的真是全世界最低点,还是只是脚下这个小坑的坑底?这一课要回答的,是梯度下降最致命的一个问题:它什么时候有保证、什么时候只是碰运气。
留下的问题:它保证能走到全局最优吗?下坡的规矩只看脚下这一小块,它根本"看不见"远处有没有更低的谷。要是地形坑坑洼洼,它很可能滚进一个局部最优的小坑就再也出不来,把那里误当成世界最低点。
本课新增:凸集与凸函数——一类特殊的"地形",在这种地形上,局部最优必然就是全局最优,梯度下走到底就是真到底。我们还要给优化加上约束,用拉格朗日乘子处理"必须满足某些条件"的最优化(这会在第 37 课的支持向量机里再次登场)。
局部最优:下坡法的噩梦
想象你被蒙上眼睛,丢在一片丘陵里,任务是找到海拔最低的地方。你的策略只能是"摸摸脚下哪边更低,就往哪边迈一步"——这正是梯度下降。如果这片地是一个单一的大碗,无论从哪起步,一路下坡都会汇到同一个碗底,那是真正的最低点。
可如果地形是连绵的丘陵,处处是小坑小谷呢?你很可能滚进离起点最近的那个小坑,坑底四周都比你高——脚下告诉你"已经到底了",于是你停下。但翻过一道山梁,也许有个深得多的峡谷你永远不会知道。这个让你停下的小坑底,就是局部最优(local optimum);那个真正最低的峡谷底,才是全局最优(global optimum)。
那有没有一种地形,能让"只看脚下"这件事突然变得足够?答案是有的,而且它有一个精确的名字:凸。一旦地形是凸的,"脚下到底了"就严格等价于"全世界到底了"。这一课剩下的部分,就是把这个"凸"字一层层讲清楚。
凸集:从任意两点连线都不出界
先说最基础的"凸"——一个集合(一块区域)的凸。定义朴素得惊人:
翻译成图像:一个实心圆、一个实心矩形、一整条直线、整个平面——都是凸的,因为你怎么在里面挑两点,连线都老老实实待在内部。而一个月牙形、一个甜甜圈(中间有洞)、或者一个"凹"进去一块的形状,就不是凸的:你能找到两点,它们的连线会穿过外面的"缺口"。"凸"这个字取得极准——边界向外鼓、绝不向内凹。
为什么先关心区域?因为优化问题常常带约束:"参数必须非负""权重之和必须等于 1""解必须落在某个范围里"。这些约束圈出了一块可行域——你只能在这块地里找最低点。如果这块可行域是凸的,后面的好性质才立得住。
凸函数:长得像一只碗
真正决定优化命运的,是函数的凸。直觉就一句话:它的图像像一只朝上的碗,处处向上弯,没有任何起伏的小坑。把这句直觉精确化,有两种等价说法,都很好懂。
说法一(弦在曲线上方):在曲线上任取两点,用一条直线段(叫"弦")把它们连起来。如果这条弦永远不低于它们之间的曲线,函数就是凸的。写成不等式:
f( t·x + (1−t)·y ) ≤ t·f(x) + (1−t)·f(y)
左边是"先把两点的位置混合,再看函数值";右边是"把两点的函数值按同样比例混合"。这个 ≤(读作"小于等于")说的就是:曲线本身总是沉在弦的下面。碗形函数满足它,倒扣的山包则反过来(那叫凹函数)。
说法二(切线在曲线下方 / 二阶导非负):对一条光滑曲线,凸还等价于——它的斜率一路只增不减。回想第 07 课的导数是斜率,第 25 课的梯度是多维的斜率;那么凸就是说二阶导数处处 ≥ 0(读作"二阶导非负",多维里对应"海森矩阵半正定")。曲线越走越陡峭地往上翘,自然形成一只碗。
把两个层次合起来,一个凸优化问题就是:在一个凸的可行域上,最小化一个凸函数。这是整个优化世界里最"乖"的一类问题,而它乖在哪,下面这条定理一锤定音。
核心定理:局部最优就是全局最优
这是本课的心脏,也是凸性值得我们大费周章的唯一理由:
为什么会这样?用反证法,一句话就懂:假设有个局部最优点 a,它脚下四周都比它高;又假设别处藏着一个更低的点 b,f(b) < f(a)。现在把弦的不等式用在 a、b 上:从 a 朝 b 挪一丁点,落在弦上的那一点,函数值不会高于 a、b 函数值的加权平均,而这个平均已经比 f(a) 低了(因为 b 更低)。也就是说,就在 a 旁边、朝 b 那个方向,立刻能找到比 a 更低的点——这直接戳穿了"a 四周都比它高"的前提。矛盾。所以根本不可能存在一个比局部最优更低的点。凸性把"局部"和"全局"这道天堑,神不知鬼不觉地填平了。
这就是为什么工程师如此偏爱凸问题:把一个学习任务设计成凸的(线性回归、逻辑回归、支持向量机都是),就等于买了一份保险——优化一定收敛到那个唯一的、可复现的、绝对最优的解,跟起点无关、跟运气无关。下面的小实验会让你直接看到凸碗与非凸丘陵的天壤之别。
带约束的最优:拉格朗日乘子
到这里我们默认可以"在整片地里随便走"。但很多问题不行——它带着约束:求最优时必须同时满足某个等式条件。比如"在所有总和为 1 的概率分配里,使损失最小",约束就是 g(x) = 0(读作"约束函数 g 等于零",把可行的点圈在一条曲线/曲面上)。这时最优点往往不在"开阔地的碗底",而恰恰卡在约束这条边界上,普通的"梯度 = 0"不再成立。
拉格朗日(Lagrange)的洞见极漂亮:在约束边界上的最优点,目标函数的等高线必定和约束曲线"相切"。想象你沿着约束这条小路走,想让海拔尽量低;当你走到路与某条等高线相切的地方,再沿路往任何方向走都不会更低了——那就是约束下的最优。相切,在数学上意味着两者的梯度方向平行:
∇f = λ · ∇g
读作"目标 f 的梯度,等于某个倍数 λ 乘以约束 g 的梯度"。这个 λ(希腊字母 lambda)就叫拉格朗日乘子。它把一个"带约束"的问题,巧妙地转写成一个"不带约束"的方程组来解——这是约束优化的万能钥匙。
你现在不必记住推导。只要记住这把钥匙的存在,以及它能干什么:它让我们在"必须守规矩"的前提下,依然找得到最优。第 37 课的支持向量机正是它的高光时刻——"找一条间隔最大的分界线"会被写成一个带约束的凸问题,再用拉格朗日乘子翻成漂亮的对偶形式,把几何、代数与优化拧成一股。那时你会回头感谢今天埋下的这颗种子。
可现实里损失大多非凸——为什么深度学习还能 work?
说了半天凸的好,得诚实面对一个尴尬事实:神经网络的损失函数几乎从不凸。几百万个参数、层层非线性叠起来的损失曲面,是一片高维的、坑坑洼洼的崇山峻岭,局部最优多如牛毛。按本课的逻辑,梯度下降在这种地形上根本没有全局最优的保证——那今天的深度学习凭什么 work?
这是一个仍在研究的深刻问题,但已有几个让人安心的答案,值得在这里点一句:
- 高维里"坏的局部最优"出奇地少。研究发现,深网络的损失曲面上,绝大多数让梯度归零的点不是封死的小坑,而是鞍点(一个方向往上、另一个方向往下,像马鞍);加上随机性,梯度下降大多能从鞍点旁溜走。
- 大多数局部最优"够好"。实践中找到的众多局部最低点,损失彼此都很接近,也都接近全局最优——不必是"那个"最低,只要"足够低"就够用了。
- 能凸就凸。所以经典机器学习极看重把模型设计成凸的(回归、SVM):买一份"必到全局最优"的保险。深度学习放弃这份保险换取了表达力,但本课的概念——凸、局部 vs 全局、约束——依然是理解它何时稳、何时崩的语言。
常见误解
- "梯度下降走到底,就是全局最优。"只有在凸问题上才成立。非凸地形里,"梯度归零、四周更高"只能保证你到了某个局部最优;它可能远不是全局最低。把"停下来了"等同于"找到最好了",是优化里最常见、也最贵的误会。
- "凸函数就是开口向上的抛物线。"抛物线是凸的没错,但凸的家族大得多:绝对值 |x|(一个尖底的"V")、指数函数、很多带尖角的分片线性函数都凸。凸不要求光滑,只要求"处处不向下凹、弦永远在曲线上方"。反过来,光滑也不等于凸——一条上下起伏的光滑曲线照样非凸。
- "局部最优 = 全局最优,是梯度下降算法的功劳。"不是。这是问题(地形)凸带来的保证,跟你用哪种下坡算法无关。换句话说,是你选对了地形,而不是算法变聪明了。算法只负责下坡;是凸性替它担保了"下到的就是最好的"。