想先说明一下,ddpm这里讲的并不好,比如说为什么系数要用根号值,为什么没有用条件概率表示却突然用epsilon去逼近神经网络最优参数等等,其中包含一些概率论与数理统计/马尔科夫决策链/詹森不等式/KL散度知识,我找了一个讲的最好的动画,公式推导的很牛逼;听一遍,整个人都通畅了;动画 扩散模型DDPM全解析_哔哩哔哩_bilibili;
第一部分:第 20 课标准答案
1. ACT 和 Diffusion Policy 的本质区别是什么?
两者都可以预测未来一段动作:
\ A_t=\[a_t,a_{t+1},\\ldots,a_{t+K-1} \]
但生成方法不同。
ACT 通过 Transformer 和 CVAE 潜变量,直接预测一段 Action Chunk:
\ \\hat A_t=\\pi_\\theta(o_t,z) \\
Diffusion Policy 则从随机噪声开始,经过多次条件去噪生成动作:
\ A\^{(S)}\\rightarrow A\^{(S-1)} \\rightarrow\\cdots\\rightarrow A\^{(0)} \\
因此核心区别是:
\ \\boxed{\\text{直接预测动作}\\quad vs\\quad\\text{迭代生成动作}} \\
2. 为什么要给真实动作加噪?
因为我们需要为扩散模型构造一个可学习的任务。
真实专家动作是:
\ A\^{(0)} \\
人为生成噪声:
\ \\epsilon \\
得到带噪动作:
\ A\^{(s)} \\
模型学习:
\ \\hat\\epsilon=\\epsilon_\\theta(A\^{(s)},s,o) \\
训练时,我们知道自己加入的真实噪声,因此能够使用预测误差监督模型。
模型最终学到的,是在不同观察条件和不同噪声水平下,如何估计动作序列中的噪声。
3. 计算加噪后的动作
已知:
\ A\^{(0)}=\[1,0 \]
\ \\epsilon=\[0,1 \]
\ \\bar\\alpha_s=0.64 \\
代入:
\ A\^{(s)} =\\sqrt{0.64}\[1,0 +\sqrt{0.36}0,1 \]
得到:
\ \\boxed{A\^{(s)}=\[0.8,0.6} \]
4. 扩散步 \(s\) 和机器人控制时间 \(t\) 有什么区别?
机器人控制时间 \(t\) 描述机器人在真实环境中执行到哪个时刻。
扩散步 \(s\) 描述模型生成一段动作时,内部处于哪个噪声水平。
例如机器人正在执行第 100 个控制时刻:
\ t=100 \\
模型可能在这一次动作预测内部经历:
\ s=50\\rightarrow49\\rightarrow\\cdots\\rightarrow1 \\
因此二者完全不是一个时间概念。
5. Diffusion Policy 中的 Action 和 Noise 有什么 Shape?
若:
\ B=16,\\quad K=10,\\quad D_a=7 \\
则干净动作、带噪动作、真实噪声和预测噪声均为:
\ \\boxed{\[16,10,7} \]
含义是:16 个样本、每个样本有 10 个未来动作、每个动作是 7 维。
这里 10 是 Action Horizon 中的动作位置数,不是扩散步数。
6. 为什么随机噪声必须与 Action Chunk 具有相同 Shape?
因为噪声是逐元素加入动作序列的。
例如:
\ A\^{(0)}= \\begin{bmatrix} a_{11}\&a_{12}\\\\ a_{21}\&a_{22} \\end{bmatrix} \\
则对应的噪声需要是:
\ \\epsilon= \\begin{bmatrix} \\epsilon_{11}\&\\epsilon_{12}\\\\ \\epsilon_{21}\&\\epsilon_{22} \\end{bmatrix} \\
让每一个动作维度都能够按照加噪公式变化。
7. 为什么 \(\bar\alpha_s\) 是累计连乘?
定义:
\ \\alpha_s=1-\\beta_s \\
每一步都会对上一状态的信号进一步缩放。
因此连续 \(s\) 步以后,原始信号的累计系数为:
\ \\boxed{\\bar\\alpha_s=\\prod_{i=1}\^{s}\\alpha_i} \\
例如:
\ \\alpha_1=0.9,\\quad\\alpha_2=0.8 \\
则:
\ \\bar\\alpha_2=0.9\\times0.8=0.72 \\
8. 为什么 Noise Predictor 需要带噪动作、扩散步和 Observation?
因为它们分别提供不同的信息:
\ A\^{(s)} \\
告诉模型当前需要修正的动作是什么样。
\ s \\
告诉模型当前动作处于什么噪声水平。
\ o_t \\
告诉模型当前机器人和环境处于什么状态,以及怎样的动作才适合当前任务。
因此:
\ \\boxed{\\hat\\epsilon=\\epsilon_\\theta(A\^{(s)},s,o_t)} \\
是一个以机器人 Observation 为条件的噪声预测模型。
9. 为什么训练时可以直接选择任意噪声步,而推理时需要逐步去噪?
训练时已有真实专家动作:
\ A\^{(0)} \\
可以利用闭式加噪公式,直接生成任何噪声等级的:
\ A\^{(s)} \\
推理时没有未来专家动作,只能从随机噪声开始,通过学习到的反向生成过程逐步得到动作序列。
10. Diffusion Policy 和 ACT 的 Loss 有什么区别?
原始 ACT 使用动作重建损失和 KL 正则:
\ L_{\\mathrm{ACT}} = L_{\\mathrm{recon}}+\\beta L_{\\mathrm{KL}} \\
而噪声预测型 Diffusion Policy 使用:
\ \\boxed{ L_{\\mathrm{diffusion}} = \\mathbb E\\left\[ \\\|\\epsilon-\\epsilon_\\theta(A\^{(s)},s,o)\\\|\^2 \\right } \]
也就是说,扩散模型训练时直接监督的是噪声预测,而不是要求网络一步直接输出最终动作。
11. 已知真实噪声,怎样恢复干净动作?
从:
\ A\^{(s)} = \\sqrt{\\bar\\alpha_s}A\^{(0)} + \\sqrt{1-\\bar\\alpha_s}\\epsilon \\
移项得到:
\ \\boxed{ A\^{(0)} = \\frac{ A\^{(s)}-\\sqrt{1-\\bar\\alpha_s}\\epsilon }{ \\sqrt{\\bar\\alpha_s} } } \\
如果模型能够准确预测噪声,就可以由带噪动作估计干净动作。
但这属于估计原始干净数据,与 DDPM 的逐步反向更新并不完全相同。
12. Diffusion Policy 有什么优势和代价?
优势在于:它能够通过条件生成过程表达较复杂、可能具有多个合理模式的动作分布。
代价在于:推理时通常需要多轮去噪,因此可能增加计算时间和推理延迟。
对于机器人,最终还必须考虑:
\ \\boxed{ \\text{动作质量} + \\text{任务成功率} + \\text{推理延迟} + \\text{闭环控制频率} } \\
不能只比较离线生成效果。
第二部分:第 21 课------DDPM 与 Noise Scheduler:扩散模型究竟怎样从随机噪声生成机器人动作?
这一课只讨论三个层面:
-
前向加噪为什么这样设计;
-
反向去噪公式从哪里来,Noise Predictor 与 Scheduler 各负责什么;
-
在具身智能中,完整训练和真实推理究竟如何运行。
一、首先明确:我们究竟要生成什么?
假设一个机械臂正在完成抓取任务。
相机看到了物体,机器人知道自己的关节位置。我们希望模型预测接下来一段连续动作。
设当前真实控制时刻为:
\ t \\
当前 Observation 为:
\ o_t=(I_t,q_t) \\
其中:
-
\(I_t\):当前视觉信息;
-
\(q_t\):当前机器人关节状态。
未来动作序列为:
\ A_t= \[a_t,a_{t+1},\\ldots,a_{t+K-1} \]
假设:
\ K=4,\\qquad D_a=2 \\
那么一个 Action Chunk 可能是:
\ A_t= \\begin{bmatrix} 0.10\&0.20\\\\ 0.15\&0.22\\\\ 0.20\&0.24\\\\ 0.25\&0.26 \\end{bmatrix} \\
它的 Shape 是:
\ \[4,2 \]
表示未来四个控制时间点、每个时间点两个动作维度。
这里的数字只是教学示例。实际机器人动作可能表示关节目标位置、末端位移或其他控制量,具体含义取决于 Action Representation。
在 ACT 中,我们尝试直接预测:
\ \\hat A_t=\\pi_\\theta(o_t,z) \\
而在 Diffusion Policy 中,我们希望学习一个条件分布:
\ \\boxed{p_\\theta(A_t\\mid o_t)} \\
也就是:
给定当前机器人观察状态,哪些未来动作序列是合理的?它们可能以什么概率出现?
为了学习这个分布,我们不直接要求神经网络一次预测最终的 \(A_t\),而是引入一个人为设计的扩散过程。
此时一定要区分三个概念:
| 符号 | 含义 |
|---|---|
| \(t\) | 机器人真实控制时刻 |
| \(k\) | Action Chunk 内第几个未来动作 |
| \(s\) | 扩散生成过程中的噪声步数 |
例如:
\ A_t\^{(s)} \\
表示:
在机器人时刻 \(t\),要生成的那段未来动作,当前处于扩散噪声等级 \(s\)。
我们约定:
\ s=0 \\
表示干净动作。
\ s=S \\
表示最高噪声等级。
这样后面的数学符号就不会混淆。
二、前向扩散:为什么要把专家动作逐渐变成噪声?
假设我们已经采集了一段正确的专家示范:
\ A_t\^{(0)} \\
它来自真实 Demonstration Dataset。
我们现在人为构造一个过程,让这段动作逐渐失去原始结构。
前向扩散:从专家动作到噪声
概念示意:动作数值随噪声发生变化;并非真实训练轨迹的数值结果。
1. 单步加噪公式
从第 \(s-1\) 步走到第 \(s\) 步,定义:
\ \\boxed{ A_t\^{(s)} = \\sqrt{\\alpha_s}A_t\^{(s-1)} + \\sqrt{\\beta_s}\\epsilon_s } \\
其中:
\ \\alpha_s=1-\\beta_s \\
\ \\epsilon_s\\sim\\mathcal N(0,I) \\
逐项解释:
\ A_t\^{(s-1)} \\
是上一扩散步的动作。
\ \\sqrt{\\alpha_s}A_t\^{(s-1)} \\
是保留下来的信号部分。
\ \\sqrt{\\beta_s}\\epsilon_s \\
是这一扩散步新加入的随机噪声。
这里的 \(\beta_s\) 决定新噪声的方差,\(\alpha_s\) 决定上一状态的信号保留系数。
为什么使用平方根?
因为我们希望控制的是信号和噪声的方差。
对于随机变量 \(X\):
\ \\operatorname{Var}(cX) = c\^2\\operatorname{Var}(X) \\
所以乘:
\ \\sqrt{\\beta_s} \\
才会使标准正态噪声的方差变为:
\ \\beta_s \\
同样,乘:
\ \\sqrt{\\alpha_s} \\
会使对应信号部分的方差按 \(\alpha_s\) 缩放。
2. 连续加噪两步,会发生什么?
假设第一步:
\ A\^{(1)} = \\sqrt{\\alpha_1}A\^{(0)} + \\sqrt{\\beta_1}\\epsilon_1 \\
第二步:
\ A\^{(2)} = \\sqrt{\\alpha_2}A\^{(1)} + \\sqrt{\\beta_2}\\epsilon_2 \\
把第一步代入第二步:
\ A\^{(2)} = \\sqrt{\\alpha_2} \\left( \\sqrt{\\alpha_1}A\^{(0)} + \\sqrt{\\beta_1}\\epsilon_1 \\right) + \\sqrt{\\beta_2}\\epsilon_2 \\
展开:
\ A\^{(2)} = \\sqrt{\\alpha_1\\alpha_2}A\^{(0)} + \\sqrt{\\alpha_2\\beta_1}\\epsilon_1 + \\sqrt{\\beta_2}\\epsilon_2 \\
这一步非常重要。
它告诉我们:
经过两轮加噪,原始动作的系数已经变成了两次 \(\alpha\) 的连乘。
推广到 \(s\) 步:
\ \\boxed{ \\bar\\alpha_s=\\prod_{i=1}\^{s}\\alpha_i } \\
这里的横线表示"累计",不是平均值。
另一方面,因为每一步添加的都是独立高斯噪声,多个噪声项的加权和仍然服从高斯分布。
例如刚才两步的总噪声方差为:
\ \\alpha_2\\beta_1+\\beta_2 \\
由于:
\ \\beta_1=1-\\alpha_1 \\
\ \\beta_2=1-\\alpha_2 \\
所以:
\ \\alpha_2(1-\\alpha_1)+(1-\\alpha_2) = 1-\\alpha_1\\alpha_2 \\
因此,连续两步的综合噪声可以合并表示。
推广之后,得到非常重要的闭式公式:
\ \\boxed{ A\^{(s)} = \\sqrt{\\bar\\alpha_s}A\^{(0)} + \\sqrt{1-\\bar\\alpha_s}\\epsilon } \\
其中:
\ \\epsilon\\sim\\mathcal N(0,I) \\
这个公式让我们能在训练时直接生成任意扩散步的带噪动作,而不必真的从第 1 步加到第 \(s\) 步。
3. 具体数字再算一遍
假设:
\ A\^{(0)}=1 \\
\ \\alpha_1=0.9,\\qquad\\alpha_2=0.8 \\
则:
\ \\bar\\alpha_2=0.72 \\
如果这次采样的综合噪声是:
\ \\epsilon=0.5 \\
那么:
\ A\^{(2)} = \\sqrt{0.72}\\times1 + \\sqrt{0.28}\\times0.5 \\
得到:
\ \\boxed{A\^{(2)}\\approx1.1131} \\
注意:噪声不一定让动作数值变小。它会使动作受到随机扰动,因此数值可能增大,也可能减小。
我们说"噪声越来越强",指的是动作中原始信号相对噪声的占比降低,而不是动作的绝对值必然减小。
三、反向扩散:模型如何知道应该朝哪个方向修正动作?
现在回到真正的生成问题。
假设机器人当前观察到一个物体位于右侧。
在该任务的某种动作表示下,合理动作可能整体倾向于右移。
但我们初始化的 Action Chunk 完全来自随机噪声:
\ A_t\^{(S)}\\sim\\mathcal N(0,I) \\
这段动作可能包含:
-
向左;
-
向右;
-
前后反复震荡;
并不符合真实任务。
于是我们训练一个条件噪声预测网络:
\ \\boxed{ \\hat\\epsilon = \\epsilon_\\theta(A_t\^{(s)},s,o_t) } \\
它必须同时理解:
当前候选动作是什么、噪声有多强、当前机器人任务条件是什么。
因此它并不是单纯做信号平滑。
如果只是简单平滑,无论看到什么物体,都可能给出类似的平滑轨迹。
但条件扩散希望做到:
\ o_t\^{(1)} \\rightarrow \\text{与场景1匹配的动作分布} \\
\ o_t\^{(2)} \\rightarrow \\text{与场景2匹配的动作分布} \\
这才是它作为机器人 Policy 的关键。
1. 为什么网络预测噪声,却不直接输出动作?
因为我们已经知道:
\ A\^{(s)} = \\sqrt{\\bar\\alpha_s}A\^{(0)} + \\sqrt{1-\\bar\\alpha_s}\\epsilon \\
如果能够估计:
\ \\epsilon \\
就能够反过来估计干净动作:
\ \\boxed{ \\hat A\^{(0)} = \\frac{ A\^{(s)}-\\sqrt{1-\\bar\\alpha_s}\\hat\\epsilon }{ \\sqrt{\\bar\\alpha_s} } } \\
所以预测噪声是一种间接学习动作分布的方法。
但这里需要注意:
给定带噪动作后,原始动作未必能够被唯一确定。
网络使用 MSE 训练时,学到的是在训练分布和条件信息下的噪声估计,而不是每次都能准确猜出人为加入的那一份真实噪声。
这种概率上的不确定性,正是为什么扩散模型需要研究反向条件分布。
2. 为什么还不能直接把 \(\hat A^{(0)}\) 输出?
标准 DDPM 希望建立的是一系列反向转移:
\ p_\\theta(A\^{(s-1)}\\mid A\^{(s)},o_t) \\
而不是只训练一个从任意噪声状态直接跳到干净动作的单步生成器。
在常见的 DDPM 设定中,反向转移被建模为高斯分布:
\ \\boxed{ p_\\theta(A\^{(s-1)}\\mid A\^{(s)},o_t) = \\mathcal N( \\mu_\\theta,\\Sigma_s ) } \\
这里:
\ \\mu_\\theta \\
是反向更新的均值。
\ \\Sigma_s \\
是反向更新的协方差。
它意味着:
给定当前带噪动作,我们不一定只有一个唯一合理的上一状态,而是通过一个条件概率分布描述下一步生成结果。
在标准 DDPM 的一种固定方差设定中,采用:
\ \\Sigma_s=\\tilde\\beta_s I \\
因此一步反向采样可写为:
\ \\boxed{ A\^{(s-1)} = \\mu_\\theta(A\^{(s)},s,o_t) + \\sqrt{\\tilde\\beta_s}\\xi } \\
其中:
\ \\xi\\sim\\mathcal N(0,I) \\
这就是"反向去噪一步"的基本结构。
四、Noise Scheduler 到底负责什么?核心反向公式从哪里来?
为了说明这个公式不是凭空规定的,我们先看前向加噪对应的概率关系。
从 \(A^{(s-1)}\) 到 \(A^{(s)}\):
\ q(A\^{(s)}\\mid A\^{(s-1)}) = \\mathcal N( \\sqrt{\\alpha_s}A\^{(s-1)}, \\beta_s I ) \\
这里的 \(q\) 表示我们人为定义的前向概率过程,不是机器人的关节坐标 \(q_t\)。
我们同时知道:
\ q(A\^{(s-1)}\\mid A\^{(0)}) \\
也服从高斯分布。
因此在知道原始干净动作和当前带噪动作的情况下,可以求得:
\ q(A\^{(s-1)}\\mid A\^{(s)},A\^{(0)}) \\
这一后验分布。
利用高斯分布的条件概率运算,可以得到它的均值:
\ \\tilde\\mu_s = \\frac{ \\sqrt{\\bar\\alpha_{s-1}}\\beta_s }{ 1-\\bar\\alpha_s }A\^{(0)} + \\frac{ \\sqrt{\\alpha_s}(1-\\bar\\alpha_{s-1}) }{ 1-\\bar\\alpha_s }A\^{(s)} \\
它的方差为:
\ \\boxed{ \\tilde\\beta_s = \\frac{1-\\bar\\alpha_{s-1}} {1-\\bar\\alpha_s}\\beta_s } \\
这说明,反向更新既要参考当前带噪动作,也要参考干净动作的信息。
但推理时我们不知道真实:
\ A\^{(0)} \\
于是用模型预测的噪声构造:
\ \\hat A\^{(0)} \\
代替真实干净动作。
将它代入反向均值公式,化简得到:
\ \\boxed{ \\mu_\\theta = \\frac{1}{\\sqrt{\\alpha_s}} \\left( A\^{(s)} - \\frac{\\beta_s}{\\sqrt{1-\\bar\\alpha_s}} \\epsilon_\\theta(A\^{(s)},s,o_t) \\right) } \\
这是当前阶段最重要的 DDPM 反向均值公式。
现在我们终于能明确划分两个模块的职责。
Noise Predictor:
\ \\epsilon_\\theta(A\^{(s)},s,o_t) \\
利用训练学到的参数,预测噪声。
Noise Scheduler:
利用:
\ \\beta_s,\\alpha_s,\\bar\\alpha_s \\
以及预测噪声,计算反向转移的均值和方差,并执行采样更新。
因此:
\ \\boxed{ \\text{Noise Predictor学习动作分布相关信息} } \\
\ \\boxed{ \\text{Scheduler执行规定的扩散更新规则} } \\
标准 DDPM 中,噪声时间表通常事先规定,不需要像神经网络权重那样通过 Backward 学习。但不同扩散模型也可以采用其他方差建模和采样规则,不能将所有 Scheduler 都视为完全相同。
一组数字,把两种结果彻底分开
沿用前面的例子:
\ A\^{(2)}=1.1131 \\
\ \\beta_2=0.2 \\
\ \\alpha_2=0.8 \\
\ \\bar\\alpha_2=0.72 \\
假设网络预测:
\ \\hat\\epsilon=0.5 \\
那么估计的干净动作:
\ \\hat A\^{(0)}\\approx1.0000 \\
而反向均值:
\ \\mu_\\theta = \\frac1{\\sqrt{0.8}} \\left( 1.1131-\\frac{0.2}{\\sqrt{0.28}}\\times0.5 \\right) \\
得到:
\ \\boxed{\\mu_\\theta\\approx1.0332} \\
这说明:
\ \\boxed{ \\hat A\^{(0)}\\neq\\mu_\\theta } \\
前者是估计最初的干净动作;后者是从第 2 步反向更新到第 1 步时的条件均值。
同时,后验方差:
\ \\tilde\\beta_2 = \\frac{1-0.9}{1-0.72}\\times0.2 \\approx0.07143 \\
所以实际采样的:
\ A\^{(1)} \\
还可能在均值基础上包含随机扰动。
这就是完整 DDPM 反向更新与"直接减掉预测噪声"之间的本质区别。
五、将 DDPM 放回具身智能:完整训练流程到底是什么?
现在我们已经理解了正向和反向数学过程。
接下来回答机器人领域最重要的问题:
这些计算到底怎样和 Demonstration Dataset、Observation、Action Chunk 联系起来?
我们先从训练开始。
假设要训练一台机器人完成 Pick-and-Place。
阶段一:采集专家 Demonstration
每一条 Episode 可以写成:
\ \\tau_i= (o_0,a_0,o_1,a_1,\\ldots,o_T,a_T) \\
其中:
\ o_t=(I_t,q_t) \\
表示某个时刻的图像与机器人状态。
\ a_t \\
是专家在该时刻执行或下发的动作。
采集后需要做好时间同步,确保动作与观察信息正确对应。
如果图像是 \(t\) 时刻拍摄的,但对应动作其实是另一个时刻的控制指令,模型会学到错误的 Observation--Action 对应关系。
阶段二:从 Episode 中构造训练样本
假设观察历史长度为:
\ T_o=2 \\
未来动作预测长度为:
\ K=4 \\
我们可以构造:
\ O_t=\[o_{t-1},o_t \]
和:
\ A_t\^{(0)} = \[a_t,a_{t+1},a_{t+2},a_{t+3} \]
于是训练样本是:
\ \\boxed{(O_t,A_t\^{(0)})} \\
这里的未来动作来自已经采集好的专家示范,不是模型提前看见了未来真实环境。
同时,实际训练通常还要按照训练集统计量对状态和动作进行归一化。
原因是不同动作维度可能具有非常不同的数值范围。扩散模型在数值空间中添加高斯噪声,因此动作归一化尤其需要与训练和推理保持一致。
阶段三:随机选择扩散步并添加噪声
训练时,随机抽取:
\ s\\in\\{1,\\ldots,S\\} \\
同时采样:
\ \\epsilon\\sim\\mathcal N(0,I) \\
然后:
\ A_t\^{(s)} = \\sqrt{\\bar\\alpha_s}A_t\^{(0)} + \\sqrt{1-\\bar\\alpha_s}\\epsilon \\
这里的:
\ A_t\^{(s)} \\
是带噪动作。
需要特别注意:噪声添加在 Action Chunk 的数值表示上,而不是必须给 RGB 图像也添加相同噪声。
在我们讨论的经典条件动作扩散中,图像和机器人状态主要作为条件信息,用来指导动作去噪。
阶段四:训练噪声预测网络
模型接收:
\ (A_t\^{(s)},s,O_t) \\
输出:
\ \\hat\\epsilon \\
训练目标:
\ \\boxed{ L(\\theta) = \\mathbb E_{t,s,\\epsilon} \\left\[ \\left\\\| \\epsilon- \\epsilon_\\theta(A_t\^{(s)},s,O_t) \\right\\\|_2\^2 \\right } \]
其中:
-
\(\theta\):Noise Predictor 的可训练参数;
-
\(t\):从 Demonstration 中选取的机器人时间位置;
-
\(s\):随机选取的扩散步;
-
\(\epsilon\):人为加入的真实噪声;
-
\(O_t\):观察条件。
训练过程不断更新:
\ \\theta \\
使模型在不同观察状态、不同噪声水平下,都能逐渐改善自己的噪声估计。
完整训练链可以总结为:
\ \\boxed{ \\begin{aligned} \&\\text{Demonstration Episode}\\\\ \&\\downarrow\\\\ \&(O_t,A_t\^{(0)})\\\\ \&\\downarrow\\\\ \&\\text{随机选择 }s\\text{ 和 }\\epsilon\\\\ \&\\downarrow\\\\ \&A_t\^{(s)}\\\\ \&\\downarrow\\\\ \&\\epsilon_\\theta(A_t\^{(s)},s,O_t)\\\\ \&\\downarrow\\\\ \&L_{\\mathrm{noise}}\\\\ \&\\downarrow\\\\ \&\\text{Gradient + Parameter Update} \\end{aligned} } \\
这里有一个关键结论:
常见的 DDPM 噪声预测训练,不要求每个样本在一次 Forward 中都执行完整的多步反向采样。
它通常随机选取一个噪声等级,进行一次噪声预测监督。
这也是为什么训练链与实际生成链看上去不同。
六、真正推理时,机器人又是怎样运行的?
现在假设模型已经训练完成。
机器人面对桌面上的物体,准备执行抓取。
推理时没有未来专家 Action。
所以第一步是取得当前 Observation:
\ O_t \\
然后创建随机 Action Chunk:
\ A_t\^{(S)}\\sim\\mathcal N(0,I) \\
注意,此时的随机数只是模型内部的候选动作表示,绝对不是直接下发给电机的控制指令。
接下来执行反向扩散:
\ A_t\^{(S)} \\rightarrow A_t\^{(S-1)} \\rightarrow\\cdots \\rightarrow A_t\^{(0)} \\
每一步都需要当前 Observation 条件和对应的扩散步:
\ \\hat\\epsilon_s = \\epsilon_\\theta(A_t\^{(s)},s,O_t) \\
Scheduler 再利用它更新:
\ A_t\^{(s-1)} \\
直到完成采样。
Diffusion Policy 的真实闭环推理
当前机器人 Observation \(O_t\)
RGB、关节状态、可能的历史观察
初始化随机 Action Chunk
\(A_t^{(S)}\sim\mathcal N(0,I)\)
重复去噪
Noise Predictor 估计噪声;Scheduler 计算上一步候选动作
得到最终预测 Action Chunk
\(\hat A_t^{(0)}:K,D_a\)
反归一化 + 执行约束
选取本轮需要执行的动作
机器人执行 → 新 Observation
进入下一轮闭环预测
1. 为什么不一定执行整个 Action Chunk?
假设模型预测未来:
\ K=16 \\
个动作,但我们选择每次只执行:
\ T_a=4 \\
步。
那么一轮是:
\ \\text{预测16步} \\rightarrow \\text{执行前4步} \\rightarrow \\text{重新观察} \\
下一轮根据新的 Observation 再生成一段新的 Action Chunk。
这就是我们此前介绍过的 Receding Horizon(滚动时域) 思想。
这样做有利于让 Policy 根据环境变化持续修正动作,而不是对最初预测的全部动作盲目执行。
2. 一次动作预测为什么可能比较耗时?
因为一次完整生成过程可能涉及:
\ S \\
次去噪网络调用。
如果去噪网络本身比较复杂,反复调用就会增加推理延迟。
机器人真正关心的是:
\ \\boxed{ \\text{生成动作所需时间} \\quad与\\quad \\text{控制系统能够接受的延迟} } \\
因此扩散策略在部署时,不仅要评估动作生成质量,还要考虑采样步数、网络规模、硬件计算能力与实际控制频率。
有些采样器可以在少于训练扩散步数的迭代次数内完成生成,但它们的更新规则需要与相应 Scheduler 配置匹配。
3. 最后得到的 Action 能直接执行吗?
不一定。
因为网络输出通常处于训练所使用的归一化 Action 空间。
因此要先进行反归一化:
\ a_{\\mathrm{physical}} = a_{\\mathrm{norm}}\\sigma+\\mu \\
之后还要按照机器人实际控制接口解释这些数值。
例如一段 Action 可能表示:
-
关节目标位置;
-
末端位姿增量;
-
某种标准化运动指令。
它不是天然等于电机驱动器的电流或脉冲指令。
所以实际执行链还需要控制器、运动学或相关控制接口,视 Action Representation 而定。
Diffusion Policy 负责生成动作策略输出,不自动取代机器人底层运动控制。
七、本课最后需要建立的完整理论认识
现在我们可以把 DDPM 分成三个层次。
第一层是前向扩散的概率模型:
\ q(A\^{(s)}\\mid A\^{(s-1)}) \\
由噪声系数决定如何逐步加噪。
第二层是需要通过数据训练的条件预测模型:
\ \\epsilon_\\theta(A\^{(s)},s,O_t) \\
学习在机器人观察条件下,怎样估计动作噪声。
第三层是反向生成过程:
\ p_\\theta(A\^{(s-1)}\\mid A\^{(s)},O_t) \\
由网络预测和 Scheduler 更新规则共同决定下一步生成结果。
因此 Diffusion Policy 的本质不是"给动作加点随机数,再把随机数减掉"。
它是:
\ \\boxed{ \\text{通过人为定义的加噪过程} \\rightarrow \\text{学习条件反向去噪} \\rightarrow \\text{逐步生成合理的动作序列} } \\
从具身智能的角度看,完整系统又多了一层:
\ \\boxed{ \\begin{aligned} \&\\text{专家示范}\\\\ \&\\downarrow\\\\ \&\\text{学习条件动作分布}\\\\ \&\\downarrow\\\\ \&\\text{观察当前环境}\\\\ \&\\downarrow\\\\ \&\\text{扩散生成Action Chunk}\\\\ \&\\downarrow\\\\ \&\\text{执行部分动作}\\\\ \&\\downarrow\\\\ \&\\text{重新观察并闭环修正} \\end{aligned} } \\
这就是从 DDPM 数学到机器人动作控制的完整因果链。
第 21 课自测
-
为什么扩散模型中必须严格区分机器人控制时刻 \(t\)、动作块位置 \(k\) 和扩散步 \(s\)?
-
\(\beta_s\)、\(\alpha_s\)、\(\bar\alpha_s\) 分别描述什么?为什么需要定义累计连乘?
-
从单步加噪:
\ A\^{(s)} = \\sqrt{\\alpha_s}A\^{(s-1)} + \\sqrt{\\beta_s}\\epsilon_s \\
如何理解多步后:
\ A\^{(s)} = \\sqrt{\\bar\\alpha_s}A\^{(0)} + \\sqrt{1-\\bar\\alpha_s}\\epsilon \\
这个结果?
-
为什么反向过程中的"估计干净动作"与"更新到上一个噪声状态"不是完全相同的操作?
-
DDPM 的反向更新为什么有时既需要均值,又需要方差?
-
Noise Predictor 与 Noise Scheduler 的职责分别是什么?哪一部分主要通过专家示范学习参数?
-
为什么训练时通常不需要对一个样本完整执行几十轮去噪,而推理时却需要执行反向生成过程?
-
Diffusion Policy 的训练过程中,Noise Target 是从哪里得到的?为什么不需要额外的人工噪声标签?
-
当 Diffusion Policy 生成一个长度为 16 的 Action Chunk 时,为什么实际机器人不一定要连续执行完整的 16 步?
-
为什么不能把去噪完成的归一化 Action 直接理解成电机控制指令?