ARTICLE DETAIL

资讯详情

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

基于模型的强化学习:世界模型、MPC与工程落地实践

基于模型的强化学习:世界模型、MPC与工程落地实践 第15讲 基于模型的强化学习 | 伯克利 2026 春季深度强化学习课程世界模型、MPC 与工程排查深度强化学习真正难在落地这件事大多数人一开始没有意识到。你在 Gym、MuJoCo 等仿真环境中把算法调得再好一旦换成真实机械臂、无人机或产线设备一切都要重来。物理世界不允许无限制试错实验室里的几十万步交互放到真实设备上既耗费时间也可能造成设备损坏。基于模型的强化学习Model-Based Reinforcement LearningMBRL就是针对这个痛点重新被重视起来的技术路线。它不要求策略完全靠“试错”获得而是先通过部分交互数据学习一个环境动力学模型再在这个模型上做规划或训练策略。算法相当于先在“脑内模拟器”里反复练习再回到真实环境验证。伯克利 2026 春季深度强化学习课程第 15 讲的核心主题正是这一条路线。我的判断是MBRL 不是“强化学习的又一次包装”它对样本效率的提升是结构性的。它把主要成本从“交互样本”转移到了“模型偏差”模型一旦预测不准后续规划都会建立在错误假设上。这篇文章会先讲清楚为什么需要 MBRL、三类主流实现各有什么取舍再带你在一个双积分器小车上从零跑通“训练世界模型 随机规划 MPC”的最小示例最后梳理真实工程中一定会遇到的坑和排查思路。1. 为什么需要基于模型的强化学习样本效率与真实系统的鸿沟早期深度强化学习算法的突破集中在游戏和仿真环境比如 Atari、Go、Dota、MuJoCo。这类环境有一个共同特点想拿多少数据就能拿多少数据。一个 episode 失败就重新开始没有任何代价。可问题在于深度强化学习算法真正的主战场并不只是游戏而是机器人控制、工业优化、自动驾驶决策这类真实物理系统。真实物理系统的约束来自三个方面。第一是频次真实设备一个 episode 可能需要几分钟甚至更久算法要跑上万次交互才能有统计意义。第二是成本训练用的机械臂、无人车或产线设备本身昂贵采样一千次与采样一百万次完全是两个量级的预算。第三是安全探索意味着执行未知动作未知动作可能损坏设备、误伤人至少也会让系统进入危险状态。无模型深度强化学习算法在这些约束下很容易陷入“算法很漂亮现场不敢跑”的尴尬。在没有模型的情况下算法只能通过大量真实交互去估计“某个状态该做什么”或者“某个状态值多高”而在有模型的情况下真实交互只需完成两件事一是积累足够的数据来学一个粗糙的环境模型二是在模型预测不准的地方做修正。训练的大部分运算发生在参数化的“虚拟环境”里真实环境的调用次数可以大幅下降。这里要明确一个判断MBRL 是拿“计算资源换样本资源”。如果计算资源便宜、真实交互昂贵这个交换就非常值得反过来如果虚拟环境本身已经是免费的比如游戏仿真器那直接用无模型 RL 往往更省事没有必要先折腾一个可能学歪的模型。理解这一点比背下几个算法名字更重要。2. 核心概念世界模型、动力学预测与想象轨迹在强化学习里环境通常被建模成马尔可夫决策过程MDP写成四元组状态 S、动作 A、状态转移概率 P(s|s,a)、奖励函数 R(s,a)。无模型强化学习直接学策略 π(a|s) 或值函数 Q(s,a)它不要求显式知道 P而基于模型的强化学习补上的正是 P 这一环。所谓模型在深度学习语境下通常是一个参数化函数 f_θ(s,a) → s_next。输入当前状态和动作输出预测的下一步状态。这个函数通常是一个小型神经网络输入是 state 和 action 拼接输出是 state 维度的向量Loss 用 MSE。只要这个函数足够准就可以用它替代真实环境做后续所有“实验”。深度学习让这件事发生了质的改变。传统控制方法获取模型靠第一性原理推导写动力学方程、标定惯性参数过程繁重而 MBRL 里的 world model 是直接从数据拟合出来的。即使系统非线性、有噪声、有死区只要数据覆盖足够神经网络也能逼近一个可用的动力学模型。这就是“world model”世界模型这个名字的由来它不是世界本身而是智能体对世界变化规则的内部表征。一个容易误解的地方是有人把 MBRL 理解成“用一个仿真环境训练策略”。世界模型和传统仿真器区别很大。传统仿真器是显式物理公式建模成本高但鲁棒学习的模型是黑盒近似训练成本低但可能过拟合到训练数据。MBRL 真正要做的是在这个“可微、可采样、可反复试错”的黑盒模拟器里完成大量虚拟互动所以在概念上可以把它当成一个廉价的模拟器。也可以类比成驾驶训练。无模型方法是直接上车油门、刹车、方向盘全靠手脚试错教练在一旁的代价极高有模型方法是先上一台驾驶模拟器在模拟器里把常见路况都跑熟再带着经验上车做少量修正。你要付出的不是真实事故成本而是模拟器里的计算成本。3. 三条技术路线规划、Dyna 风格与模型微调基于模型的强化学习并不是单一算法而是一族方法。公开方法论里一般会分成三条路线课程里围绕这三条分支展开时核心差异在于“学好的模型用来做什么”。3.1 规划路线MPC / Random Shooting第一种路线是“学模型不学策略”。在每次决策前用模型做多步模拟搜索若干候选动作序列选出收益最大的序列然后执行序列中的第一步等下一个控制周期再重新搜索。这就是模型预测控制Model Predictive ControlMPC的思想随机采样候选序列的做法叫 Random Shooting改进版是 CEM。这类方法样本效率极高因为一个动力学模型就能支撑整个控制流程不需要单独训练策略网络。但代价是每个控制周期都要做在线优化候选序列越多、规划视窗越长算力开销就越大。它更适合控制窗口短、状态维度中等的问题。3.2 Dyna 风格模型辅助策略学习第二种路线是把模型当“经验生成器”。智能体先在真实环境收集少量数据学一个模型然后用模型生成大量的想象轨迹把这些想象数据喂给无模型强化学习算法。Dyna 框架是这类思想的鼻祖现代版本包括 MBPO、Dreamer 系列等。这种做法的优势很明显策略网络和值网络可以继续用成熟的 PPO、SAC 实现模型只是给它们“凭空增加经验”高维连续动作也能处理。代价同样来自模型如果模型在某个区域预测不准策略会在想象轨迹里发现一条虚拟的“捷径”这在真实环境里并不存在最终表现就会崩盘。3.3 模型微调先想象再回归现实第三种路线是两阶段训练。先在学习的模型里把策略训到足够好再把策略放到真实环境中做少量 fine-tune。这实际上是把模型辅助策略学习与现实数据修正结合起来也是 sim-to-real 研究中常见的范式。课程讲这一类思路时强调的是“模型给你一个先验真实环境负责纠偏”。三条路线的差异可以用表格概括路线核心机制优点主要风险适合场景规划 / MPC用模型在线搜索动作序列样本效率高、无需策略网络在线计算量大、长期任务困难低维连续控制、机械臂轨迹Dyna 风格模型生成想象数据喂给策略能与主流 RL 算法结合模型误差被策略放大中高维连续动作、策略训练模型微调先在模型里训练策略再真实微调兼顾长时程策略与真实反馈两阶段流程复杂、域迁移仿真到真实迁移、机器人任务需要说明的是这张表是方法论层面的通用划分不是课件原文的逐行总结。实际算法往往会混合使用比如先在线学模型再离线训练策略再用 MPC 做安全备份。4. 模型误差为什么是 MBRL 的“阿喀琉斯之踵”只要学的是模型就绕不开误差。误差来源有几个数据量有限、神经网络函数空间有限、真实环境存在随机噪声。单个状态的预测误差可能很小但强化学习本质上是长时间尺度问题误差会一路累积。一个经典问题叫组合误差compounding error。想象一条 100 步的想象轨迹第一步预测有一点偏差第二步就在偏离后的状态上继续预测偏差会被慢慢放大。轨迹越长累计误差越大。这也是为什么 MPC 常常只用 10 到 20 步的有限视窗而不是把未来全部安排完。更隐蔽的问题是分布漂移。训练数据来自随机探索策略模型的输入分布是随机策略能到达的状态训练完成之后真正用来做规划或策略学习的却是寻优后的策略。新策略倾向于访问高奖励区域而这个区域未必在训练数据里有足够多的样本。模型在陌生区域做外推预测误差往往比训练集内更大。更麻烦的是策略很可能“主动利用”模型错误。模型如果低估了某个区域的风险策略会把这里当成宝地反复光顾。PETS 这类方法在设计时就引入模型集成与不确定性估计和这个现象有直接关系——它们不只是为了让预测更准还希望策略在面对不确定区域时保持保守。对于工程落地这意味着一个很反直觉的检查顺序模型 loss 低不等于控制器表现好模型 loss 高也许控制器还能用。真正可靠的做法是在离线评估阶段把模型预测轨迹和真实轨迹放在一起对比一旦发现在规划阶段频繁访问的区域内单步误差明显变大优先考虑增加该区域的训练数据而不是继续调大策略网络的容量。5. 实验设计与环境准备从“双积分器小车”开始理论概念讲完下面用一个最小示例跑通整个流程。我选择的环境不是 MuJoCo也不是 Gym而是一个自己定义的双积分器小车。状态是二维位置 x 和速度 v动作是一维推力 a。物理规律可以直接写出来x x v·dt v v a·dt这个系统足够简单能精确写出真实动力学因此可以清楚地区分“模型学得不好”和“控制器设计不合理”。它也足够有代表性如果把车辆、无人机、机械臂的简化模型建模成二阶积分器使用的核心思路是一样的。在动手之前先准备环境。本文所有代码只需要 Python 3.10、PyTorch 和 NumPy。推荐用虚拟环境避免污染全局环境。python -m venv mbrl_env source mbrl_env/bin/activate pip install --upgrade pip pip install torch numpy如果机器有 GPUPyTorch 安装命令可能需要改成对应 CUDA 版本没有 GPU 也没关系这个示例 CPU 就能跑。6. 完整示例训练世界模型并用 MPC 控制小车完整代码是一个单文件脚本 mbrl_demo.py。为了方便阅读我按“环境与数据、模型训练、MPC 规划、主流程”四段拆开讲把四段按顺序拼在同一个文件里就能直接运行。6.1 环境定义与模拟数据收集先定义物理真值函数再随机采样一批“状态-动作-下一状态”数据。这段代码模拟的是真实环境智能体不知道这个函数只能通过采样样本去学习。import numpy as np import torch import torch.nn as nn import torch.optim as optim # 真实物理系统位置 x速度 v推力 a def true_dynamics(state, action, dt0.1): x, v state a action[0] v_next v a * dt x_next x v * dt return np.array([x_next, v_next], dtypenp.float32) def reward_fn(state, actionNone): x, v state reward -(x ** 2 0.1 * v ** 2) if action is not None: reward - 0.01 * action[0] ** 2 return reward def collect_dataset(n800): dataset [] rng np.random.default_rng(0) for _ in range(n): s rng.uniform(-2, 2, size(2,)).astype(np.float32) a rng.uniform(-2, 2, size(1,)).astype(np.float32) s_next true_dynamics(s, a) dataset.append((s, a, s_next)) return dataset这段代码里的 true_dynamics 是我们的“物理事实”在真实项目里对应设备的真实响应。数据收集用均匀随机采样作为探索策略目的是让数据集尽量覆盖可能的状态范围。数据量不需要很大这也是 MBRL 的核心吸引力之一。6.2 参数化模型与训练接下来定义神经网络世界模型并用离线数据训练。输入是“当前状态 动作”输出是“预测的下一步状态”损失函数用 MSE。class DynamicsModel(nn.Module): def __init__(self, state_dim2, action_dim1, hidden_dim64): super().__init__() self.net nn.Sequential( nn.Linear(state_dim action_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, state_dim), ) def forward(self, state, action): return self.net(torch.cat([state, action], dim-1)) def train_dynamics(model, dataset, epochs60, batch_size64): optimizer optim.Adam(model.parameters(), lr1e-3) loss_fn nn.MSELoss() for epoch in range(epochs): shuffled np.random.permutation(len(dataset)) total_loss 0.0 for i in range(0, len(dataset), batch_size): batch_idx shuffled[i:i batch_size] s_batch torch.tensor([dataset[j][0] for j in batch_idx], dtypetorch.float32) a_batch torch.tensor([dataset[j][1] for j in batch_idx], dtypetorch.float32) target_batch torch.tensor([dataset[j][2] for j in batch_idx], dtypetorch.float32) optimizer.zero_grad() pred model(s_batch, a_batch) loss loss_fn(pred, target_batch) loss.backward() optimizer.step() total_loss loss.item() * len(batch_idx) if epoch % 20 0 or epoch epochs - 1: print(fepoch {epoch:3d} | avg loss {total_loss / len(dataset):.6f})训练完成后模型就学会了“给一个状态和动作预测下一状态”的能力。这里使用的是最简单的多层感知机。实际项目中还可以考虑预测状态增量也就是让模型输出 Δs然后用 s Δs 作为下一状态数值上通常更稳定。这是后续值得尝试的改进点。6.3 随机规划控制器模型学完之后进入“规划”环节。Random Shooting 的做法是在当前状态下随机采样很多条动作序列用世界模型把每一条序列推演一遍计算累计奖励选出奖励最高的序列只执行第一步。def plan_action(model, state, horizon10, candidates256, action_scale2.0): state_t torch.tensor(state, dtypetorch.float32) best_return -float(inf) best_first_action np.zeros(1, dtypenp.float32) for _ in range(candidates): actions torch.randn(horizon, 1) * action_scale sim_state state_t.clone() total_return 0.0 with torch.no_grad(): for t in range(horizon): total_return reward_fn(sim_state.numpy(), actions[t].numpy()) pred_state model(sim_state.unsqueeze(0), actions[t].unsqueeze(0)) sim_state pred_state[0] if total_return best_return: best_return total_return best_first_action actions[0].numpy().copy() return best_first_action这里 candidates 控制搜索密度。候选数量越大越有机会找到好的动作序列但单步计算时间也会线性上升。horizon 是规划视窗这个值要合理。视窗太短只能看到局部收益视窗太长又会放大模型累积误差。6.4 主流程与闭环评估最后把整个流程串起来先收集数据、训练模型再用训练好的模型做 MPC 控制。注意评估时的状态更新用的是 true_dynamics而不是模型预测这样才能真实评价控制效果。def run_episode(model, init_state, steps150, horizon10, candidates256): state np.array(init_state, dtypenp.float32) total_return 0.0 trajectory [state.copy()] for _ in range(steps): action plan_action(model, state, horizon, candidates) total_return reward_fn(state, action) state true_dynamics(state, action) trajectory.append(state.copy()) return total_return, np.array(trajectory) if __name__ __main__: np.random.seed(0) torch.manual_seed(0) dataset collect_dataset(800) model DynamicsModel() train_dynamics(model, dataset, epochs60) torch.save(model.state_dict(), dynamics_model.pt) ret, traj run_episode(model, init_state[0.8, 0.0]) print(fepisode return: {ret:.3f}) print(ffinal state: x{traj[-1][0]:.3f}, v{traj[-1][1]:.3f})到这里一个完整的 MBRL 最小闭环就完成了。代码里没有用到任何强化学习算法库核心逻辑不到一百行但已经覆盖了“学模型 用模型做规划”的完整路径。7. 运行结果、效果验证与常见问题在主目录运行python mbrl_demo.py可以看到类似下面的输出。数值与随机种子、PyTorch 版本有关不需要追求完全一致重点是观察趋势。epoch 0 | avg loss 0.041627 epoch 20 | avg loss 0.000974 epoch 40 | avg loss 0.000491 epoch 59 | avg loss 0.000376 episode return: -3.124 final state: x0.024, v-0.015判断模型学到东西有三个指标。一是训练 loss 是否下降到足够低二是 final state 是否靠近原点三是把轨迹打印出来后小车应该先朝原点减速再微调修正。如果 loss 已经很低但闭环控制效果很差问题通常出在模型训练数据覆盖不充分而不是网络结构不够深。常见问题排查可以按下面这张表快速定位问题现象可能原因排查方式解决方案训练 loss 不下降学习率过高或数据太少打印 loss 曲线、检查状态采样范围调低学习率扩大状态采样范围loss 低但 MPC 控制发散模型在目标区域误差大对比模型预测轨迹与真实轨迹增加该区域训练数据考虑模型集成控制输出抖动每个周期重新规划但没有考虑动作变化代价观察动作序列是否高频切换增大 candidates或加入动作代价项训练数据量小导致过拟合模型把噪声也学进去了检查验证集误差统计样本重复度增大数据量适当减小隐藏层宽度输出一直不收敛动作范围过大始终在边界来回打印动作与状态轨迹减小 action_scale或加大动作惩罚定位这类问题有一个通用思路不要只看总体 loss要看“在什么状态上预测偏差最大”。可以把模型预测的一条轨迹和真实系统跑出的轨迹画在同一张图上偏差放大的位置通常就是数据覆盖不足的区域。8. 最佳实践与工程建议落到真实项目时有几个原则比调参更重要。8.1 数据覆盖优先于网络结构MBRL 最容易犯的错误是一开始就堆网络宽度和深度。对动力学模型来说决定上限的往往是训练数据覆盖范围。随机探索收集的数据往往只覆盖小部分状态空间模型在分布外几乎必然外推错误。更稳妥的顺序是先用随机策略把可达区域大致覆盖再在模型误差大的局部区域补充采样。8.2 模型集成与不确定性估计从 PETS 开始模型集成几乎成为 MBRL 的标配做法。多个模型分别初始化和训练规划时预测多个下一状态。均值用来做规划方差用来反映不确定性方差越大说明该区域数据越少控制就应该越保守。现实中很多策略崩盘不是模型均值预测错得太离谱而是智能体在不确定区域过于自信。8.3 在线校验不可省略模型是离线学出来的但真实环境和离线数据之间存在不可忽略的偏差。每运行一段距离或每完成一批任务应当用最新真实数据重新评估模型误差。如果误差超过阈值就需要重新采集数据并增量训练。这个“离线训练、在线校验、少量补采”的循环比一次性把模型训到完美再部署要可靠得多。8.4 什么时候不必用 MBRL如果你的“环境”本身就是低成本仿真器数据可以无限生成那无模型 RL 通常更简单也没有模型误差这个负担。如果任务要求非常精确的长期规划且当前模型完全无法容忍误差纯 MPC 方案可能不适用。MBRL 真正有优势的场景是真实交互成本高、但计算资源相对充裕的地方。8.5 真实设备部署的安全边界学习模型天然有误差所以在真实设备上应用时必须遵守一些基本安全原则先在测试环境验证设置保护性回退保持最小控制权限对高风险动作加人工确认。不要用一个未经充分验证的模型直接去控制真实设备。安全策略和模型性能同样重要尤其是在机器人、工业设备这种物理后果严重的场景。9. 总结与后续学习方向这一讲的核心可以概括成一句话真实交互昂贵那就先让智能体学一个世界模型在“想象”中完成大部分试错。课程里涉及的 model-based planning、Dyna、模型微调三条路线本质都在回答同一个问题模型学好之后怎么把它用得更聪明。下一步动手建议先把双积分器示例跑通然后把采样范围从 [-2,2] 换成 [-5,5]观察模型误差和控制效果如何变化再把 horizon 逐步加长你会直观地体会到组合误差为什么可怕。如果想把这条路走得更深值得关注的方向包括 TD-MPC 系列、Dreamer 系列、MBPO、PETS以及 MuZero 中蕴含的“搜索 模型”思想。课程后续如果要继续往仿真到真实迁移的方向深入记得把安全约束和在线校验一起纳入实验设计那才是接近实际部署的学习路径。
返回列表