想象一位街头艺人要连续表演十次抛接球,每次接住球再抛向空中。如果每次都等球落到掌心才开始准备下一次抛掷,动作会手忙脚乱、节奏拖沓。但高手会把十次抛接看作一个连贯的“手势串”,一次规划好轨迹,手像流水一样顺滑完成全套动作。具身智能中的 ACT(Action Chunking Transformer)算法,正是让机器人学会这种“成套出手”的本领——不再一步一停地挤牙膏式输出动作,而是一次性端出一盘连续动作的“拼盘”。本文用“操盘手排练手势串”的故事,带你拆解动作分块 ACT 的构思、架构与训练秘诀。

岗位关联

对 AI 从业者而言,ACT 是理解“预测式控制如何赋能真实机器人”的经典范本,学透它能帮你快速上手具身智能领域的策略建模与部署。

目录
  1. 可视化演示
  2. ACT概述
  3. BCT的困境
  4. 动作分块思想
  5. CTransformer架构
  6. 训练策略
  7. 策略头设计
  8. 对比BC优势
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示具身智能动作分块ACT算法原的核心机制,通过开始/执行/监控/完成四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

具身智能动作分块ACT算法原:动作分块 动作分块的核心动机与设计思想 CTransformer架构设 核心机制可视化 具身智能动作分块ACT算法原整体架构与关键组件

ACT概述

操盘手拿到一份全新的“手势串”剧本时,不会急着先比划第一个动作,而是先把整段手势在心里默排一遍,再连贯地演出来。ACT(Action Chunking Transformer,动作分块 Transformer)正是这样一个“先想后动”的策略模型:它观察当前环境图像和任务指令,一次性地输出未来一段时间内的完整动作序列,而不是只决定“下一步该怎么做”。

从技术身份看,ACT 属于模仿学习(Imitation Learning)家族——它从人类示教数据中学习“看到什么状态就输出什么动作”的映射。但与经典行为克隆(Behavior Cloning, BC)不同,ACT 的输出粒度不是一个动作,而是一段动作块(action chunk),这正是它名字里“Chunking“的由来。你可以把动作块理解为”把 30 个单步动作打包成一张连续的操作清单”。

ACT 的提出来自斯坦福团队的 ALOHA 机器人项目,旨在解决双机械臂精细操作(如拉链、穿针)中“动作卡顿、误差累积”的痛点。它把 Transformer 的序列建模能力和条件变分自编码器(CVAE)的分布建模能力结合,成为具身智能领域“预测式控制”路线的代表作。简单说:给机器人一双“会预演的眼睛”和一副“会写连笔字的笔”。

BCT的困境

想象一位新手操盘手一次只练一个动作:先比一个“剪刀手”,停下来想想,再比一个“握拳”,再停下来……虽然每一步都标准,但连起来看就像卡顿的视频,毫无行云流水之感。传统行为克隆 BC(Behavior Cloning Transformer)正是这种“一步一测”的典型:模型每一步都根据当前观测预测一个动作,执行完再重新预测下一步。

这种“挤牙膏”式策略在真实机器人上会放大三个问题。第一是误差累积:第一步预测偏移一点点,执行后状态和演示分布出现偏差,第二步基于偏差状态预测又偏一点,就像醉汉走路越走越歪。第二是动作不连贯:每一步都是独立决策,相邻动作之间缺少约束,会出现莫名其妙的抖动或停顿。第三是长程任务的漂移:任务越长,累积误差越大,最终完全偏离演示轨迹。

更隐蔽的痛点是数据利用率低。每一步只学一个动作,模型很难捕捉“连续动作之间的时序相关性”——明明十个动作是成套编排的,却被硬生生拆成十次独立学习。这好比教学生弹钢琴时,不教整段乐句,只让每个音符单独练,学生永远学不会“乐感”。

这些困境指向同一个答案:机器人需要的不是“下一步的碎片指令”,而是“未来一段时间的整体规划”。ACT 的动作分块思想正是针对这个靶心射出的一支利箭。

动作分块思想

既然一步一测会让人手忙脚乱,那干脆一次打包十次动作再出手——这就是动作分块(Action Chunking)的核心直觉。ACT 在每一个决策时刻,不是输出单个动作,而是输出长度固定的一段动作序列,比如未来 30 步的关节角度、末端位置或夹爪开合指令。这段序列就是“动作块”。

