🤖 roboto_origin_03 Wiki
首页 / RSL-RL / 对称性增强与镜像损失

在机器人强化学习中,大量智能体具有内在的肢体对称性——人形机器人、四足机器人的左右肢在结构上是镜像关系。对称性增强与镜像损失利用这一先验知识,通过对称数据扩充或正则化约束,降低有效样本复杂度并提升策略的泛化能力。该特性深度集成于 PPO 与 PPO-AMP 的训练循环中,通过配置即可开启,无需修改算法核心逻辑。

系统架构与数据流

对称性系统由三层协作构成:配置解析层负责将环境对象注入算法配置;算法层update() 中根据配置决定增强或正则化的执行路径;环境层提供 data_augmentation_func,封装特定任务的对称变换逻辑(如左右肢体关节角度镜像、观测向量翻转)。

flowchart LR
    subgraph Config["配置解析层"]
        A[train_cfg.symmetry_cfg] --> B[resolve_symmetry_config]
        B --> C[注入 _env 对象]
    end
    subgraph Algorithm["算法层 (PPO / PPO-AMP)"]
        C --> D[初始化 symmetry_cfg]
        D --> E{use_data_augmentation}
        D --> F{use_mirror_loss}
        E -->|是| G[扩展 mini-batch 数据]
        F -->|是| H[计算镜像 MSE 损失]
    end
    subgraph Env["环境层"]
        I[data_augmentation_func] -->|obs/actions| G
        I -->|obs/actions| H
    end

对称性配置通过 OnPolicyRunner 在算法构造前完成解析,随后 PPO(或 PPOAMP)在初始化时校验策略兼容性并解析增强函数。在每次策略更新的 mini-batch 迭代中,系统根据两个布尔开关决定是扩展训练数据还是施加正则损失。

Sources: symmetry.py, on_policy_runner.py

双模式工作机制

本框架提供两种互补机制,可单独开启也可同时启用:

模式 配置项 作用阶段 对梯度的影响 适用场景
对称数据增强 use_data_augmentation=True Mini-batch 生成后 镜像样本直接参与 Surrogate / Value loss 计算 样本稀缺,需要扩充有效数据量
镜像损失正则化 use_mirror_loss=True 损失聚合阶段 以 MSE 损失项加入总损失,系数可配 保持策略输出的对称一致性,轻量级约束

两个开关独立控制:若同时启用,数据增强会先扩充 batch,随后镜像损失在扩充后的数据上进一步约束;若仅启用镜像损失,则不会修改 batch 大小,仅在原始数据上计算正则项。

Sources: ppo.py

对称数据增强

use_data_augmentation=True 时,算法对每个 mini-batch 调用 data_augmentation_func(obs_batch, actions_batch, env=...),返回的观测与动作张量在 batch 维度上被拼接扩展。假设每个原始样本生成 $k-1$ 个增强样本,则总 batch 大小变为 $k \times N$。为保证 PPO 损失计算的一致性,优势、回报、旧对数概率等张量会被 repeat(k, 1) 同步扩展。

sequenceDiagram
    participant G as MiniBatch Generator
    participant A as PPO.update()
    participant F as data_augmentation_func
    participant P as Policy

    G->>A: 提供 (obs, actions, advantages, ...)
    A->>F: obs_batch, actions_batch
    F-->>A: aug_obs [k*N], aug_actions [k*N]
    A->>A: repeat advantages, returns, old_log_prob by k
    A->>P: act(aug_obs), evaluate(aug_obs)
    P-->>A: 在所有 k*N 样本上计算 loss
    Note over A: 原始与镜像样本同等参与梯度更新

关键实现细节:策略重新计算的动作对数概率与值函数覆盖全部增强样本,但 KL 散度与熵的计算仅保留前 original_batch_size 个原始样本,防止噪声估计干扰自适应学习率调度。

Sources: ppo.py

镜像损失正则化

镜像损失是对称性框架的核心正则项。其数学直觉为:若将观测进行左右镜像得到 $o'$,策略输出的动作均值 $\mu(o')$ 应当等于原始动作均值的镜像 $\text{mirror}(\mu(o))$。该约束通过均方误差实现。

