一条演示,16 个物体:DemoMimic 用「局部接触几何」学会泛化
做机器人操作这些年,我最怕听到的一句话就是:“换个物体试试?”模型在训练集里跑得再漂亮,一旦遇到外形稍有不同的新物体,成功率立刻崩盘。这种挫败感,做过模仿学习的人都懂。最近我深入复现了 DemoMimic 这套方案,它只用一条人类演示,就能让机器人把同一个操作泛化到 16 个不同物体上,核心思路就是「局部接触几何」。这篇文章我会把它的设计逻辑、关键模块、训练细节和踩坑记录都拆开讲,适合正在做机器人操作、模仿学习或者抓取泛化的朋友参考。
DemoMimic 解决的问题非常具体:人类示范一次“倒水”,机器人能不能在 16 个形状、大小、材质都不同的杯子上都倒成?传统的模仿学习方案通常会输在“全局轨迹过拟合”上——模型记住了演示中手臂走过的三维空间路径,换个位置放杯子就失效。DemoMimic 的做法是换一个表征层次,从“手和物体接触区域的局部几何”来抽象任务,从而让策略天然具备跨物体迁移的能力。
1. 一条演示到底能教会机器人什么
1.1 为什么“一条演示”这么难
模仿学习入门很容易,但数据效率一直是绕不开的坎。常见的做法是收集几千甚至几万条专家演示,训练一个行为克隆模型或者逆动力学模型,让机器人学会“状态到动作”的映射。这么做的问题是:数据一少,策略就退化成“背轨迹”。
你仔细想,人类在操作物体时,大脑记住的并不是手臂在空间中划过的绝对轨迹,而是“我的手和物体之间应该保持什么样的相对关系”。比如倒水,真正核心的是水杯倾斜到某个角度、出水口对准目标容器。至于你的手是在桌子左侧还是右侧伸过去的,根本不重要。
但传统行为克隆模型没有这个区分能力。它看到的是高维状态输入,比如关节角度、末端位姿、视觉图像,目标是拟合一个函数。当演示数据只有一条时,模型很容易把所有与任务无关的变量也一起记住。最典型的翻车案例就是:机器人在训练时杯子放在桌面左侧,换到右侧后,它还会朝左侧空抓一把。
所以“一条演示”难,本质上是“从极度稀疏的数据中提取任务本质”难。数据不够时,模型没有机会通过对比多个演示来区分“哪些变量变了没关系”,它只能靠先验结构去补足这个信息。DemoMimic 的解法是,在表征层面就告诉模型:你要关注的是局部接触几何,而不是全局空间位置。
1.2 泛化卡的从来不是视觉,是接触
很多人有个误区,觉得泛化不好是视觉识别不够准。换一个物体失败,就以为是物体检测没认出来。但在操作任务里,真正决定成败的是“手和物体接触之后的物理交互”。
视觉再准,也只能告诉你物体在哪里、长什么样。当手接触物体之后,能不能稳定施力、能不能沿着正确方向运动,这跟视觉没有直接关系,跟接触的局部几何密切相关。
举一个简单的例子:拔瓶塞。无论是红酒软木塞还是药瓶里的橡胶塞,只要能建立“手指在瓶塞上表面形成可靠接触、然后垂直向上发力”这样的接触模型,不需要理解“软木塞”和“橡胶塞”这两个类别区别,任务就成了。
从机器学习的角度看,局部接触几何相当于一个“任务相关的中间表征”。它过滤掉了物体的颜色、纹理、绝对尺寸、类别等无关信息,保留了驱动操作成功的关键结构:接触位置、接触法向、接触区域的形状匹配度。
我在复现过程中试过直接用完整点云做输入,网络确实能过拟合一个物体,但换物体成功率不到两成。后来改成先提取接触点、再做局部坐标归一化,泛化能力一下子就上来了。这个对比让我确信:泛化瓶颈不在视觉特征好不好,而在你有没有给网络一个“会泛化的归纳偏置”。
2. DemoMimic 的设计思路拆解
2.1 核心思路:从“轨迹匹配”变成“接触映射”
传统模仿学习解决操作任务的路径是“轨迹匹配”:输入当前状态,输出一个期望的末端轨迹或者关节轨迹。DemoMimic 的路径是“接触映射”:输入当前物体点云和手部状态,输出一组接触点以及接触点的局部几何约束,再基于这些约束解算出运动。
说人话就是:传统方法在模仿“手往哪儿走”,DemoMimic 在模仿“手该碰哪里、怎么碰”。
这个转变带来的一个巨大优势是:接触点的预测天然与坐标系无关。假设训练时演示的是从右侧抓取一个马克杯的把手,模型中学习到的是“手指与把手圆柱体侧面的接触关系”。推理时换一个形状稍有差异的杯子,网络要预测的仍然只是“接触点在哪里”,而不需要重新规划一条从右侧伸向把手的空间路径。
当然,光有接触点还不够,还需要一个“接触优先级”。在操作过程中,有些接触是本质性的,比如倒水时手对杯壁的握持;有些接触是意外碰撞,比如手背蹭到杯沿,应该被忽略。
DemoMimic 的做法是使用接触注意力机制,给每个候选接触点分配一个权重。权重高的接触点在后续运动生成中占据主导地位,权重低的可以直接忽略。这个设计很关键,它能防止网络把“视觉遮挡造成的伪接触”和“真正的任务接触”混为一谈。
我自己的验证结果也支持这套逻辑:在只给网络 1 条演示的前提下,接触注意力权重主要集中在一两个接触区域,而全局轨迹模型会把注意力分散到整条手臂的点云上。背后原因很简单,局部接触几何的表征维度比全局轨迹低得多,网络不需要大量数据就能收敛到稳定解。
2.2 一图流的整体 Pipeline
为了便于理解,我把 DemoMimic 的完整流程拆成几个阶段,每一阶段都有明确的输入输出:
- 演示采集:记录人类演示时的手部姿态、物体点云、接触状态,可以作为训练监督。
- 接触提取:从演示数据中计算手部与物体的重叠区域,生成接触图(contact map),包含接触点坐标、法向方向、接触区域大小。
- 接触条件化:把接触图从全局坐标系转换到以手部为中心的正则坐标系,消除世界坐标带来的歧义。
- 策略推理:输入新物体的点云和当前手部姿态,预测接触注意力、目标接触点、接触法向。
- 运动生成:根据目标接触约束,用轨迹优化或者逆运动学生成平滑动作,执行操作。
- 反馈修正:如果接触点丢失或者滑移,根据接触力反馈做局部调整。
这个流程最巧妙的地方在第 3 步和第 4 步的组合。第 3 步让训练数据具备正则性,第 4 步让推理阶段可以直接复用训练时学到的接触模式。
我在实际复现时把第 6 步简化成了视觉反馈闭环,没有用真实的力传感器。结果发现,只要第 4 步的接触点预测足够准,视觉闭环就能维持较高的成功率。但如果在预测不准的情况下强行执行开环动作,失败率会非常高,后面我会在常见问题部分详述。
3. 关键模块的实现细节
3.1 接触表征的构建方法
接触图是 DemoMimic 的核心表征,构建方式决定了整个系统的上限。我的实现流程是这样的。
第一步,采集演示数据时同步记录手部模型和物体点云。这里有个关键点:手部模型必须是一致的网格模型,不能像普通 RGB-D 骨架一样只有关键点,否则计算不出真实的接触区域。
第二步,计算手部网格与物体点云之间的距离。对物体点云中的每个点,找到手部网格上最近的点,计算欧氏距离。距离小于某个阈值(我用的 3mm)的点,标记为候选接触点。
第三步,对候选接触点做聚类,剔除离散噪点,得到连续接触区域。每个接触区域记录三个核心属性:接触区域中心点坐标、接触区域表面法向、接触区域面积。
这里要注意法向的方向一致性。如果直接用原始点云的法向,不同物体上同一个接触点的法向方向可能完全相反,网络会非常困惑。我的处理是:把法向对齐到“从物体指向手部”的方向,也就是接触力的大致方向。
还有一个容易被忽略的细节:接触图需要区分“静态接触”和“动态接触”。在演示中,握持阶段手和物体相对静止,接触区域基本不变。但在翻转、倾倒过程中,接触点可能会缓慢滑动,产生一个接触轨迹。DemoMimic 的策略网络需要同时预测接触点的位置和移动方向,因此我在构建接触图时保留了时序信息,不只是输出单帧接触状态,而是输出一小段接触变化趋势。
3.2 网络结构与训练目标
网络结构上,我参考了常见的点云处理框架,没有做太复杂的设计。整体分四个部分:
- 点云编码器:用 PointNet++ 提取新物体点云的全局和局部特征。
- 接触注意力模块:基于点云特征和当前手部状态,输出每个点为“理想接触点”的概率。
- 接触属性预测头:对高概率接触点,预测目标法向、接触区域面积、期望接触力方向。
- 运动解码器:把预测出的接触约束转化为平滑的末端轨迹,并用二次规划保证运动学可行。
训练目标函数我用了三部分损失相加:
- 接触点分类损失(Focal Loss):由于一张点云中真正的接触点只占很小比例,正负样本极不平衡,用 Focal Loss 比用交叉熵好很多。
- 接触属性回归损失(Smooth L1 Loss):对法向和面积做回归,使用 Smooth L1 可以有效抑制异常点的干扰。
- 接触滑动一致性损失:约束相邻时间步的接触区域中心点移动方向与演示一致,避免出现接触点跳变。
实操时建议把三类损失设成不同权重,分类损失权重最高,滑动一致性损失权重最低。我一开始把三个损失设成等权,训练出来接触点分类很准,但运动生成时末端抖动非常严重,就是因为滑动一致性约束太弱。
3.3 16 个物体的评测设计
16 个物体不是随便选的,而是按照泛化难度分了四个层级,每个层级 4 个物体:
- 层级一:同一类别,尺寸变化。比如不同容量的马克杯,形状几乎一样,只是大小不同。
- 层级二:同一类别,结构差异。同样是杯子,有的带把手,有的是无把手的直身杯。
- 层级三:不同类别,但操作方式类似。比如保温杯、花瓶、水壶,虽然外观差异大,但“握住并倾斜”这个接触模式相同。
- 层级四:材质和表面属性变化。比如玻璃杯、纸杯、带纹理的陶瓷杯,接触区域的摩擦特性完全不同。
这个评测设计的价值在于它能告诉你模型到底学到了什么。如果层级一成功率高、层级三失败,说明模型还是在“形状匹配”,没有真正抓住“接触模式”;如果层级三和层级四也能保持较高成功率,说明接触几何表征确实起到了作用。
我复现出来的实验结果是:16 个物体平均成功率约 87%。层级一和层级二接近 95%,层级三约 85%,层级四约 75%。层级四的失败主要出现在纸杯的接触区域变形上,这个属于传感器层面的物理局限,不是策略层面的崩溃。
4. 实操过程与踩坑记录
4.1 数据采集和标注的实操细节
数据采集是整个流程中最费人力的部分,也是最容易被低估的一环。仅有一条演示,意味着这段演示的质量直接决定模型上限。我踩过几个比较典型的坑。
第一个坑是接触标注噪声过大。用手部网格和点云做碰撞检测时,深度相机的噪声会造成大量零散的伪接触点。一开始我直接用原始深度图重建点云,接触区域边缘总是有一圈细碎的杂点。后来换成多角度扫描重建的物体模型,噪声明显下降,接触提取干净了很多。这里也建议大家:如果条件允许,尽量用高精度扫描模型替代深度相机实时重建。
第二个坑是演示速度不一致。人在演示时,动作速度不是均匀的,拿取阶段慢、移动阶段快。如果直接按时间帧均匀采样训练数据,网络会把大量权重分配到“移动阶段”的接触状态,而真正关键的“接触建立瞬间”反而样本稀少。我的处理方式是做动态时间规整(DTW),把演示中的接触状态变化重采样到等步长,保证接触注意力模块看到的是节奏一致的数据。
第三个坑是手部自遮挡。深度相机拍到人体示范时,手经常被物体挡住,导致接触区域点云缺失。改进方法是在演示环境中放置两个不同角度的深度相机,融合点云后再做接触提取。融合后的接触区域完整度比单视角提升了很多,基本上解决了遮挡问题。
4.2 训练中最容易翻车的三个点
翻车点一:接触注意力发散。训练前期,注意力权重会落在一些完全没有任务意义的点云上,比如桌面、背景物体,甚至手指尖。我排查后发现,原因是负样本加入得太少。后来在每个训练 Batch 中随机加入 30% 的背景点云作为负样本,这个问题就消失了。背景点云采样时要避开物体本身,否则网络会把物体点云和背景点云混淆。
翻车点二:局部坐标系定义不一致。第二个翻车点很隐蔽,如果训练时以“手部掌心坐标系”为接触图的正则坐标系,推理时却用了“末端执行器坐标系”,接触点预测结果会整体偏移几个厘米。我的解决办法是统一使用手部背面的一个小平面作为参考坐标系,并且在数据增强时加入 ±10 度的随机旋转和 ±5mm 的随机平移,让网络对坐标系扰动更鲁棒。
翻车点三:接触属性回归震荡。法向和接触力的预测值在训练后期会出现震荡,虽然分类准确率稳定,但连续几个 epoch 的损失一直在小幅波动。原因是一个接触区域边缘的微小点云扰动会导致法向计算剧烈变化。我在采样接触区域时采用了按距离加权的平均法向,而不是直接用最近邻点法向,震荡就缓解了。
4.3 常见失败模式与排查方法
| 失败现象 | 可能原因 | 排查方法 |
|---|---|---|
| 换物体后抓取位置偏移严重 | 接触注意力集中在全局形状特征上 | 检查接触图可视化,看注意力是否覆盖任务关键区域 |
| 抓取成功但操作时物体滑落 | 接触属性回归精度不足,法向预测偏差超过 5 度 | 减少演示中快速运动段,增加接触属性书写精度 |
| 同一物体多次试验成功率波动大 | 点云重建噪声不一致,接触提取阈值不稳定 | 固定深度相机参数,做点云配准后再输入网络 |
| 训练损失低但泛化差 | 过拟合演示的接触轨迹 | 增大局部坐标系扰动范围,增加背景负样本比例 |
| 遮挡严重时完全失败 | 接触提取阶段点云完整性不够 | 改用多视角点云融合,或者增加接触区域补全模块 |
我在复现过程中发现,最容易排查也最容易犯的错误是第一种:总以为模型“学到了泛化”,实际上只是记住了物体的形状轮廓。判断方法也很简单,换一个形状结构差距特别大的物体,看看接触注意力是否仍然落在功能区域上。如果落在别的区域,那基本就是全局形状特征在主导,需要回到接触表征的归一化处理上。
5. 泛化边界与评测方法
5.1 除了成功率,还要看什么
成功率当然是最直观的指标,但仅凭成功率判断系统好坏会误导后续优化方向。我在评测中增加了三个观察维度,建议做相关工作的朋友也参考一下。
第一个是接触保持率。指操作过程中,策略维持有效接触的时间占比。如果接触只在刚接触时保持,运动一开始就断了,说明预测出的接触位置是静态准确的,但是缺少动态更新能力。
第二个是接触模式的可辨识度。具体做法是把预测出的接触注意力可视化,看它是否清晰地集中于一个或少数几个连续区域。注意力连续、集中,说明网络真正学到了结构化的接触表征;注意力分散、跳跃,说明它还是在用低层几何特征做匹配。
第三个是干预率。如果操作过程中需要人远程干预才能完成,说明系统对一些边界条件没处理好。干预率低,才能从实验室走向真实工作场景。我建议在记录成功率时同步记录干预原因,后续优化优先级会更清晰。
5.2 什么情况会失效
DemoMimic 的适用边界也很清晰,以下几个场景它处理不了。
第一,任务本身无法用“局部接触”定义的情况。比如“把积木推到标记区域”,这个任务的本质是全局位置约束,而不是局部接触约束。接触几何表征会退化成“推到哪里都行”,策略直接失效。
第二,需要精细力度控制的任务。比如捏鸡蛋、拧螺丝,接触几何能告诉你接触在哪里,但无法只靠几何信息推断“该施多少力”。这类任务需要叠加力控或者触觉传感,单靠视觉点云接触提取,精度不够。
第三,演示中存在大量非接触式工具操作。如果任务是“用螺丝刀拧螺丝”,关键接触发生在工具和螺丝之间,手与工具的接触反而只是辅助。这时候需要扩展接触图的定义,把工具也纳入接触计算,工作量会大不少。
我在做失败分析时发现,很多看似“泛化失败”的案例,其实是停止条件设置得不合理。比如接触点在物体点云边缘时,网络的注意力权重天然偏低,如果阈值设得太高,就错过正确的接触点。合理的做法是根据接触面积动态调整阈值,而不是固定一个数值。
5.3 从单演示到更多任务的扩展方向
从统计学习理论的角度看,DemoMimic 做的事本质上是缩小了假设空间。给定一条演示数据,如果直接学“像素到动作”的映射,假设空间巨大,泛化误差界也会很松。但引入局部接触几何表征后,网络只需要在“接触模式”这么一个小得多的空间里做拟合,天然更容易泛化。这与深度学习里的数据泛化理论一脉相承:先验约束越强、目标空间越小,数据需求量就越低。
顺着这个思路,后续可以扩展的方向有三块。
第一块是多接触任务。当前方案主要处理单个接触区域,如果任务需要两只手同时接触不同物体,接触图的维度会上升,但核心思路不变,只需要把注意力模块扩展成多头结构。
第二块是接触模式的组合。比如“拿起杯子、倒水、放下”,其实是三个接触模式的组合。如果把每个模式分解成独立的接触图,再训练一个切换高层策略,就能实现多步骤操作的泛化,而不再局限于单条演示。
第三块是要不要引入跨任务预训练。现在是一条演示对应一个策略,如果能在大规模接触数据上预训练一个“接触基座模型”,那么新任务可能只需要更新一个小的适配模块,或者连更新都不需要,直接 zero-shot 迁移。这个方向目前还有不少技术难点,但值得持续关注。
回到开头那句“换个物体试试”,DemoMimic 给出的答案不是让模型“见过更多物体”,而是让模型“只看到该看的东西”。这个思路对我来说启发很大,也解决了我之前一直头疼的跨物体操作问题。之后再做新的操作任务,我会优先问自己:这个任务的局部接触几何是什么?而不是:我要准备多少条演示数据。有时候,答案往往藏在问题本身的物理结构里。