动作分块带来了立竿见影的三个好处。第一,误差累积被截断:每 30 步才做一次预测,在这 30 步内机器人按照预先规划的动作块执行,不会被单步误差带偏;执行完一个块再根据最新观测重新规划下一个块,误差被“分段清零”。第二,执行连贯性大幅提升:块内的动作天然是连续轨迹的一部分,不会出现一步一停的卡顿。第三,推理频率降低:原本每步都要跑一次模型,现在每 30 步才跑一次,计算开销和延迟显著下降。

形式化地看,动作分块是对策略输出的一个时序抽象。设机器人在时刻 $t$ 的观测为 $o_t$,动作分块长度 $k$,则策略输出的不是 $a_t$,而是从 $t$ 到 $t+k$ 的动作序列:

比喻回扣:动作分块就像操盘手把十次抛接球的轨迹画成一张连贯的“手势谱面”,每次拿到谱面就一口气演完,而不是每抛一次球都停下来翻谱。误差被“谱段”截断,节奏由“块”掌控,整场表演自然如行云流水。

at:t+k={at, at+1, ⋯ , at+k−1}\displaystyle a_{t:t+k} = \{ a_t,\ a_{t+1},\ \cdots,\ a_{t+k-1} \}
动作分块的本质是“用一段整体规划代替单步决策”,相当于把连续控制问题从单步预测扩展为短时域规划。它让误差无法无限累积,让操作更接近人的整体运动控制。
  1. 动作序列定义策略一次性输出未来 $k$ 步的动作序列,$k$ 是分块长度(如 30 步)。
    at:t+k={at, at+1, ⋯ , at+k−1}\displaystyle a_{t:t+k} = \{ a_t,\ a_{t+1},\ \cdots,\ a_{t+k-1} \}
  2. 下标语义$a_{t:t+k}$ 表示从时刻 $t$ 到 $t+k-1$ 的 $k$ 个动作,方括号表示集合包含关系,$a_t$ 是当前时刻动作。
    at:t+k∈Rk×da\displaystyle a_{t:t+k} \in \mathbb{R}^{k \times d_a}
  3. 矩阵维度$k$ 行 $d_a$ 列,$d_a$ 是单步动作维度(如 7 个关节角),整块动作是一个矩阵而非向量。
    A=[at; at+1; ⋯ ; at+k−1]\displaystyle A = [a_t;\ a_{t+1};\ \cdots;\ a_{t+k-1}]

CTransformer架构

操盘手要演好一套手势串,需要一个“导演”帮他构思整体编排,还需要一个“执行者”把编排落实到每个手指的动作。ACT 的 CTransformer 架构正是这样一对配合:编码器当导演,解码器当执行者,二者合体成为条件变分自编码器(CVAE)。

CVAE 是 ACT 的骨架。它的“条件”二字指的是:整个模型以当前观测(摄像头图像 + 机械臂状态)为条件,生成动作块。训练时,编码器把专家演示的动作块压缩成一个隐变量 $z$(相当于导演从整场演出中提炼出的“风格摘要”);推理时,解码器不依赖编码器,而是在给定观测和隐变量的条件下直接生成动作块。隐变量在推理时从先验分布中采样,相当于每次表演时导演给执行者一个细微的“即兴提示”,让动作具有合理多样性。

ACT 的编码器是视觉 Transformer(ViT)——把多视角图像切成 patch 后做自注意力,提取出富含空间语义的视觉特征;解码器是 Transformer 解码器,通过交叉注意力把视觉特征和隐变量融合,逐位置生成动作序列。CTransformer 的完整流程是:图像特征 + 状态向量 + 隐变量 → 解码器逐 token 输出动作块。整个模型用专家示教数据做端到端训练,目标是让生成的动作块尽可能接近演示的动作块:

比喻回扣:编码器像导演看完彩排后写下“这场演出要活泼灵动”的风格笔记,推理时机械臂则像熟练的执行者,拿到“活泼灵动”的提示和当前舞台画面,就能即兴编排并演出一整段流畅的手势串。

