Dreamer 系列算法详解

Dreamer 是由 Danijar Hafner 等人开发的一系列基于潜在世界模型的强化学习算法。本文档详细解析从 V1 到 V4 的核心设计、训练目标和实现细节。

概览

版本年份核心贡献代表任务
Dreamer V12020从像素学习的潜在世界模型Atari, DeepMind Lab
Dreamer V22021KL平衡、离散潜变量Atari
Dreamer V32023固定超参数、symlog损失Atari, Mogwai
Dreamer V42025可扩展架构、多任务学习Minecraft

核心思想

Dreamer 的核心思想是:

  1. 学习潜在世界模型:将高维图像压缩为紧凑潜在表示
  2. 潜在空间想象:在潜在空间中进行长期规划(Rollout)
  3. 端到端训练:通过梯度反传优化所有组件
┌─────────────────────────────────────────────────────────────┐
│                      Dreamer 框架                            │
│                                                              │
│  ┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐   │
│  │Dataset  │──▶│World    │──▶│Imagine  │──▶│Update   │   │
│  │Buffer   │   │Model    │   │Rollout  │   │Policy   │   │
│  │{o,a,r}  │   │E,D,P    │   │in latent│   │& Value  │   │
│  └─────────┘   └─────────┘   └─────────┘   └─────────┘   │
│       ▲                                                            │
│       │ 真实交互                                               │
│       │                                                            │
│  ┌─────────┐                                                     │
│  │ Env     │                                                     │
│  └─────────┘                                                     │
└─────────────────────────────────────────────────────────────┘

Dreamer V1 (2020)

论文信息

  • 标题: Dream to Control: Learning Behaviors by Latent Imagination
  • 会议: ICLR 2020

架构设计

Dreamer V1 包含三个核心组件:

1. 潜在世界模型 (Recurrent State Space Model, RSSM)

Encoder :

  • 使用 LSTM 编码历史信息
  • 输出高斯分布参数
  • 重参数化采样:

Dynamics Model :

  • 预测下一个潜在状态
  • 不依赖观测(纯先验)

Reward Predictor :

  • 预测即时奖励
  • 用于想象 Rollout

Decoder :

  • 重建观测(可选)
  • 辅助表示学习

2. 价值函数

使用 GRU 预测价值估计:

3. 策略

使用 Gaussian 策略:

训练目标

世界模型训练

注意: 使用 posterior sampling 训练先验,使其能够「反演」观测。

策略和价值训练

通过潜在空间的想象 Rollout 优化策略:

其中 是预测奖励, 是想象 horizon。

想象 Rollout 详解

时间步 t:
┌──────────────────────────────────────────────────────────┐
│                                                          │
│  z_t ──▶ dynamics(z_t, a_t) ──▶ z_{t+1}                 │
│   │                                    │                 │
│   │                                    ▼                 │
│   │                              reward(z_{t+1}, a_t)   │
│   │                                    │                 │
│   │                                    ▼                 │
│   │                               ĥ_{t+1}               │
│   │                                    │                 │
│   └────────────────────────────────────┘                 │
│                    累积奖励                               │
└──────────────────────────────────────────────────────────┘

梯度通过整个想象轨迹反传:


Dreamer V2 (2021)

论文信息

  • 标题: Mastering Atari with Discrete World Models
  • 会议: ICML 2021

核心改进

1. 离散潜在变量

将连续高斯分布替换为分类分布(Categorical Distribution):

其中 是 one-hot 向量,来自 个离散类别。

优势

  • 更好的表示能力
  • 更稳定的训练
  • 可以使用注意力机制

2. KL 平衡

训练动态模型时,平衡先验和后验的 KL 散度:

其中 是平衡系数(通常 0.8 或 0.9)。

作用:防止后验坍缩,鼓励先验学习有用的结构。

3. 特征重构

不仅重建像素,还重建中间特征:

其中 是预训练的视觉特征提取器(如 ResNet)。


Dreamer V3 (2023)

论文信息

  • 标题: Mastering Diverse Domains through World Models
  • arXiv: 2301.04104

核心改进

1. 固定超参数

Dreamer V3 声称可以在无需超参数调整的情况下处理多种不同任务:

  • 离散/连续动作空间
  • 图片/向量观测
  • 稀疏/密集奖励
  • 简单/复杂环境

这是通过精心设计的归一化和损失函数实现的。

2. Symlog 损失

对于价值函数和奖励预测,使用 symlog 变换:

作用

  • 处理不同尺度的奖励
  • 避免极端值的影响
  • 提高训练稳定性

3. 价值分解

使用 TD-lambda 估计优势函数:

其中

4. 改进的策略梯度

