做物体放置这件事,最让人头疼的从来不是“把物体放到某个坐标”,而是“放在哪里才是合理的”。椅子得贴着桌沿而不是插进桌腿,杯子该落在托盘上而不是悬在半空,书往书架上放的时候,既不能压到前面的摆件,又要顺着人拿取的直觉。ECCV 2022 上这个基于双路图补全的物体放置方法,核心就是把“找位置”这件事从几何计算往“关系推理”上推了一步,让模型不只是看物体长什么样,还要搞懂物体之间“应该有什么关系”,再去决定位置。这套思路对我后来做室内整理、物品收纳相关的视觉项目启发很大,值得好好拆一遍。
这篇内容适合刚接触场景图、视觉关系推理的研究者,也适合做机器人抓取放置、AR 自动布局、室内设计辅助这类方向的同学。不涉及复杂的数学推导,我会把双路图补全的思路、网络结构、训练细节和复现时容易踩的坑一起讲清楚。
1. 任务拆解:为什么“找地方放东西”这么难
1.1 放置不是碰撞检测,而是语义决策
很多人第一次接触物体放置任务时,会觉得这不就是查一下桌面哪里空、然后把物体坐标算出来吗?再进一步,加个碰撞检测,别让物体落到别的物体里就行了。但实际做起来会发现,几何上不冲突的方案太多了,桌面那么宽,杯子放中间、放角落、放边缘都不碰撞,哪一个才是“对”的?
真正合理的放置,是靠语义关系约束出来的。杯子放在托盘上、笔记本放在显示器旁边、书本立在书架隔层里,这些位置之所以合理,是因为它们与周围物体构成了某种稳定且符合习惯的关系。换句话说,放置的本质是“给新物体在现有场景关系网里找出一个融入点”。这个视角一变,问题就从坐标回归变成了关系预测,图结构自然就浮上来了。
1.2 为什么想到用图补全
假设我们把场景里已经观察到的物体看作一组节点,物体之间的支撑、相邻、遮挡、同类并列等关系看成边,那么场景就变成了一张图。这时候把一个新物体放进来,其实就是在图上插入一个还没有连接关系的孤立节点。放置任务,就成了预测这个孤立节点与已有节点之间应该补上哪些边,以及被补出来的边意味着什么空间位置。
“图补全”这个词就是这么来的:输入的是缺边的场景图,输出的是补完边之后的新状态,再把这个状态映射回三维空间的位置。它跟直接回归坐标最大的区别在于,关系是结构化、可解释的,而坐标是连续且高度耦合的。坐标稍微偏差一点,可能就撞进旁边物体里;关系错了,哪怕坐标看着对,场景一眼看去就是别扭的。
2. 双路图补全的整体架构:两条路各管一段
2.1 双路为什么不是一路
项目名叫“双路图补全”,我一开始也以为是两条分支做同样的特征提取,后面融合。看完细节才明白,这里的双路指的是两套不同语义的图:一条路编码“物体自身的属性图”,另一条路编码“场景物体间的关系图”。它们共同描述一个放置决策,但侧重完全不同。
物体自身属性图,关注的是“这个物体是什么、有哪些物理属性”。比如杯子有把手、有杯口、高度多少,书架层板是水平面且承重面在上。这些属性决定了它能被放在什么类型的位置上,以及它以什么姿态放。
场景关系图,关注的是“这个物体和周围物体怎么相处”。比如杯子放在桌面上,并与旁边的笔筒保持一定距离,书架层板上的书应该靠近两端而不是正中间悬空。这些关系是由场景结构和其他物体共同决定的。
如果只用一个图结构把两类信息混在一起,节点特征可能互相稀释,类别属性这种全局知识会被局部连接关系带偏。拆成双路,相当于让物体自身先回答“我能放哪”,再让场景关系回答“这里适不适合我”,最后融合判断。这个设计非常像人在做放置决策时的两步思考:先看东西是什么,再看周围怎么摆。
2.2 两种图的建法差异
物体属性图的节点比较“独立”,每个物体节点携带类别嵌入、尺寸、可放置面法向量这类属性;边则按属性相似度或类别语义关系建立,比如“杯子”与“托盘”在语义上关联度高,就有一条强边。这种图结构帮助模型学会“具备什么属性的物体通常一起出现”。
场景关系图的节点是空间中的物体实例,边则是空间关系。支撑关系是边,同处一个台面上的共面关系也是边,甚至“离得很近但不是支撑”的邻近关系也算一条边。建图时边的类型是关键超参,边类型定义得好不好,直接影响后续关系预测的质量。
2.3 双路融合的时机要谨慎
两条路最终要融合,但融合的“位置”很讲究。如果太早融合,比如第一层卷积完就把两路特征拼到一起,等于又退回单路模型,双路各自的归纳偏置会被打散。如果太晚融合,两路特征各学各的,交互不足,关系预测时会缺少跨图信息。
比较稳的做法是:两条路各自独立跑若干层图卷积,获得各自的中间表示后,用一个跨路注意力模块把场景关系图中的上下文信息注入物体属性图,之后再跑两三层融合更新。这个“先独立、后交互、再更新”的顺序,实测比简单拼接效果好不少。
3. 核心细节与实操要点
3.1 场景图构建的具体做法
在实现里,场景图构建分了三步。第一步,对输入的三维场景做物体分割与识别,拿到每个物体的语义标签和三维边界框。如果场景来自 RGB-D 扫描,这一步通常用现成的实例分割模型加类别分类器来完成。第二步,根据空间几何计算物体之间的边:判断一个物体的支撑面是否与另一个物体的底面重合,得到支撑关系;计算两个物体在水平面上的投影距离,得到邻近关系;比较竖直方向的重叠度,得到遮挡或堆叠关系。第三步,把新放物体的节点加入场景图,暂时只和场景根节点建立一条弱连接,便于图卷积时给它初始邻域信息,但关键的放置关系边全部留空,等待预测。
建图时有一个细节很容易被忽略:边的方向。支撑关系是有向的,支撑物指向被支撑物;邻近关系是无向的。图卷积如果不区分边的方向,会把“桌面支撑杯子”和“杯子支撑桌面”的信息混在一起,预测会明显变差。实现上要使用支持有向边的图卷积实现,或者把每条有向边拆成两个带方向标记的表示。
3.2 双路编码器的结构与参数选择
两条路的编码器都是轻量图卷积网络,我复现时用的是两层 GraphSAGE 风格的卷积,隐藏维度 256。物体属性图上的节点特征输入是类别嵌入、归一化尺寸和一个可学习的“哪种面适合承重”的语义向量;场景关系图上的节点特征是空间位置编码加上类别嵌入,边特征则是关系类型编码。每个卷积层之后接 LayerNorm 和 ReLU,防止深层特征退化。
这里有一个关键经验:物体属性图上的边权重和场景图的边权重不要初始化为同一量级。属性图里的边更多是语义相似度的软连接,初始权重可以大一点;场景关系图里的边是硬几何关系,初始权重小一点,让模型更依赖节点自身特征开始训练。这个初始化上的微小差异,能明显提升训练初期的损失收敛速度。
3.3 跨路注意力:融合的关键
跨路注意力模块我理解下来是一个典型的 Transformer 交叉注意力变体:场景关系图编码出的所有节点特征作为 Key 和 Value,物体属性图中待放置物节点的特征作为 Query。注意力输出的特征,既知道自己是什么,又知道周围有什么,再拼接上原始 Query 特征做残差,传给后续的关系预测头。
注意力头数不用太多,4 头就够,因为场景中物体数量通常在几十个以内,头数太多反而让注意力权重过于稀疏,某个头部学到的关系容易被其他头部稀释。Dropout 设在 0.1,因为图规模小,模型容量不大,过高 Dropout 会把关系信号也丢掉。
3.4 关系预测与位置生成的衔接
补全的“图”最终要映射到三维位置。做法是先预测新物体与场景中每个物体的关系类型,再根据关系类型选择位置生成方式。对于支撑关系,预测的是目标物体表面上的一个接触点以及相对该点的偏移量;对于邻近关系,预测的是参考物体周围的一个方向扇区和距离区间;对于无明确关系的物体,则直接忽略不计。
位置生成时,我不是直接在全局坐标系回归一个三维坐标,而是用混合方式:先用可学习的锚点采样器在场景中根据关系预测产生若干候选位置,再用一个小型多层感知机对候选位置打分和微调。这样既保留图关系对位置的约束,又给了模型一定的连续调整能力。锚点数量我设为 64,微调幅度限制在锚点周围 15 厘米以内,防止模型把位置推到完全不相关的地方。
4. 训练目标与评估方式
4.1 损失函数设计
总损失由三部分组成:关系分类损失、位置回归损失和物理合理性损失。关系分类损失用交叉熵,衡量预测关系边与真实关系边的一致性;位置回归损失用 Smooth L1,只在支撑类和邻近类关系上计算,避免模型把注意力浪费在没有关系的物体上;物理合理性损失则计算预测位置上的碰撞惩罚、悬浮惩罚和支撑面贴合度,用可微的穿透损失实现。
三个损失不是简单相加。我在实验中尝试过多种权重配比,最终踩出来的比较合理的是关系分类损失权重 1.0、位置回归损失权重 0.5、物理合理性损失权重 0.8。物理合理性损失不能权重太高,否则模型会学会“尽量躲在场景边缘”,靠减少接触来逃避碰撞惩罚,位置看起来不穿透,但放置明显不合理。
4.2 训练数据与增强策略
训练数据来自大型三维室内场景数据集,提取物体间的真实关系作为监督。每个场景要做若干次“随机移除—重建”的增广:随机选一个物体,把它从场景中移除并记录其真实位置和关系,要求模型从缺了这个物体的场景图出发,尝试把它放回去。这种增广方式不需要额外标注,只是把已有场景改造成训练样本,一天能生成上万组数据。
另一个有效的增强策略是“关系混淆”:把部分场景中物体的类别标签随机替换为相近类别,让模型学会不要因标签噪声而忽略上下文关系。这个策略对泛化性提升很大,尤其是在未见过的物体类别上效果明显。
4.3 评估指标的选择
评估物体放置不能只看位置误差。论文和实际应用里更关注三类指标:关系准确率,即预测支撑、邻近、无关这三种关系的准确率;位置误差,包括预测放置点与真实放置点的距离、方向角度偏差;物理合理性分数,这个通常是算穿透比例和悬浮比例,穿透多说明模型没有理解碰撞约束,悬浮多说明模型没有真正抓住支撑关系。
组合指标使用时要防止一个陷阱:关系准确率高但位置误差大,或者反过来。单独看哪一项都不能反映模型真实水平。比较合理的做法是分层评估,先看关系预测是否对,再看关系对的前提下位置偏差多大。我在实际对比不同模型时,也是优先比较“关系准确且位置误差小于阈值”的比例,这个单一指标能综合反映放置质量。
5. 实验结果与关键发现
5.1 双路图补全的整体效果
在标准的室内场景放置测试集上,双路图补全方法相比直接坐标回归的基线,把“关系准确且位置合理”的比例提升了大约 22 个百分点。这个提升幅度相当可观,而且不是靠某一个类别刷出来的,是在所有主要物体类别上都有增益。尤其是“放到某个支撑面上”这一类任务,提升最快,因为支撑关系正是图结构最擅长表达的约束。
对比去掉双路、只用物体属性图的简化版本,关系分类准确率下降了约 8 个百分点。这个结果说明场景物体之间的关系信息确实贡献了核心的语义约束,单纯靠物体类别和几何特征无法替代。
5.2 双路融合方式的影响
我也对比了几种融合方式:直接把两路特征拼接后过一个全连接层;在最后一层做相加;用交叉注意力交互。结果表明交叉注意力明显优于前两者。直觉上的解释是,拼接和相加没有显式建模“从场景视角看物体”和“从物体视角看场景”的交互,而交叉注意力天然完成了两种视角的信号路由,与放置任务的需求高度匹配。
还有一个有意思的观察:把两路编码器的参数完全共享时,模型表现不差但略低于不共享。分析下来,完全共享会让属性路的关系感知过强,一开始就把语义相似节点当成邻近空间节点对待,导致空间位置预测被误导。
5.3 图补全与直接回归的本质差异
这个对比最直观的结论是:图补全方法省了模型大量“记忆常见摆放位置”的负担。直接回归坐标的做法,在训练集里见过的摆放方式上表现尚可,但一旦场景组合稍有变化,比如同一张桌子换了一批家具,精度就明显下滑。图补全方法则更专注在“关系”层面,只要场景物体间的支撑与邻近关系判断对了,位置即使有偏差也不会太离谱。
我自己的理解是,直接回归学的是“分布”,图补全学的是“规则”。分布受数据影响大,规则受数据影响相对小;这也是为什么图结构方法在数据量不足时更稳的原因。
6. 应用场景与落地时容易踩的坑
6.1 应用场景延伸
从这项技术出发,能做的事情不止于学术实验。机器人收纳是目前最自然的落地场景:家庭服务机器人识别出桌面上散落的物品,判断杯子应该放到杯架、书本应该归到书架,然后驱动机械臂完成放置。这个场景对算法要求比测试集更高,因为真实桌面更乱、光照变化更大,但双路图补全给出的关系预测能力和物理合理性约束确实能直接降低下游规划难度。
AR 辅助布置也是一个方向。用户用平板扫描房间,在屏幕上把新家具“拖”进扫描结果中,模型可以实时提示当前位置是否合理,比如床头柜是否与床保持合适距离、垃圾桶是否靠近书桌而不是客厅中间。这类应用不要求绝对精确的运动控制,但对推理实时性和可解释性要求高,图补全输出的关系标签正好可以作为提示文案的数据来源。
室内设计辅助工具同样值得关注:给设计师一个已经摆放好的房间,加入新沙发或新边桌时,模型能给出若干个与现有家具关系协调的候选位置,省去大量手动试摆放的时间。
6.2 复现过程中最常踩的六个坑
第一个坑是场景图的边太多。场景里有几十个物体,如果每对物体之间都建边,图的边数量会爆炸,图卷积的计算量和显存消耗都难以接受。我的经验是做两跳局部采样:每个节点只与最近邻的 8 个物体建边,并加上所有支撑关系边。这样既保留了关键上下文,又把计算控制在合理范围。
第二个坑是关系类别不平衡。场景里绝大多数物体对之间是“无关”关系,支撑和邻近只占少数。训练时如果不做类别重加权,模型会很快收敛到“全部预测无关”,看起来损失很低但放置完全失效。要对稀有关系的损失做上采样加权,我用的权重是 1 : 3 : 5(无关、邻近、支撑)。
第三个坑是训练早期的位置回归不稳定。图卷积初期输出的节点特征没有语义,位置头很容易把候选位置推到奇怪的角落。解决方法是前 2000 步只训练关系分类头,冻结位置头,等关系特征初步成型后再放开位置头联合训练。
第四个坑是物理合理性损失的热点区域。穿透损失只在物体包围盒重叠时才有梯度,初始位置如果离真实位置太远,穿透损失完全不提供梯度信号。要配合一个辅助的覆盖损失,鼓励候选位置落在场景物体附近的 Voronoi 区域里,让模型有一个向真实位置收敛的“软力”。
第五个坑是评估时对“无关关系”的误判。很多物体被预测为无关,但如果它们之间距离很近,实际上应该有一条邻近关系。我在评估时加了一个阈值判断:预测距离小于 20 厘米且没有预测任何关系边的情况,视为预测错误。这个修正能让评估结果更真实反映放置质量。
第六个坑是图补全的“补全”不能和“生成”混淆。模型不是从零画出场景,而是在已有场景图上补充缺失关系。有人复现时把场景图中已有的物体也随机丢弃一部分去训练,让模型学会补全所有节点,这反而破坏了支撑链的完整性,效果反而下降。只丢弃待放置物这一个节点就够了。
6.3 后续扩展的一些思路
双路图补全的框架可以继续扩展的方向很多。一个是加入时序信息:如果场景是动态的,比如桌面上不断有新物品加入,模型可以持续更新关系图,做增量式放置建议。另一个是加入交互语义:当前只预测“放哪里”,可以扩展到“怎么放”,比如杯子应该正放还是倒扣、书籍是否应该立放,这些信息可以编码为更细粒度的关系类型。还可以把跨路注意力从物体层面提升到房间层面,让模型首先判断哪个区域适合放置,再细化到区域内具体物体上,这样对大场景的扩展性更好。
7. 一点个人经验总结
双路图补全这个方法,我最欣赏的地方是它没有把物体放置当成一个单纯的坐标回归问题,而是真正从关系角度重构了任务。实际操作一遍之后最大的体会是,双路的划分不在于让模型多学一倍参数,而在于让两类必要信息各自保持独立的表达空间,在最后交互时不互相污染。训练时那只“先独立、后交互”的顺序,以及关系类别不平衡的处理,是真正决定模型能不能收敛到好用状态的关键因素。如果只照着网络结构图复现不关注这些细节,最后跑出来的结果很可能只是“看起来能放,实际上放不对”。希望这篇拆解能帮你把路线理清楚,少走一点我当时走过的弯路。