z∼qϕ(z∣st,at:t+k),a^t:t+k=fθ(st, z)\displaystyle z \sim q_{\phi}(z \mid s_t, a_{t:t+k}) \quad,\quad \hat{a}_{t:t+k} = f_{\theta}(s_t,\ z)
CTransformer 本质是 CVAE:训练时编码器捕捉动作块的风格分布(隐变量),推理时解码器在条件观测下直接生成动作块。这种“训练有导演、推理靠执行者”的设计让输出既稳又有多样性。
  1. 隐变量采样训练时从后验分布 $q_{\phi}$ 中采样隐变量 $z$,$s_t$ 是当前状态,$a_{t:t+k}$ 是演示动作块。
    z∼qϕ(z∣st,at:t+k)\displaystyle z \sim q_{\phi}(z \mid s_t, a_{t:t+k})
  2. 动作生成解码器 $f_{\theta}$ 以条件状态和隐变量 $z$ 为输入,生成预测动作块;$\theta$ 是解码器参数。
    a^t:t+k=fθ(st, z)\displaystyle \hat{a}_{t:t+k} = f_{\theta}(s_t,\ z)
  3. 推理简化推理时无演示动作可用,改为从先验分布 $p_{\psi}(z \mid s_t)$ 采样,再代入上式生成动作块。
    z∼pψ(z∣st)\displaystyle z \sim p_{\psi}(z \mid s_t)

训练策略

要教操盘手演好手势串,光给剧本不够,还得反复排练、纠正偏差。ACT 的训练策略同样讲究“排练与纠偏”:它在模仿学习的框架下做联合训练,用多条损失函数约束模型,让生成的动作块不仅“像”演示,还要“稳”。

ACT 的训练损失主要由三部分构成。其一是重建损失(reconstruction loss):让解码器重建的动作块与专家演示动作块之间的均方误差最小化,这是模仿学习的核心目标。其二是 KL 散度损失:约束编码器输出的后验分布 $q_{\phi}$ 与先验分布 $p_{\psi}$ 尽量接近,确保推理时从先验采样不会偏离训练分布。其三是 L1 损失作为辅助:相比 L2(MSE),L1 对离群点更鲁棒,能减少动作块中偶发的尖峰抖动。

训练时,编码器(导演)和解码器(执行者)是端到端联合优化的。专家示教数据以“状态-动作块”配对的形式喂入模型,梯度同时回传到视觉编码器和动作解码器。这种联合训练的好处是:视觉特征并非独立预训练,而是为了生成高质量动作块而自适应调整,就像导演和演员在排练中互相磨合、共同进步。

整体损失函数可写作:

比喻回扣:训练就像操盘手的排练厅——L1 损失是导演说“你的手势偏离剧本太多了”,KL 散度是导演说“你的即兴发挥别太离谱”。两条鞭子一起抽,操盘手越练越稳,最终既能忠实剧本,又保留一点个人风格。

L=E(s,at:t+k)∼D[∥a^t:t+k−at:t+k∥1+β⋅DKL(qϕ(z∣s,at:t+k) ∥ pψ(z∣s))]\displaystyle \mathcal{L} = \mathbb{E}_{(s, a_{t:t+k}) \sim \mathcal{D}} \left[ \| \hat{a}_{t:t+k} - a_{t:t+k} \|_1 + \beta \cdot D_{\mathrm{KL}}\big( q_{\phi}(z \mid s, a_{t:t+k}) \ \|\ p_{\psi}(z \mid s) \big) \right]
训练策略的两条腿:L1 重建损失保证动作块“像演示”,KL 散度约束保证隐变量“不乱跑”,二者联合让模型既准确又稳定。
  1. 期望与数据分布$\mathcal{D}$ 是专家示教数据集,期望表示对所有示教样本取平均,$s$ 是状态,$a_{t:t+k}$ 是演示动作块。
    L=E(s,at:t+k)∼D[∥a^t:t+k−at:t+k∥1+β⋅DKL(⋅)]\displaystyle \mathcal{L} = \mathbb{E}_{(s, a_{t:t+k}) \sim \mathcal{D}} \left[ \| \hat{a}_{t:t+k} - a_{t:t+k} \|_1 + \beta \cdot D_{\mathrm{KL}}( \cdot ) \right]
  2. L1 重建损失$\| \cdot \|_1$ 是 L1 范数,即预测与真值的绝对误差之和,鼓励逐元素贴近演示动作块,对离群点不敏感。
    ∥a^t:t+k−at:t+k∥1=∑i=1k∣a^t+i−at+i∣\displaystyle \| \hat{a}_{t:t+k} - a_{t:t+k} \|_1 = \sum_{i=1}^{k} | \hat{a}_{t+i} - a_{t+i} |
  3. KL 散度约束$D_{\mathrm{KL}}$ 衡量两个分布的差异,$q_{\phi}$ 是后验,$p_{\psi}$ 是先验,$\beta$ 是平衡两项损失的权重。
    β⋅DKL(qϕ(z∣s,at:t+k) ∥ pψ(z∣s))\displaystyle \beta \cdot D_{\mathrm{KL}}\big( q_{\phi}(z \mid s, a_{t:t+k}) \ \|\ p_{\psi}(z \mid s) \big)