使用 Reinforce 配合 baseline:


Dreamer V4 (2025)

论文信息

  • 标题: Foundation Model for World Modeling
  • 期刊: Nature 2025

核心突破

Dreamer V4 是世界模型领域的重大突破,首次在 Nature 发表:

1. 可扩展架构

使用现代深度学习组件:

  • Transformer 替代 LSTM 处理序列
  • ViT 风格的图像编码器
  • 更大规模的模型(对比 V3)

2. Minecraft 钻石任务

在 Minecraft 中从零学习收集钻石:

  • 无人工先验:完全从头学习
  • 长时程规划:需要数百步的规划
  • 稀疏奖励:钻石极为罕见
  • 复杂环境:开放世界、多样物体

结果:Dreamer V4 是首个成功解决此任务的算法。

3. 多任务学习

使用单一模型处理多种任务:

  • 迁移能力更强
  • 共享表示学习
  • 超越任务专用算法

训练规模

组件Dreamer V3Dreamer V4
模型参数量~250M~1B+
训练步数10M100M+
硬件16 TPU512+ TPU

算法伪代码

以下是 Dreamer 训练的核心伪代码:

def dreamer_training(env, config):
    # 初始化组件
    encoder = Encoder(config)
    dynamics = Dynamics(config)      # 先验 p(z_t | z_{t-1}, a_{t-1})
    reward_predictor = RewardPredictor(config)
    decoder = Decoder(config)
    actor = Actor(config)
    critic = Critic(config)
    
    dataset = ReplayBuffer(config)
    
    # 收集初始数据
    for _ in range(config.init_steps):
        action = random_policy()
        obs, reward, done = env.step(action)
        dataset.add(obs, action, reward, done)
    
    # 主训练循环
    for step in range(config.train_steps):
        # 1. 数据采集
        for _ in range(config.env_steps):
            z = encoder.encode(obs)  # 当前潜在状态
            action = actor(z)
            obs, reward, done = env.step(action)
            dataset.add(obs, action, reward, done)
        
        # 2. 世界模型训练
        batch = dataset.sample(config.batch_size)
        model_loss = train_world_model(encoder, dynamics, reward_predictor, decoder, batch)
        
        # 3. 潜在空间想象 Rollout
        imagine_rollouts = []
        for _ in range(config.rollout_batch_size):
            z = encoder.encode(batch.obs[0])  # 从真实观测开始
            trajectory = []
            for h in range(config.imagination_horizon):
                action = actor(z)
                z_next = dynamics.predict(z, action)  # 纯模型预测
                reward_hat = reward_predictor.predict(z, action)
                trajectory.append((z, action, reward_hat))
                z = z_next
            imagine_rollouts.append(trajectory)
        
        # 4. 策略和价值训练
        actor_critic_loss = train_policy_critic(actor, critic, imagine_rollouts)
        
        # 5. 更新
        optimizer.step()
        
    return encoder, dynamics, actor, critic

关键实现细节

1. 重参数化技巧

连续变量的重参数化:

def reparameterize(mu, logvar):
    std = torch.exp(0.5 * logvar)
    eps = torch.randn_like(std)
    return mu + eps * std

2. KL 散度计算

def kl_divergence(q, p):
    # 两种方向
    kl_forward = kl_div(q, p)      # log q - log p
    kl_reverse = kl_div(p, q)
    return args.beta * kl_forward - (1 - args.beta) * kl_reverse

3. 想象 Rollout 梯度截断

为防止梯度爆炸,限制反向传播的步数:

def imagine_rollout(z0, actor, dynamics, horizon, detach_every=5):
    z = z0
    for t in range(horizon):
        if t % detach_every == 0:
            z = z.detach()
        action = actor(z)
        z = dynamics(z, action)
    return z

性能对比

Atari 100k 基准

算法DQNSimPLeDreamer V2Dreamer V3
人类归一化得分24%75%200%+200%+
训练步数200k100k100k100k

Dreamer V2 首次超越人类水平,Dreamer V3 保持竞争力且更加通用。

样本效率

训练曲线(人类归一化得分 vs 环境步数):

▲ Human: 100%
│
│                    ████ Dreamer V3
│               ████
│          ████
│     ████
│ ████      Dreamer V2
│██
│
│▓▓▓▓▓▓▓▓▓▓▓▓▓▓ SimPLe
│
│
└──────────────────────────────────────▶
  0       50k     100k    150k    200k

与 MuZero 的对比

维度DreamerMuZero
状态表示潜在空间隐式表示
规划算法策略梯度MCTS
模型类型自回归生成模型对抗模型
训练方式离线 + 在线完全离线
泛化性弱(任务专用)

参考文献

相关主题