9.3 基于模型的强化学习
本节导读
核心内容
- 理解 Model-Based RL 和 Model-Free RL 的根本区别:为什么"先学环境模型再训策略"能把样本效率提升 10-100 倍。
- 掌握 Dyna 框架:如何把环境模型当成"额外数据生成器",每次真实交互后做 N 次模拟更新。
- 理解模型误差累积问题:为什么长 rollout 会让预测误差爆炸,Lipschitz 常数怎么刻画这个问题。
- 了解 PETS 如何用概率集成(probabilistic ensembles)量化两种模型不确定性,配合 CEM 规划做鲁棒控制。
- 掌握 MBPO 的短 horizon rollout 思想:为什么只做 5 步模型预测就重置到真实状态,能避免误差累积同时大幅提升样本效率。
上一节 9.2 我们解决了连续控制 model-free 算法的稳定性问题——TD3 用三个工程补丁、SAC 用最大熵重构目标函数,让 DDPG 终于在 MuJoCo 上稳定可用,训练百万步能给出相当不错的策略。
但是,让我们停下来想一下。百万步在仿真器(MuJoCo)里可能只要几小时,但如果是真实机器人呢?机械臂的电机有磨损、电池续航有限、真实环境中碰撞可能损坏设备——每次真实环境采样都是有成本的。百万步对真实机器人来说,可能意味着几个星期甚至几个月的不间断运行,这在实践中根本不可承受。
这就引出了 Model-Based RL 的核心问题:能不能让智能体在和真实环境交互很少的情况下,也能学到好策略? Model-Based RL 给出的答案是:学一个环境模型——也就是学一个"如果我在状态 做动作 ,下一状态会是什么、奖励会是多少"的预测器——然后让策略主要在这个模型上训练,把和真实环境的交互次数从百万步降到万步级别。
这一节我们就来拆解 model-based RL 的三条主流路线:从最简单的数据增强(Dyna),到概率集成 + 轨迹采样(PETS),再到短 horizon rollout(MBPO)。
Model-Based 与 Model-Free 的根本区别
前面所有算法(DDPG/TD3/SAC)都是 model-free 的。你可能会问:"model-free 是什么意思?free 的是什么?" Model-free 不是说"没有模型",而是说智能体不试图去理解、建模环境的运作规律。它就像一个强化学习者:你给我状态、我输出动作、你给我奖励,我只根据奖励信号调整策略——至于环境为什么会给出这个奖励、做了这个动作世界会怎么变,我完全不关心。
Model-Based RL 反其道而行之。它说:在学策略之前,或者在学策略的同时,我先学一个环境模型:
让我们把这两个符号拆开看:
- :这是动力学模型。给定当前状态 和动作 ,预测下一状态 的概率分布。帽子 表示这是我们学到的近似模型,不是真实环境 。
- :这是奖励模型。给定状态 和动作 ,预测即时奖励。
有了这两个模型,智能体就可以"在脑子里想象":如果我现在做这个动作,会发生什么?会得到多少奖励?然后基于这些想象出来的轨迹来做规划或者训练策略。
为什么用模型?
最核心的动机就是样本效率。
让我们用具体数字感受一下差距。Model-free 算法(比如 SAC)在 MuJoCo 上通常需要 100 万步(1M steps)才能收敛到好策略。Model-based 算法呢?MBPO 只需要 10-100 千步(10K-100K steps)就能达到同等性能——样本效率提升了 10-100 倍。
这不是一个小数字。如果每一步真实交互需要 1 秒(真实机器人运动需要时间),100 万步就是约 11.5 天不间断运行;而 10 万步只需要约 1 天。对于更昂贵的场景——比如自动驾驶、工业机器人、化学反应控制——这个差距可能就是"能用"和"不能用"的区别。
为什么 model-based 能省这么多真实样本?因为一旦模型学好了,你可以在模型里无限次"想象"采样,而这些想象出来的采样几乎是零成本的。就像人学下棋:你不需要真的把每盘棋都下完,你可以在脑子里推演"如果我走这一步,对方会怎么走,然后我再怎么走"——这种"脑子里的推演"就是 model-based planning。
但是——你可能已经想到一个问题——模型如果学错了怎么办?在错误的模型上训练出来的策略,到真实环境里会不会也错?这就是 model-based RL 的核心矛盾:模型偏差(model bias)。后面我们会看到,Dyna、PETS、MBPO 这三个算法,本质上是在用三种不同的方式应对这个矛盾。
三大范式概览
在深入细节之前,我们先把 model-based RL 的三大主流范式列出来,给你一个全景:
| 范式 | 核心思想 | 代表算法 | 适用场景 |
|---|---|---|---|
| Dyna | 模型作为数据增强 | Dyna-Q | 离散动作,快速训练 |
| PETS | 概率集成 + 轨迹采样 | PETS | 高精度控制,模型不确定性重要 |
| MBPO | 短 horizon rollout | MBPO | 通用连续控制 |
让我们从最简单的 Dyna 开始。
模型作为数据增强
Sutton 在 1990 年提出的 Dyna 框架,是 model-based RL 最经典、最朴素的思路。它的想法简单到让人惊讶:模型就是一个额外的数据生成器。每次你和真实环境交互一次,拿到一条真实经验 ,你就用这条经验同时做两件事:
- 像往常一样用它做一次 model-free 更新(比如 Q-learning);
- 用它训练你的环境模型;
- 然后——关键来了——从模型里"想象"出 N 条假经验,用这些假经验再做 N 次 model-free 更新。
让我们看代码理解这个流程:
for step in range(total_steps):
# 1. 真实交互
a = policy.select(s)
s_prime, r = env.step(a)
replay_buffer.add(s, a, r, s_prime)
# 2. 用真实数据更新 model-free 算法(如 Q-Learning)
q_learning_update(replay_buffer.sample())
# 3. 用真实数据训练环境模型
model.train(s, a, r, s_prime)
# 4. 用模型生成"假"数据,再做 N 次 Q-Learning 更新
for _ in range(N): # N = 10-100
s_sim, a_sim = replay_buffer.sample_state_action()
s_sim_next, r_sim = model.predict(s_sim, a_sim)
q_learning_update(s_sim, a_sim, r_sim, s_sim_next)看明白了吗?每次真实交互后,我们额外做 N 次"模拟"的 Q-learning 更新——这些更新用的不是真实环境,而是模型预测出来的数据。如果 N=10,那相当于每做 1 次真实交互,我们就做了 11 次 Q-learning 更新;理论上,样本效率就能提升约 N 倍。
这想法太美了,对吧?但等等——这里有个问题。
Dyna 的关键限制
让我们停下来想一下:上面的代码用的是确定性模型——直接预测下一状态 。但即使你用概率模型,有一个根本问题是绕不开的:在连续物理环境(比如 MuJoCo)里,如果你反复把模型的预测结果作为下一步的输入,误差会像滚雪球一样越积越大。
为什么会这样?我们来做个数学分析。假设每一步模型预测的误差不超过 ——也就是预测状态和真实状态之间的距离 。再假设真实环境的动力学函数关于状态是 Lipschitz 连续的,Lipschitz 常数为 。
你可能会问:"Lipschitz 常数是什么?" 简单说,Lipschitz 常数 衡量的是"状态变一点点,下一状态会变多少"。如果 ,那状态差多少,下一状态就差多少;如果 ,误差会放大;如果 ,误差会自动缩小。对于像 MuJoCo 这样的物理环境, 通常接近 1 甚至略大于 1。
那么,在同一动作序列下,我们递推一下每一步的状态误差 :
我们来验证一下这个递推式对不对:第 步我们已经有误差 ,经过真实动力学,这个误差最多被放大 倍变成 ;然后我们自己的模型又额外引入最多 的单步预测误差——所以第 步的总误差上界就是两者相加。
那 步之后误差会累积到多大?我们可以把这个递推式展开:
让我们用具体数字算一下,这样你就有直觉了:
- 情况 1:(误差自动收缩)。等比数列求和,当 很大时,和收敛到 。误差不会无限增长,最终被控制在 以内。这是最理想的情况。
- 情况 2:(误差不放大也不缩小)。每一步加一个 , 步后误差就是 ——线性增长。rollout 100 步,误差就是单步误差的 100 倍。
- 情况 3:(误差放大)。等比数列增长, 步时,和是 。单步误差如果是 0.01,50 步后误差就超过 11——这对于状态维度通常在几十量级的机器人控制来说,预测已经完全不准了。
这就是为什么简单的 Dyna 在像网格世界这样的简单离散环境里工作得很好,但在复杂连续控制环境里会出问题:rollout 越长,模型误差累积越严重,到后面模型预测出来的轨迹和真实轨迹已经完全是两回事了。用这样的假数据训练策略,策略很可能被带偏。
那怎么办呢?后续的工作(PETS、MBPO)都在解决同一个核心问题:"如何量化并应对模型误差?"
- PETS 的思路:我知道模型不确定,那我就显式建模这种不确定性。用概率集成(多个模型一起预测)来表达"我对这个预测有多确信",规划的时候考虑这种不确定性,让策略对"模型可能错"保持鲁棒。
- MBPO 的思路:既然长 rollout 误差爆炸,那我就不做长 rollout。只做很短的(比如 5 步)模型预测,然后立刻重置到真实状态,不让误差有机会累积太多。
我们先看 PETS。
概率集成轨迹采样
Probabilistic Ensembles with Trajectory Sampling(Chua et al. 2018),简称 PETS,有一个关键观察:模型的不确定性其实分两种,它们来源不同,应对方式也不同。
你可能会问:"模型不就是不准吗?不确定性还分种类?" 是的,分两种,而且这个区分非常重要:
- 认知不确定性(epistemic uncertainty):这种不确定性来自数据不足。因为你没见过足够多类似 的情况,模型本身不知道会发生什么——就像一个新手司机第一次在雪天开车,他不确定会发生什么,不是因为下雪本身是随机的,而是因为他没经历过。这种不确定性可以通过更多数据消除。
- 偶然不确定性(aleatoric uncertainty):这种不确定性来自环境本身的随机性。即使你有无限多的数据,你也没法完美预测——就像掷骰子,不管你观察多少次,下一次掷出什么还是随机的。这种不确定性无法被更多数据消除,你只能建模它。
PETS 用两种不同的机制分别处理这两种不确定性:
- 用集成(ensemble)——也就是训练 个独立的模型——来表达认知不确定性。如果这 个模型的预测都一致,说明模型在这个区域很确定;如果它们预测差异很大,说明这里模型没见过、不确定。
- 用概率输出 ——也就是不是预测一个确定的 ,而是预测一个高斯分布的均值和方差——来表达偶然不确定性。方差大的地方,说明环境本身就随机。
模型架构
PETS 的模型是 个概率神经网络的集成,通常 就够了。我们来看代码结构:
class PEModel:
def __init__(self, n_models=5):
self.models = [ProbabilisticNN() for _ in range(n_models)]
def predict(self, s, a):
# 每个模型输出 (mean, var)
means, vars = [], []
for m in self.models:
mu, sigma = m(s, a)
means.append(mu); vars.append(sigma)
return means, vars # 集成散度 = epistemic uncertainty每个 ProbabilisticNN 不直接输出下一状态,而是输出一个高斯分布的均值 和标准差 ——也就是假设 。
训练的时候,每个模型独立初始化、独立训练,用的都是真实交互数据,但可以用不同的 mini-batch 顺序、不同的初始化,让它们最终学到的模型略有不同。
Trajectory Sampling 策略
有了概率集成模型,怎么用它做规划呢?PETS 用 MPC(模型预测控制) 思想:每一步都重新规划未来 H 步的动作,但只执行第一步,然后走到下一状态再重新规划。这种"滚动优化"的思想能让策略不断根据最新的真实状态修正规划,不容易被模型误差带太远。
具体的规划算法用的是 CEM(Cross-Entropy Method,交叉熵方法)——这是一种简单但强大的采样式优化算法,特别适合连续动作空间的规划。我们来看代码:
def cem_planning(model, s, horizon=10, n_samples=500, n_iters=5):
# 初始化动作分布
action_mean = zeros(horizon, action_dim)
action_var = ones(horizon, action_dim)
for it in range(n_iters):
# 1. 采样 N 条动作序列
action_seqs = sample_normal(action_mean, action_var, n_samples)
# 2. 用模型 rollout,每条序列用随机一个集成模型
rewards = []
for seq in action_seqs:
model_id = random_int(0, K)
s_pred = s
total_r = 0
for a in seq:
s_pred, r = model[model_id].predict(s_pred, a)
total_r += r
rewards.append(total_r)
# 3. 选 top 20% 的序列,更新分布
elite = top_k_indices(rewards, k=0.2 * n_samples)
action_mean = action_seqs[elite].mean(0)
action_var = action_seqs[elite].var(0)
return action_mean[0] # 只执行第一步(MPC 思想)这里有一个关键细节:第 2 步做模型 rollout 的时候,每条轨迹从头至尾用同一个随机选出来的集成模型,而不是每一步都随机换模型。这叫做 TS1(Trajectory Sampling with 1 model),为什么要这样做?因为如果每一步都随机换模型,你其实是在"平均模型"的动力学上做规划——但真实世界只有一个,不是五个模型的平均;固定用一个模型 rollout 整条轨迹,能更好地捕捉多模态的未来,让规划对模型不确定性更鲁棒。
CEM 的工作原理也很直观:
- 一开始我们对"什么是好的动作序列"一无所知,所以用一个很宽的高斯分布(方差 1)来采样;
- 采样出 500 条候选序列,用模型 rollout 看看哪条序列的预期总奖励高;
- 选出奖励最高的前 20%(精英序列),用它们的均值和方差作为下一轮迭代的采样分布;
- 重复 5 次,分布会逐渐收敛到"看起来最好"的动作序列区域。
这比梯度优化简单得多,而且不容易陷入局部最优——因为每次都有大量采样的探索。
PETS 的实验结果
PETS 在 MuJoCo 上首次让 model-based 算法达到了和 model-free 算法(比如 SAC)同等水平的性能,但采样步数减少了 10-50 倍。这是一个里程碑式的结果——第一次证明了 model-based 方法在连续控制基准上不是"玩具",确实能用。
但是——你应该能想到——PETS 也有代价:规划时计算量非常大。每选一个动作,要做 5 轮 CEM 迭代,每轮采样 500 条序列,每条序列 rollout 10 步——这就是 5 × 500 × 10 = 25,000 次模型预测,只为了选一个动作。如果是真实机器人控制,每一步控制可能需要 20ms,这样的规划开销在部署时是很大的负担。
有没有办法既能享受到 model-based 的样本效率,又不用像 PETS 那样每一步都做昂贵的规划?这就是 MBPO 要解决的问题。
模型策略迭代
Model-Based Policy Optimization(Janner et al. 2019),简称 MBPO,它的核心创新说穿了其实就是一句话:既然长 rollout 误差累积爆炸,那我就只做很短的模型 rollout。
等等,这听起来是不是太简单了?Dyna 也可以做短 rollout 啊,MBPO 的贡献在哪?关键在于 MBPO 发现了一个很反直觉的结论:rollout 长度不需要很长——只要 1-5 步就够了——就能获得几乎所有 model-based 带来的样本效率提升,同时把模型误差的影响控制在可接受范围内。
短 horizon rollout
让我们回到前面那个误差累积的公式。如果 (非常接近 1,略有放大),单步误差 :
- rollout 1 步:误差
- rollout 5 步:误差约 (还很小)
- rollout 20 步:误差约 (开始变大了)
- rollout 100 步:误差约 (状态本身可能也就这个量级,预测已经不准了)
看明白了吗?前几步误差增长其实很慢——只有当 rollout 长到一定程度后,误差才开始指数爆炸。MBPO 的策略就是:我只吃前几步误差很小的"安全区域",在误差还没来得及累积太多的时候,就"踩刹车"——重置到真实状态,再开始下一段模型 rollout。
我们来看代码理解这个流程:
# 短 horizon rollout 与 模型误差可控
for rollout_step in range(K_short): # K_short = 5
a = policy(s_sim)
s_sim, r = model.predict(s_sim, a)
replay_buffer.add(s_sim, a, r, s_sim)
# 关键:每 5 步必须"重置"到真实状态
if rollout_step % K_short == 0:
s_sim = real_env.state注意这里的逻辑:不是从初始状态一直 rollout 到底,而是从真实数据中的某个状态(从 replay buffer 里采样出来的、智能体实际到过的状态)开始,只 rollout 5 步,然后就停下来,再换一个真实状态继续。这样每段模型轨迹的起点都是"准确的"(来自真实环境),最多只有 5 步的误差累积——误差被严格控制在很小的范围内。
MBPO 训练流程
把这些整合起来,MBPO 的训练流程其实是一个三步循环,我们用流程图看清楚:
┌────────────────────────────────────────────┐
│ 1. 用真实数据训练模型 M │
│ M.predict(s, a) → s', r │
├────────────────────────────────────────────┤
│ 2. 用 M 生成短 rollout(5 步) │
│ 起点:真实数据中的某个 s │
│ 每步:a = policy(s), s' = M(s, a) │
│ 结果:(s, a, r, s') × 5 加入 replay │
├────────────────────────────────────────────┤
│ 3. 在 replay buffer(混合真假)上 SAC 更新 │
└────────────────────────────────────────────┘这个流程非常巧妙。你看,它没有像 PETS 那样做 MPC 规划——相反,它还是像 Dyna 一样,用模型生成数据,然后用一个标准的 model-free 算法(SAC)在 replay buffer 上训练。不同的是:
- 模型生成的数据不是 1 步,而是 5 步短 rollout;
- 每段 rollout 的起点都来自真实数据;
- 底层用 SAC 这样稳定的 off-policy 算法做策略优化。
更妙的是,MBPO 里模型 rollout 长度 不是固定的——它可以随着训练进行动态调整。刚开始模型很不准, 设成 1(只能做 1 步预测);随着模型越来越准, 可以慢慢增加到 5 甚至更长。这就像人学东西:一开始对世界规律没把握,只能推演一步;后来理解深了,可以推演好几步。
MBPO 的实验结果非常惊人:在 MuJoCo 上达到了和 model-free SAC 同等甚至更好的性能,但采样步数减少了 10-100 倍。而且因为它最终训练的是一个 SAC 策略,部署时不需要像 PETS 那样每步做昂贵的 CEM 规划——直接跑策略网络就行,和 model-free 部署成本一样。
Model-Based RL 三大算法对比
我们把 Dyna、PETS、MBPO 这三个里程碑式的算法放在一起对比,方便你在实战中选择:
| 算法 | 模型类型 | 规划方式 | 样本效率 | 计算成本 |
|---|---|---|---|---|
| Dyna | 确定性 | 1 步假数据 | ~10× | 低 |
| PETS | 概率集成 | CEM MPC | ~50× | 高 |
| MBPO | 确定性 | 短 rollout | ~100× | 中 |
实战选择建议:
- 快速实验、验证想法:选 Dyna。实现简单,行为稳定,不需要处理概率模型和规划,作为 baseline 很好。
- 高精度控制、机器人操作:选 PETS。概率集成能很好地处理模型不确定性,MPC 闭环控制非常鲁棒,适合安全关键、精度要求高的场景——但要接受规划计算成本高。
- 通用连续控制 benchmark:选 MBPO。样本效率最高,部署和 model-free 一样快,MuJoCo 全套环境都能 work,是目前 model-based 连续控制的强基线。
加餐:为什么不用长 rollout?MBPO 的理论分析
Janner 等人在论文里给出了一个关于模型偏差如何影响策略性能的理论界。大致结论是:如果模型预测误差在某个 TV 距离(total variation distance)度量下是 ,那么在模型里学到的策略 和在真实环境里的最优策略 之间的性能差距满足:
注意分母的 项——当 接近 1(我们通常用 0.99),分母很小,这意味着即使模型误差 很小,性能差距也可能被放大很多倍。
但是——如果我们只用短 rollout,相当于把有效 horizon 缩短了,这等价于用了一个更小的有效 ,分母就不会那么小,模型误差的影响也就被控制住了。这就是 MBPO 短 rollout 的理论依据。
本节总结
Model-Based RL 通过学习环境模型 来大幅提升样本效率,我们这一节讲了三代算法的演进:
- Dyna 把模型作为"额外数据生成器",每次真实交互后用模型生成 N 条假数据做额外更新,样本效率提升约 N 倍——但在连续控制中会遇到误差累积问题,长 rollout 可能让预测完全失效。
- PETS 正视模型不确定性:用概率集成分别建模认知不确定性(集成散度)和偶然不确定性(概率输出方差),配合 CEM 采样做 MPC 规划,首次让 model-based 在 MuJoCo 上达到 model-free 同等性能——代价是每步规划计算昂贵。
- MBPO 用短 horizon rollout(通常 5 步)巧妙绕开误差累积问题:每段模型预测都从真实状态出发,只走几步就重置,误差还没来得及爆炸;最终还是用 SAC 训练策略,部署时没有额外计算开销,样本效率达到 model-free 的 10-100 倍。
Dyna → PETS → MBPO 这条线,我们称之为"数据增强路线"——模型的角色是生成更多数据,最终策略还是用 model-free 的方式训练。但 model-based RL 还有另一条完全不同的旗舰路线——显式搜索 + 神经网络估值。这条路线从 AlphaGo 到 AlphaZero 到 MuZero 再到 Dreamer V3,代表了 model-based RL 的理论天花板,也直接启发了 LLM 时代的 Process Reward Model 搜索。这就是下一节要讲的内容。
下一节 9.4 搜索与世界模型,我们来看看:当你不仅有模型,还能在模型里做lookahead搜索,能达到什么样的性能上限?