策略头设计

当操盘手站上舞台,他需要一个清晰的“出场提示”来知道自己该从哪个动作开始。ACT 的策略头设计解决的就是这个问题:如何让解码器在推理时有序地生成一整段动作块。

ACT 的策略头采用了一个巧妙的设计——查询向量(query)机制。它不是让解码器自动回归地逐个生成动作 token(像写文章那样逐个字蹦),而是预设一组“查询位置编码”,每个位置对应动作块中的一个时间步。解码器用这组查询向量去注意力池中检索相关信息,一次性并行解码出整段动作序列。这就像一个乐队的首席,不用逐拍指挥,而是用一套手势提示所有乐手同时演奏出完整的和弦。

这组查询向量其实是在模仿“位置编码”的工作方式:每个查询 $q_i$ 代表“时刻 $t+i$ 的动作应该是什么”。解码器对每个查询独立执行交叉注意力,输出对应的动作 token,所有 token 拼起来就是动作块。由于查询之间通过自注意力交互,动作块内部依然保持时序一致性——既有并行生成的速度,又有序列建模的连贯。

从控制角度看,策略头输出的动作块是一个矩阵,每一行是某一时刻的所有关节指令。机器人拿到这个矩阵后,直接按时间顺序执行即可,无需中途重新规划。这种“查表式”执行方式极大地简化了控制回路,且天然贴合低层控制器的高频执行需求。

比喻回扣:策略头就像舞台监制给操盘手的一组“出场提示牌”——每张牌写着“第 3 秒做握拳、第 6 秒做翻转”,操盘手一眼扫完所有牌子,就能行云流水地演完整套动作,不用每做一个动作回头看一眼提示。

ActionChunk=DecoderHead(VisionTokens, QueryTokens)\displaystyle \text{ActionChunk} = \text{DecoderHead}(\text{VisionTokens},\ \text{QueryTokens})
策略头设计的关键是“用查询向量并行解码动作块”:一组位置查询对应一组动作输出,一步前向传播生成整段动作,兼顾速度与连贯性。
  1. 动作块生成DecoderHead 是解码器策略头,VisionTokens 是视觉编码器输出的图像特征 token,QueryTokens 是 $k$ 个查询向量。
    ActionChunk=DecoderHead(VisionTokens, QueryTokens)\displaystyle \text{ActionChunk} = \text{DecoderHead}(\text{VisionTokens},\ \text{QueryTokens})
  2. 查询数量查询向量个数等于动作块长度 $k$,第 $i$ 个查询负责生成第 $i$ 个动作;$k$ 个查询可并行处理。
    {q1, q2, ⋯ , qk}↦{at, at+1, ⋯ , at+k−1}\displaystyle \{ q_1,\ q_2,\ \cdots,\ q_k \} \mapsto \{ a_t,\ a_{t+1},\ \cdots,\ a_{t+k-1} \}
  3. 多模态控制查询机制天然支持多维度动作输出,$d_a$ 维的向量可同时表达关节、夹爪或末端笛卡尔坐标指令。
    A^∈Rk×da\displaystyle \hat{A} \in \mathbb{R}^{k \times d_a}

对比BC优势

