🤖 roboto_origin_03 Wiki
首页 / 训练 / 注意力编码器感知机制

足式机器人在复杂地形中行走时,策略网络需要同时处理两类异构信息:低维的本体感觉信号(如关节位置、角速度)和高维的空间感知数据(如地形高度扫描)。直接将高度扫描展平后拼接为一维向量会导致空间结构信息丢失,且参数量随分辨率线性膨胀。注意力编码器感知机制通过卷积神经网络提取地形局部特征,再借助多头注意力机制让本体感觉查询自适应地关注关键地形区域,从而在保持网络紧凑的同时实现精细的地形感知。

Sources: attn_encoder.py, actor_critic_attn_enc.py

整体架构与数据流

注意力编码器感知机制由三个层级组成:环境层负责生成结构化的感知观测;编码器层负责将二维地形扫描压缩为语义化的地形嵌入;策略层将地形嵌入与本体感觉融合后送入 Actor-Critic 网络。下图展示了从原始传感器数据到策略输出的完整数据链路。

flowchart TB
    subgraph Env["环境层 (AttnEncEnv)"]
        A[高度扫描传感器<br/>height_scanner] --> B["perception_a / perception_c<br/>(B, W, L)"]
        C[本体感觉观测<br/>actor/critic obs] --> D["policy / critic<br/>(B, d_obs)"]
    end

    subgraph Encoder["编码器层 (AttentionEncoder)"]
        B --> E["CNN 局部特征提取<br/>(B, d-3, W, L)"]
        F["位置编码<br/>(2, W, L)"] --> G["拼接: [xy, z, CNN特征]<br/>(B, d, W, L)"]
        E --> G
        G --> H["展平为点级特征<br/>(B, L*W, d)"]
        D --> I["本体感觉线性投影<br/>(B, 1, d)"]
        H --> J["多头注意力<br/>query=本体感觉, kv=地形"]
        I --> J
        J --> K["地形嵌入<br/>(B, d)"]
        J --> L["注意力权重<br/>(B, W, L)"]
    end

    subgraph Policy["策略层 (ActorCriticAttnEnc)"]
        D --> M["融合向量<br/>[obs, embedding]"]
        K --> M
        M --> N[Actor MLP]
        M --> O[Critic MLP]
        N --> P["动作分布<br/>Normal(mean, std)"]
        O --> Q["状态价值<br/>V(s)"]
    end

    style Encoder fill:#e1f5fe

AttnEncEnv 中,环境将高度扫描以二维网格形式输出到 perception_a(演员用,可能加噪声)和 perception_c(评论家用,无噪声)两个观测组中。ActorCriticAttnEnc 通过 get_actor_obsget_critic_obs 方法分离本体感觉观测与感知观测,随后将感知观测送入 AttentionEncoder 进行编码。编码结果与本体感觉拼接后分别进入演员网络和评论家网络。

Sources: attn_enc_env.py, actor_critic_attn_enc.py

AttentionEncoder 核心设计

AttentionEncoder 的设计遵循“局部特征提取 + 全局注意力聚合”的范式。其输入为二维地形高度图 map_scans(形状 (B, W, L))和本体感觉向量 proprioception(形状 (B, d_obs)),输出为地形嵌入 map_encoding(形状 (B, d))和可选的空间注意力权重 attn_weights(形状 (B, W, L))。

CNN 局部特征提取模块接收单通道的高度图,通过三层卷积将其映射到 embedding_dim - 3 个通道。第一层输出 16 通道,第二层输出 32 通道,第三层输出 embedding_dim - 3 通道。卷积核大小固定为 3,步长为 1,使用 replicate 边界填充和 ELU 激活,且使用池化操作,以保留原始空间分辨率。这种设计确保每个空间位置都能获得以其邻域为中心的局部上下文特征。

