第一部分:ACT 阶段总结——从 Behavior Cloning 到完整的 Transformer Action Policy
经过第 1~19 课,我们已经从最简单的神经网络训练,逐步走到了第一个完整的机器人操作学习模型:
ACT(Action Chunking with Transformers)。
对应论文为 Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware,作者包括 Tony Z. Zhao、Vikash Kumar、Sergey Levine 和 Chelsea Finn,发表于 2023 年。
官方代码:tonyzhaozh/act。
这部分总结要回答三个问题:
ACT 想解决什么?它怎样训练?它又怎样真正驱动机器人?
一、ACT 的核心:不是一次预测一个动作,而是学习一段连续行为
我们最早的 Behavior Cloning(BC)是:
\[ \hat a_t=\pi_\theta(o_t) \]
假设机器人要完成一次抓取,需要连续经历:
动作 1
靠近物体
动作 2
下降夹爪
动作 3
闭合夹爪
动作 4
抬起物体
这是便于理解的动作阶段示意;真实机器人一段动作通常包含远多于四个控制时间步。
普通单步 BC 每次只预测当前动作。ACT 则直接输出一段未来动作:
\[ \boxed{ \hat A_t = \pi_\theta(o_t,z) = [\hat a_t,\hat a_{t+1},\ldots,\hat a_{t+K-1}] } \]
其中:
-
\(o_t\):当前 Observation;
-
\(z\):CVAE 潜变量;
-
\(K\):Action Chunk 长度;
-
\(D_a\):单个 Action 的维度。
如果:
\[ B=8,\quad K=100,\quad D_a=14 \]
那么一次 Forward 输出:
\[ \boxed{\hat A:[8,100,14]} \]
即 8 个训练样本,每个样本预测未来 100 个 14 维动作。
这是与原始 ACT 双臂系统的动作表示及 README 示例配置对应的一个例子,不能把 100 和 14 当成所有机器人版本的固定值。
Action Chunking 的意义,是把一段具有时间联系的动作作为整体学习,而不是把每个控制时刻完全孤立地对待。
但 Chunking 也有一个代价:如果只预测一次、再连续执行很长一段动作,机器人中途就缺少新观察带来的修正。因此 ACT 还引入了 Temporal Ensembling,我们稍后会把它接上。
二、ACT 的完整网络:谁负责看、谁负责理解、谁负责产生动作?
用工厂做类比,可以把它理解为:
-
视觉 Backbone 是观察员,将相机画面整理为视觉特征;
-
Transformer Encoder 是信息整理员,让输入 Token 彼此交流;
-
Transformer Decoder 是动作生成员,利用 Action Queries 从 Encoder Memory 中读取信息;
-
Action Head 是输出接口,将内部特征转换为具体 Action 数值。
真正的数据流是:
\[ \boxed{ \begin{aligned} &\text{RGB Images}\rightarrow\text{Visual Backbone}\\ &\text{Visual Features}+\text{Joint State}+\text{Latent }z\\ &\hspace{18mm}\downarrow\\ &\text{Transformer Encoder}\rightarrow\text{Memory}\\ &\hspace{18mm}\downarrow\\ &\text{Transformer Decoder + Action Queries}\\ &\hspace{18mm}\downarrow\\ &\text{Action Head}\rightarrow\hat A \end{aligned} } \]
这条链里,我们最应该保留下来的 Shape 认识是:
| 阶段 | 教学 Shape | 作用 |
|---|---|---|
| RGB 输入 |
| \(N\) 台相机 |
| Visual Tokens |
| 图片变成视觉特征序列 |
| 加入状态和潜变量 |
| 增加两个条件 Token |
| Encoder Memory |
| 上下文化特征 |
| Decoder Queries |
| \(K\) 个未来动作位置 |
| Action Head 输出 |
| 预测 Action Chunk |
这是为理解而统一成 Batch-First 的表示;作者原始 Transformer 文件中的多处计算实际采用 Sequence-First 排列 [S,B,D]。
现在你应该能自己解释:为什么 Encoder 输入 \(S_v+2\) 个 Token,Decoder 却能输出 \(K\) 个动作?
因为 Decoder 的输出位置数由 Action Queries 决定,而不是由 Encoder Memory 的长度决定。
它们通过 Cross-Attention 连接:
\[ Q_{\text{action}}K_{\text{memory}}^T \]
生成关系矩阵,再将 Memory 中的 Value 聚合到动作位置。
这也正是我们花几课学习 \(Q,K,V\)、矩阵转置、reshape 和 transpose 的原因。
三、ACT 为什么还要 CVAE?这不是已经有 Transformer 了吗?
因为 Transformer 负责处理信息关系,并不自动保证模型能妥善表达多个合理的动作模式。
假设同样的起始状态,人可以从障碍物左侧绕过去,也可以从右侧绕过去。普通确定性 MSE 回归可能把两种动作平均,输出一条不理想的中间轨迹。
ACT 引入 CVAE(Conditional Variational Autoencoder),训练时额外读取专家动作序列:
\[ (q_t,A_t) \xrightarrow{\text{CVAE Encoder}} (\mu,\log\sigma^2) \]
通过重参数化:
\[ \boxed{ z=\mu+\sigma\odot\epsilon,\qquad \epsilon\sim\mathcal N(0,I) } \]
获得一个潜变量 \(z\)。
然后让 Policy 使用 Observation 和 \(z\) 预测 Action Chunk:
\[ \hat A_t=\pi_\theta(o_t,z) \]
CVAE 就像训练时的“示范分析员”,负责学习动作示范中的潜在变化因素。这里的 \(z\) 并不是事先定义好的“向左/向右”开关,模型也不能保证每个维度都具有可直接解释的动作语义。
训练目标可以概括为:
\[ \boxed{ L_{\text{ACT}} = L_{\text{recon}}+\beta L_{\text{KL}} } \]
重建损失要求动作预测接近专家:
\[ L_{\text{recon}}=L_1(\hat A,A) \]
KL Loss 则约束潜变量分布与标准正态先验之间的差异:
\[ L_{\text{KL}} = D_{\mathrm{KL}}\left( q_\phi(z\mid q,A) \parallel\mathcal N(0,I) \right) \]
作者当前官方 policy.py 实现采用 L1 + KL。
训练中的简化 PyTorch 代码就是:
pred_actions, mu, logvar = model( images, qpos, expert_actions, is_pad)recon_loss = masked_l1(pred_actions, expert_actions, is_pad)kl_loss = gaussian_kl(mu, logvar)loss = recon_loss + beta * kl_lossoptimizer.zero_grad()loss.backward()optimizer.step()
其中 masked_l1、gaussian_kl 是为了突出逻辑使用的函数名,不是直接可运行的官方 API;它们的计算我们已在第 17 和 19 课分别展开过。
这里最重要的是看清两条梯度路径:重建损失会训练动作生成相关参数,并通过重参数化路径影响 CVAE Encoder;KL Loss 则直接约束潜变量分布参数。
四、为什么训练时需要专家动作,而推理时不需要?
这点可以说是 ACT 最容易混淆、又最应该掌握的地方。
训练阶段
专家 Action Chunk
CVAE Encoder
采样 \(z\)
Policy → Action Chunk
计算重建损失与 KL 损失
推理阶段
当前 Observation
固定 \(z=0\)
Policy → Action Chunk
不需要未来专家动作或 CVAE Encoder
训练时,专家动作已经包含在 Dataset 中,因此可以利用它们学习潜变量。
推理时,未来专家动作根本不存在。原始 ACT 采用:
\[ \boxed{z=0} \]
即使用标准正态先验的均值,生成预测 Action Chunk。
这也意味着:原始 ACT 并不是每次推理都随机抽取不同的 \(z\),再随机挑选动作风格。
五、Action Chunk 预测出来以后,机器人怎样执行?
假设模型每个时刻都预测未来四步。
| 预测时刻 | 针对未来的动作 |
|---|---|
| \(t=0\) | \(\hat a_{0\mid0},\hat a_{1\mid0},\hat a_{2\mid0},\hat a_{3\mid0}\) |
| \(t=1\) | \(\hat a_{1\mid1},\hat a_{2\mid1},\hat a_{3\mid1},\hat a_{4\mid1}\) |
| \(t=2\) | \(\hat a_{2\mid2},\hat a_{3\mid2},\hat a_{4\mid2},\hat a_{5\mid2}\) |
到了时刻 \(t=2\),我们可以找到三个对同一执行时刻的预测:
\[ \hat a_{2\mid0},\quad \hat a_{2\mid1},\quad \hat a_{2\mid2} \]
Temporal Ensembling 就是把它们按权重融合:
\[ \boxed{ a_2= \frac{\sum_i w_i\hat a_{2\mid i}} {\sum_i w_i} } \]
重要的是:融合的是对同一未来时刻的多个预测,不是把不同执行时刻的动作直接平均。
原论文使用指数权重,并明确从较旧预测开始赋予权重。
得到当前 Action 后,还必须经过训练时归一化操作的逆变换,并按照机器人执行接口的语义处理,再送入底层控制系统。
最终形成:
\[ \boxed{ Observation \rightarrow ACT \rightarrow Action\ Chunk \rightarrow Temporal\ Ensembling \rightarrow Execution \rightarrow New\ Observation } \]
这才是一条真正闭环的策略执行链。
六、ACT 的价值、边界,以及我们已经掌握什么
ACT 的主要价值不是简单地“用了 Transformer”,而是将动作序列预测、生成式潜变量建模和重叠动作预测融合起来,用于高精度机器人模仿学习。
但它也存在需要正确理解的边界。原始 ACT 不是带文本指令理解能力的完整 VLA;它仍然依赖质量可靠的示范数据、清楚的 Action Representation 和与训练条件相匹配的部署接口。固定 \(z=0\) 的推理方式,也不等于充分采样所有可能的动作模式。
经过这一阶段,你应该已经能够把 ACT 拆成四个层次:
| 层次 | 现在应该理解的内容 |
|---|---|
| 数据层 | Episode、Action Chunk、Normalization、Padding Mask |
| 模型层 | Visual Backbone、Encoder、Decoder、Action Query、CVAE |
| 训练层 | Forward、L1、KL、Backward、Optimizer、Checkpoint |
| 执行层 | \(z=0\)、Chunk Prediction、Temporal Ensembling、Denormalization、Rollout |
官方代码的主线也已经建立:
utils.py → imitate_episodes.py → policy.py → detr/models/detr_vae.py → detr/models/transformer.py
我们已经具备进一步修改和调试 ACT 类模型所需的理论框架。 但这不等于已经完成真实训练复现;后者还需要数据质量验证、任务配置、实验日志、实际 Rollout 和指标复核。
接下来再学 Diffusion Policy,就能形成真正有意义的模型比较:同样预测 Action Chunk,为什么 ACT 使用 CVAE + Transformer,而 Diffusion Policy 选择从噪声中逐步生成动作?
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)