分而治之解决非凸预测优化:端到端决策学习之路

📅 发布时间:2026/10/4 3:11:46
分而治之解决非凸预测优化:端到端决策学习之路
先说一个反直觉的结论在“预测优化”这类系统里预测模型把验证集准确率练到95%最终业务收益可能还不如一个准确率90%、但“知道什么时候该乱猜”的模型。这不是说准确率不重要而是因为很多团队在搭这类系统时把预测和优化当成了两段独立的流水线——先用机器学习预测未来需求、价格、流量再把预测值塞进一个优化模型里求解。预测模型只对“预测误差”负责优化模型只对“给定输入后的决策质量”负责两者之间没有反馈回路。预测错了优化器就拿着错误的输入一本正经地算出错误的决策。把这两个环节打通的工作近年来在AI领域有个专门的称呼Predict-Then-Optimize也就是“预测优化”。方法本身并不新鲜但绝大多数早期工作都假设下游优化问题是凸问题——因为只有凸问题你才能从最优解稳定地反推梯度回传给上游的预测模型。一旦下游问题变成非凸的整个端到端闭环就会卡死。这也是我看到这篇AAAI论文标题时的第一反应拿分而治之来处理非凸的预测优化问题这个切入点补的正是整个领域最痛的缺口。这篇文章我会从问题本质、算法拆解、最小案例到复现注意点逐一讲清楚我是怎么理解这个方法以及如果你打算在自己的场景里复现它有哪些坑需要提前避开。1. 先从“预测”与“优化”的貌合神离说起1.1 为什么预测准了决策反而变差了先看一个最常见的业务场景库存补货。假设你是一家零售商需要决定未来一周每个SKU补多少货。缺货了损失销售利润积压了占用仓库还要折价处理。传统做法是先训练一个销量预测模型把未来七天的需求预测出来然后扔给整数规划求解器在“补货上限、仓库容量、起订量”这些约束下求出最优补货计划。问题出在哪出在损失函数不对齐。销量预测模型的训练目标是让预测需求与实际需求的均方误差MSE尽量小。但下游优化器真正关心的是补货决策导致的期望利润损失。预测误差在哪个区间、朝哪个方向偏对最终利润的影响完全不同。MSE把每个预测点的误差同等对待优化器却只在乎那些“会让决策翻车”的误差。举个极端例子某商品历史销量方差很大预测模型为了压MSE把预测值拉向均值。如果你按这个均值决定补货量结果大概率是既没备足旺季销量又留下了淡季库存。相反一个“赌徒型”预测模型虽然平均误差更大但它在高波动时给出的预测区间能正确引导优化器多备货、少积压最终利润反而更好。这就是“预测优化”要解决的核心问题你的预测模型不该学真实需求的整体分布而该学“对下游决策损失最敏感的那部分信息”。1.2 从两阶段到端到端损失函数怎么反传要做到这一点只有一条路把优化器也变成可微的让决策损失直接反传到预测模型的参数上。于是就有了SPOSmart Predict-then-Optimize这类方法。它的思路不复杂——不直接惩罚预测误差而是惩罚“用预测值做出的决策”与“用真实值做出的最优决策”之间的损失差距用预测参数解一次优化问题得到一个决策用真实参数解一次优化问题得到最优决策两者之间的目标函数值差距就是当前预测模型在决策层面犯的错把这个差距作为损失对预测模型反向传播。这个方法在凸优化问题上表现很好因为凸问题有良性的对偶性质你可以从最优解处隐式求导把梯度回传给预测模型的输出。具体点说在凸问题里最优解对外部参数的导数可以由KKT条件的隐函数求导得到——这保证了梯度路径是可计算、稳定的。但是这个方法有一个几乎无法绕开的软肋它要求下游优化问题是凸的。1.3 非凸问题的出现几乎是一种必然很多真实决策问题天生就是非凸的。举几个常见的整数约束补货量必须是整箱、卡车数量必须是整数、排班人数必须是整数。这类离散约束让可行域变成离散格点凸性瞬间没了。固定成本结构开一条产线有固定启动成本只要产量超过0就触发。这种“阶梯状”成本让目标函数非凸。非线性组合投资组合里涉及交易手续费、最小持仓单位、涨跌停约束物流调度里涉及路径耦合。这些约束叠加在一起可行域往往是非凸的甚至不连通。如果下游优化问题是非凸的SPO那套“从最优解反推梯度”的路径就塌了。因为非凸问题可能有多个局部最优解你找到的“最优解”很可能只是其中一个KKT条件不再是全局最优的充分条件隐式求导得到的梯度可能指向错误的方向优化求解器本身可能都不保证收敛到全局最优你又怎么把不稳定的解作为“标签”去训练预测模型所以这篇论文标题里的“非凸”不是故意找难题而是所有做落地的人都必然会撞上的墙。想办法让预测优化在非凸问题里也能形成有效闭环才是这项工作真正的价值所在。2. 为什么非凸问题让端到端学习寸步难行2.1 非凸的数学困境局部最优、不可微、对偶断裂要理解这个方法得先把“非凸之难”拆开看。第一难局部最优不是全局最优。在凸优化中局部最优解就是全局最优解而且对偶间隙为零。如果算法找到一个解它就有保证。但在非凸问题中光滑的山谷里有无数个低洼处每个低洼处看着都像“最优”。你用梯度下降或内点法求解大概率收敛到离初始点最近的那个山谷而不是全局最低点。作为训练标签这个解不可靠——同样参数下换个初始点结果就变了预测模型学到的规律也会跟着震荡。第二难最优解对参数的导数不连续。预测优化靠的是梯度反传但很多非凸问题尤其是带整数约束的真正最优解可能在一个参数区间的边缘处发生跳变。参数微调一点点最优决策直接从“备货100箱”跳到“备货0箱”。这种跳变使得最优值函数对参数不可微梯度不存在隐式求导直接失效。第三难对偶断裂。凸问题里原问题和对偶问题可以来回切换很多梯度信息可以从对偶变量影子价格中读出。非凸问题中强对偶一般不成立对偶间隙不为零你没法再从对偶空间中拿梯度信息。这三重困境叠加的结果就是你既没有一个稳定的最优解当标签也没有一条平滑的梯度路径可以反传整个端到端训练就像在布满地雷的迷宫里找出口——每一步都可能踩炸。2.2 现有方法为什么治标不治本面对非凸问题研究者其实已经试过好几条路但都有各自的短板方法思路具体做法瓶颈光滑化Smoothing用连续函数近似离散约束例如把整数约束放松成Sigmoid惩罚近似误差大决策可能不满足严格约束随机抽样求梯度对非凸问题做多次随机初始化收集一批局部最优解用REINFORCE类方法估计梯度方差极大训练不稳定样本效率低代理损失Surrogate Loss不用真实决策损失改用代理函数如交叉熵、MSE训练代理函数和决策目标错位等于退回两阶段凸松弛Convex Relaxation把非凸可行域放大到凸包在凸包里求解凸包解可能落在不可行区域对离散约束尤其危险你会发现这些方法有个共同问题它们都在“绕开”非凸性而不是“处理”非凸性。你把非凸问题放松成凸问题梯度好算了但解已经不是你真正想要的解了你用随机梯度估计解还是那个非凸问题的解但梯度方差大到训练根本走不动。2.3 分而治之为什么能站在“处理”而非“绕开”的一侧“分而治之”这个词在算法里一点都不新鲜但用在预测优化的非凸问题上逻辑很顺既然整个问题非凸、没法一刀切地求梯度那就先把它拆成若干个子问题让每个子问题具备更良好的结构比如凸的、可微的、或规模足够小到可以暴力搜索全局最优再把子问题的解组合回原问题。这个思路相当于不打阵地战改成游击战目标函数在一个广阔区域上崎岖不平但我可以把区域切成几块每块地形相对简单在每块地形里用合适的武器求出局部最优最后再根据全局协调规则把各块的最优解拼成原问题的一个高质量候选解。关键在于三件事怎么拆、怎么治、怎么合。拆得好子问题结构良好治得好子问题能被可靠求解合得好组合出来的解逼近全局最优而且梯度路径能被保留下来。后面的核心章节我就按这个逻辑来拆解这篇AAAI工作。3. 分而治之算法的三个关键设计3.1 第一刀怎么把非凸问题拆成相对好解的子问题这一步是整个算法的地基。论文标题只给了“分而治之”这个方向具体怎么分是有讲究的。按我过去处理混合整数规划的经验切分方式通常分两类结构切分变量分组。看目标函数和约束的依赖图如果某些变量之间耦合很小可以按耦合关系把变量分成几个组。比如库存问题里不同品类的补货决策只通过“仓库总容量”这一个约束耦合那就可以把每个品类看成独立的子问题仓储约束放到协调层去处理。这种切分保留了问题的结构特征每个子问题内部可能还是非凸的但耦合没了求解难度大幅下降。空间切分可行域划分。把非凸可行域按某种规则切成若干个区域在每个区域内目标函数和约束都变得相对简单。一个经典的做法是沿着决策变量的边界切比如整数变量只有0和1两个取值那就天然形成一个二叉划分树每个叶子节点上整数变量被固定剩下的连续变量构成一个凸子问题。沿着树往下走在每个叶子节点求凸问题的解再回溯比较得到全局最优候选。到我读这篇论文时的理解它更接近两种方式的结合先用问题结构做一次粗粒度分组然后在组内用空间划分处理残留的非凸性。这种“粗分细分”的组合比单独用任何一种切分方式都稳健。# 切分问题的伪代码示意 def partition_nonconvex_problem(params): # 1. 按变量耦合关系做粗粒度分组 groups detect_coupled_variable_groups(params) subproblems [] for group in groups: # 2. 在组内检查非凸约束 if has_nonconvex_constraints(group): # 3. 对非凸部分做空间切分分支、区域划分等 partitions split_region_by_boundaries(group) for subregion in partitions: subproblems.append(build_convex_subproblem(subregion)) else: subproblems.append(build_subproblem(group)) return subproblems3.2 第二刀子问题求解与梯度回传的缝合机制子问题建好之后面临一道坎每个子问题可以用成熟的凸优化求解器或在极小规模下用穷举/分支定界求出解但这些“解”是离散的、不可微的。顶层还有一个预测模型等着拿梯度梯度路径不能断。这里常见的缝合技巧是用**软组合Soft Combination**代替硬选择。什么叫硬选择“哪个子问题得分高就只选哪个子问题的解”——这是一个argmax操作不可微。软组合的做法是给每个子问题的目标值算一个权重例如用温度参数缩放的Softmax然后把各子问题的解按权重做凸组合。当某个子问题的目标值远好于其他子问题时Softmax权重会逼近独热One-Hot软组合解趋近于该子问题的解当多个子问题解质量差不多时权重分布平滑梯度可以从每个子问题的解上均匀流回预测模型温度参数控制了软硬程度推理阶段可以把温度调到接近0得到近似硬选择的结果训练阶段用较高的温度保留梯度信息。这个机制的好处在于它没有试图对非凸问题“求导”而是把一个非凸的取最优操作替换成了一个可微的加权平均操作。权重的梯度是解析可算的每个子问题内部的梯度路径也能通过凸求解器的隐式求导拿到。两条路径缝合在一起整条预测→求解→决策链路就打通了。3.3 第三刀训练循环怎么保证收敛稳定光有缝合机制还不够端到端训练的稳定性也是重头戏。我见过很多项目在凸问题上跑得好好的一上非凸就梯度爆炸、loss发散。分而治之架构里有几个环节特别容易出问题。子问题赋权可能产生退化。如果某一个子问题的解在当前参数下显著占优Softmax权重会变成近似独热码梯度几乎全部从这一个子问题回流。这个子问题本身的解又强烈依赖预测参数梯度将会非常大可能让预测模型参数一步跳飞。缓解手段是给权重加标签平滑Label Smoothing限制最大权重或者在回传梯度时对梯度的范数做截断Gradient Clipping。子问题划分边界上的不可微跳变。预测参数变化可能让某个子问题从“可行”变为“不可行”对应到代码里就是分支条件的跳变。这个跳变本身不可微实测中会表现为训练loss曲线上的尖刺。论文类工作常用滑溜近似Smooth Approximation处理边界但具体落地时你也可以在边界处做线性插值人为给跳变一个过渡区间。交替优化的节奏。有些实现是预测模型和子问题求解器交替迭代先固定预测模型解一批子问题再固定子问题解更新预测模型。这种交替更新在凸情况下有理论保证在非凸场景下则容易在两个状态之间震荡。我的经验是给预测模型的更新步长做热启动——前几轮小步长只求“不炸”后期再恢复正常学习率。for epoch in range(max_epochs): # 1. 预测模型输出参数 pred_params demand_model(batch) # 2. 分而治之切分并求解子问题 subproblems partition_nonconvex_problem(pred_params) local_solutions [solve_convex(solver, sp) for sp in subproblems] # 3. 软组合得到最终决策 weights softmax([sp.cost for sp in local_solutions], temperature) final_decision weighted_sum(local_solutions, weights) # 4. 决策损失回传 loss decision_cost(ground_truth, final_decision) loss.backward() # 5. 梯度修剪 参数更新 torch.nn.utils.clip_grad_norm_(demand_model.parameters(), max_norm1.0) optimizer.step()说句实在话这些设计里最让我欣赏的点在于“软组合”这个思路——它没有试图假装非凸问题不存在而是给非凸问题的求解结果留了一条平滑的出路让梯度能够在离散解之间穿梭。4. 一个能跑通的最小实例带整数约束的库存补货问题4.1 问题定义为什么选库存补货做基准理论讲再多不如一个具体问题通透。我选库存补货做最小实例是因为它同时具备两个特征决策变量带整数约束且非凸性来自“固定运输成本”。这两个特征叠加让它天然成为非凸优化问题但又不至于复杂到无法手动建模。问题设定如下有3个SKU统一放在一个仓库里仓库容量200箱每个SKU补货时必须凑整箱每箱容量分别为5、8、10箱每次只要某个SKU补货量不为0就会触发一笔固定的订货成本比如运输和清关费用需求由上游预测模型估计真实值在训练数据中可见补货决策的目标是最大化期望利润 销售收入 - 采购成本 - 缺货损失 - 固定成本。这个问题的非凸性从哪来固定订货成本让目标函数在“0”这个点产生一个跳跃——从0到1箱成本突然跳出一个固定值。这种阶梯状结构直接让目标函数非凸而且可行域被整数约束切成了离散格点。4.2 怎么用分而治之的思路建模按前面说的方法论这个问题的切分逻辑很清晰结构切分。3个SKU之间只通过仓库容量这一条约束耦合所以可以先把每个SKU当作独立子问题每个子问题是“该SKU在给定需求预测下订几箱最赚”。这是一个带固定成本的单变量整数规划规模极小甚至可以用穷举法遍历所有可能箱数求全局最优。说完结构再谈空间切分单一SKU的子问题虽然规模小目标函数仍然带固定成本跳跃所以还需要把“订0箱”和“订N箱”拆成两个子区域。订0箱成本为0利润为0直接算出一个基准解订N箱固定成本触发剩下的是一个在连续域上凹/凸的单变量问题可以解析求解。于是原问题被切成子问题ASKU 1 订0箱子问题BSKU 1 订N箱N为整数满足仓库约束子问题C、DSKU 2 同理子问题E、FSKU 3 同理协调层把各SKU的解组合起来更新仓库容量拉格朗日乘子迭代至收敛。每个子问题都是可微的订N箱子问题里最优N可以通过遍历全部可行箱数再从箱数到利润的反向关系推导梯度协调层又是一个标准的凸问题整条链路就能通起来。4.3 训练效果的关键对比指标如果你要复现并验证这个方法我强烈建议同时跑两个基线做对比基线1两阶段方法。预测模型只用MSE训练输出预测值再喂给同款整数规划求解器。它代表大多数团队当前的生产做法基线2SPO的凸松弛版本。把固定成本放松成线性惩罚项把整数约束放松成连续域约束在凸近似问题上用SPO损失训练。评价指标不能只看决策损失还要看预测模型在决策层面对齐的程度。我常用的一个指标是“后悔值”Regret用预测参数做出的决策放在真实参数环境里产生的成本减去用真实参数做出的最优决策的成本。后悔值越小说明预测优化闭环越紧。在我的经验里这三条曲线通常会呈现出截然不同的走势两阶段方法在预测误差上最优但后悔值偏高——因为预测模型没有感知决策代价凸松弛版本在训练早期后悔值下降快但后期停滞——因为松弛后的解在真实约束里不可行后悔值被隐藏的不可行惩罚拉高分而治之算法下降曲线不一定最快但最终后悔值最低——因为它在真实约束下优化了解的质量。这条“虽然慢一点但是能到更远”的曲线基本就是分而治之方法的写照。5. 复现过程中的训练细节与避坑心得5.1 子问题切分粒度别切得太碎第一个坑切分粒度。子问题切得越细每个子问题越简单但缝合的损耗越大。因为软组合需要跨越的子问题边界越多梯度在边界处的衰减和扭曲就越明显。我的建议是先做一次变量耦合分析把“强耦合”的变量留在同一个子问题里只把“弱耦合”的变量切开。怎么判断强弱看约束矩阵里非零元的分布。库存问题里两个SKU如果共用同一个仓库容量约束它们之间的耦合就是间接的可以切开但两个SKU如果共享同一个供应商的折扣阶梯这种折扣会在目标函数里強烈耦合切开以后每个子问题都算不准。5.2 Softmax温度参数的调度策略第二个坑温度参数。温度太高软组合权重过于平滑所有子问题解都按接近均匀的权重混合最终决策严重偏离最优解 温度太低权重趋近独热梯度方差和尖锐度拉满训练不稳定。我在实践里试过几种调度策略比较稳的一条经验是指数衰减式调度前10-20个epoch温度从5开始快速降到1左右让模型先学会“哪些子问题区域的地形明显更优”建立初始判别能力中段训练温度保持在0.5左右维持足够的梯度通量最后20个epoch把温度降到0.1以下让决策逐渐硬起来逼近真实部署时的选择行为。如果你发现损失在小范围内反复震荡同一批数据训多轮loss上下乱跳大概率是温度降得太快梯度还没法把稳定的信息传回预测模型。5.3 求解器的选择可微性与可用性的平衡第三个坑子问题求解器。理想情况下子问题的求解器要既能返回最优解又能返回解对输入参数的导数。成熟的凸优化求解器如ECOS、OSQP和部分商业求解器都支持这种敏感性分析。但业界常用的混合整数规划求解器如SCIP、OR-Tools的CP-SAT、Gurobi混合整数模式则不提供导数信息。如果你的子问题仍然是混合整数规划那你需要给求解器包一层“可微代理”。我试过两种方案方案A对整数决策做连续化比如把整数变量放松成[0,1]区间内的连续变量求解凸松弛再用扰动法求数值梯度。简单但有偏差。方案B在子问题内部再套一层小规模穷举只对包含少数整数变量的最小粒度子问题穷举然后手工推导“箱数→成本→参数”的闭式梯度。准确但只适用于极小规模。结合这篇论文的思路我更推荐在做结构切分时刻意把整数变量集中到少数子问题里让“穷举小规模整数子问题凸求解连续子问题”成为可能。这听起来像绕路但实际比硬解一个大混合整数规划要稳得多。5.4 评估时不要看单一指标最后一条心得也是我觉得很多人会忽略的端到端方法上线评估时务必同时看两套指标。一套是决策指标后悔值、利润/成本、约束违反率。这是方法的胜负手不用多解释。另一套是行为指标预测模型输出的参数分布是否合理、子问题权重的熵是否过高、决策变量在不同预测区间上的连续性如何。行为指标不会直接决定业务收益但它们能帮你判断训练是否走偏。比如当子问题权重熵长期维持在较高水平说明预测模型一直没能形成清晰的优先级判断——这种模型即使决策指标看着不错换一批数据也容易翻车。我踩过最痛的一次坑就在这里某个项目在训练集后悔值降得很漂亮但上线第一周就出现大批不可行解。排查到最后发现由于温度参数降得太快模型在训练结束后几乎固定选择某个子问题区域但该区域在训练数据中密集在真实数据分布里却只占一小部分。如果当时多看一层行为指标早就能发现权重熵下降过快这个危险信号。6. 写在最后非凸处理能力意味着什么这篇AAAI工作最有价值的地方不在于它给出了一个新的优化求解器而在于它把“预测优化”这条端到端链路的适用范围从凸问题边界往前推进了一大块。对研究者来说这个方向的价值在于提供了一个更贴近真实业务的基准场景。非凸问题不是边角料它是大多数运营决策的常态。能让算法在非凸条件下依然保持梯度传播的有效性这比在凸问题上刷一个漂亮的理论保证要难得多也实用得多。对工程团队来说这篇工作的核心方法论值得借鉴的点在于“分而治之”不只是一个算法框架更是一种建模心态不要试图用一个巨型非凸问题的整体解去同时承担求解和梯度回传两个任务而是把它拆成适合各自工具的零件——分布治之的切分结构凸求解的局部求解能力以及软组合的缝合机制。这个思路哪怕你不做端到端训练只是用预测模型配合传统优化器做决策也很有参考价值。我个人在实际操作中的体会是端到端方法的入门门槛不算高真正难的是让它在真实数据的噪声和约束漏损面前还能保持稳定。分而治之算法不是银弹它的软组合机制会引入额外的超参数温度、切分粒度、梯度截断阈值需要投入精力调参但比起在非凸问题上绕路放松约束这已经是目前我看到的最值得一试的路径。如果你手头正好有一个预测优化的业务场景且下游优化模型带着整数约束或者固定成本结构不妨按这篇文章的思路搭一个最小实验出来。先用小规模数据跑通再逐步扩大子问题规模。整个过程里最需要耐心的是观察温度调度如何影响训练稳定性以及权重熵如何指示模型是否真的学到了决策层面的规律。