ACT 详解:Action Chunking with Transformers
这里的 ACT 指机器人模仿学习算法 Action Chunking with Transformers。它最早用于 ALOHA 双臂机器人,核心目标是:
根据当前视觉和机器人状态,一次预测未来一段动作,而不是只预测下一步动作。
ACT 本身严格来说不是完整的 VLA:原始版本没有语言输入,主要是一个 Vision + Proprioception → Action 的单任务低层控制策略;但很多后续 VLA 系统会采用类似的 Action Chunking 思路,或者直接把 ACT 作为动作解码器。
1. ACT 要解决什么问题
假设示范轨迹为:
其中:
- \(I_t\):一个或多个相机图像
- \(q_t\):机器人关节位置、夹爪状态等本体状态
- \(a_t\):机器人动作
普通 Behavior Cloning 通常学习:
也就是每次只预测一个动作。
这种方法主要有三个问题。
1.1 累积误差
训练数据中的状态来自人类专家,但部署时的状态由机器人之前预测的动作产生。
一旦某一步产生小误差:
机器人就可能进入训练集中没有出现过的状态。之后的预测会更加不准确,误差不断放大。
ACT 主要针对精细操作中的这一问题,例如插电池、打开杯盖、穿扎带等。这些任务对毫米级的位置偏差非常敏感。
1.2 单步动作缺少时间一致性
人类动作通常是一段连续运动,例如:
- 移动到物体附近;
- 调整姿态;
- 闭合夹爪;
- 抬起物体。
单步 Behavior Cloning 分别预测每个控制周期的动作,模型没有被直接要求这些动作组成一条连贯轨迹,因此容易产生:
- 抖动;
- 突然停顿;
- 左右摆动;
- 夹爪反复开合。
1.3 人类示范具有多模态性
相同场景可能存在多种正确动作:
- 从物体左边绕过去;
- 从物体右边绕过去;
- 先移动左臂;
- 先移动右臂。
若直接使用 MSE 回归,模型可能输出多个模式的平均值,而这个“平均动作”可能根本不可执行。
2. ACT 的核心:Action Chunking
ACT 不学习单步映射:
而是学习:
其中 \(K\) 是 Chunk Size,即动作块长度。
例如控制频率为 \(50\ \mathrm{Hz}\)、\(K=100\),模型一次预测未来约 \(2\) 秒的动作。
输出张量通常为:
其中:
- \(K\):预测的动作步数;
- \(d_a\):动作维度。
原始 ALOHA 系统控制两个 6-DoF 机械臂及两个夹爪,动作是双臂的绝对关节目标,因此:
模型输出形状近似为:
3. 为什么 Action Chunking 有效
3.1 降低有效决策时域
假设任务共有 \(H\) 个控制步。
单步 Behavior Cloning 需要完成大约 \(H\) 次连续决策:
动作分块后,一段高层运动由一个 Chunk 表示,因此有效决策时域可近似理解为:
这并不意味着部署时必须完全开环执行 \(K\) 步。ACT 还可以通过重叠预测和 Temporal Ensembling 重新引入高频视觉反馈。
3.2 强制学习轨迹结构
模型不是只判断“下一步去哪”,而是必须预测:
因此 Transformer 会学习:
- 动作的速度趋势;
- 抓取前后的时序关系;
- 双臂之间的配合;
- 夹爪和机械臂的同步;
- 接近、接触、插入等运动阶段。
3.3 缓解暂停造成的时间混淆
在人类示范中,操作者可能会短暂停顿。对于单步 Markov 策略,同样的视觉状态可能对应:
- 继续移动;
- 保持不动。
模型很难仅凭瞬时观察判断示范者正处于哪个动作阶段。
动作 Chunk 包含局部时间上下文,因此能够把“停顿”理解为一段轨迹的一部分,而不是孤立动作。
4. ACT 的整体模型结构
ACT 本质上是:
模型有两个主要部分:
- CVAE Encoder:仅在训练时使用;
- CVAE Decoder / ACT Policy:训练和部署时都会使用。
整体数据流如下:
训练阶段:
示范动作块 A_t ─────┐
当前关节状态 q_t ───┼─> CVAE Encoder ─> μ, logσ² ─> z
│
多相机图像 I_t ─────┐
当前关节状态 q_t ───┼─> ACT Decoder ─> 未来 K 步动作
潜变量 z ───────────┘
部署阶段:
多相机图像 I_t ─────┐
当前关节状态 q_t ───┼─> ACT Decoder ─> 未来 K 步动作
z = 0 ───────────────┘
原始 ACT 将策略训练为 CVAE 的 Decoder;CVAE Encoder 在部署时会被丢弃。
5. CVAE Encoder:动作风格编码器
5.1 Encoder 的输入
训练时,随机选择轨迹中的时间点 \(t\),获得:
- 当前关节状态 \(q_t\);
- 未来专家动作块 \(A_t\)。
动作块定义为:
CVAE Encoder 建模:
原始实现为了加快训练,CVAE Encoder 不读取相机图像,只读取:
- 当前关节状态;
- 专家动作序列。
5.2 Token 构造
Encoder 输入可近似表示为:
每个动作经过线性层投影到 Transformer 的 Hidden Dimension,并加入位置编码。
经过 Transformer Encoder 后,取 [CLS] Token 的输出:
然后预测潜变量分布参数:
从而得到:
ACT 将 \(z\) 称为动作序列的 Style Variable。它可以编码:
- 从哪一侧接近;
- 动作快慢;
- 双臂先后顺序;
- 局部轨迹差异;
- 示范者的操作风格。
5.3 重参数化
训练时通过重参数化采样:
这样梯度可以从 Decoder 反向传播到 Encoder。
6. ACT Decoder:真正部署的机器人策略
ACT Decoder 建模:
输入包括:
- 多相机 RGB 图像;
- 当前关节状态;
- Style Latent \(z\)。
输出未来 \(K\) 个动作。
6.1 图像编码
每个相机图像分别经过 CNN,一般使用 ResNet Backbone:
得到空间特征:
随后展平为空间 Token:
并加入二维位置编码,使模型知道每个视觉 Token 来自图像中的哪个位置。
多相机特征随后被拼接:
6.2 本体状态和潜变量编码
当前关节状态通过线性层:
潜变量通过另一线性层:
然后与视觉 Token 一起输入 Transformer Encoder:
Transformer Encoder 负责融合:
- 不同相机视角;
- 物体空间位置;
- 当前机器人姿态;
- 动作风格信息。
6.3 Action Query
ACT 的实现借鉴了 DETR。
模型准备 \(K\) 个可学习的 Action Query:
每个 Query 代表未来动作块中的一个时间位置:
- Query 1:预测 \(a_t\);
- Query 2:预测 \(a_{t+1}\);
- \(\ldots\)
- Query \(K\):预测 \(a_{t+K-1}\)。
Transformer Decoder 执行:
然后通过动作输出头:
最终得到:
7. ACT 的损失函数
ACT 的损失包含两部分:
7.1 动作重建损失
官方实现使用 L1 Loss:
对于轨迹末尾不足 \(K\) 步的部分,会使用 Padding Mask,使补齐的虚假动作不参与有效损失。
代码形式可写为:
all_l1 = torch.nn.functional.l1_loss(
actions,
pred_actions,
reduction="none",
)
valid_mask = (~is_pad).unsqueeze(-1)
l1_loss = (all_l1 * valid_mask).mean()
L1 Loss 相对 MSE 对少量大误差不那么敏感,通常也不容易过度平均尖锐的动作变化。
7.2 KL 散度
CVAE 要求潜变量分布接近标准正态分布:
因此:
对于对角高斯:
总损失为:
7.3 \(\beta\) 的意义
\(\beta\) 控制动作重建与潜变量正则化之间的平衡。
- \(\beta\) 太小:Encoder 可能把整条动作轨迹全部编码进 \(z\),Decoder 过度依赖 \(z\);部署时令 \(z=0\) 会产生较大的训练—测试差异。
- \(\beta\) 太大:潜变量可能发生 Posterior Collapse,\(z\) 几乎不包含动作模式信息。
- 合适的 \(\beta\):让 \(z\) 只表达必要的示范风格,同时让观察条件承担主要预测责任。
8. 推理阶段为什么设置 \(z=0\)
部署时没有未来专家动作 \(A_t\),因此无法计算:
ACT 直接丢弃 CVAE Encoder,并令:
于是推理变为:
这样推理是确定性的。
这也意味着原始 ACT 虽然在训练时使用 CVAE 处理示范的多样性,但默认部署不会不断随机采样多个 \(z\),而是输出学习到的中心风格或典型模式。
9. 两种动作块执行方式
9.1 直接执行整个 Chunk
在时间 \(t\) 查询一次策略:
然后连续执行这 \(K\) 个动作,直到下一次查询。
优点:
- 推理负载低;
- 动作连贯;
- 能显著降低策略查询次数。
缺点:
- 在 \(K\) 步内缺少新的视觉反馈;
- 物体被碰动后不能及时修正;
- Chunk 太长时接近开环控制。
9.2 Temporal Ensembling
ACT 更重要的部署方式是:
每一个控制周期都重新预测一个未来动作块。
例如:
t=0 预测:â0, â1, â2, â3
t=1 预测: â1, â2, â3, â4
t=2 预测: â2, â3, â4, â5
在时刻 \(t=2\),会有多个模型预测对应同一个真实时间点:
ACT 对这些针对同一时刻的预测进行加权平均:
其中:
这和普通低通滤波不同。
普通滤波平均的是不同时间点的动作,例如 \(a_{t-1}\)、\(a_t\) 和 \(a_{t+1}\);ACT 平均的是多个模型对同一个时间点 \(t\) 的预测,因此不会直接把不同轨迹时间位置混在一起。
9.3 Temporal Ensembling 的直觉
较早生成的预测具有:
- 更强的长期轨迹一致性;
- 不容易因为单帧视觉噪声突然改变。
较新的预测具有:
- 更新的视觉信息;
- 更强的环境扰动响应能力。
时间集成在两者之间取得平衡:
10. ACT 的训练数据构造
给定长度为 \(T\) 的示范轨迹,训练时通常执行:
- 随机选择轨迹;
- 随机选择时间点 \(t\);
- 读取当前图像 \(I_t\);
- 读取当前关节状态 \(q_t\);
- 截取未来动作:
- 不足 \(K\) 步时进行 Padding;
- 构造
is_padMask; - 对关节状态和动作进行数据集统计量标准化;
- 前向计算 L1 Loss 和 KL Loss;
- 反向传播并更新参数。
部署时必须使用与训练阶段完全一致的均值和标准差,对当前关节状态进行标准化,并将模型输出反标准化回真实关节目标。
11. ACT 训练伪代码
for images, qpos, actions, is_pad in dataloader:
# images: [B, num_cameras, C, H, W]
# qpos: [B, action_dim]
# actions: [B, chunk_size, action_dim]
# is_pad: [B, chunk_size]
# CVAE Encoder
mu, logvar = encoder(qpos, actions, is_pad)
std = torch.exp(0.5 * logvar)
eps = torch.randn_like(std)
z = mu + std * eps
# ACT Decoder
pred_actions = policy(images, qpos, z)
valid_mask = (~is_pad).unsqueeze(-1)
l1_loss = (
torch.abs(pred_actions - actions) * valid_mask
).mean()
kl_loss = -0.5 * (
1 + logvar - mu.pow(2) - logvar.exp()
).sum(dim=-1).mean()
loss = l1_loss + beta * kl_loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
12. ACT 部署伪代码
action_buffer = {}
for t in range(episode_length):
images = read_cameras()
qpos = read_joint_positions()
qpos_norm = normalize_qpos(qpos)
# 原始 ACT 部署使用 z = 0
z = torch.zeros(1, latent_dim, device=device)
# 输出形状:[1, K, action_dim]
action_chunk = policy(images, qpos_norm, z)
# 将第 i 个预测放到对应的绝对时间 t+i
for i in range(chunk_size):
target_time = t + i
action_buffer.setdefault(target_time, [])
action_buffer[target_time].append(action_chunk[0, i])
predictions = action_buffer[t]
weights = exponential_weights(len(predictions))
action_norm = weighted_average(predictions, weights)
action = denormalize_action(action_norm)
action = apply_safety_limits(action)
send_joint_target(action)
真实系统还应在发送动作前增加:
- 关节上下限裁剪;
- 速度限制;
- 加速度限制;
- 碰撞检测;
- 急停逻辑;
- 相机与机器人时间戳同步检查。
13. Chunk Size 怎么选
Chunk Size 是 ACT 最重要的超参数之一。
13.1 Chunk 太小
当 \(K\approx1\) 时,ACT 接近普通单步 Behavior Cloning:
- 累积误差严重;
- 动作时间结构弱;
- 更容易抖动;
- Transformer 的序列建模优势有限。
13.2 Chunk 太大
当 \(K\) 接近完整 Episode 长度时:
- 模型要一次预测很长轨迹;
- 未来不确定性增大;
- 对视觉扰动反应变慢;
- Temporal Ensemble 的缓存和计算成本增大;
- 容易产生按初始观察执行的开环行为。
13.3 工程选择原则
假设控制频率为 \(f\),Chunk 对应的时间长度为:
通常应让一个 Chunk 覆盖一个有意义的局部动作阶段,例如:
- 接近物体;
- 完成抓取;
- 完成一次插入;
- 抬起并转移一小段。
可使用以下范围作为初始实验配置:
| 控制频率 | Chunk Size | 覆盖时间 |
|---|---|---|
| \(10\ \mathrm{Hz}\) | 10–30 | 1–3 秒 |
| \(20\ \mathrm{Hz}\) | 20–60 | 1–3 秒 |
| \(50\ \mathrm{Hz}\) | 50–100 | 1–2 秒 |
14. ACT 常见失败模式
14.1 机器人动作中途暂停
可能原因:
- 数据中存在较多停顿;
- 训练时间不足;
- 多种示范节奏相互冲突;
- Chunk 太短;
- Temporal Aggregation 权重过度偏向旧预测。
14.2 动作抖动
常见原因:
- 没有启用 Temporal Ensemble;
- 图像或关节状态不同步;
- 动作标准差太小,反标准化时放大噪声;
- 底层控制器跟踪性能不足;
- 示范动作本身不平滑;
- 模型尚未充分收敛。
14.3 预测出平均动作
假设数据中一半示范从左侧绕行,一半从右侧绕行。
虽然 CVAE 可以在训练阶段把两种模式编码到不同的 \(z\),但部署时固定 \(z=0\) 仍可能落在两个模式之间。
常见解决方式:
- 统一示范策略;
- 按动作模式拆分任务;
- 加入语言条件或任务 ID;
- 部署时采样多个 \(z\) 并选择轨迹;
- 使用表达能力更强的生成策略,如 Diffusion Policy。
14.4 开始动作正确,后期逐渐漂移
可能原因:
- 数据没有覆盖失败恢复状态;
- 相机视角下目标逐渐被遮挡;
- Episode 太长;
- 没有使用历史信息;
- 策略只依赖瞬时观察,存在感知歧义。
ACT 能缓解累积误差,但不能彻底解决训练分布之外的状态恢复问题。
14.5 训练 Loss 低但真实成功率低
这通常意味着:
需要重点检查:
- 相机标定和安装位置是否变化;
- 图像预处理是否与训练一致;
qpos和 Action 标准化是否正确;- 动作定义是 Absolute、Delta 还是 Velocity;
- 控制频率是否匹配;
- 夹爪量程是否一致;
- 是否存在网络或相机延迟;
- 训练集是否覆盖物体位置变化。
15. ACT 与 Diffusion Policy 对比
两者的共同点是:
但生成动作序列的方法不同。
| 特性 | ACT | Diffusion Policy |
|---|---|---|
| 生成模型 | CVAE | 条件扩散模型 |
| 推理方式 | 一次 Transformer 前向 | 多步迭代去噪 |
| 输出 | 动作 Chunk | 动作轨迹 |
| 多模态能力 | 中等 | 通常更强 |
| 推理延迟 | 较低 | 通常较高 |
| 训练复杂度 | 较低 | 较高 |
| 时间平滑 | Temporal Ensemble | 轨迹生成与 Receding Horizon |
| 部署确定性 | 默认 \(z=0\) | 可确定或随机采样 |
| 适用场景 | 实时性强、数据较统一 | 行为高度多模态、轨迹复杂 |
15.1 适合选择 ACT 的情况
- 控制频率高;
- GPU 算力有限;
- 需要较低推理延迟;
- 单任务或少量任务;
- 示范行为比较一致;
- 希望快速建立机器人模仿学习基线。
15.2 适合选择 Diffusion Policy 的情况
- 同一场景存在明显的多种合法轨迹;
- 动作空间较复杂;
- 推理预算充足;
- 数据规模较大;
- 需要更强的动作分布建模能力。
16. ACT 最本质的理解
不要把 ACT 简单理解为:
用 Transformer 输出多个动作。
ACT 真正有效的是以下设计共同作用:
- Action Chunking:学习局部运动原语,减轻长时程累积误差;
- CVAE:处理人类示范的随机性和多种动作风格;
- Transformer:融合多相机视觉、本体状态和动作序列结构;
- Temporal Ensembling:在每步重新观察环境的同时保持动作平滑。
一句话概括:
ACT 是一个以当前视觉和机器人状态为条件,利用 CVAE-Transformer 一次生成未来动作块,并通过重叠动作块的时间集成实现平滑闭环控制的模仿学习策略。