从“一步一测”升级到“动作分块”,ACT 到底赢在哪里?用一句话概括:BC 像在流沙上砌砖,ACT 像用预制板搭桥。BC 的每一步预测都建立在执行前一步之后的新状态上,这个状态已偏离演示分布,导致误差在时间轴上随机游走、越积越大;ACT 则在一个动作块内不参考新观测,直接按块执行,误差只能在每个块的边界处重置,不会被放大。

从数学视角看,两者差异可以刻画为误差传播方差的差异。设单步预测误差的方差为 $\sigma^2$,BC 执行 $T$ 步后累积方差约为 $T\sigma^2$(发散型),而 ACT 每 $k$ 步重置一次误差,累积方差约为 $k\sigma^2$(有界型)。动作块长度 $k$ 远小于 $T$,因此 ACT 的轨迹方差显著更小,这就是它“更稳”的数学根源。

除了稳定性,ACT 在执行平滑度和数据效率上同样占优。块内动作共享同一段上下文生成,天然连续,不像 BC 那样步与步之间可能突变。训练时,ACT 一次性学习 $k$ 步的动作序列,能够捕捉动作间的时序相关性,数据利用率更高——好比学生一次学一整句句型结构,而不是孤立记单词。综合来看,ACT 在长程精细操作上的成功率远高于 BC,这也是它成为具身智能领域标杆方法的原因。

| 对比维度 | BC(一步一测) | ACT(动作分块) |

|---|---|---|

| 误差传播 | 随步数累积、发散 | 分块边界重置、有界 |

| 轨迹平滑 | 步间突变、抖动明显 | 块内连续、平滑稳定 |

| 决策频率 | 每步推理一次 | 每块推理一次 |

| 数据利用 | 逐点学习、忽略时序 | 整块学习、捕捉关联 |

| 长程成功率 | 任务越长越差 | 长度鲁棒性更强 |

比喻回扣:如果说 BC 是“走一步看一步”的盲人摸象,ACT 就是“举着手电筒照出十步路”的夜行者。误差不再是无限累积的雪球,而是被“块”这个护栏一段段挡住,让机器人的每次出手都稳如磐石。

AI 应用场景

场景一:ALOHA 双机械臂精细操作

阶段:模仿学习与动作生成

解决的问题:传统 BC 在双机械臂协同任务(如拉上拉链、穿针引线)中,每步推理导致动作卡顿、误差累积,长程操作成功率极低。ACT 通过动作分块让两条机械臂分别生成同步的动作块,按块执行,显著降低误差漂移。

具体案例:在 ALOHA 平台上,研究人员用 ACT 训练机械臂完成“整理桌子”任务:识别桌上物品位置,一次规划 30 步的夹取与移动动作块,连续执行完整个整理流程而不中途停顿,成功率远超 BC 基线。

场景二:灵巧手抓取与操作

阶段:策略部署与闭环控制

解决的问题:灵巧手自由度极高,每步预测会带来累计位移误差,且高频推理对算力要求苛刻。ACT 的低频推理特性(每 30 步一次)让灵巧手能在嵌入式设备上流畅运行。

具体案例:在灵巧手旋转魔方场景中,ACT 将每次旋转动作打包成一个动作块,块内各关节按规划轨迹协同运动,实现魔方面的连续翻转与换面,块边界处用最新视觉反馈修正下一块规划。

场景三:自动驾驶车辆的运动规划

阶段:行为预测与轨迹规划

解决的问题:自动驾驶中,逐帧预测轨迹会产生累积漂移,且高频决策消耗计算资源。借鉴动作分块思想,车辆一次预测未来 3~5 秒的轨迹块,块内按规划执行,块边界再结合新感知更新轨迹。

具体案例:在城市道路跟车场景中,ACT 风格的轨迹块生成模块输出一段平滑的加速/转向指令序列,车辆稳定跟随前车,避免逐帧预测带来的抖动和急刹。

Python 演示

