Diffusion policy: Visuomotor policy learning via action diffusion:时序扩散 Transformer
文章概括
引用:
@article{chi2023diffusion,
title={Diffusion policy: Visuomotor policy learning via action diffusion},
author={Chi, Cheng and Feng, Siyuan and Du, Yilun and Xu, Zhenjia and Cousineau, Eric and Burchfiel, Benjamin and Song, Shuran},
journal={arXiv preprint arXiv:2303.04137},
year={2023}
}
Chi, C., Feng, S., Du, Y., Xu, Z., Cousineau, E., Burchfiel, B. and Song, S., 2023. Diffusion policy: Visuomotor policy learning via action diffusion. arXiv preprint arXiv:2303.04137.
原文:https://arxiv.org/abs/2303.04137
代码、数据和视频:https://diffusion-policy.cs.columbia.edu/
文章解析原文:
https://blog.csdn.net/xzs1210652636/article/details/142500842
1. 采用 minGPT 架构
(1) GPT-like 结构非常适合序列预测
- 在自然语言处理里,GPT 是通过自回归解码的方式,依次预测下一个词。
- 将其借鉴到动作生成中时,可以把 “动作序列” 类比成 “文本序列” :每个时间步的动作就是一个 “token(令牌)”。
(2) 将动作向量离散化 or 直接视作向量 token
- 如果动作是连续值(如机械臂关节角度等),可以:
- 直接将每个时间步的动作(如一个 d d d-维向量)投影到一个Embedding空间,得到一个长度 d ′ d' d′ 的嵌入(例如先过线性层映射,或用其他手段)。
- 在 minGPT 里,每个时间步就对应一个 token embedding,序列长度为“预测时域的步数”。
- 带噪声的动作:在扩散采样时,你先随机初始化一条“动作序列” A t K \mathbf{A}^K_t AtK,它含有噪声;然后把这条序列的每个时间步当作 GPT 的输入 token。
(3) 因果(自回归)注意力
- 因果注意力约束:在 Transformer Decoder 中,每个 token(当前动作步)只能关注到自身与之前的动作 token,不能看到之后的动作 token(防止信息泄露)。
- 这样就像语言模型中“预测下一个词”那样,动作序列在去噪时也遵循时间顺序。
举个小例子
- 任务:机器人需要在未来 3 步内移动到桌子中央,并拿起一个物体。
- 动作序列长度:
T
p
=
3
T_p = 3
Tp=3。设每个动作是 2 维(例如线速度、角速度),那么一条“带噪声的动作序列”可能长这样:
A t K = [ ( 0.3 , − 0.8 ) , ( 0.1 , 0.9 ) , ( − 0.6 , 1.2 ) ] + 一些随机扰动 \mathbf{A}^K_t \;=\; [\, (0.3, -0.8),\; (0.1, 0.9),\; (-0.6, 1.2) ] \;+\; \text{一些随机扰动} AtK=[(0.3,−0.8),(0.1,0.9),(−0.6,1.2)]+一些随机扰动 - 输入到 minGPT Decoder:
- 我们先把 ( 0.3 , − 0.8 ) (0.3, -0.8) (0.3,−0.8) 映射到一个 embedding e 1 e_1 e1。
- 把 ( 0.1 , 0.9 ) (0.1, 0.9) (0.1,0.9) 映射到 embedding e 2 e_2 e2。
- 把 ( − 0.6 , 1.2 ) (-0.6, 1.2) (−0.6,1.2) 映射到 embedding e 3 e_3 e3。
- 再把它们按照顺序 [ e 1 , e 2 , e 3 ] [e_1, e_2, e_3] [e1,e2,e3] 送进 Transformer Decoder,Decoder 里会有因果注意力 mask,让第 3 个 token 只能看见 token1、token2 以及它自身,不会泄露“未来”(若在语言场景下就是下文)。
在训练或去噪时,每一层 Decoder 都会输出对噪声的估计或中间表示,最后一层输出 “ ε θ \varepsilon_{\theta} εθ 值”,表示对每个动作 token 当前噪声量的估计。
2. 扩散迭代步作为正弦嵌入
(1) 为什么要告诉模型当前是第几步?
- 在 DDPM 里,每个去噪迭代 k k k 代表噪声程度的不同阶段。模型需要知道 “我现在是在早期(噪声很大)还是在后期(噪声较小)”,这样才能决定如何去噪。
- 类似在语言模型里,位置编码告诉模型“这是序列中的第几个位置”;在扩散模型里,“这是第几次扩散迭代”。
(2) 具体做法
- 使用正弦位置编码(sinusoidal embedding),把 k k k(如 1, 2, …, K)映射到一个定长向量 ϕ k \phi_k ϕk;
- 这个 ϕ k \phi_k ϕk 可以视为一个额外 token,或者附着到每个动作 token embedding 中。
- 在 minGPT 的输入序列最前面(或通过可学习embedding方式)添加这个 “ ϕ k \phi_k ϕk” 信息,让网络知道当前去噪迭代步。
举个小例子
- 假设总扩散步数 K = 20 K=20 K=20。当前是第 k = 7 k=7 k=7 步去噪。
- 正弦编码(自己设定的):
ϕ 7 = [ sin ( ω 1 ⋅ 7 ) , cos ( ω 1 ⋅ 7 ) , sin ( ω 2 ⋅ 7 ) , … ] , \phi_7 \;=\; [\sin(\omega_1 \cdot 7),\, \cos(\omega_1 \cdot 7),\, \sin(\omega_2 \cdot 7),\, \dots\,], ϕ7=[sin(ω1⋅7),cos(ω1⋅7),sin(ω2⋅7),…],
在原始论文(Vaswani et al., 2017)中,正弦位置编码通常定义为:
P E ( p o s , 2 i ) = sin ( p o s / 1000 0 2 i / d model ) , P E ( p o s , 2 i + 1 ) = cos ( p o s / 1000 0 2 i / d model ) , PE(pos, 2i) = \sin\bigl(pos / 10000^{\,2i/d_{\text{model}}}\bigr), \quad PE(pos, 2i+1) = \cos\bigl(pos / 10000^{\,2i/d_{\text{model}}}\bigr), PE(pos,2i)=sin(pos/100002i/dmodel),PE(pos,2i+1)=cos(pos/100002i/dmodel),
这样得到一个固定长度向量(比如维度=64)。
- 如何使用:
- 直接把 ϕ 7 \phi_7 ϕ7 拼接在动作序列 embedding 前面,形成 [ ϕ k , e 1 , e 2 , e 3 ] [\phi_k, e_1, e_2, e_3] [ϕk,e1,e2,e3] 这一串输入;
- 或者在每个动作 embedding 内部加上 ϕ 7 \phi_7 ϕ7 作为偏置,使得网络层层感知“现在是去噪的第 7 步”。
这样,每个时间步的动作 token 都能通过注意力机制获取 ϕ 7 \phi_7 ϕ7 这个信号,知道自己正处于哪个扩散阶段。
3. 观察 O t \mathbf{O}_t Ot 转成“观察嵌入序列”
(1) 为什么要做交叉注意力 (Cross-Attention)
- 动作的去噪并不只取决于动作本身,还需要当前环境观测(如图像特征、激光雷达特征等),以便知道“物体在桌子哪里?”、“机器人现在在哪?” 等信息。
- 因而,我们需要让动作 tokens 能够查询(query) 观察特征,得到相应的上下文信息。
(2) 具体实现
- 共享 MLP:将观测向量
O
t
\mathbf{O}_t
Ot(可能是图像经过CNN提取出的特征,也可能是状态信息)转换成一个序列嵌入
O
t
e
m
b
\mathbf{O}^{emb}_t
Otemb。
- 例如,若 O t \mathbf{O}_t Ot 是一个 512 维的图像特征,可以切分成若干小块或直接映射成多维 token。
- 在 Transformer Decoder 中,会有一个“交叉注意力(Cross-Attention)”层:
- 动作 tokens(“query”)会去关注/匹配 观察 tokens(“key”/“value”),从而获取环境信息。
- 不同的动作时间步可以“查阅”观察向量的不同部分,比如:
- 第 1 步动作想先看看“目标物体位于何处”;
- 第 2 步动作还想关注“障碍物位置”;
- 第 3 步动作关心“抓取或推送是否成功”等。
具体示例
- 观察:假设 O t \mathbf{O}_t Ot 包含一个 128 维图像特征 + 机器人当前位姿(6D),合并到一起是 134 维。
- 共享 MLP:我们可能把这 134 维映射成一个序列 O t e m b = [ o 1 , o 2 , . . . , o m ] \mathbf{O}^{emb}_t = [o_1, o_2, ..., o_m] Otemb=[o1,o2,...,om],维度合适 Transformer’s d m o d e l d_{model} dmodel。
- 交叉注意力:
- 动作 token 1 (embedding e 1 e_1 e1) 会通过 Attention ( e 1 , O t e m b ) \text{Attention}(e_1, \mathbf{O}^{emb}_t) Attention(e1,Otemb) 查阅整段观测嵌入;
- 动作 token 2 (embedding e 2 e_2 e2) 同样会查阅 O t e m b \mathbf{O}^{emb}_t Otemb;
- 这样,每个动作时间步都能“感知”到观察信息的不同部分或整体概况,从而做更精细的噪声修正。
4. 结合示例:一个完整的去噪步骤
假设当前是去噪第 k = 7 k=7 k=7 步,我们有:
- 带噪动作序列 A t 7 = [ a t 7 , a t + 1 7 , … ] \mathbf{A}^7_t = [a^7_t, a^7_{t+1}, \dots] At7=[at7,at+17,…].
- 观察 O t \mathbf{O}_t Ot(例如机器人摄像头看到桌面上一块红色物体)。
- 正弦嵌入 ϕ 7 \phi_7 ϕ7.
输入到 Transformer Decoder:
- 首先,对 A t 7 \mathbf{A}^7_t At7 里的每个动作做线性映射到嵌入 [ e 1 , e 2 , . . . ] [e_1, e_2, ...] [e1,e2,...]。
- 把 ϕ 7 \phi_7 ϕ7 也合并进来,告诉模型这是第 7 步迭代。
- 观测 O t \mathbf{O}_t Ot 经过一个共享 MLP => O t e m b \mathbf{O}^{emb}_t Otemb(提取图片特征)。
- 在 Decoder 中:
- 自注意力(因果注意力): 动作 tokens 只能看到过去和自己,保持时间顺序;
- 交叉注意力: 动作 tokens 与 O t e m b \mathbf{O}^{emb}_t Otemb 交互,根据环境信息判断如何修正各动作的噪声;
- 输出: 对应每个时间步动作的噪声向量 ε θ ( O t , A t 7 , k ) \varepsilon_{\theta}(\mathbf{O}_t, \mathbf{A}^7_t, k) εθ(Ot,At7,k)。
更新动作:
A t 6 = α ( A t 7 − γ ε θ ( … ) + N ( 0 , σ 2 I ) ) , \mathbf{A}^{6}_t = \alpha \bigl(\mathbf{A}^{7}_t - \gamma \,\varepsilon_{\theta}(\dots) + \mathcal{N}(0, \sigma^2 \mathbf{I})\bigr), At6=α(At7−γεθ(…)+N(0,σ2I)),
得到去噪后的一条新动作序列 A t 6 \mathbf{A}^6_t At6,噪声相对更少。
5. 进一步说明
-
为什么要这么做?
- 序列建模:GPT-like自回归结构擅长处理序列关系(时间上的依赖),特别适合动作序列;
- 交叉注意力:环境观测随时变化,需要让动作时刻“看”到观测;
- 正弦嵌入:告诉网络当前是去噪过程的早期/中期/后期,方便网络自适应不同噪声水平。
-
与 CNN 方案对比:
- CNN 也能在时间维度卷积,但注意力机制更灵活地捕捉长距离依赖,也能更细粒度地融合环境观察;
- 然而 Transformer 通常训练更难,需要更仔细的超参搜索。
6. 小结
通过上述更细节的解释与示例,可以看到这套“时序扩散 Transformer”流程是如何把噪声动作序列、迭代步信息、以及环境观察结合起来,实现从纯噪声到高质量动作的去噪生成。关键要点包括:
- minGPT-like 自回归解码:动作被视为 token,因果注意力保证时间一致。
- 正弦嵌入告诉模型当前去噪步数,区别早期/后期的噪声特征。
- 交叉注意力让动作 tokens 可以“查阅”观察特征嵌入,得到环境上下文进行去噪修正。
这就是这一“时序扩散 Transformer”方法的完整脉络,也是为什么它可以在高频动作变化或复杂场景下优于传统的 1D 时间卷积网络。