凸性
优化里最重要的一个"好性质":碗状的地形里只有一个谷底,沿着坡往下走,一定走得到。数学上把这种碗叫凸函数。一个问题是凸的,意味着局部最小就是全局最小,算法有保证、有速度、结果可复现;不是凸的,就要靠运气和经验。认清哪些机器人问题凸、哪些不凸,是选对工具的第一步。
1为什么机器人需要它
机器人领域有一条几乎通用的工程经验:能写成凸问题的,就写成凸问题。全身控制每毫秒要解一个二次规划 (QP),模型预测控制 (MPC) 在线性模型下是一个凸 QP,线性最小二乘标定一步到位。它们都是凸的,所以求解器几毫秒内给出可靠、唯一、可复现的答案,不用担心卡在局部最小、不用调初值。
反过来,机械臂的逆运动学、视觉里程计的位姿优化、神经网络训练都不是凸的,我们只能找"一个够好的谷底"。这一节要建立的是一副"眼镜":给你一个问题,你能判断它的地形是碗还是山脉,从而知道可以对结果有多大的信心。
2直觉:弦在曲线之上
取函数曲线上任意两点,连一条线段(弦)。如果无论你取哪两点,弦都不会钻到曲线下面,这个函数就是凸的:它像一个碗,向上"兜住"每一条弦。只要有一对点,弦钻到了曲线下面,就说明那里有个"凸起",凸性被破坏。
这个看似平淡的性质威力巨大。假设碗里有两个"谷底",它们之间的弦必须在曲线之上(或重合);可两个谷底都是最低值 \(m\),弦的高度恰好是 \(m\),而曲线又不可能低于 \(m\),于是两点之间的曲线被夹住,处处等于 \(m\):两个谷底其实是同一片平地。如果两个谷底一高一低,弦从高的那个谷底出发就向下倾斜,紧挨着它的曲线也被压到它的高度之下,它根本不是局部最小(第 7 节给出严格证明)。凸函数不可能有彼此孤立的两个局部最小值。先亲手试试弦测试。
3动手玩:弦测试
选一个函数,拖动曲线上的两个点 A、B。弦在曲线之上的部分填绿色,钻到曲线之下的部分填红色。滑块 \(\theta\) 在弦上取一点,对比 \(f(\theta a+(1-\theta)b)\) 与弦的高度 \(\theta f(a)+(1-\theta)f(b)\)。"全面扫描"会测试 780 对点(区间上 40 个点两两配对),告诉你有多大比例的弦违反了凸性。
- 在"双谷"或"波浪"上找到一对点,让弦钻到曲线之下。
- 在 \(0.04x^4\) 上做"全面扫描":它在 \(x=0\) 处几乎是平的,却仍然是凸的,违反比例是 0。
- 在凹函数 \(3-0.3x^2\) 上扫描:违反比例是多少?为什么凹函数的"弦"总在曲线下面?
凸性是一个"全局"性质,却能用"两点之间"来检验。你不需要知道整个地形,只要任意两点之间的弦不下沉,就知道没有多余的谷底。这也是为什么它能给出全局保证:局部信息(梯度为零)加上凸性,就等于全局信息。
4凸集:约束的形状
同样的"弦测试"用在集合上:一个集合是凸的,当且仅当其中任意两点之间的线段完全留在集合里。球、半空间、盒子是凸的;有凹口的"月牙"、带洞的区域、几块分离的区域都不是。
它为什么重要?因为可行集(6.1 节)就是一个集合。如果约束是凸的,从可行点出发朝另一个可行点走,永远不会"撞墙"。反之,一个障碍物就能把可行集变成非凸的:从左边绕还是从右边绕,是两条不同的路,这正是路径规划难的原因。
- 在"月牙"或"星形"里,把 A、B 都放在集合内,却让弦跑出集合。
- 选"透镜"(圆盘 ∩ 半平面)并做随机扫描:两个凸集的交仍然是凸集,违反数为 0。
5第二个视角:切线在下,曲率向上
弦测试需要同时看两个点,不方便。对可导函数,有两个"单点"检验:
- 一阶条件:凸函数整条曲线都在它任何一条切线之上。选一点 \(x_0\),画出切线,曲线不能钻到切线下面。
- 二阶条件:曲率处处非负,即 \(f''(x)\ge0\)(多维时是 Hessian \(\nabla^2 f\succeq0\),3.5 节)。曲线始终"向上弯"。
下面拖动 \(x_0\):上图画切线,红色表示曲线跑到了切线之下;下图画 \(f''\),红色表示曲率为负。你会发现这两件事严格同步:只要某处 \(f''<0\),就一定能找到一条切线被曲线穿透;反之,\(f''\ge0\) 处处成立则切线永远在下面。
- 在"双谷"上拖动 \(x_0\),找到一个位置使得切线被曲线穿透。此时 \(f''\) 在 \(x_0\) 处一定为负吗?(不一定:试试 \(x_0=1\)。)
- 在"指数"上拖遍整条曲线:切线是否永远在曲线之下?
6二维地形:弦、Hessian 与"负曲率区"
到了二维,把 \(x_0\) 换成平面上的点,曲率换成 Hessian 的两个特征值 \(\lambda_1\ge\lambda_2\)(1.11 节)。\(\lambda_2\ge0\) 说明各个方向都向上弯,是碗;\(\lambda_2<0\le\lambda_1\) 说明有的方向向下弯,是鞍;两个都为负是山顶。凸函数要求处处是碗。
下图在平面上拖动 A、B,下方的小图画出 \(f\) 沿这条线段的剖面(实线)和弦(虚线)。红色背景标出 Hessian 有负特征值的地方,那是"非凸区"。试试四种地形:只有第一个是凸的。
- 在 Rosenbrock 上放 A、B,使剖面鼓到弦之上(它只有一个谷底,却不是凸的)。
- 在 log-sum-exp 上随便拖拽 A、B:剖面永远在弦下面,红色区域也不出现。
7再看数学
提示:悬停在带底色的符号上,FIG 1、3、4 里对应的元素(弦、切线、非凸区)会被强调。
定义
集合 \(C\) 是凸集,如果对任意 \(\x,\y\in C\) 与 \(\theta\in[0,1]\),都有 \(\theta\x+(1-\theta)\y\in C\)。函数 \(f\) 是凸函数,如果定义域是凸集,且
左边是弦下方曲线上的点的高度,右边是弦的高度(FIG 1 的滑块 \(\theta\))。把 \(\le\) 换成 \(<\)(\(\x\ne\y\),\(\theta\in(0,1)\))就是严格凸:碗底没有平的部分,最小点唯一。\(-f\) 凸则称 \(f\) 为凹。
一阶与二阶条件
若 \(f\) 可微,则 \(f\) 凸 \(\iff\) 对所有 \(\x,\y\):
右边正是 \(f\) 在 \(\x\) 处的一阶泰勒展开(切线 / 切平面,FIG 3 的紫线)。若 \(f\) 二阶可微,则 \(f\) 凸 \(\iff\)
为什么凸问题"容易"
1. 局部最小就是全局最小。设 \(\x^\star\) 是局部最小,却有 \(\y\) 使 \(f(\y)<f(\x^\star)\)。沿线段取点 \(\x_t=(1-t)\x^\star+t\y\),由凸性 \(f(\x_t)\le(1-t)f(\x^\star)+tf(\y)<f(\x^\star)\),对任意小的 \(t>0\) 都成立,而 \(\x_t\) 可以任意接近 \(\x^\star\),与"局部最小"矛盾。
2. 梯度为零就够了。在一阶条件里令 \(\nabla f(\x^\star)=\mathbf0\),得 \(f(\y)\ge f(\x^\star)\ \forall\y\):驻点就是全局最小。6.1 节说"梯度为零只是必要条件",对凸函数它也是充分条件。
3. 算法有保证。强凸(\(m I\preceq\nabla^2f\preceq L I\))时,梯度下降的误差按 \(\big(\tfrac{\kappa-1}{\kappa+1}\big)^k\) 衰减,\(\kappa=L/m\) 就是 6.3 节的条件数;Newton 法(6.6 节)在最优点附近二次收敛。
怎样得到凸函数:保凸运算
| 运算 | 结论 | 机器人里的例子 |
|---|---|---|
| 非负加权和 | \(\sum_i w_if_i,\ w_i\ge0\) | 误差 + \(\lambda\)·能耗 |
| 与仿射映射复合 | \(f(A\x+\mathbf b)\) | \(\|A\x-\mathbf b\|^2\):线性最小二乘(1.13 节) |
| 逐点取最大 | \(\max_i f_i\) | 最大关节误差;\(\ell_\infty\) 范数 |
| 范数、二次型 (PSD) | \(\|\x\|,\ \x^\top Q\x\) | 马氏距离、力矩平方 |
| 凸集的交 | \(C_1\cap C_2\) | 限位 ∩ 速度上限 ∩ 摩擦锥 |
注意非线性复合会破坏凸性:\(\|A\x-\mathbf b\|^2\) 凸,但 \(\|\mathrm{FK}(\mathbf q)-\mathbf t\|^2\) 里的 \(\mathrm{FK}\) 不是仿射的,所以逆运动学的代价对关节角 \(\mathbf q\) 不凸,见下一节。
8机器人中的它:逆运动学为什么不凸
对于一个目标位置 \(\mathbf t\),最小化 \(f(\mathbf q)=\tfrac12\|\mathrm{FK}(\mathbf q)-\mathbf t\|^2\)。如果把末端位置 \(\mathbf p\) 当变量,\(\tfrac12\|\mathbf p-\mathbf t\|^2\) 是一个完美的碗;可变量是关节角 \(\mathbf q\),\(\mathbf p=\mathrm{FK}(\mathbf q)\) 里全是 \(\sin,\cos\),碗被"揉皱"了。最直接的证据:肘朝上和肘朝下两个解的代价都是 0,而在关节空间里把两个解连成一条线段,中点的代价却大于 0,弦在曲线下面。
拖动下图右侧的 A、B(初始在两个解上,拖动目标会自动吸附到新解),滑块 \(t\) 让手臂沿着这条线段在关节空间里"插值"。注意中途手爪明显偏离了目标,代价鼓起一个包。红色区域是 Hessian 有负特征值的地方。
- 把滑块 \(t\) 拖到中间 (0.4–0.6),读出中点代价:它是否大于两端代价的平均值?
9常见误区
反例就是 Rosenbrock(FIG 4):只有一个最小点,却不是凸的,弦能钻到曲线下面。"单峰"(unimodal)比"凸"弱得多。不凸但单谷的函数,局部算法通常也能找到最小点,只是没有凸性那样的速度保证(沿弯曲山谷爬得很慢)。
二阶条件必须在整个定义域上成立。一个点的 Hessian 正定只说明局部像碗(它是局部最小的二阶充分条件)。FIG 4 里的双谷在每个谷底都是正定的,整体却不凸。
单位球(\(\le\))是凸集,单位球面(\(=\))不是:球面上两点连线穿过球内部。这就是为什么"四元数模长为 1"、"旋转矩阵正交"这类约束让问题变得不凸,也是第 6.10 节要在流形上直接优化的原因之一。非线性等式约束一般都会破坏凸性;凸问题里的等式约束必须是仿射的。
凸性保证"没有坏的局部最小",但不保证"快"。条件数 \(\kappa\) 很大的凸问题,梯度下降仍然龟速(6.3 节);规模巨大的凸问题仍然需要好的算法和实现。反过来,也有很多不凸的问题(如神经网络训练)在实践中被解得很好。
10小练习
11延伸阅读
- S. Boyd & L. Vandenberghe, Convex Optimization, Ch. 2–3 — 凸集、凸函数、保凸运算的完整讲解,含大量图示(可免费下载)
- J. Nocedal & S. Wright, Numerical Optimization, 2nd ed., Ch. 1–2 & App. A — 凸性在局部最优性条件中的作用
- G. Strang, Linear Algebra and Learning from Data, Ch. VI — 凸函数、正定性与深度学习中的优化