Skip to content

Latest commit

 

History

History
474 lines (381 loc) · 16.7 KB

File metadata and controls

474 lines (381 loc) · 16.7 KB

双策略PPO架构设计文档

📐 系统架构概览

┌────────────────────────────────────────────────────────────────┐
│                    双策略PPO系统架构                             │
└────────────────────────────────────────────────────────────────┘
                              │
                              │
        ┌─────────────────────┼─────────────────────┐
        │                     │                     │
        ▼                     ▼                     ▼
┌──────────────┐    ┌──────────────┐     ┌──────────────┐
│   环境交互    │    │   策略网络    │     │  好奇心模块   │
│  Environment  │◄──►│   Networks   │◄───►│  Curiosity   │
└──────────────┘    └──────────────┘     └──────────────┘
        │                     │                     │
        │            ┌────────┴────────┐            │
        │            │                 │            │
        ▼            ▼                 ▼            ▼
┌──────────────┐  ┌─────────┐   ┌─────────┐  ┌──────────┐
│  经验缓冲区   │  │主策略    │   │对手策略  │  │内在奖励   │
│ ReplayBuffer │  │π_actor  │   │π_opponent│  │Intrinsic │
└──────────────┘  └─────────┘   └─────────┘  └──────────┘
        │                 │           │             │
        └─────────────────┴───────────┴─────────────┘
                          │
                          ▼
                  ┌──────────────┐
                  │   训练器      │
                  │   Trainer    │
                  └──────────────┘

🧩 核心组件详解

1. ActorCriticNetwork (Actor-Critic网络)

位置: dual_policy_ppo.py

职责: 策略和价值函数的神经网络表示

架构:

输入: 状态 s ∈ ℝ^d
    │
    ▼
┌─────────────────┐
│  共享特征层      │
│  (2层MLP + LN)  │
└─────────────────┘
    │
    ├────────────────┬────────────────┐
    ▼                ▼                │
┌────────┐      ┌────────┐      ┌────────┐
│Actor头  │      │Critic头 │      │        │
│(策略)   │      │(价值)   │      │        │
└────────┘      └────────┘      └────────┘
    │                │                │
    ▼                ▼                ▼
  π(a|s)          V(s)          (特征)

关键特性:

  • 支持离散和连续动作空间
  • 使用LayerNorm提升训练稳定性
  • 正交初始化加速收敛
  • 共享特征提取层减少参数

输出:

  • 动作分布: π(a|s) (Categorical或Normal)
  • 状态价值: V(s) (标量)

2. CuriosityModule (好奇心模块)

位置: dual_policy_ppo.py

职责: 生成内在奖励,引导探索

架构:

状态 s_t, 动作 a_t, 下一状态 s_{t+1}
    │
    ├────────────────────────┬────────────────────────┐
    ▼                        ▼                        ▼
┌──────────┐          ┌──────────┐          ┌──────────┐
│特征编码器 │          │特征编码器 │          │          │
│  φ(s_t)  │          │ φ(s_{t+1})│          │          │
└──────────┘          └──────────┘          └──────────┘
    │                        │                        │
    ├────────────────────────┼────────────────────────┤
    │                        │                        │
    ▼                        │                        ▼
┌──────────────────┐         │              ┌──────────────┐
│  前向动力学模型   │         │              │逆向动力学模型 │
│ f: (φ(s_t), a_t)│         │              │g: (φ(s_t),   │
│     → φ(s_{t+1})│         │              │   φ(s_{t+1}))│
└──────────────────┘         │              │    → a_t     │
    │                        │              └──────────────┘
    │                        │                      │
    ▼                        ▼                      ▼
