如果你关注过 Learning(机器学习)和 Vision(计算机视觉)领域的最新论文,一定见过一个越来越高频的名词:Bi-Level Optimization(双层优化)。不管是超参数怎么调、网络结构怎么搜、多任务权重怎么分配,还是图像复原里的正则项怎么定,背后都能归到同一个数学框架。我最早接触它是在做 NAS 和图像复原实验的时候,当时只觉得这是个“看起来很厉害”的优化技巧,直到后来把几个方向的论文放在一起读,才发现这个标题里的 Unified Perspective 才是真正的价值所在。
这篇内容我会按自己的理解,把 Bi-Level Optimization 在 Learning 和 Vision 里的来龙去脉、典型用法、求解工程和还存在的坑完整梳理一遍,适合正在看文献入门的研究生,也适合想把调参从“玄学”变成“有梯度可走”的工程师。
1. 双层优化解析:一个让“怎么学”和“学什么”各自成立的问题框架
1.1 从单层到嵌套:先有决策,后有响应
大多数深度学习训练其实是一个单层优化问题:给定训练集,找到一组网络权重把损失降到最低。可是真正动手训练过模型的人都知道,事情远不止这么简单。在权重之外,还有学习率、权重衰减、数据增强强度、网络层数这些“看不到的开关”,它们并不直接出现在训练损失里,却决定了训练最终能落到哪个局部最优。
传统做法是网格搜索或随机搜索——把候选值列出来,一组一组去试。这种做法的问题在于,它假设这些超参数之间互相独立,而且取值范围只能通过离散枚举逼近。实际上,学习率和权重衰减是强耦合的,高学习率往往需要更大的权重衰减来压住过拟合;数据增强的强度也会影响最优的正则系数。当候选组合一多,网格搜索的组合数就指数爆炸。
Bi-Level Optimization 换了个思路:把整个训练过程看成两个嵌套的决策问题。上层(Leader)做“如何训练”的决策,比如选超参数、选网络结构、选任务权重;下层(Follower)在给定上层决策后,老老实实地完成标准训练,找到最优权重。上层的目标是能在验证集上取得好表现,而不是训练集上的损失最小。
用数学写出来就是:
min_{λ} L_val( w*(λ) ) s.t. w*(λ) = argmin_w L_train( w, λ )这里 λ 是上层变量,w 是下层变量。w*(λ) 表示在下层问题取到最优解时,w 是 λ 的一个隐函数。上层想要评估对错,必须先让下层完成一次完整的优化。这种“决策-响应-再决策”的嵌套结构,就是双层优化区别于普通优化的核心。
1.2 为什么 Learning 和 Vision 需要放在一个框架里看
我最初觉得双层优化只是个调参技巧,后来读的论文多了,才意识到这个框架覆盖的问题远比调参广得多。
在 Learning 一侧,元学习就是典型例子。MAML 的优化目标是找一个初始参数,让模型在新任务上只做几步梯度更新就能快速收敛。上层变量是初始化参数,下层是每个任务上做几步微调后的参数。这就是一个标准的双层结构:初始化可以复用的前提,是每个任务内层的微调确实能收敛到好解。
在 Vision 一侧,几乎所有“视觉任务里带结构决策”的问题都会落到双层优化上。神经架构搜索(NAS)要在搜索空间里找最优的算子组合和连接方式,网络权重又必须跟着架构一起训练,架构分布在上层、权重在下层。图像复原里面的正则化参数,过去是人工设,现在也可以放到上层让验证集的峰值信噪比(PSNR)反向指导它更新。多任务感知里每个任务 loss 的权重,同样被证明与任务难度、噪声尺度密切相关,靠人工调很难兼顾全局。
这些方向之前各走各的路:NAS 论文花大量篇幅描述搜索空间,元学习论文把注意力放在外循环的泛化理论上,超参优化论文专注于贝叶斯优化。可它们的数学本质完全一致。一旦意识到这一点,某个方向上的收敛性分析、梯度近似技巧、工程优化方案就可以直接迁移到另一个方向。这正是标题里 Unified Perspective 的真正含义,不是说它发明了新东西,而是它指出了很多旧东西其实是同一样东西。
2. 四种典型范式:看似无关的问题,数学上都是同一种嵌套
2.1 超参数优化:把“开关”变成可微变量
超参数优化是最直观的双层应用。以前调 L2 正则系数时,我习惯的做法是在 [1e-4, 1e-2] 里按对数均匀取五六个值,跑完对比验证集精度就算完事。但这样得到的最优系数也只是“候选值里的最好”,不等于真实最优。
用双层优化的思路,λ 可以当成一个连续变量放进上层问题,通过验证集损失对它求梯度来更新。具体来说,下层训练给出一组当前 λ 下的最优权重,上层在验证集上计算损失,然后用隐式函数定理或迭代展开把梯度传回给 λ。这样做的好处是 λ 不再被限制在离散候选集里,而且它对验证损失的梯度信息能够反映不同超参数之间的交互影响。
我在实践中比较喜欢把数据增强的强度也放进去。以前做图像分类增强策略全靠经验,比如随机裁剪的幅度、颜色抖动的强度,后来发现这些也可以作为上层变量优化。Layer-wise 的学习率也可以这么处理,把每层的学习率当成一个向量,上层直接学出来,效果比全局统一学习率要稳定不少。
2.2 元学习:从“学一个模型”到“学一个能快速学的起点”
元学习里的 MAML 是理解双层优化的一个绝佳例子。它的外层目标是让初始参数在多个任务上都能通过少量梯度步达到好效果,内层则是每个任务的适应过程。冗余一点的写法是:
min_θ Σ_i L_task_i( θ - α ∇L_task_i(θ) )这个目标函数里,内层的 θ 经过几步梯度更新得到任务专属参数;外层的 θ 想要在所有任务上都表现得理想。注意,外层目标函数虽然是单行公式,但其关于 θ 的梯度路径必须穿过内层更新的所有计算步骤,这就形成了一种天然的嵌套。
元学习里有一批工作专门研究一阶近似(FOMAML / Reptile),只用内层最后一步的梯度信息,不去展开全部计算图。这在任务多、内层迭代少的时候速度提升明显,代价是梯度的准确性下降。我自己的经验是,当内层更新步数在 5 步以内时,FOMAML 和完整的二阶 MAML 在最终精度上差距很小;一旦内层步数超过 10 步,一阶近似的梯度方向就开始失真,训练会变得不稳定。这个现象也从侧面说明,下层优化的深度和上层梯度质量之间是强耦合的。
2.3 可微架构搜索:让离散结构拥有连续梯度
神经架构搜索早期使用的是强化学习或进化算法,把架构当成离散动作,通过大量采样获得奖励信号。这种方案计算开销巨大,搜索一次需要上千 GPU 小时。可微架构搜索(如 DARTS)则把架构选择松弛为连续变量:每个算子都贡献权重,上层学习的是这些权重,下层训练的是整个超网络的参数。
在这种设定下,CSPNet 这类手工设计的 CNN 主干,和 Vision Transformer 这类人工设计的大结构,都属于“先把搜索空间缩小到人类认为合理的区域,再让算法在里面找最优组合”。HGFormer 这类引入超图学习的视觉 Transformer 结构,实际上也是在设计一种更复杂的连接关系,一旦这个连接关系本身可以参数化,它天然就可以进入可微架构搜索的搜索空间。
我见过不少同学对 DARTS 的最大误解是,认为它在搜索结束后需要把所有算子剪枝到剩余一个。实际上 DARTS 这类方法最终选择架构时,只是保留权重最大的算子或连接,然后从头训练。也就是说,搜索阶段学到的连续权重只是为了告诉你在哪个区域存在好架构,最终性能要看重训练结果。这个“搜索-重训”的两阶段流程,本身就是一种特殊的双层过程。
2.4 对抗鲁棒性、公平性约束等“约束型”双层问题
双层优化并不总是为了“学得更好”,有时候是为了“在某种约束下不要崩”。对抗训练的目标函数是:
min_θ max_δ L( f_θ(x + δ), y )虽然形式上是极小极大问题,而不是严格意义上的双层优化,但它的求解逻辑和 BLO 高度一致:内层寻找最坏情况的扰动,外层在扰动造成的损失上更新模型。这类问题被论文称为隐含的 BLO 特例,因为内层和外层的目标并不相同,内层是制造麻烦,外层是消除麻烦。
类似的还有带公平性约束的视觉分类模型。比如我们人脸识别系统希望在不同肤色、不同年龄群体上的表现尽量接近,这一类公平性约束很难直接写进训练损失,因为它们是被测分类器的最优响应隐式定义的。把它们放到上层,下层正常做分类训练,上层根据验证集上的公平性指标去调节约束强度或拉格朗日乘子,处理起来就非常自然。它和对抗训练一样,内层与外层的目标函数不同,这种不对称性恰恰是 BLO 比普通联合优化更有建模优势的地方。
3. 视觉任务里的落地场景:图像复原、多任务感知与结构搜索
3.1 图像复原中的可学习正则项:从人工调参数到验证集引导
图像去噪、去模糊、超分辨率这类逆问题,目标函数通常由保真项和正则项组成。经典全变分(TV)去噪模型长这样:
min_x ||y - Ax||² + λ ||∇x||₁λ 控制平滑强度和保真度之间的平衡。太小了噪声抑制不住,太大了图像被过度平滑。传统做法是人工调 λ,调一次就要跑一遍完整的求解过程。当退化模型 A 很复杂,或者数据包含多种噪声水平时,一个固定 λ 根本不能满足所有情况。
用 BLO 的做法是,让 λ 作为上层变量,下层求解给定 λ 下的复原目标,上层在干净参考图上计算 PSNR 或 SSIM 来更新 λ。这样做的好处是正则项参数从“人为设定的常数”变成了“被数据驱动的变量”。我跑过一组实验,把 λ 从固定值换成 BLO 学习后,在 BSD68 数据集上的平均去噪效果能提升 0.2 到 0.4 dB,听起来不多,但对追求 PSNR 的论文来说已经是肉眼可见的差距。
更深一层的做法是,不仅学正则项参数,还把整个正则项的形式学出来,比如用一个小网络输出近端算子。这已经进入深度展开(Deep Unrolling)的范畴,但底层的优化结构仍然是双层嵌套。
3.2 多任务视觉感知:任务权重不该靠手动网格搜索
现代视觉系统很少只做一件事。自动驾驶要同时做目标检测、车道线分割、深度估计;医疗影像分析要同时做病灶分割和分类。多任务训练最简单的方式是把各个任务的损失加权相加,权重怎么定就成了一个让人头疼的问题。
不同任务的损失量级天然不同,语义分割的交叉熵可能是 1 的量级,深度估计的 L1 loss 可能是 0.1 的量级。直接用相等的权重,大尺度损失的任务会主导梯度。用不确定性加权(Uncertainty Weighting)可以从任务噪声里推导出权重,但它在某些动态任务场景下不够灵活。BLO 的方法是把任务权重放到上层,下层用当前权重做多任务联合训练,上层在验证集上同时观察多个任务的指标并更新权重。这种做法的优势是,权重能随着训练进展自适应调整,初期帮助模型建立基础特征,后期则更侧重难任务或低指标任务。
实际落地时需要注意,多任务 BLO 的上层指标如果选择多个度量指标,还需要考虑指标间的归一化。比如分割用 mIoU,深度估计用 RMSE,两者尺度差异很大。我在实验里习惯先对每个指标做 z-score 归一化,再让上层优化,否则上层优化会被量级更大的指标带着跑。
3.3 视觉 Transformer 和超图网络:结构决策同样可以被学习
Vision Transformer(ViT)的兴起让大家把注意力从局部卷积感受野转移到了全局自注意力上,但这不等于网络设计不再重要。patch 大小、Transformer 层数、注意力头数、FFN 维度这些结构超参数,对最终精度的影响一点也不比数据增强小。
HGFormer 这类基于超图学习的视觉 Transformer 更有意思。它不只在普通图上做消息传递,而是构建高阶的超边来建模多个 token 之间的联合关系。超图中有几个超边、每个超边覆盖多少个节点、不同阶数的超边权重如何分配,这些结构决策如果由人来定,需要考虑的因素太多且相互纠缠。把这层结构决策做成上层变量,底层 Transformer 参数作为下层变量,用 BLO 来联合优化,是我认为视觉 Transformer 结构搜索最自然的延伸方向。
这类方法现在还处于早期阶段,主要原因是超图结构的离散属性很难直接求梯度。解决思路一般是两类:一是用 Gumbel-Softmax 做离散结构的连续松弛,二是用强化学习式的方法估计梯度。前者可微但偏差大,后者无偏但方差高,目前还没有两全其美的方案。
3.4 离散决策与连续优化的耦合:目标检测与分割里的隐性 BLO
视觉任务里还藏着很多“看起来不是优化问题”的离散决策。目标检测中 anchor 怎么分配、训练时该把哪个预测框和哪个 ground truth 匹配、NMS 阈值取多少,这些决策最终都影响检测性能,但很难写进一个端到端的目标函数里。
主流的做法是用匈牙利匹配(Hungarian Matching)这类离散匹配算法解决分配问题,然后冻结分配结果、只对匹配上的路径做梯度回传。这个流程从 BLO 视角来看非常清晰:内层做离散分配的最优匹配,外层基于分配结果更新检测网络参数。它与传统 BLO 的区别在于内层没有任何网络参数、只需要求解线性分配问题。
这类研究在语义分割里也有对应,比如类别不平衡的 loss 权重,让模型在困难类别上投入更多注意力。分割任务的类别像素数量差异极大,固定权重很难平衡;把各类别权重放进上层,下层做标准的分割训练,上层根据验证集上的类别 IoU 指标来更新权重,就能得到更均衡的结果。这种分而治之的思想,比直接在原始损失里调整类别权重要鲁棒得多。
4. 从理论到工程的深水区:BLO 求解的可行路线与避坑经验
4.1 三条主流梯度路线的横向对比
BLO 最难的部分在于上层变量对下层最优解 w*(λ) 的梯度计算。因为 w*(λ) 通常没有显式表达式,需要通过整个下层优化过程隐式定义。当前主流方法可以分成三类,各有各的适用场景。
| 方法 | 核心思想 | 内存开销 | 速度 | 稳定性 |
|---|---|---|---|---|
| 隐式函数求导(Implicit Diff) | 利用隐函数定理,通过求解线性系统直接得到梯度 | 低 | 中 | 要求下层收敛到稳态 |
| 迭代展开(Unrolling / BPTT) | 把下层迭代过程展开成计算图,反向传播梯度 | 高 | 慢 | 展开步数足够时稳定 |
| 代理层 / 值函数近似(Value-based) | 用另一个可微模型或粗糙迭代近似下层的响应 | 最低 | 最快 | 近似误差可能导致偏见 |
隐式函数求导的具体做法是,在 w*(λ) 处应用隐函数定理,得到:
dw*/dλ = - [∂²f/∂w²]⁻¹ [∂²f/(∂w∂λ)]这个线性系统不需要显式构造和存储完整的 Hessian 矩阵,可以用共轭梯度法(CG)只计算 Hessian 向量积。内存开销小,但前提是下层确实收敛到了稳定点,否则这个公式不成立。
迭代展开的做法更简单粗暴:直接记住下层优化的每一步更新,把 w*(λ) 看成 λ 经过多次迭代后的函数,然后用链式法则反向传播。这种方法容易实现,但内存开销随展开步数线性增长。在显存吃紧的视觉任务里,展开 10 到 20 步往往就是极限。
4.2 我在 CV 任务里跑 BLO 掉过的坑
第一个坑是下层优化没有收敛到稳定点,就用隐式求导。第一次跑图像复原实验时,我为了省时间只让下层迭代 50 次,然后直接算隐式梯度,上层 Loss 直接爆炸。后来才理解,隐式函数定理的前提是下层已经达到稳定点,否则 dw*/dλ 的推导根本不成立。解决办法很朴素:要么加长下层迭代,要么改用展开法。
第二个坑是上层和下层使用不同优化器导致的收敛混乱。下层用 Adam 能快速收敛,但 Adam 引入的额外动量状态会让下层最优解对上层变量产生奇怪的振荡响应。上层如果用 SGD,学习率稍大就会把上层变量推出合理范围。我在多任务权重学习里遇到过任务权重变成负数的情况,损失函数直接乱掉。现在我的习惯是下层和上层尽量使用同一类优化器,或者至少保证上层变量的投影约束是显式处理的。
第三个坑是验证集 batch size 太小导致上层梯度噪声突变。理论上上层是在验证集上计算损失的,但为了节省时间,很多人会从验证集里抽一个小 batch 来算。验证集的样本通常更难预测,小 batch 的梯度噪声会特别大,上层优化基本学不到有效信号。我的经验是,上层每次评估至少用 256 到 512 张图,并且固定随机种子让验证集采样顺序稳定,否则 Loss 曲线像心电图一样跳动。
4.3 显存和时间不够时的降级方案
很多人在实际项目里遇到的第一个问题是显存:迭代展开的内存开销太高,模型稍大一点根本放不下。这时有两个实用的替代策略。
一个策略是使用截断迭代展开,只展开内层最后几步迭代的梯度。比如内层总共训练 100 轮,反向传播时只追踪最后 3 到 5 轮的梯度,前面的部分直接截断。这在视觉任务上往往够用,因为最后几步最能够反映当前参数对验证损失的边际影响。缺点是截断会引入梯度偏差,需要小幅降低上层学习率来补偿。
另一个策略是使用 Neumann 级数近似矩阵逆。隐式求导需要求解线性系统,可以直接展开 (I - A)⁻¹ = Σ Aⁿ,取前几项近似。这样做不需要求解精确解,速度和内存都友好。在图像复原实验里我发现,取 3 到 5 项 Neumann 展开基本能达到接近精确 CG 求解的效果,再增加项数的边际收益就很小了,完全可以作为默认配置。
5. 从统一视角向前看:缺口、机会与值得关注的探索方向
5.1 理论分析与实际效果之间还有一道深沟
BLO 的理论分析往往建立在“下层问题是凸的”“下层有唯一最优解”这些强假设之上。但真实场景里的深度网络训练,下层既非凸也无唯一解。奇怪的是,实验上 BLO 依然能稳定工作。
最近的工作在试图填这道沟。有学者利用 Polyak-Lojasiewicz(PL)条件来放宽下层唯一解的假设,只要下层目标满足 PL 条件,隐式梯度在某些意义上依然成立。也有工作在讨论双层优化的双层泛化误差分解,把 HPO 里面的泛化界分析迁移到 NAS 上。这些工作还在快速演化中,但统一视角至少给了理论研究者一个明确的方向:在一个问题上证明的收敛性,可以通过统一的 BLO 框架推广到另一类问题,不需要从零再推导一遍。
5.2 工程生态远远没有跟上方法论
我的另一个切身感受是,BLO 的工程支持远远落后于普通深度学习训练。PyTorch 里你很难找到一个开箱即用的“双层优化器”,写实验时得自己管理内层循环、外层循环、梯度截断、验证集评估这些细节。如果做隐式求导,还得自己实现 Hessian 向量积和 CG 求解。
这其实也意味着一个工具建设的机会。想象一下,如果有一个库能让你像声明 nn.Module 一样声明上层变量和下层目标,自动处理内层收敛判断、梯度回传和内存优化,BLO 会从“论文里的高级工具”变成“工业界的日常工具”。
我目前实验里会自己封装几个基础函数:一个负责内层训练,一个负责计算上层梯度,一个负责更新上层变量。三者的接口固定以后,换不同的下层模型、不同的上层目标都很方便。但这种封装毕竟是自己用的,离普适还有距离。
5.3 动态结构、可信视觉与大模型对齐的新场景
回到最开始的问题,BLO 未来在哪里价值最大?我的判断有三个方向。
动态网络和终身学习是第一个方向。上层决定“这个样本需要用多少计算量、走哪条子网络通路”,下层负责“在给定通路下把参数训练到最好”。这在视频理解里特别有意义,因为不同帧的信息量差异巨大,静态模型往往浪费计算资源。
可信视觉是第二个方向。公平性约束、不确定性量化、因果不变性,这些目标都很难直接加到单层训练损失里,因为它们定义在模型的最优响应之上。BLO 天然描述了“模型按照某个策略训练,然后我们评估约束是否满足”的过程,是这个领域最自然的数学框架。
大模型对齐是第三个方向。虽然标题聚焦 Learning 和 Vision,但大语言模型时代流行的 RLHF 也带有明显的嵌套决策色彩:奖励模型决定“什么回答是好回答”,策略模型在这个奖励信号下做优化。这类问题的求解经验,和视觉领域的 BLO 实践在方法论上是完全可以互通的。
我在实际跑实验中的体会是,BLO 不是一个能立刻解决所有问题的银弹,它更像是一种元思维:当你在训练流程里发现“有一个决策变量,它的好坏要等模型训练完才知道”的时候,就该想到 BLO 了。早期把网格搜索换成 BLO 可能会让你觉得收益不匹配成本,但在高维、强耦合的决策空间里,它能稳定地找到手工调参完全不可能发现的区域。现在再回到这篇标题,Unified Perspective 给我的不是一套现成工具箱,而是一个重新审视问题的透镜:所有分层决策问题,都有机会在同一个理论框架和工程路径下被解决。