矩闭包下的不确定性规划:解析传播与在线优化实践

📅 2026/8/27 15:52:16
矩闭包下的不确定性规划:解析传播与在线优化实践
拿到“Analytic Planning under Uncertainty with Moment Closure”这个主题时我第一反应是想起一个自动规划Demo的现场控制序列看起来完全正确但实验环境里明显有随机扰动同一个动作反复跑成功率就是上不去。当时很多人的直觉是“增加安全余量”把参数调保守一点。可后来发现问题不在于参数不够保守而在于规划器压根没有把“不确定性怎么传播”放进决策过程里。这时候再用蒙特卡洛去模拟又会发现在线规划根本等不起几千次采样。矩闭包Moment Closure给出的是一条中间路线把状态分布压缩成少数几个能解析演化的矩再把这些矩作为规划器的输入让优化问题拥有可求导的解析结构。这个主题的真正价值不是“算得更准”。在不确定条件下做解析规划矩闭包真正改变的是它把无穷维的概率演化压缩成有限维的解析方程。代价是引入了近似误差但换来的是可以实时优化、可以求梯度、可以复用的决策模型。如果你正在做自动驾驶决策、机械臂运动规划、随机最优控制或者带噪声的机器人任务规划这个思路迟早会出现在你的技术选型清单里。1. 先把问题说清楚不确定条件下的规划到底难在哪里1.1 同一段轨迹在不同的随机实现里可能走向完全不同的结局不考虑不确定性时一个典型的轨迹规划问题很简洁给定状态初值选一个控制序列让名义状态轨迹满足动力学同时最小化成本。问题是现实系统几乎不存在严格的确定性动力学。地面摩擦系数可能有偏差轮胎模型是近似出来的执行器响应有延迟和噪声外部风阻或负载也会波动。这些扰动单独看都很小但经过非线性动力学传播后可能把“名义上的安全轨迹”推到一个很危险的状态。规划时如果不把概率分布放进去最终得到的往往不是一个真正的最优策略而是一个只在仿真名义模型上成立的策略。更麻烦的是这种情况不能靠“留安全裕量”简单解决。安全裕量加得太大任务完成度和能耗会变得很差加得太小在概率分布的尾部又会有突破约束的风险。真正需要回答的问题是在当前信念状态下执行某个控制序列未来状态落在约束内的概率是多少期望成本是多少。1.2 蒙特卡洛很直观但在线规划时很难承担它的代价蒙特卡洛是检验不确定性的自然选择。对系统做大量随机采样得到状态轨迹或者成本的经验分布。这在离线评估、算法对比、最终验证时非常好用。但在线规划的循环里蒙特卡洛的代价往往很难承担。假设一个优化循环要迭代100步每一步又要评估控制序列的好坏每个序列又需要几百次仿真采样才能压住方差。这个开销乘起来在嵌入式环境或实时控制场景里基本不可行。更隐蔽的问题是如果你要用策略梯度这类方法做优化蒙特卡洛得到的成本估计本身有随机噪声梯度很容易被噪声淹没导致收敛慢、不稳定。所以在实践中蒙特卡洛更适合做“事后验证”而不是每一次迭代都去跑。规划器内部需要一种更紧凑、更容易求导的预测模型。这正是矩闭包登场的背景它不是要替代蒙特卡洛而是要在规划循环内部充当一个快速的解析预测器。1.3 解析规划的诉求让不确定性成为可计算的结构“解析规划”这四个字听起来可能有点吓人实际含义并不复杂就是把概率预测从“用一堆样本来描述”变成“用一组确定性的解析方程来描述”。比如给定当前均值、协方差和控制量下个时刻的均值和协方差可以通过公式直接算出来。一旦有了这种解析结构整个优化问题就变成了一个确定性的非线性优化问题。规划器看到的不再是噪声成本和未知风险而是一组能随着控制输入平滑变化的统计量。这样梯度下降、序列二次规划、微分动态规划这些常规优化器全都能用上。这种能力的代价是你必须做一个近似假设把系统的概率分布限制在某个有限维的矩空间里。做这个假设的过程就是矩闭包。2. 为什么是“矩闭包”它把不确定性的演化变成可解析的方程2.1 状态分布演化是无穷维的但规划器只需要少数几个统计量在随机动力系统中严格来说未来状态不是一个固定点而是一个概率分布。这个分布的演化由随机微分方程或随机差分方程控制。在线性高斯系统里事情很优雅高斯分布经过线性变换仍然是高斯分布均值方程和协方差方程各自闭合不需要考虑别的信息。非线性系统就没有这么好的运气。任何一个非线性函数作用在高斯分布上结果也可能是非高斯的。均值下一步怎么演化取决于二阶矩二阶矩怎么演化又取决于三阶矩和四阶矩。以此类推形成一个无穷递推链。如果不做截断规划器需要维护一个无穷维对象这在工程上不可能。矩闭包本质上就是选择“在这里切断递推链”。最常见的选择是假设状态分布始终近似为高斯分布于是只需要保存均值向量和协方差矩阵。这个假设一旦做出整个概率演化就从无穷维降到了有限维。2.2 常见的闭包方式不只一种但本质都是“截断”“矩闭包”在不同文献里对应着不同的实现我根据工程中常见的做法列几条闭包方式核心假设优点典型风险高斯闭包 局部线性化状态分布始终保持高斯用一阶泰勒展开近似非线性动力学公式最简单梯度容易算强非线性下会低估协方差特别是长期预测统计线性化 / 加性偏置用一阶导数项加上偏置项来逼近非线性比纯线性化更能保留均值偏移对强非线性、多模态分布仍不够无迹变换 / Sigma点闭包通过有限个采样点传播再重新拟合高斯分布均值和协方差的估计比线性化更稳计算量增加且“解析求导”需要额外处理高阶矩截断保留到三阶或四阶矩忽略更高阶项误差更小适合更复杂的分布实现复杂度高数值稳定性需要额外维护实际项目中我见过最多的是“局部线性化 高斯闭包”因为它实现成本低特别适合梯度类优化。无迹变换在“方差估计不准”的问题上通常表现更好但它要同时维护一组西格玛点在求导和反向传播时没那么直接。2.3 闭包之后规划器得到了什么一旦完成闭包状态预测就变成了一组确定性递推公式。以高斯闭包 局部线性化为例均值递推m_{t1} f(m_t, u_t)协方差递推P_{t1} A P_t A^T B Q B^T其中A是动力学函数对状态的雅可比矩阵B是动力学函数对噪声的雅可比矩阵Q是过程噪声协方差。这组公式正是规划器想要的给定m_t, P_t, u_t可以确定性地算出m_{t1}, P_{t1}。沿着时间轴不断向前推就得到一整条“不确定性走廊”。规划器能在这个走廊上计算期望成本也能评估状态进入危险区域的概率。这里需要特别说明所谓“解析”不一定是符号积分凑出来的美妙公式。现代工程里它可以是一段能稳定计算、且可以自动求导的数值递推过程。重点是它没有内部随机性输入一样输出就一样这对优化器非常重要。3. 实际规划流程从闭包假设到可优化策略的六步走3.1 第一步把随机控制问题写成状态空间模型不要一上来就推导公式。先把自己的问题变成标准形式状态x_t、控制u_t、随机扰动w_t、动力学x_{t1} f(x_t, u_t, w_t)、观测模型z_t、成本函数J。这一步最容易被跳过。很多项目直接从代码开始结果闭包假设和动力学模型之间根本不匹配。如果动力学里带有乘性噪声即噪声项本身依赖状态闭包方程里会多出好几项如果扰动不是高斯分布那高斯闭包给出的置信区间可能需要额外校正。3.2 第二步选择闭包假设并且把假设写清楚我一般会先把“闭包假设”单独记录下来而不是混在代码注释里。比如写下假设状态分布近似为高斯分布。非线性动力学通过一阶泰勒展开做局部线性化。过程噪声为零均值高斯白噪声协方差为Q。这看起来很简单但实际作用是当最终的规划结果和蒙特卡洛验证对不上时你可以回去逐条查看是哪一条假设出了问题。3.3 第三步推导或实现解析传播方程如果你选高斯闭包和线性化递推公式如下A ∂f/∂x (在 m_t, u_t 处求导) B ∂f/∂w (在 m_t, u_t 处求导) m_{t1} f(m_t, u_t, 0) P_{t1} A P_t A^T B Q B^T如果你选无迹变换就需要生成一组西格玛点通过非线性函数传播后再重新计算加权均值和协方差。这也能得到一个确定性的m_{t1}, P_{t1}只是代码会稍多一点。注意递推协方差时尽量使用P_{t1} A P_t A^T B Q B^T的对称结构不要手动展开成逐元素算式否则对称性很容易因为浮点误差被破坏。3.4 第四步把期望成本写成均值和协方差的函数闭包给了你一条不确定性走廊走廊的形状会影响决策。期望成本可以不用方差但那样你就丢失了闭包带来的最大价值让风险进入目标函数。以二次成本为例假设目标状态是x_g那么期望成本里会出现两项J Σ [ (m_t - x_g)^T W (m_t - x_g) trace(W P_t) ]第一项是均值偏差成本第二项是状态不确定性的代价。即使均值已经到目标点只要协方差很大总成本也会惩罚它。这正好对应“平均轨迹好但风险高”的情况。如果还要处理约束例如“位置不能进入障碍物区域”可以通过高斯近似把它写成一个机会约束P(g(x) ≤ c) ≈ Φ( (c - g(m_t)) / sqrt(grad_g^T P_t grad_g) )然后将它转换成优化器里的一类惩罚项或硬约束。这个公式本身不复杂复杂的是判断g的线性化在约束边界附近是否可信。3.5 第五步用梯度优化器求解控制序列闭包之后整个问题变成了确定性优化问题这时候梯度下降、iLQR、SQP 都能用。一个简化的迭代循环如下# 一个说明用的伪代码结构 m m0 P P0 u init_control_sequence() for iteration in range(max_iters): traj_m, traj_P forward_propagate(m, P, u, closurelinear_gaussian) J expected_cost(traj_m, traj_P, x_goal, u) J chance_constraint_penalty(traj_m, traj_P, obstacles) grad compute_gradient(J, u) u - learning_rate * grad在真实系统里控制序列通常做成闭环的比如模型预测控制MPC。每个控制周期从当前滤波估计出的m_t, P_t出发求解一小段有限时域优化只执行第一段控制量然后滚动更新。3.6 第六步用蒙特卡洛做交叉验证这一步不是可选的。闭包假设毕竟只是假设。规划器给出的结果在“它自己的假设世界”里是最优的但真实系统不一定遵守你的高斯闭包假设。我建议离线阶段固定留两组样本一组是训练仿真用的关键场景另一组是验证用的随机场景。在验证组里跑几百次蒙特卡洛对比三个指标平均成本是否接近规划器预测值。状态落点分布的方差是否接近闭包预测的协方差。约束违反频率是否接近机会约束设定的阈值。如果这三个指标偏差很大先不要急着调成本权重回到第二步和第三步检查闭包假设和传播方程。4. 工程落地的数值细节这些地方最容易翻车4.1 协方差的正定性维护在闭包递推中协方差矩阵必须保持对称半正定。实际代码里浮点误差会悄悄破坏对称性尤其在你的动力学雅可比矩阵很长、状态维度又高的时候。我一般会在每次递推之后强制对称化P 0.5 * (P P.T)。更稳的做法是保存协方差矩阵的 Cholesky 因子每次更新矩阵平方根。如果发现P_t中出现负的特征值先不要急着加人工抖动。先检查是不是线性化点取了名义轨迹但实际控制让系统走到了另一个状态导致雅可比矩阵根本不在有效工作点上。4.2 线性化点和控制轨迹的耦合高斯闭包 线性化最大的坑是线性化点本身必须和当前候选控制轨迹一致。如果你的优化器在一个控制序列下计算了梯度然后更新控制量下一次迭代必须重新计算雅可比矩阵而不是沿用旧矩阵。这个“重新线性化”非常关键。在 iLQR 类算法里这通常由算法本身保证因为它在每次后向传播时都会重新计算局部线性化。但如果你用通用的自动微分框架很容易出现“闭包方程里还挂着上一次迭代的雅可比”的现象。结果就是协方差预测严重失真优化方向也会偏。4.3 过程噪声协方差 Q 的取值不能拍脑袋闭包之后Q的大小会直接影响机会约束和成本。如果你把Q设得太小规划器会过度自信认为协方差走廊很窄约束风险很低如果你把Q设得太大规划器会变得过度保守几乎不敢执行任何激进动作。我的经验是先通过一次开环仿真或真实日志估计噪声统计量。如果实在没有数据宁可把Q调大一点然后在验证阶段看约束违反率是否真的在指标以内。4.4 时间离散化带来的误差随机系统的离散化不是简单地把dt塞进公式。对非线性系统欧拉离散在dt较大时会产生明显的离散误差也会让协方差推算和真实连续系统差很多。常见做法是先把控制周期拆成更小的积分步长在积分步内做闭包递推再把多步结果汇总成控制周期的预测。这个做法会增加计算量但能明显减少闭包近似和离散化近似共线叠加的风险。注意如果你发现闭包预测的协方差和蒙特卡洛仿真差出好几倍先检查时间步长再检查线性化方式。很多时候不是闭包思路错了而是离散化精度不够。5. 排查链路当闭包规划器给出的结果不靠谱时先查哪里5.1 不要直接从参数开刀规划器跑出来的结果和蒙特卡洛对不上时最常见的错误是一上来就调成本权重、调控制惩罚或者把安全阈值改小。这样调出来的参数没有解释力换个场景又失效。我建议按照下面这条链路逐层排查先看现象是平均成本差太多还是最终状态方差不对还是约束违反率偏高再看输入分布过程噪声真的近似高斯吗有没有明显的重尾、死区和周期性扰动再看传播方程闭包递推中雅可比矩阵是否和控制轨迹匹配协方差有没有被线性化点“带偏”再看目标和约束你的机会约束线性化是否只在障碍物边缘附近成立成本里的方差惩罚项是否被其他项淹没最后看工具边界闭包本身适合这个系统的非线性程度吗还是说系统已经出现明显多模态必须换粒子方法5.2 一个简单的分层排查表现象最可能原因先看哪里规划器认为低风险蒙特卡洛约束频繁失效高斯闭包低估了尾部检查闭合的P_t和相关非线性程度优化过程不收敛成本抖动大梯度计算里噪声大或线性化点陈旧检查自动微分是否每次重新计算雅可比协方差爆炸或消失数值稳定性问题检查 Q 取值、时间步长和 Cholesky 更新名义轨迹很好但最终结果经常偏出目标动力学模型里的确定性偏差没有建模检查均值递推是否忽略了非线性均值漂移只在小误差下有效大扰动下失效闭包只适合局部近似考虑换无迹变换或提升矩截断阶数这条排查链路的本质是先确认是哪一层假设被破坏了再决定要不要换方案。闭包近似最可怕的不是有误差而是你不知道误差长什么样子。5.3 一个实操建议小成本交叉验证在正式跑完整规划前我会先做“短时域交叉验证”只预测 3 到 5 步用闭包递推算出末端均值协方差再用 500 次蒙特卡洛仿真得到末端统计量。如果短时域都偏差很大那一定是闭包方程或线性化实现有问题而不是优化器的问题。短时域验证通过之后再逐步扩大时域。这个习惯能省下大量排查时间。很多项目以为问题出在“不确定性处理”的高级环节结果查到最后只是A矩阵算错了位置。6. 这个方法的适用边界什么场景该用什么场景换方案6.1 适合的场景中等非线性 连续控制 在线再规划矩闭包 解析规划最适合的场景有几个共同特征动力学非线性程度中等不会出现严重突变或分叉。控制量是连续的问题可以用梯度类方法优化。系统需要在线反复规划不能每次都跑蒙特卡洛。状态分布基本可以用均值和协方差来描述或者至少概率质量集中在单一模态附近。自动驾驶的横向控制、机械臂的平滑轨迹跟踪、无人机编队中的局部避障、随机模型预测控制都属于这类场景。它们对实时性要求高对“快速得到一个足够好的解”的期望远高于“精确算出一个全局最优解”。6.2 不适合的场景多模态、接触突变、长尾安全风险闭包假设在以下场景里会明显失效状态分布呈现多模态比如一个目标可能出现在两个完全不同的位置造成信念状态双峰。动力学存在接触、碰撞、切换逻辑一个很小的状态变化会改变整个动力学模式。安全约束对尾部概率极其敏感例如不允许有百万分之一概率的碰撞而你的闭包近似把尾部概率截平了。过程噪声非常大非线性又强导致高斯闭包预测的协方差和真实系统差出数量级。在这些场景里粒子方法、场景树方法、鲁棒控制或分布鲁棒优化往往更合适。哪怕计算量大一点也比“用错误分布计算出的自信结果”更可靠。6.3 边界判断的标准看残差不看型号一个项目适不适合用矩闭包不能只看它属于哪个行业要看它能量化出来的近似残差。我会在离线阶段直接做一组实验闭包预测出的协方差走廊和蒙特卡洛跑出的状态散点分布叠在一张图里看重叠程度。如果散点大部分落进协方差椭圆里那么这个系统还可以继续用矩闭包。如果散点明显偏斜、出现多簇分布那就说明闭包的截断假设已经撑不住了。7. 沉淀成一套可复用的落地框架MCP-OV 五步检查法7.1 框架结构为了让你不至于看完文章又回到“从代码开始”的老路我把前面的经验收成一个五步检查法缩写为 MCP-OVModel、Closure、Propagate、Optimize、Validate。阶段核心问题产出物常见错误Model 建模随机动力学、噪声和成本是否写清楚状态空间模型、噪声统计量把噪声设为固定常数完全忽略乘性噪声Closure 闭包采用哪个假设误差边界在哪闭包方式说明、适用范围描述选了高斯闭包却要求系统处理强多模态Propagate 传播均值协方差递推是否稳定精确可求导的确定性递推方程线性化点陈旧或协方差不对称Optimize 优化期望成本和机会约束是否可微目标函数、控制序列更新规则成本里只有均值项没有方差风险项Validate 验证闭包预测和真实或蒙特卡洛是否一致短时域交叉验证报告、约束违反率跳过验证直接上真实系统7.2 每阶段最重要的一个建议Model 阶段先把噪声来源写出来。到底是执行器噪声、环境噪声还是模型参数不确定这三种噪声在闭包方程里的位置完全不同。Closure 阶段不要追求“更高级的闭包”先看系统非线性程度。如果你的动力学函数在典型工作区间里接近线性高斯闭包 线性化就足够了。Propagate 阶段用平方根滤波的思路维护协方差防止负特征值让优化器产生虚假梯度。Optimize 阶段期望成本里一定要放一项目标方差或约束边界相关的惩罚否则闭包只是个花架子规划器不会真正“看到”风险。Validate 阶段用独立于优化过程的蒙特卡洛样本做验证而且验证场景要覆盖你可能用到的控制幅度范围不能只用一套温和场景。7.3 从检查法带出的一个判断这些步骤累加起来背后其实是同一个判断不确定性下的解析规划本质上是用“分布的形状假设”换“优化的实时能力”。矩闭包给规划器带来的是结构和速度代价是你必须接受它在分布形状上的粗化。用这个判断去看项目你会比单纯搜索“moment closure 是什么”更有收获。真正的工程难点不是如何实现递推公式而是如何确定我的系统有没有资格承担这个高斯假设我是否知道闭包之后丢掉了什么只要你能回答这两个问题矩闭包就不再是一个充满黑话的研究术语而是一个可以在具体场景里反复验证和迭代的决策工具。