python88 行
import torchimport torch.nn as nnimport math class PositionalEncoding(nn.Module):    """位置编码:给查询向量注入时间步信息"""    def __init__(self, d_model, max_len=100):        super().__init__()        pe = torch.zeros(max_len, d_model)        pos = torch.arange(max_len).unsqueeze(1).float()        div = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))        pe[:, 0::2] = torch.sin(pos * div)        pe[:, 1::2] = torch.cos(pos * div)        self.register_buffer('pe', pe.unsqueeze(0))     def forward(self, x):        return x + self.pe[:, :x.size(1)] class CVAEEncoder(nn.Module):    """编码器:以 状态+动作块 -> 隐变量分布"""    def __init__(self, obs_dim, act_dim, chunk_size, latent_dim=32):        super().__init__()        self.net = nn.Sequential(            nn.Linear(obs_dim + act_dim * chunk_size, 256),            nn.ReLU(), nn.Linear(256, 128), nn.ReLU())        self.mu_head = nn.Linear(128, latent_dim)        self.logvar_head = nn.Linear(128, latent_dim)     def forward(self, obs, action_chunk):        x = torch.cat([obs, action_chunk], dim=-1)        h = self.net(x)        return self.mu_head(h), self.logvar_head(h)     def sample(self, obs, action_chunk):        mu, logvar = self.forward(obs, action_chunk)        std = torch.exp(0.5 * logvar)        eps = torch.randn_like(std)        return mu + eps * std class ActionDecoder(nn.Module):    """解码器:以 状态+隐变量+查询位置 -> 动作块"""    def __init__(self, obs_dim, act_dim, chunk_size, latent_dim=32, d_model=128):        super().__init__()        self.d_model = d_model        self.chunk_size = chunk_size        self.pos_enc = PositionalEncoding(d_model)        self.input_proj = nn.Sequential(            nn.Linear(obs_dim + latent_dim, d_model), nn.ReLU())        self.query_emb = nn.Parameter(torch.randn(1, chunk_size, d_model))        self.cross_attn = nn.MultiheadAttention(d_model, 4, batch_first=True)        self.self_attn = nn.MultiheadAttention(d_model, 4, batch_first=True)        self.out_proj = nn.Linear(d_model, act_dim)     def forward(self, obs, z):        B = obs.size(0)        ctx = self.input_proj(torch.cat([obs, z], dim=-1)).unsqueeze(1)        q = self.query_emb.expand(B, -1, -1)        q = self.pos_enc(q)        attn_out, _ = self.cross_attn(q, ctx, ctx)        attn_out, _ = self.self_attn(attn_out, attn_out, attn_out)        action_chunk = self.out_proj(attn_out)        return action_chunk class SimplifiedACT(nn.Module):    """简化版 ACT:CVAE 编码器 + 动作解码器"""    def __init__(self, obs_dim, act_dim, chunk_size, latent_dim=32):        super().__init__()        self.chunk_size = chunk_size        self.encoder = CVAEEncoder(obs_dim, act_dim, chunk_size, latent_dim)        self.decoder = ActionDecoder(obs_dim, act_dim, chunk_size, latent_dim)     def forward(self, obs, action_chunk):        z = self.encoder.sample(obs, action_chunk)        return self.decoder(obs, z)     def predict(self, obs):        z = torch.randn(obs.size(0), 32)        return self.decoder(obs, z) if __name__ == '__main__':    torch.manual_seed(0)    B, obs_dim, act_dim, chunk_size = 4, 16, 7, 30    model = SimplifiedACT(obs_dim, act_dim, chunk_size)    obs = torch.randn(B, obs_dim)    demo_chunk = torch.randn(B, chunk_size * act_dim)    pred_chunk = model(obs, demo_chunk)    print('输出形状:', pred_chunk.shape)    print('隐变量采样生成的预测块形状:', model.predict(obs).shape)
目的:演示 ACT 的核心数据流——编码器将“状态 + 演示动作块”压缩为隐变量,解码器以“状态 + 隐变量 + 查询位置”并行解码生成完整动作块。
  1. class CVAEEncoder编码器网络,把状态和动作块拼起来,映射为隐变量的均值和方差。
  2. mu + eps * std重参数化采样,让随机性可微,反向传播得以通过采样节点。
  3. self.query_emb = nn.Parameter(...)一组可学习的查询向量,每个对应动作块中的一个时间步。
  4. self.pos_enc(q)向查询注入位置信息,让解码器知道每个查询代表第几步动作。
  5. self.cross_attn(q, ctx, ctx)查询从状态上下文检索信息,生成对应时刻的动作指令。
  6. self.self_attn(...)块内自注意力,让各时刻动作彼此协调,保持连贯性。
  7. model.predict(obs)推理时不需要真实动作块,从标准正态采样隐变量即可生成动作块。

