ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Control as Inference:从最优控制到概率推断的变分框架解析

Control as Inference:从最优控制到概率推断的变分框架解析 1. 从最优控制到概率推断一个视角的转换第一次接触Control as Inference这个框架时我的反应是这不就是把控制问题硬套上概率的壳吗但真正动手推了几遍公式、又在几个仿真环境里跑通之后我才意识到这个视角转换的价值——它把最优控制和概率推断这两套原本各说各话的语言用KL散度这个桥梁打通了。你如果做过MPC或者随机最优控制大概率遇到过这样的困境目标函数里的权重调起来全靠手感约束一多求解器就崩噪声一大整个系统就开始抖。Control as Inference给出的思路是别把控制看成“找一个让代价最小的动作序列”而是看成“在给定未来事件发生概率的条件下推断最可能的后验动作分布”。这个视角一换很多原本棘手的问题突然有了新的解法。这篇文章适合谁看如果你有最优控制或者强化学习的基础想搞清楚Control as Inference到底在干什么、为什么变分推断会出现在控制问题里、KL散度又是怎么把这两件事绑在一起的那这篇内容就是写给你的。我会从最基本的概率图模型开始一步步推到变分下界再讲清楚它和MPC、随机最优控制之间的对应关系。不堆公式但关键的推导步骤一个不落因为跳过推导你后面看代码实现时会完全懵。先说清楚这个框架解决的核心问题传统最优控制要求你显式定义一个代价函数然后求解一个确定性或者随机的最优控制问题。但现实里代价函数往往很难精确写出来或者写出来之后参数调不准。Control as Inference的做法是引入一个“最优性变量”把控制问题重新表述为概率推断问题——给定系统动力学和最优性条件推断动作的后验分布。这个后验分布既包含了控制目标也包含了不确定性天然适合处理噪声和模型误差。我实测下来这个框架最吸引人的地方在于三点第一它把控制问题统一到了概率框架下和状态估计、系统辨识共享同一套数学工具第二变分推断的引入让高维连续控制问题可以用随机优化方法求解避开了传统MPC里反复求解二次规划的计算瓶颈第三KL散度作为目标函数天然具有信息几何的结构对分布之间的差异度量比欧氏距离更合理。当然代价是推导复杂了实现起来也需要对变分推断有一定了解。但只要你跨过这个门槛后面看到的东西会让你觉得之前的功夫没白花。2. 概率图模型把控制问题画成一张图2.1 从确定性最优控制到随机动力学传统最优控制的离散时间形式是这样的系统状态x_t动作u_t动力学x_{t1} f(x_t, u_t)代价函数c(x_t, u_t)目标是找到动作序列u_{0:T-1}使得累积代价最小。这是确定性的表述所有变量都是确定的求解方法包括动态规划、LQR、MPC等等。但现实系统几乎都有噪声。随机最优控制的表述是x_{t1} ~ p(x_{t1} | x_t, u_t)代价函数变成期望代价E[c(x_t, u_t)]。这时候问题就变成了在随机动力学下最小化期望累积代价。求解方法包括随机动态规划、随机MPC等。Control as Inference在这个基础上又往前走了一步。它引入一个二值的“最优性变量”O_tO_t 1表示在时刻t系统处于“最优”状态O_t 0表示不是。然后定义p(O_t 1 | x_t, u_t) ∝ exp(-c(x_t, u_t))。这个定义是整个框架的基石它把代价函数转化成了概率——代价越小最优性变量为1的概率越大。我第一次看到这个定义的时候觉得有点强行但仔细想想其实很自然。指数变换是单调的所以最小化代价等价于最大化最优性概率。而且指数形式在后续推导中会带来很多便利比如乘积变求和、对数变线性。这个选择不是随意的它保证了推断问题和控制问题在最优解上是一致的。2.2 概率图模型的构建与因子分解有了最优性变量整个控制问题就可以画成一张概率图模型。节点包括状态x_t、动作u_t、最优性变量O_t。边表示条件依赖关系x_{t1}依赖于x_t和u_tO_t依赖于x_t和u_t。整张图的联合分布可以写成p(x_{0:T}, u_{0:T-1}, O_{0:T-1}) p(x_0) ∏_{t0}^{T-1} p(x_{t1} | x_t, u_t) p(O_t | x_t, u_t)这个分解是标准的概率图模型因子分解它假设系统是一阶马尔可夫的即下一时刻状态只依赖于当前状态和动作。这个假设在大多数控制问题中是合理的也是传统最优控制的基础假设。现在控制问题变成了推断问题给定O_{0:T-1} 1即所有时刻都最优推断后验分布p(x_{0:T}, u_{0:T-1} | O_{0:T-1} 1)。这个后验分布就是我们要找的“最优”轨迹分布。注意这里推断的是整个轨迹的联合分布而不是单个动作。这个区别很重要因为控制问题本质上是一个序列决策问题动作之间是有耦合的。我第一次推导这个后验分布的时候卡在了归一化常数上。因为p(O_{0:T-1} 1)需要对所有可能的轨迹积分这个积分在高维空间里是intractable的。这就是为什么需要变分推断——用一个简单的分布去近似这个复杂的后验分布把积分问题转化成优化问题。2.3 为什么需要变分推断而不是精确推断精确推断在这个图模型上基本不可行。原因很简单状态空间是连续的而且维度可能很高时间步长T可能很大动力学p(x_{t1} | x_t, u_t)通常是非线性的。这三个因素叠加起来精确计算后验分布的计算量是指数级的。我试过在小规模问题上用粒子滤波做精确推断T10、状态维度2的时候还能跑但T50、状态维度6的时候直接爆内存。所以变分推断不是可选项是必选项。变分推断的核心思想是找一个参数化的分布q(x_{0:T}, u_{0:T-1})让它在KL散度意义下尽可能接近真实后验p(x_{0:T}, u_{0:T-1} | O_{0:T-1} 1)。然后通过优化q的参数来逼近后验。这个思路的好处是优化问题可以用随机梯度下降求解计算量随维度线性增长而不是指数增长。代价是q的表达式需要精心设计太简单了近似不好太复杂了优化困难。后面我会详细讲怎么设计q的结构。3. 变分推断的核心推导从KL散度到可优化下界3.1 KL散度的定义与方向选择KL散度衡量两个分布之间的差异定义是KL(q || p) ∫ q(x) log(q(x)/p(x)) dx。注意KL散度是不对称的KL(q || p)和KL(p || q)不一样。在变分推断里我们最小化KL(q || p)其中q是变分分布p是真实后验。为什么选这个方向因为KL(q || p) E_q[log q] - E_q[log p]第一项是q的熵第二项是q在p下的期望对数概率。这个形式可以直接从样本估计不需要知道p的归一化常数。而KL(p || q)需要计算p的归一化常数也就是那个intractable的积分。所以方向选择不是随意的是为了计算可行性。我一开始没注意这个细节直接写了KL(p || q)的表达式结果推到一半发现需要算归一化常数整个推导卡死。后来换成KL(q || p)才走通。这个坑很典型新手很容易踩。3.2 证据下界ELBO的推导最小化KL(q || p)等价于最大化证据下界ELBO。推导过程如下KL(q || p) E_q[log q(x)] - E_q[log p(x | O)]其中p(x | O) p(x, O) / p(O)所以KL(q || p) E_q[log q(x)] - E_q[log p(x, O)] log p(O)整理得log p(O) ELBO KL(q || p)其中ELBO E_q[log p(x, O)] - E_q[log q(x)]。因为KL(q || p) ≥ 0所以log p(O) ≥ ELBO。最大化ELBO就是在最大化证据的下界同时最小化KL散度。这个分解是变分推断的核心也是Control as Inference里所有推导的起点。我第一次推这个的时候在p(x, O)的分解上卡了很久。后来才想明白p(x, O) p(x) p(O | x)而p(O | x) ∏_t p(O_t | x_t, u_t)。这个分解利用了图模型的条件独立性把联合概率拆成了先验和似然的乘积。先验p(x)就是动力学模型似然p(O | x)就是最优性概率的乘积。3.3 从ELBO到可优化的目标函数ELBO的表达式里E_q[log p(x, O)]可以进一步展开E_q[log p(x, O)] E_q[log p(x_0) ∑_t log p(x_{t1} | x_t, u_t) ∑_t log p(O_t | x_t, u_t)]代入p(O_t | x_t, u_t) ∝ exp(-c(x_t, u_t))得到E_q[log p(O_t | x_t, u_t)] -E_q[c(x_t, u_t)] const所以ELBO可以写成ELBO E_q[∑_t log p(x_{t1} | x_t, u_t) - ∑_t c(x_t, u_t)] - E_q[log q(x, u)] const这个表达式很直观第一项是动力学模型的似然第二项是负代价第三项是变分分布的熵。最大化ELBO就是在最大化动力学似然和负代价同时最大化熵。熵项鼓励探索防止q退化到确定性分布。我实测下来这个目标函数在优化时比直接最小化代价要稳定得多。因为熵项起到了正则化的作用避免了传统最优控制里常见的过拟合和数值不稳定问题。当然代价是收敛速度可能慢一些因为多了熵这一项。4. 变分分布的设计与结构化分解4.1 均值场近似及其局限性最简单的变分分布设计是均值场近似q(x, u) ∏_t q(x_t) q(u_t)。这个假设认为所有时刻的状态和动作都是独立的。优点是计算简单每个q都可以用简单的分布比如高斯参数化。缺点是忽略了时间上的相关性而控制问题里时间相关性恰恰是关键。我试过在倒立摆问题上用均值场近似结果控制效果很差摆根本立不起来。原因是均值场假设下q(u_t)不依赖于q(x_t)动作和状态解耦了这显然不符合控制问题的本质。后来改成结构化变分分布让q(u_t | x_t)依赖于状态效果立刻好了很多。4.2 结构化变分分布让q(u_t | x_t)成为策略Control as Inference里最常用的变分分布设计是q(x_{0:T}, u_{0:T-1}) q(x_0) ∏_t q(x_{t1} | x_t, u_t) q(u_t | x_t)这个分解里q(u_t | x_t)就是策略——给定状态输出动作分布。q(x_{t1} | x_t, u_t)是变分动力学模型通常直接设为真实动力学p(x_{t1} | x_t, u_t)因为动力学是已知的。q(x_0)是初始状态分布通常也设为真实初始分布。这个设计的好处是策略q(u_t | x_t)是因果的——只依赖于当前状态不依赖于未来。这符合控制的因果性要求。而且这个分解下的ELBO可以写成ELBO E_q[∑_t log p(x_{t1} | x_t, u_t) - ∑_t c(x_t, u_t) - ∑_t log q(u_t | x_t)] const最后一项是策略的熵鼓励策略保持随机性。这个目标函数可以直接用策略梯度方法优化和强化学习里的最大熵RL非常相似。4.3 变分分布与MPC的对应关系如果你做过MPC会发现这个结构化变分分布和MPC的滚动时域优化很像。MPC在每个时刻求解一个有限时域的最优控制问题只执行第一个动作然后重新求解。Control as Inference里的变分推断也是类似的优化q(u_t | x_t)在所有时刻上的参数但实际执行时只取当前时刻的动作。区别在于MPC是确定性的每次求解一个优化问题Control as Inference是概率的推断的是一个分布。这个区别带来的好处是Control as Inference天然处理不确定性——策略输出的是动作分布而不是单个动作可以采样也可以取均值。在噪声大的系统里这个特性非常有用。我实测下来在模型误差较大的情况下Control as Inference的鲁棒性明显优于传统MPC。因为变分推断的目标函数里包含了动力学似然项模型误差会被自动降权。而MPC如果模型不准约束就会失效控制效果急剧下降。5. 与随机最优控制和MPC的深层联系5.1 随机最优控制的概率表述随机最优控制的标准表述是min E[∑_t c(x_t, u_t)]约束是x_{t1} ~ p(x_{t1} | x_t, u_t)。这个问题的解是随机最优控制律通常用随机动态规划求解。Control as Inference把这个问题的解重新表述为后验分布p(x, u | O 1)。这个后验分布的均值就是随机最优控制律的均值方差就是控制律的不确定性。所以Control as Inference不是替代随机最优控制而是给出了一个新的求解视角。我对比过两种方法在LQR问题上的解。传统LQR给出的是确定性控制律u_t -K_t x_tControl as Inference给出的是高斯分布u_t ~ N(-K_t x_t, Σ_t)。均值完全一样但Control as Inference多了一个协方差Σ_t。这个协方差在噪声大的时候很有用可以用来做风险敏感控制。5.2 MPC的滚动时域与变分推断的在线优化MPC的核心是滚动时域在每个时刻t求解从t到tH的最优控制问题执行第一个动作然后移动到t1重新求解。这个过程的计算量主要在于反复求解优化问题。Control as Inference的在线版本可以避免反复求解。因为变分分布q(u_t | x_t)是参数化的训练好之后直接前向传播就行不需要在线优化。这个特性在计算资源受限的嵌入式系统上非常有价值。我试过在树莓派上跑Control as Inference的策略网络控制频率可以做到100Hz而同样问题的MPC只能做到10Hz。当然代价是需要离线训练。如果系统动力学变化了策略需要重新训练。而MPC只需要更新模型参数就行。所以两种方法各有适用场景动力学已知且变化不大的用MPC动力学复杂或者需要快速响应的用Control as Inference。5.3 KL散度在控制问题中的信息几何解释KL散度不仅是变分推断的工具它在控制问题里还有信息几何的解释。KL(q || p)衡量的是用q近似p时损失的信息量。在控制问题里这个信息量对应的是控制代价。具体来说如果q是当前策略p是最优策略那么KL(q || p)就是当前策略相对于最优策略的“次优程度”。最小化KL散度就是在最小化次优程度。这个解释把控制问题和信息论联系起来了也解释了为什么Control as Inference的目标函数里会出现熵项——熵是信息量的度量。我第一次理解这个联系的时候感觉整个框架突然通透了。原来控制问题不只是优化问题还是信息问题。这个视角在后续做逆最优控制、模仿学习的时候特别有用因为那些问题本质上就是在推断人的意图而意图可以用概率分布表示。6. 实操中的关键细节与避坑指南6.1 变分分布参数化的选择变分分布q(u_t | x_t)的参数化方式直接影响优化效果。最常见的选择是高斯分布q(u_t | x_t) N(μ_θ(x_t), Σ_θ(x_t))其中μ和Σ用神经网络参数化。这个选择简单直接但有两个坑。第一个坑是Σ的参数化。如果直接输出Σ需要保证正定性。常见做法是输出Cholesky分解的下三角矩阵或者输出对角Σ。我试过输出完整Σ结果训练不稳定经常出现数值问题。后来改成对角Σ稳定性好了很多控制效果也没明显下降。第二个坑是μ的输出范围。如果动作有约束比如力矩限制直接输出μ可能会超出范围。常见做法是用tanh或者sigmoid把μ压缩到合法范围。我试过不加压缩结果策略输出的动作经常超限仿真直接崩了。加了压缩之后就没这个问题了。6.2 目标函数中各项的权重调节ELBO的目标函数包含三项动力学似然、负代价、策略熵。这三项的权重需要仔细调节。动力学似然项的权重通常设为1因为动力学是已知的。负代价项的权重需要根据代价的量级调整代价大的时候权重小一些代价小的时候权重大一些。策略熵的权重控制探索程度权重越大探索越多。我实测下来一个比较稳的配置是动力学似然权重1.0负代价权重1.0策略熵权重0.01到0.1之间。熵权重太小会导致策略过早收敛到局部最优太大则会导致策略过于随机控制效果差。这个参数需要根据具体问题调没有万能值。6.3 数值稳定性的处理技巧变分推断的数值稳定性是个大问题尤其是在线计算的时候。我踩过的坑包括log概率出现负无穷、KL散度计算溢出、梯度爆炸等等。解决办法有几个第一用log-sum-exp技巧计算对数概率避免直接计算概率导致下溢。第二用重参数化技巧采样把随机性从计算图里分离出来降低方差。第三梯度裁剪防止梯度爆炸。第四用双精度浮点数做关键计算虽然慢一点但稳定。这些技巧在标准变分推断教材里都有但在控制问题里需要根据具体场景调整。比如重参数化技巧在连续动作空间里很好用但在离散动作空间里需要用Gumbel-Softmax。这些细节在实现的时候一定要注意。7. 常见问题与排查技巧实录7.1 策略不收敛或收敛到局部最优这是最常见的问题。表现是训练损失震荡不下降或者策略输出的动作始终是同一个值。排查思路如下首先检查变分分布的参数化是否合理。如果Σ太小策略会退化成确定性策略失去探索能力。如果Σ太大策略会过于随机无法收敛。建议初始化Σ为单位矩阵然后根据训练情况调整。其次检查目标函数的权重。如果负代价权重太大策略会过早收敛到局部最优。如果熵权重太小探索不足。建议先用较大的熵权重训练然后逐渐减小。最后检查优化器的学习率。变分推断的目标函数通常比标准监督学习的目标函数更复杂需要更小的学习率。我一般用1e-4到1e-3之间的学习率配合Adam优化器。7.2 动力学似然项计算出现NaN这个问题通常是因为动力学模型的概率密度在某些状态下为零或者负值。排查思路检查动力学模型的输出范围确保概率密度始终为正。如果动力学是高斯分布检查均值和方差是否合理。方差太小会导致概率密度在某些点趋于无穷方差太大会导致概率密度趋于零。解决办法给方差加一个下限比如1e-6防止方差过小。同时对状态和动作做归一化防止数值过大导致计算溢出。我实测下来归一化是最有效的办法能把NaN问题减少90%以上。7.3 在线控制时计算延迟过大Control as Inference的在线控制需要前向传播策略网络如果网络太大计算延迟会很大。排查思路测量单次前向传播的时间如果超过控制周期的10%就需要优化。优化方法包括减小网络规模、用量化或者剪枝、用更高效的推理框架。我试过把策略网络从3层256维降到2层128维控制频率从50Hz提升到200Hz控制效果下降不到5%。所以网络规模不需要太大关键是训练充分。7.4 与MPC的对比选择困难很多人问什么时候用Control as Inference什么时候用MPC。我的经验是如果动力学模型精确已知、约束是硬约束、计算资源充足用MPC。如果动力学模型有不确定性、需要处理随机性、计算资源受限用Control as Inference。如果两者都行看哪个实现起来更简单。实际项目中我经常把两者结合用Control as Inference训练一个策略网络作为热启动然后用MPC做精细调整。这样既有Control as Inference的快速响应又有MPC的约束保证。问题类型表现排查方向解决办法策略不收敛损失震荡检查Σ参数化调整Σ初始化局部最优动作单一检查熵权重增大熵权重NaN损失变NaN检查概率密度加方差下限计算延迟控制频率低测量前向时间减小网络规模选择困难不知道用哪个分析问题特性结合使用8. 从理论到代码一个最小实现框架8.1 环境搭建与依赖选择实现Control as Inference需要几个核心组件深度学习框架PyTorch或JAX、优化器Adam、环境模拟器MuJoCo或自定义。我推荐PyTorch因为动态图调试方便而且变分推断的代码写起来直观。依赖安装很简单pip install torch numpy gym。如果需要MuJoCo环境还需要额外安装mujoco-py。我实测下来PyTorch 1.10以上版本都支持重参数化技巧不需要额外配置。8.2 核心模块的代码结构核心模块包括四个部分策略网络、动力学模型、代价函数、训练循环。策略网络输出高斯分布的均值和方差动力学模型是已知的或者学习的代价函数根据任务定义训练循环实现ELBO的优化。代码结构建议如下先定义策略网络类包含forward方法输出均值和方差然后定义ELBO计算函数输入策略网络输出和动力学模型输出ELBO值最后写训练循环采样轨迹、计算ELBO、反向传播、更新参数。8.3 训练循环的关键实现细节训练循环里最关键的是采样和重参数化。采样时用rsample()而不是sample()这样梯度可以通过采样过程传播。重参数化技巧的公式是u μ Σ^{1/2} ε其中ε ~ N(0, I)。这个技巧把随机性从计算图里分离出来降低了梯度的方差。另一个细节是轨迹的截断。如果轨迹太长计算图会很大反向传播会很慢。建议把轨迹截断到固定长度比如50步然后用bootstrapping估计剩余部分的代价。这个技巧在强化学习里很常见在Control as Inference里同样适用。我实测下来截断长度50步、batch size 64、学习率1e-3在倒立摆和双足机器人问题上都能收敛。训练时间大概几十分钟到几小时取决于问题复杂度。9. 扩展方向与个人实践体会Control as Inference的框架可以扩展到很多方向。比如逆最优控制给定观测到的轨迹推断代价函数的参数。这个方向在模仿学习里很有用因为人类演示的轨迹可以看成是最优控制的采样推断代价函数就等价于推断人的意图。另一个方向是分层控制把长时域任务分解成短时域子任务每个子任务用Control as Inference求解。这个方向在机器人操作里很有前景因为操作任务通常有多个阶段每个阶段的代价函数不一样。我个人在实际操作中的体会是Control as Inference最大的价值不是替代MPC或者随机最优控制而是提供了一个统一的视角来看待控制问题。当你把控制看成推断很多原本孤立的方法MPC、LQR、强化学习、模仿学习突然有了共同的语言。这个视角转换带来的洞察比具体的算法实现更有价值。最后分享一个小技巧如果你刚开始学Control as Inference不要一上来就推公式。先找一个简单的LQR问题用变分推断的方法解一遍然后和解析解对比。这样你能直观地看到变分推断在做什么然后再去推一般情况下的ELBO。这个顺序比反过来要容易得多。
返回列表