显式位置编码是本设计的关键细节。编码器不采用传统的正弦/余弦位置编码,而是直接使用归一化后的物理坐标:_create_position_encoding 方法生成 x_gridy_grid(形状 (2, W, L)),其中坐标原点位于地图几何中心,单位为米。这些坐标被注册为不可学习的 buffer,与 CNN 特征和原始高度值 z_values 在通道维度上拼接,形成每个空间点的完整表征 [x, y, z, cnn_feat...]。这种显式坐标注入使得注意力机制具备物理空间感知能力。

多头注意力聚合将本体感觉投影为单一查询向量 (B, 1, d),将所有空间点展平为键值对 (B, L*W, d)。通过 nn.MultiheadAttentionbatch_first=True),查询向量与所有空间位置计算注意力权重,最终输出加权聚合后的地形嵌入。在注意力计算前后分别应用层归一化(ln_qln_kvln_out)以稳定训练动态。

Sources: attn_encoder.py

ActorCriticAttnEnc 集成策略

ActorCriticAttnEnc 是标准的 Actor-Critic 架构与注意力编码器的集成体。它不仅封装了编码器,还引入了两种可选的辅助机制来增强表征学习:观测编码器(Obs Encoder)评论家估计(Critic Estimation)

观测融合方式

演员网络和评论家网络的输入构建遵循不同的逻辑。对于演员,默认取历史观测的最后一帧 obs[:, -single_actor_obs_dim:] 作为编码器的本体感觉输入;对于评论家,取 critic_history_length 帧中的最后一帧。编码器输出的地形嵌入与处理后的本体感觉在特征维度拼接,形成 MLP 的完整输入。

下表总结了不同配置下演员网络 MLP 的输入维度构成:

配置组合 MLP 输入维度 说明
基础配置 embedding_dim + num_actor_obs 地形嵌入 + 完整历史观测
enable_obs_encoder=True embedding_dim + single_actor_obs_dim + latent_dim 地形嵌入 + 最后一帧观测 + 观测编码
enable_critic_estimation=True embedding_dim + single_actor_obs_dim + num_estimation 地形嵌入 + 最后一帧观测 + 评论家预测值
双启用 embedding_dim + single_actor_obs_dim + latent_dim + num_estimation 以上三者之和

评论家网络的输入构建逻辑与演员类似,但使用 critic_obs_normalizercritic_obs_encoder,并且当 enable_critic_estimation 为真时,它使用真实的评论家观测切片 last_critic_gt 而非预测值。

Sources: actor_critic_attn_enc.py, actor_critic_attn_enc.py

观测编码器与评论家估计

观测编码器是一个独立的 MLP,将完整的(可能包含历史帧的)观测向量压缩为低维隐变量 latent_dim。该隐变量同时送入演员和评论家的编码器输入端,为编码器提供经网络提炼的全局上下文信息,而非原始的本体感觉向量。

评论家估计是一种自监督辅助任务。网络通过 estimator MLP 从演员观测中预测评论家观测的某些维度(由 estimation_slice 指定,例如线速度)。在 act 阶段,预测值被拼接进编码器输入;在 evaluate 阶段,真实的评论家观测切片被用作标签。两者之间的 MSE 通过 get_aux_loss 方法暴露给 PPO 优化器,作为辅助损失项。

Sources: actor_critic_attn_enc.py, actor_critic_attn_enc.py

训练中的辅助损失

ActorCriticAttnEnc 实现了 get_aux_loss() 接口,这是其与标准 ActorCritic 的关键差异之一。当配置中 enable_aux_loss=true 时,PPO 算法在每次策略更新时会调用该接口获取辅助损失,并以 aux_loss_coef 为权重将其加入总损失。

flowchart LR
    subgraph PPOUpdate["PPO Update Loop"]
        A[计算 surrogate_loss] --> B[计算 value_loss]
        B --> C[总损失 = surrogate + value - entropy]
        C --> D{enable_aux_loss?}
        D -->|是| E["aux_loss = policy.get_aux_loss()"]
        E --> F["总损失 += aux_loss_coef * aux_loss"]
        D -->|否| G[反向传播]
        F --> G
    end