┌──────────────────┐   ┌──────────┐        ┌──────────────┐
│  预测误差        │   │真实特征   │        │  动作预测    │
│ ŷ = f(φ(s), a)  │   │y = φ(s') │        │  â = g(...)  │
└──────────────────┘   └──────────┘        └──────────────┘
    │                        │                      │
    └────────────────────────┤                      │
                             ▼                      ▼
                     好奇心奖励 = ||ŷ - y||²   逆向损失

关键公式:

  • 前向损失: L_forward = ||f(φ(s_t), a_t) - φ(s_{t+1})||²
  • 逆向损失: L_inverse = CE(g(φ(s_t), φ(s_{t+1})), a_t)
  • 好奇心: curiosity = L_forward (预测误差)

设计理念:

  • 前向模型: 预测误差越大 → 状态越新奇
  • 逆向模型: 学习特征空间,使得特征包含与动作相关的信息
  • 特征编码: 降维,提取关键信息

3. DualPolicyPPO (双策略PPO核心)

位置: dual_policy_ppo.py

职责: 统一的探索-利用-稳定性框架

核心机制:

3.1 改进的内在奖励

r_intrinsic = curiosity(s, a) × [1 - KL(π_actor || π_opponent)]

可视化:

高好奇心 + 低KL散度 = 高内在奖励  ✓ (有价值的新奇)
高好奇心 + 高KL散度 = 低内在奖励  ✗ (危险的新奇)
低好奇心 + 低KL散度 = 低内在奖励  ✓ (已知状态)
低好奇心 + 高KL散度 = 低内在奖励  ✗ (不合理的偏离)

3.2 统一损失函数

L_total = L_PPO + λ_intrinsic × E[r_intrinsic] - λ_KL × KL(π || π_opp)
         ───┬───   ─────────┬────────────────   ──────────┬──────────
            │              │                              │
        标准PPO          探索激励                     稳定性约束

各项解释:

  • L_PPO: 标准PPO裁剪损失,优化策略性能
  • λ_intrinsic × E[r_intrinsic]: 内在奖励的期望,鼓励探索
  • λ_KL × KL(π || π_opp): KL散度惩罚,防止偏离对手策略过远

3.3 对手策略更新策略

每隔 N 个回合:
    if 性能稳定提升:
        π_opponent ← π_actor  # 更新对手策略
    else:
        保持 π_opponent 不变   # 继续使用旧锚点

条件: 连续N个回合性能单调递增

意义:

  • 对手策略代表"可达到的优秀性能"
  • 避免过于保守(对手策略太弱)
  • 避免过于激进(对手策略过强)

4. Trainer (训练器)

位置: trainer.py

职责: 管理训练循环和环境交互

训练流程:

初始化
  │
  ▼
┌────────────────────────────────────┐
│  收集经验 (collect_experience)      │
│  - 与环境交互                       │
│  - 存储到缓冲区                     │
└────────────────────────────────────┘
  │
  ▼
┌────────────────────────────────────┐
│  更新策略 (agent.update)           │
│  - 计算内在奖励                     │
│  - 计算GAE优势                     │
│  - 多轮PPO更新                     │
└────────────────────────────────────┘
  │
  ▼
┌────────────────────────────────────┐
│  评估 (evaluate)                   │
│  - 确定性策略评估                   │
│  - 记录性能                        │
└────────────────────────────────────┘
  │
  ▼
┌────────────────────────────────────┐
│  更新对手策略                       │
│  (update_opponent_policy)          │
│  - 检查性能趋势                     │
│  - 决定是否更新                     │
└────────────────────────────────────┘
  │
  ▼
  回到"收集经验"或结束

🔄 数据流图

训练阶段

环境 → 状态 s_t
         │
         ▼
    主策略 π_actor
         │
         ├─────────────┐
         │             │
         ▼             ▼
      动作 a_t    状态价值 V(s_t)
         │             │
         ▼             │
    环境执行动作         │
         │             │
         ▼             │
 (s_{t+1}, r_t, done)  │
         │             │
         └─────┬───────┘
               │
               ▼
        存入经验缓冲区
               │
               ▼
        计算内在奖励
      r_int = Curiosity × (1 - KL)
               │
               ▼
        总奖励 = r_t + λ × r_int
               │
               ▼
          计算GAE优势
               │
               ▼
          PPO策略更新

内在奖励计算流程

(s_t, a_t, s_{t+1})
        │
        ├──────────────┬──────────────┐
        │              │              │
        ▼              ▼              ▼
  特征编码        好奇心计算       KL散度计算
  φ(s_t),         Curiosity      KL(π_actor||
  φ(s_{t+1})         │            π_opponent)
        │              │              │
        └──────────────┼──────────────┘
                       ▼
              r_int = Curiosity × (1 - KL)

⚙️ 关键超参数

核心超参数表

参数 符号 默认值 作用 调优建议
内在奖励系数 λ_intrinsic 0.1 控制探索强度 稀疏奖励↑, 密集奖励↓
KL散度系数 λ_KL 0.01 控制稳定性 震荡环境↑, 稳定环境↓
KL散度阈值 ε_KL 0.3 内在奖励抑制点 需快速探索↑, 需稳定↓
对手更新间隔 N_update 10 对手策略更新频率 快速适应↓, 长期稳定↑
学习率 α 3e-4 优化器步长 大环境↓, 小环境可保持
折扣因子 γ 0.99 未来奖励权重 长期任务↑ (如0.995)
PPO裁剪 ε_clip 0.2 策略更新幅度限制 标准值即可

环境特定建议

稀疏奖励环境 (LunarLander, MountainCar)

intrinsic_coef: 0.2 - 0.3  # 更强探索
kl_coef: 0.01
kl_threshold: 0.3 - 0.5    # 允许更大偏离

连续控制环境 (Pendulum, BipedalWalker)

intrinsic_coef: 0.03 - 0.08  # 较弱探索
kl_coef: 0.015 - 0.02        # 更强稳定约束
kl_threshold: 0.2 - 0.25     # 更严格阈值

易震荡环境

kl_coef: 0.02 - 0.03          # 显著增强稳定性
update_opponent_interval: 15   # 更长的稳定期

🔬 理论分析

1. 为什么乘法内在奖励有效?

传统方法 (加法):

r_total = r_external + λ₁ × Curiosity - λ₂ × KL

问题: 好奇心和KL约束是独立的,可能冲突

我们的方法 (乘法):

r_total = r_external + λ × [Curiosity × (1 - KL/ε)]

优势:

  • 自然融合:只有"安全的新奇"才获得奖励
  • 自动平衡:高KL自动抑制高好奇心
  • 语义清晰:内在奖励 = 信息增益 × 安全性

2. 对手策略的作用

双策略系统:

主策略: 探索 + 利用
对手策略: 保守锚点

优势:

  1. 有界探索: KL(π_actor || π_opponent) ≤ ε 保证不会偏离过远
  2. 动态锚点: 对手策略会更新,不会过于保守
  3. 单调改进: 只在性能提升时更新,保证长期进步

3. 收敛性分析(直观)

定理(非正式): 在合理假设下,双策略PPO收敛到局部最优策略。

关键观察:

  1. PPO本身有收敛保证(单调改进)
  2. KL约束限制了策略变化范围(有界)
  3. 对手策略更新机制保证长期性能不下降(单调性)
  4. 内在奖励随探索充分逐渐降低(收敛)

非正式推理:

性能 P(t) 随时间单调递增或稳定
  ⇒ 对手策略 π_opp(t) 单调改进
  ⇒ KL约束变紧但主策略仍能改进
  ⇒ 最终收敛到 π* 附近

🎯 与相关工作对比

方法 探索机制 稳定性机制 耦合方式
标准PPO 熵正则 PPO裁剪 N/A
PPO + ICM 好奇心(ICM) PPO裁剪 独立(加法)
PPO + RND 随机网络 PPO裁剪 独立(加法)
TRPO变体 熵正则 KL约束 独立
双策略PPO 可控好奇心 对手策略+KL 协同(乘法)

关键创新: 探索和稳定性的协同设计,而非独立模块。


📊 性能特征

优势

  1. 样本效率高: 内在奖励引导高效探索
  2. 训练稳定: 对手策略锚定,防止崩溃
  3. 通用性强: 离散/连续,稀疏/密集均适用
  4. 可解释性: 每个组件作用明确

局限性

  1. 额外计算: 需要维护两个策略网络和好奇心模块
  2. 超参数: 引入了额外的超参数(但含义清晰)
  3. 内存开销: 对手策略需要额外内存

适用场景

特别适合:

  • 稀疏奖励环境
  • 易震荡的连续控制
  • 需要平衡探索和稳定的任务

⚠️ 不太适合:

  • 极简单的任务(开销大于收益)
  • 完全随机环境(好奇心失效)
  • 资源极度受限场景

🔮 未来扩展方向

1. 自适应超参数

λ_intrinsic(t) = f(exploration_progress, performance)
λ_KL(t) = g(policy_variance, training_stability)

2. 多对手策略集成

π_opponents = {π₁, π₂, ..., πₖ}  # 历史多个策略
KL_multi = E_i[KL(π || πᵢ)]

3. 元学习加速

# 快速适应新环境
θ* = MAML(θ, {task_1, ..., task_n})

4. 分层强化学习

# 高层策略选择子目标
# 低层策略执行具体动作
r_intrinsic_high = curiosity_high(subgoal)
r_intrinsic_low = curiosity_low(action | subgoal)

📚 参考资源

理论基础

  • PPO: Schulman et al. (2017) - Proximal Policy Optimization
  • ICM: Pathak et al. (2017) - Curiosity-driven Exploration
  • Trust Region: Schulman et al. (2015) - Trust Region Policy Optimization

相关工作

  • RND: Burda et al. (2018) - Random Network Distillation
  • NGU: Badia et al. (2020) - Never Give Up
  • Ape-X: Horgan et al. (2018) - Distributed Prioritized Experience Replay

本架构文档持续更新

如有疑问或建议,欢迎提Issue!