常见误区

误区我以为动作分块就是把原来的单步动作在时间上复制几份,或者把几个连续动作简单首尾相连,就算完成“分块”了。

正解动作分块不仅拼接动作,而是让模型以整段动作为目标做联合预测。每个动作块作为一个整体被优化,块内动作共享上下文信息、彼此协调。就像编排舞蹈,不是把几个独舞动作连起来,而是让每个动作都服务于整段舞蹈的韵律。

为何常见:因为“分块”这个字面词容易让人联想到数据打包、拼接,忽略了它在建模层面“整体预测、联合优化”的本质。

误区既然分块能减少误差,那我直接把分块长度设成 200、500,岂不是能让机器人一次规划完整场任务?

正解分块长度并非越大越好。块越长,单次预测的难度越高,模型越难精准预测远期动作;而且面对突发扰动时,过长的块意味着“撞了南墙也不回头”。ACT 通常选 30~100 步作为折中,既能覆盖一段连贯动作,又保留块边界的纠错机会。

为何常见:人们容易从“分块减少误差”推导出“分得越多越好”,忽略了预测难度和闭环修正频率之间的平衡。

误区ACT 推理时直接从先验采样隐变量,编码器完全被跳过了,那训练编码器是不是浪费算力?

正解编码器是训练阶段的关键“导演”。它把专家演示动作块压缩成隐变量的后验分布,让解码器学会“看到隐变量就还原动作块”。推理时虽然不用编码器,但解码器早已在训练中内化了“隐变量-动作块”的映射关系。没有编码器的训练,解码器就成了无源之水。

为何常见:只看到推理流程图里编码器没有出现,忽略了训练阶段编码器对解码器能力的塑造作用。

误区ACT 是 ALOHA 项目的专用算法,换到单臂或轮式机器人上应该就不行了。

正解ACT 的“动作分块 + CVAE”思想是通用的策略建模方法,只要任务能用“状态-动作轨迹”描述,就能应用。单臂抓取、灵巧手操作、移动操作甚至自动驾驶轨迹规划等领域,都有 ACT 风格方法的成功案例。它解决的是“一步一测误差累积”的共性痛点。

为何常见:因为 ACT 论文以 ALOHA 硬件平台的实验为主,读者容易把算法绑定到特定硬件上。

误区既然 ACT 一次性输出 30 步动作且块内不观测新状态,那它不是开环控制吗?是不是完全放弃了反馈?

正解ACT 不是彻底的开环,而是“块内开环、块间闭环”。执行完一个动作块后,机器人会用最新观测重新规划下一个块,相当于在每个块边界处做一次反馈修正。这种设计既保留了规划和执行的连贯性,又不会完全失明。好比司机不是每分钟都重新看路,但每个路口都会确认方向。

为何常见:看到“一次输出一段动作”就容易联想到“开环”,忽略了动作块边界处的重规划机制。

面试题

Q1. ACT 中“动作分块”指的是什么?

单选题 · easy

  • A.把长任务拆成多个子任务
  • B.一次预测并输出一整段动作序列← 正确答案
  • C.把动作库压缩成小块存储
  • D.把单个动作重复执行多次

答案:B。动作分块是指策略在每一步决策时输出未来 $k$ 步的动作序列(动作块),而不是单个动作。A 选项描述的是任务分解而非动作输出粒度;C 选项是存储压缩概念;D 选项是重复执行,与分块的“一次规划整段”本质不同。

Q2. 传统 BCT(一步一测)方法最核心的缺陷是什么?

单选题 · easy

  • A.模型参数量过大
  • B.每步预测误差在时间轴上累积漂移← 正确答案
  • C.无法处理图像输入
  • D.训练数据必须人工标注

答案:B。BCT 每步只预测一个动作,执行后基于新状态再预测下一步。单步误差会传导到下一步的状态中,形成累积漂移,这是它长程任务成功率低的根源。参数、图像输入、数据标注并非 BCT 的核心瓶颈。

Q3. ACT 采用 CVAE 架构的核心动机是什么?

单选题 · mid

  • A.压缩模型参数量
  • B.让动作生成具有合理多样性的同时保持稳定← 正确答案
  • C.加速推理速度
  • D.替代视觉编码器

