从BC到Difussion Policy:机器人动作生成算法入门
第 1 讲为什么需要 Diffusion Policy1.1 普通 BC 方法普通的行为克隆是单步回归模型每次只根据当前观测预测“下一步的动作”容易将多种可行的动作平均掉。行为克隆的伪代码obs_t当前图像当前关节角 action_tmodelobs_t 其中模型action输出的只是一瞬间的动作--关节1转多少度、关节2转多少度 lossmsepred_actionexpert_action1.2 BC 的局限性为什么单步回归会将多种动作平均掉通常来说会用MSE或者L2 loss训练那么根据下面的公式我们可以假设一个单一维度的动作来验证MSEMean Squared Error–均方误差将每一个预测误差先平方再求平均M S E 1 N ∑ i 1 N ( y i − y ^ i ) 2 MSE \frac{1}{N}\sum_{i1}^{N}(y_i - \hat{y}_i)^2MSEN1i1∑N(yi−y^i)2L2 loss把所有维度误差平方后加起来相比MSE少➗了NL ∣ ∣ y − y ^ ∣ ∣ 2 − − − − − − − ∣ ∣ y − y ^ ∣ ∣ 2 ∑ i ( y i − y ^ i ) 2 L ||y - \hat y||^2 -------||y-\hat y||^2 \sum_i (y_i - \hat y_i)^2L∣∣y−y^∣∣2−−−−−−−∣∣y−y^∣∣2i∑(yi−y^i)2为什么叫L2因为它来自数学里的范数NormL1 norm∣ ∣ x ∣ ∣ 1 ∣ x 1 ∣ ∣ x 2 ∣ . . . ||x||_1 |x_1||x_2|...∣∣x∣∣1∣x1∣∣x2∣...L2 norm∣ ∣ x ∣ ∣ 2 x 1 2 x 2 2 . . . ||x||_2 \sqrt{x_1^2x_2^2...}∣∣x∣∣2x12x22...平方后的 L2∣ ∣ x ∣ ∣ 2 2 x 1 2 x 2 2 . . . ||x||_2^2 x_1^2x_2^2...∣∣x∣∣22x12x22...所以L2 loss 误差向量的欧几里得长度平方几何上就是预测点和真实点之间的平方距离。当训练数据中存在一半往左一半往右的动作模型为了让mse误差最小根据这个公式就会预测其中的平均值这就是BC的局限性所在。1.3 多模态动作问题在同一个任务下抓杯子可以从左侧抓、右侧抓插孔可以从左侧绕、右侧绕这些都可以是正确动作所以不是一个状态一个正确答案而是一个状态对应多个合理动作这种现象就叫动作分布是多模态/多峰的1.4 Diffusion Policy 的引入单步回归就是模型根据当前观测预测下一步的动作比如输入当前图像和关节状态输入当前时刻的关节动作。对于动作分布的多模态现象单步回归中的MSE或者L2这类回归损失训练会输出平均值–选择障碍物这种情况但是在机器人动作中平均值不一定是合理动作所以说普通的单步回归容易将多模态动作分布平均掉DP和FL的优势在于他们学习的是动作分布可以生成不同合理的动作序列而不是只输出一个平均动作BC actionmodelobs DP noise--denoise--action_chunk FL noise--沿速度场流动--action_chunk第 2 讲DDPM 基础原理参考材料DDPM论文https://arxiv.org/abs/2006.11239HuggingFace-DDPMhttps://huggingface.co/docs/diffusers/api/schedulers/ddpmDDPM 全称是 Denoising Diffusion Probabilistic Models-去噪扩散概率模型是 Ho 等人在 2020 年提出的一类扩散生成模型。它的基本思想是前向过程逐步破坏数据反向过程学习把噪声还原成数据。在本课程中我们最终关心的不是图像生成而是机器人动作生成。所以这一讲虽然从图像扩散讲起但每个概念都会对应到机器人动作序列中。2.1 扩散模型基本思想DDPM的本质就是先人为地把真实数据破坏成噪声再训练模型学会如何从噪声恢复数据。前向扩散过程也就是加噪过程清晰图片 → 有一点噪声 → 有很多噪声 → 纯噪声反向去噪过程也就是生成过程纯噪声 → 去掉一点噪声→ 更清晰 → 生成图片DDPM 本来是生成图片的方法但它的核心不是“图片”而是“从噪声中生成数据”。如果数据是图片它就生成图片如果数据是机器人动作序列它就可以生成动作。真实动作序列 → 加噪 → 随机动作噪声随机动作噪声 → 去噪 → 生成动作序列2.2 前向加噪过程DDPM 原论文中前向过程被定义为一个固定的马尔可夫加噪过程也就是逐步往数据里加入高斯噪声前向加噪过程的作用是把干净数据 x0 逐步变成噪声 xTx 0 → x 1 → x 2 → . . . → x T x_0 → x_1 → x_2 → ... → x_Tx0→x1→x2→...→xTx0 是原始干净数据x1 是加了一点噪声的数据xt 是第 t 步加噪后的数据xT 接近纯高斯噪声DDPM 里最常用的加噪公式核心公式是x t α ˉ t x 0 1 − α ˉ t ϵ x_t \sqrt{\bar{\alpha}_t}x_0 \sqrt{1-\bar{\alpha}_t}\epsilonxtαˉtx01−αˉtϵx0 是原始干净的数据xt 是第 t 步加噪后的数据ϵ是随机高斯噪声t是扩散时间步数αˉt是噪声调度系数当 t 很小时xt更像 x0当 t 很大时xt 更像 noise2.3 反向去噪过程前向过程是干净数据 → 噪声 反向过程是噪声 → 干净数据也就是x T → x T − 1 → x T − 2 → . . . → x 0 x_T→ x_{T-1} → x_{T-2} → ... → x_0xT→xT−1→xT−2→...→x0#推理时我们没有真实数据 x0所以只能从随机噪声开始xtorch.randn(shape)#然后不断调用模型预测噪声并更新当前样本fortinreversed(range(T)):pred_noisemodel(x,t)xdenoise_step(x,pred_noise,t)#最后得到x ≈ 生成出来的数据DDPM 的反向过程就是训练一个模型去近似从 xt 到 x_{t-1} 的去噪过程。Hugging Face 的 Diffusers 文档中DDPMScheduler 也正是用于处理训练加噪和推理去噪中的调度步骤。为什么推理时从高斯噪声开始因为 DDPM 训练时已经学会了从任意噪声程度的xt 中预测 noise。所以推理时可以从最严重的噪声开始也就是xT ≈ 纯高斯噪声然后一步步去噪最终生成一个符合训练数据分布的新样本。放到机器人里就是随机动作噪声 → 去噪 → 合理动作序列这也是 Diffusion Policy 能生成多种动作的原因之一每次初始噪声不同最终生成的动作序列也可能不同第 3 讲Diffusion Policy 基本原理参考材料DP论文https://arxiv.org/abs/2303.04137DP代码https://diffusion-policy.cs.columbia.edu/?utm_sourcechatgpt.com上一讲我们讲的是DDPM从噪声中生成数据这一讲要理解的是Diffusion Policy在机器人观测条件下从噪声中生成机器人未来一段动作序列action chunk在了解完DDPM基本实现后继续回答一个问题如何把图像扩散模型改造成机器人策略模型3.1 从图像扩散到动作扩散modelxt,t图像扩散模型的目标是从随机噪声中生成一张符合数据分布的图片。modelobs,xt,t而动作扩散的核心是根据当前观测新增条件下把机器人动作序列当成 DDPM 中的 x0来生成连续的动作序列两者本质上都是对一类数据在去噪只不过一个在像素空间中一个在连续动作空间中。3.2 DP 的输入与输出DP的输入Diffusion Policy 和普通 DDPM 的最大区别是DP 是条件生成模型基于当前观测obsp r e d n o i s e m o d e l ( o b s , x t , t ) pred_{noise} model(obs, x_t, t)prednoisemodel(obs,xt,t)Obs图像、关节角度信息、语言指令、历史观测信息xtxt.shape [B, pred_horizon, action_dim]-------根据数据的形状可以看出xt代表第 b 条样本中未来第 t 步机器人要执行的 7 维动作指令。Bbatch size批量样本数pred_horizon预测动作序列长度action_dim每一步动作的维度 t扩散时间步DP的输出#DP的输入pred_noisemodel(obs,xt,t)#xt输入形状xt.shape[B,pred_horizon,action_dim]#DP的输出#pred_noise形状与xt一样pred_noise.shape[B,pred_horizon,action_dim]#训练时计算losslossF.mse_loss(pred_noise,noise)#推理时更新动作序列xscheduler.step(pred_noise,t,x)3.3 条件去噪过程p r e d n o i s e m o d e l ( o b s , x t , t ) pred_{noise}model(obs,x_t,t)prednoisemodel(obs,xt,t)所谓条件去噪相对DDPM多出来的obs就是条件xt:是一段被污染的动作t告诉模型当前动作被污染得多严重obs告诉模型当前目标在哪里障碍物在哪里机器人自己在哪里总结在当前观测条件下判断这段带噪声动作里哪些部分应该被去掉学习过程 #输入真实动作x0x0batch[action_chunk]#生成随机噪声并添加到x0上得到xtnoisetorch.randn_like(x0)xtnoise_scheduler.add_noise(x0,noise,t)#将obsxtt输入模型让模型预测噪声pred_noisemodel(obs,xt,t)#监督pred_noise接近noiselossF.mse_loss(pred_noise,noise)推理过程#输入随机的噪声其中x与真实动作形状一样xtorch.randn([B,pred_horizon,action_dim])#逐步去除噪声fortinscheduler.timesteps:pred_noisemodel(obs,x,t)xscheduler.step(pred_noise,t,x).prev_sample#输出最终去噪后的动作序列action_chunkx第4讲DDPM 图片项目生成项目链接第5讲DP-PushT项目项目链接第6讲DP-2D轨迹项目项目链接第7讲DP与其他算法对比第8讲常见面试问答与总结