在机器人强化学习中,大量智能体具有内在的肢体对称性——人形机器人、四足机器人的左右肢在结构上是镜像关系。对称性增强与镜像损失利用这一先验知识,通过对称数据扩充或正则化约束,降低有效样本复杂度并提升策略的泛化能力。该特性深度集成于 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))$。该约束通过均方误差实现。
计算流程如下:
- 获取增强观测:若未启用数据增强,则临时调用
data_augmentation_func(obs=obs_batch, actions=None, ...)生成镜像观测,此时obs_batch被替换为[原始; 镜像]的拼接。 - 推断动作均值:通过
policy.act_inference(obs_batch.detach().clone())获得所有观测(含镜像)上的确定性动作输出mean_actions_batch。 - 构造目标动作:取前
original_batch_size个原始观测对应的均值action_mean_orig,再调用data_augmentation_func(obs=None, actions=action_mean_orig, ...)得到理论上应当出现的镜像动作actions_mean_symm_batch。该调用同样遵循"原始在前、增强在后"的约定,因此返回张量的后半部分即为目标镜像动作。 - 计算 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
限制与兼容性约束
当前实现存在以下架构级约束,在选型与配置时需特别注意:
- 循环策略不兼容:
ActorCriticRecurrent因隐藏状态与序列时序的复杂性,不支持对称数据增强。初始化时会显式抛出ValueError。 - 增强函数约定:
data_augmentation_func必须严格遵循"原始样本在前、增强样本在后"的拼接约定,且输入输出维度一致。若返回的增强倍数与预期不符,会导致 MSE 计算时的张量形状错误。 - 熵与 KL 的基准:在数据增强模式下,熵与自适应 KL 调度仅基于原始样本计算,避免增强样本的分布偏移干扰学习率自适应。
下一步阅读
若需了解策略网络的基础结构设计,请参阅 Actor-Critic 基础架构设计;若关注 PPO 算法的整体训练流程与损失计算,请返回 PPO 算法实现与训练流程。对于需要在策略训练中引入探索奖励的场景,可继续阅读 RND 随机网络蒸馏探索。