答案:B。CVAE 通过隐变量捕捉任务中的多模态信息,推理时从先验采样得到合理差异,又通过编码器的分布约束避免动作不合理偏离。压缩参数量、加速推理、替代视觉编码器都不是 CVAE 的核心作用。

Q4. 动作分块长度 $k$ 的影响,下列说法正确的是?

单选题 · mid

  • A.$k$ 越大越好,反正能减少推理次数
  • B.$k$ 越小越好,预测更精准
  • C.$k$ 需要权衡预测难度与误差重置频率← 正确答案
  • D.$k$ 只影响推理速度不影响精度

答案:C。$k$ 过大会增加单次预测难度、降低对扰动的响应能力;$k$ 过小则退化为一步一测。因此需要权衡,一般取 30~100 步。选项 C 准确描述了这一权衡关系,其他选项都过度绝对化。

Q5. 关于 ACT 的训练损失,下列说法正确的是?(多选)

单选题 · mid

  • A.使用 L1 损失对离群点更鲁棒← 正确答案
  • B.KL 散度约束隐变量分布接近先验← 正确答案
  • C.不需要重建损失
  • D.编码器和解码器是联合训练的← 正确答案

答案:ABD。ACT 使用 L1 重建损失保证动作块贴演示,L1 相比 L2 对离群点更鲁棒;KL 散度约束后验分布与先验接近;编码器与解码器端到端联合训练。重建损失是训练目标的核心,C 选项明显错误。

Q6. ACT 策略头中使用“查询向量”的作用是什么?

单选题 · mid

  • A.存储训练好的动作块
  • B.并行解码生成整段动作序列← 正确答案
  • C.压缩图像特征
  • D.计算损失函数

答案:B。查询向量组对应动作块中的每个时间步,每个查询通过注意力机制从视觉特征中检索信息,并与其他查询交互,从而并行生成整段动作序列。它们既不存储数据、不压缩图像,也不计算损失。

Q7. 相比 BCT,ACT 在哪些方面具有优势?(多选)

单选题 · hard

  • A.长程任务误差累积更小← 正确答案
  • B.轨迹平滑性更强← 正确答案
  • C.推理频率更低← 正确答案
  • D.一定比 BCT 模型参数少

答案:ABC。ACT 的动作分块使误差在块边界重置而不会无限累积,块内动作共享上下文使轨迹平滑,整块推理也降低了频率。但 ACT 因为 Transformer + CVAE 结构,参数通常比 BCT 更多而非更少,D 错误。

Q8. 推理时,ACT 的隐变量 $z$ 从哪里获得?

单选题 · hard

  • A.由编码器对当前观测编码得到
  • B.从先验分布 $p_{\psi}(z \mid s_t)$ 中采样← 正确答案
  • C.直接从训练数据中查找
  • D.解码器自己学习得到

答案:B。推理时没有演示动作块可用,无法用编码器计算后验分布。ACT 从以当前状态为条件的先验分布中采样获得 $z$,再交给解码器生成动作块。训练后编码器不再参与推理,A、C、D 都不对。

Q9. 以下哪个任务最适合使用 ACT 的动作分块思想?

单选题 · easy

  • A.单步按钮按下
  • B.连续 5 秒的插拔 USB 动作← 正确答案
  • C.单次关节角度读取
  • D.每帧图像分类

答案:B。动作分块适用于“有连续时序、需要连贯执行”的操作任务。连续 5 秒的插拔 USB 涉及多步骤连续动作控制,是 ACT 的理想场景。A、C 是单步动作,D 是感知任务而非动作生成任务。

Q10. 关于动作分块训练的数据利用效率,下列说法正确的是?(多选)

多选题 · hard

  • A.每次学习一整段动作序列,捕捉时序相关性← 正确答案
  • B.分块间重叠部分会被重复利用← 正确答案
  • C.相比单步学习,数据利用率更高← 正确答案
  • D.分块后每个样本独立,无任何关联

答案:ABC。ACT 以整段动作序列为学习目标,能捕捉动作间的时间关联;实际训练中分块窗口重叠使得部分数据被多次使用,提升了样本利用效率。D 完全相反,分块之间因重叠窗口而存在关联。