计算流程如下:

  1. 获取增强观测:若未启用数据增强,则临时调用 data_augmentation_func(obs=obs_batch, actions=None, ...) 生成镜像观测,此时 obs_batch 被替换为 [原始; 镜像] 的拼接。
  2. 推断动作均值:通过 policy.act_inference(obs_batch.detach().clone()) 获得所有观测(含镜像)上的确定性动作输出 mean_actions_batch
  3. 构造目标动作:取前 original_batch_size 个原始观测对应的均值 action_mean_orig,再调用 data_augmentation_func(obs=None, actions=action_mean_orig, ...) 得到理论上应当出现的镜像动作 actions_mean_symm_batch。该调用同样遵循"原始在前、增强在后"的约定,因此返回张量的后半部分即为目标镜像动作。
  4. 计算 MSE 损失:将镜像观测上的实际预测 mean_actions_batch[original_batch_size:] 与目标镜像动作 actions_mean_symm_batch[original_batch_size:] 作 MSE。
flowchart TB
    subgraph Input["输入"]
        O1[原始观测 o]
    end
    subgraph MirrorObs["步骤 1: 生成镜像观测"]
        O1 --> F1[data_augmentation_func<br>obs=o, actions=None]
        F1 --> O2[镜像观测 o']
    end
    subgraph Inference["步骤 2: 策略推断"]
        O1 --> P[π.act_inference]
        O2 --> P
        P --> M1[μ(o)]
        P --> M2[μ(o')]
    end
    subgraph Target["步骤 3: 构造目标"]
        M1 --> F2[data_augmentation_func<br>obs=None, actions=μ(o)]
        F2 --> M3[mirror(μ(o))]
    end
    subgraph Loss["步骤 4: 损失计算"]
        M2 --> L[MSELoss]
        M3 --> L
        L --> SL[symmetry_loss]
    end

最终,若 use_mirror_loss=True,则 loss += mirror_loss_coeff * symmetry_loss;否则 symmetry_loss 仅做 detach 用于日志记录,不参与反向传播。

Sources: ppo.py

配置参数详解

对称性配置以字典形式嵌入算法配置 algorithm 中,由 PPO.__init__ 直接消费。OnPolicyRunner 在构造算法前通过 resolve_symmetry_config 将环境实例 _env 注入该字典,供增强函数内部访问观测空间定义与维度信息。

参数 类型 必填 说明
use_data_augmentation bool 是否启用对称数据增强,直接扩展训练 batch
use_mirror_loss bool 是否将镜像一致性作为正则损失加入总损失
mirror_loss_coeff float 镜像损失的权重系数,仅在 use_mirror_loss=True 时生效
data_augmentation_func str / Callable 是* 对称变换函数,支持字符串名(通过 resolve_callable 解析)或直接传入 callable
_env VecEnv 自动注入 环境实例,由 resolve_symmetry_config 自动填充,增强函数可通过该参数访问环境配置

* 当 symmetry_cfg 不为 None 时,data_augmentation_func 必须可解析且可调用。

Sources: ppo.py, symmetry.py

与 AMP 及多模块的协同

PPOAMP 继承自 PPO,完全复用了父类的对称性逻辑,镜像损失计算位于 AMP 判别器损失之前。这意味着对称性约束会同时影响策略梯度与 AMP 风格奖励下的策略行为。在梯度应用阶段,PPO 优化器、RND 优化器(若启用)与 AMP 判别器优化器各自独立更新,对称性损失仅通过 PPO 的 loss.backward() 影响策略网络与价值网络。

Sources: ppo_amp.py, ppo_amp.py

限制与兼容性约束

当前实现存在以下架构级约束,在选型与配置时需特别注意:

  1. 循环策略不兼容ActorCriticRecurrent 因隐藏状态与序列时序的复杂性,不支持对称数据增强。初始化时会显式抛出 ValueError
  2. 增强函数约定data_augmentation_func 必须严格遵循"原始样本在前、增强样本在后"的拼接约定,且输入输出维度一致。若返回的增强倍数与预期不符,会导致 MSE 计算时的张量形状错误。
  3. 熵与 KL 的基准:在数据增强模式下,熵与自适应 KL 调度仅基于原始样本计算,避免增强样本的分布偏移干扰学习率自适应。

Sources: ppo.py, ppo.py

下一步阅读

若需了解策略网络的基础结构设计,请参阅 Actor-Critic 基础架构设计;若关注 PPO 算法的整体训练流程与损失计算,请返回 PPO 算法实现与训练流程。对于需要在策略训练中引入探索奖励的场景,可继续阅读 RND 随机网络蒸馏探索