当前实现中,辅助损失仅包含评论家估计的 MSE 损失。这一设计通过迫使演员观测包含足够信息来重构部分 privileged critic 观测,缓解了演员与评论家之间的信息不对称问题,从而提升策略的泛化性。

Sources: ppo.py, actor_critic_attn_enc.py

配置参数详解

在 Isaac Lab / RoboLab 的配置体系中,注意力编码器通过 RslRlPpoEncActorCriticCfg 配置类暴露全部可调参数。以下是核心参数的说明:

参数 类型 默认值 说明
class_name str "ActorCriticAttnEnc" 必须指定为 ActorCriticAttnEnc
embedding_dim int 64 注意力嵌入维度,必须大于 3 且能被 head_num 整除
head_num int 8 多头注意力的头数
map_size tuple (17, 11) 地形扫描网格尺寸 (L, W),对应高度扫描的列数和行数
map_resolution float 0.1 每个网格单元的物理边长(米),用于位置编码的尺度归一化
actor_history_length int 5 演员观测的历史帧长度,影响输入观测的拼接维度
critic_history_length int 1 评论家观测的历史帧长度
enable_critic_estimation bool False 是否启用评论家估计辅助任务
estimation_slice list[int] [78, 79, 80] 需要从演员观测预测的评论家观测维度索引
enable_obs_encoder bool False 是否启用观测编码器生成低维隐变量
latent_dim int 16 观测编码器的输出维度
actor_hidden_dims list[int] [256, 256, 256] 演员 MLP 的隐藏层维度
critic_hidden_dims list[int] [256, 256, 256] 评论家 MLP 的隐藏层维度

在 ATOM01 的注意力编码器任务配置中,采用了 embedding_dim=32head_num=4 的轻量配置,并同时启用了观测编码器(latent_dim=32)和评论家估计(预测线速度维度),配合 aux_loss_coef=0.05 进行联合优化。

Sources: atom01_attn_enc_agent_cfg.py

注意力权重的可视化与调试

AttentionEncoder 在前向传播中返回了 attn_weights,其形状为 (B, W, L),表示每个空间位置对当前本体感觉查询的注意力响应强度。在 act_inference 方法中,可通过设置 return_attention=True 获取该权重矩阵,用于以下调试与诊断场景:

需要注意的是,标准训练流程中的 actevaluate 方法默认丢弃注意力权重以减少内存开销,仅在推理模式下通过 act_inference 暴露。

Sources: attn_encoder.py, actor_critic_attn_enc.py

与其他感知机制的对比

本项目在 rsl_rl/modules 中提供了多种 Actor-Critic 变体,下表从感知处理角度对比注意力编码器与其他方案:

特性 ActorCritic(基线) ActorCriticCNN ActorCriticAttnEnc
感知输入维度 一维拼接 二维图像/网格 二维网格 + 一维本体感觉
空间结构保留 否(展平后丢失) 是(卷积保留局部结构) 是(卷积 + 注意力)
自适应关注 无(固定感受野) 有(查询驱动的注意力)
感知与本体感觉交互 隐式(MLP 混合) 分离处理(CNN + MLP 拼接) 显式(注意力聚合)
参数量 最低 中等 可控(分辨率无关)
适用场景 平坦地形 / 无高度扫描 视觉输入(相机图像) 结构化的地形高度扫描

ActorCriticCNN 更适合处理稠密的视觉输入,而 ActorCriticAttnEnc 针对结构化的地形扫描做了专门优化:其位置编码使用物理坐标而非图像像素坐标,注意力机制允许策略根据当前运动状态选择性地关注地形中的关键区域,而非对所有空间位置做均匀处理。

Sources: actor_critic.py, actor_critic_cnn.py

阅读路径与后续步骤

理解注意力编码器感知机制需要熟悉其上游的数据来源和下游的训练循环。建议按以下顺序深入: