场景生成新思路:可学习程序库如何解决真实感与可控性难题

发布时间:2026/10/20 12:29:05
场景生成新思路:可学习程序库如何解决真实感与可控性难题
从Programs到Poses我读懂了可学习的程序库为什么能解决真实场景生成的老大难问题以前做过室内场景合成的人应该都有同感过去我们想让模型生成一个客厅最高频的翻车点是生成的图看起来像画但细看要么沙发叠在茶几上要么椅子悬空十厘米要么窗帘把门堵死。用扩散模型硬磨像素能磨出质感特别好的材质但它的空间常识其实相当有限。真正到了我要一个沙发对面放电视柜、沙发左前方0.4米再放一个茶几、灯不许挡门这种带约束的场景光靠像素级别的生成器根本保证不了约束成立。今年这篇NeurIPS论文《From Programs to Poses: Factored Real-World Scene Generation via Learned Program Libraries》给了我一个很有价值的思路把场景生成拆成学出来的程序库和程序到姿态的落地两件事。程序库负责表达场景的抽象规则Poses负责把这些规则翻译成具体三维摆放中间的连接点是Factored分解式表示。换句话说它不是用一个黑盒模型一把梭生成整张图而是让模型先学会关于场景的代码再一个函数一个函数地渲染出来。这篇内容我打算拆成几段来讲先说说为什么像素级生成解决不了可控性问题再拆解Factored表示到底在拆什么然后是Programs到Poses这条链路的每一层是怎么工作的最后聊聊训练程序库时最容易踩的坑以及如果要复现这类工作我会从哪里入手。1. 场景生成的硬骨头为什么像素级生成解决不了可控问题1.1 真实场景和一张好看的图像是两层问题很多人会把场景生成理解成生成一张像样的图。但把它当图像生成任务做只解决了外层问题。内层问题是场景的三维结构物体类别是否合理、物体之间的支撑关系是否成立、相对位置是否符合人类使用习惯、光照和布局是否匹配起居室这个语义。举个最常见的例子一张AI生成的卧室图床尾对着门床头柜浮空桌子上摆着两盏互相穿透的台灯这种图在2D图像层面几乎看不出毛病但在任何需要与场景交互的应用里——机器人搬东西、游戏角色穿行、室内装修预览——都是不能用的。因为真实场景的合理性不是像素层面的而是结构层面的。真实空间里一把椅子之所以能出现在餐桌旁是因为椅子围绕餐桌摆放这个规则。桌椅间距、椅子面朝餐桌的方向、椅子不穿过桌腿这些约束同时成立才构成人类认知里正常的餐厅场景。1.2 扩散模型的重灾区离散约束和连续表示之间有一道裂缝扩散模型在生成图像的时候本质是在连续潜空间里做去噪。它对连续域的分布拟合能力很强但约束这种东西往往是离散的、逻辑性的物体A在物体B的左侧上方物体C不能与物体D重叠所有物体都要落在支撑平面上。这类条件不是平滑函数很难靠隐变量插值来处理。我曾经试过用扩散模型加空间条件来生成客厅场景结果发现只要条件里同时出现两个以上的空间关系模型就开始顾此失彼。左边满足了右边的物体关系就开始乱。原因不复杂像素级模型看到的永远是排列好的一堆像素它没有真正的物体概念。你给它一个模块化的布局条件它也只能把它当成一种模糊的视觉提示而不是可执行的规则。1.3 手写规则的尽头程序化生成为什么又累又不通用那干脆用代码生成场景呢程序化建模确实可控我曾经见过美术同事用节点式程序生成器搭了大量房间模板效果不错但每一类场景的规则都要人肉调试很久。换个风格、换个户型、换种家具组合规则就要重写。这暴露了纯程序化方法的核心问题规则本身是人工的而不是从数据里学出来的。如果说图画模型有常识但没逻辑手写程序有逻辑但没常识那理想方案显然是把两者结合。这就是标题里Learned Program Libraries要干的事情——把程序规则从真实场景数据中自动学出来让程序库里积累的是数据驱动得来的空间常识而不是人的一拍脑袋。2. Factored的底层逻辑场景不是一张图而是一组可组合因子2.1 分解式表示到底在拆什么论文标题里的关键词是Factored。直白讲就是把一个完整场景拆成若干个独立的因子来建模。一个真实场景至少包含这几类因子物体类别床头柜、台灯、物体几何外观床的长宽高比例、柜子的造型、空间关系床头柜在床的左侧、台灯在床头柜上、支撑关系一切物体都落在支撑面上、光照与氛围黄昏暖光或者阴天冷白。这些因子各有各的规律。床头柜的外观规律和床左边摆床头柜的空间规律不是一回事。前者由家具设计风格决定后者由人类的起居行为决定。把它们放在同一个隐向量里建模模型会把两类信息搅在一起。Factored的意思就是分开建分开学最后再合起来。2.2 为什么拆开比合在一起更适合学程序从程序的角度看因子天然对应函数。一个程序库里的BedPlacement函数只管放床给定房间边界和朝向偏好返回床的位置、朝向、尺寸。另一个NightstandPlacement函数只管在床的左右侧找位置放床头柜。各自职责清晰组合起来就能生成一个完整的卧室。合在一起做统一模型的问题在于牵一发动全身。你改了某个物体类别的外观统计整个隐空间分布都要跟着变你新增一个物体类别原来的分布可能被污染。分解之后每个程序模块相对独立可以单独更新、单独扩展过程中不会影响其他模块。这种可组合性是程序库解决场景生成问题最大的结构优势。2.3 因子组合的语法场景不是梦话是有文法结构的拆成因子之后还需要一个东西把它们组织起来否则因子再独立组合的时候也会出现沙发长在墙上这种非法结构。研究者通常用场景文法Scene Grammar来做这件事规定一个场景必须由地面、墙面、物体集合组成物体必须有一个类别、一个形状、一个姿态和一组与其他物体的关系。这类文法很像编程语言的语法树。语法树保证了任意生成结果在结构上是合法的就像编译器不允许你写出if if else这种没有操作数的语法。程序库里的每个程序就是语法树上的一个节点实现。这一层结构是可控二字的来源——不是靠运气生成而是每一次生成都会先搭建一棵合法语义树再去执行。我记得第一次接触这个思路的时候一句话点醒了我场景生成的问题不在于精度而在于结构合法性。Factored表示加场景文法就是在源头掐断非法结构的出现。对比维度统一表示Unified分解式表示Factored类别和关系的关系强耦合改一个影响全局解耦独立建模独立调整新增物体类别需要重新训练整个模型新增对应程序模块即可可解释性黑盒只能看输出可以通过程序树追踪生成依据典型风险分布坍缩后难以定位原因因子之间组合时可能出现误差累积3. Programs到Poses从符号说明书到具体摆放的完整链路3.1 程序写出来是要被执行不是用来观赏的程序树的产物看起来像一段伪代码客厅场景包含一个沙发位置靠东墙面朝电视一个茶几位于沙发正前方距离0.4米一盏落地灯位于沙发右侧贴墙。它本身只是抽象描述。一个完整的场景生成系统必须能够把这些抽象描述执行成具体的三维姿态——每个物体中心点的坐标、朝向四元数、缩放比例——这就是标题里的Programs to Poses。这一段是整条流水线里最难做的部分。因为沙发正前方0.4米落实到3D坐标时要考虑房间的实际大小、沙发的实际尺寸、茶几不能压到沙发底、地面必须水平支撑。抽象产物和具体数值之间有天然的语义鸿沟。3.2 语义关系不是查表而是一个求解过程一开始做类似项目时我的直觉是所有语义关系都可以靠查表解决先定义前方是物体朝向的正方向0.4米是直接偏移。实际操作才发现完全不是这样。如果每件家具的位置都是孤立地按照语义翻译那最后物体之间必然大面积穿模。真实的姿态生成一定是一个联合约束求解的过程。正确的姿势是先用程序树给出每个物体的初始候选姿态把这些候选放进一个优化器同时约束支撑、碰撞、相对距离和朝向关系不断调整这些姿态直到所有约束都满足。也就是说语义关系提供的是硬性条件而姿态求解器负责在满足硬性条件的前提下寻找最合理的一组数值。这个过程的计算量不小但它不会出现桌子穿过沙发这样低级错误。3.3 姿态之后还有一公里渲染出图才算真实感闭环把姿态算完只是完成了几何布局。下一步要解决外观、材质、光照、相机参数最终渲染出图。我在复现类似方案时发现几何布局做漂亮之后最怕的是渲染环节掉链子要么材质太假要么灯光方向不对渲染出来的图像一眼就看穿是合成的。工业上的做法一般分两条路。一条是用离线渲染器做高保真渲染质量好但速度慢另一条是实时渲染或者可微渲染速度快、能回传梯度但容易出现纹理漂移。论文里更常见的做法是两者结合先用快速渲染器得到一个粗糙图像再用可微渲染微调姿态和材质参数让图像级损失参与反向传播。这一步的意义是把整个Program-to-Pose的管线最终接到图像质量上。用一句直白的话来打比方程序是乐高说明书姿态是拼装出来的积木位置渲染是给拼好的模型拍照。链条很长但好在每一层都是可观察、可干预的——你不需要在所有环节同时Debug。4. 学习程序库数据从哪来Loss怎么设计程序怎么生长4.1 程序库不是人写的是拿重构能力当学习信号Learned Program Libraries最核心的主张是程序库里的程序是可以被学习出来的。学习信号是什么是重构能力。具体来说给定一个真实场景的结构化标注——物体类别、位置、朝向、支撑关系——系统尝试用当前程序库里的程序去重构这个场景。如果某个程序能生成和真实场景高度一致的布局说明它准确捕捉了这个场景的规律如果重构误差很大说明现有程序库还解释不了这类场景要么调整已有程序的参数要么增长新程序。这套思路可以用自编码器来理解输入是真实场景的结构化标注中间表示是程序树输出是重构出的场景布局。只不过中间表示从连续向量换成了离散程序树。好处是中间表示可读、可编辑、可插入约束。4.2 训练循环的骨架候选程序生成、解释执行、误差回传训练过程大致是三步。第一步从观测场景提取结构化标注。这步依赖上游的物体检测、位姿估计、关系推理模型标注质量直接影响程序库学习上限。第二步在程序库里做候选程序搜索。由于程序树的搜索空间极大通常会用束搜索beam search采样一批候选程序而不是暴力枚举所有可能性。第三步用解释器把程序树解成场景预测和观测场景对比计算损失。这里有个工程难点程序树是离散结构没法直接对离散树做梯度回传。实际方案大体分两派一派是设计可微解释器让程序参数都能参与梯度计算另一派是用强化学习的策略梯度训练程序选择器。我自己更看好可微解释器方案因为它训练更稳定也不需要额外设计奖励函数。但它对解释器库的完备性要求很高如果你想让程序库支持在墙上挂画这种操作解释器里就得有对应的可微实现。4.3 程序库不只要学会还要会长程序库在训练过程中不是一成不变的。最开始可能只有一个万能放家具程序随着训练进行系统会发现放沙发和放茶几的布局规律差异太大一个程序解释不过来于是会自动分裂成两个程序反过来如果两种物体在布局上高度一致系统又会把它们合并成一个带类型参数的通用程序。这种库的结构也参与学习的设计是程序库方法区别于普通参数模型的地方。它有点像孩子积累词汇的过程第一次见到新物体先建立一个新程序条目随着见识增多发现有些条目可以泛化就合并成更抽象的规则。为了让库不至于无限膨胀Loss里通常要加入最小描述长度MDL正则项程序越简洁正则惩罚越小。这保证了程序库既能覆盖数据又不至于复杂到无法管理。4.4 训练数据与模型规模的坑偏差是程序库的慢性病我在实际做这类方向时踩过的最大坑是数据偏差。程序库是从场景数据里学的如果训练数据里沙发程序只在豪华客厅出现程序库生成的普通客厅就一定不对味。程序库的规则是全局共享的一旦某个类别学歪了它会影响所有包含该类别程序的生成结果而且错误还会向下游传递。另一个工程问题是训练效率。程序树的变长结构批处理起来非常麻烦树节点数量不一致导致GPU利用率很难拉满。重复试验中程序搜索最耗时的瓶颈往往不在模型计算本身而在树结构的组织与调度。5. 如果我要复现这个方向我会从这几个地方入手5.1 先从小程序库小数据集起步别一上来就想全场景复现这类工作最忌讳的是一上来就追求完整的室内全场景程序库。正确路径是先搭一个只有3到5种家具的客厅程序库比如沙发、茶几、电视柜、落地灯、地毯每个程序手写一个简化版本先把程序生成-姿态求解-渲染出图的闭环跑通。只要你能让一个程序稳定生成茶几在沙发前方0.4米并排不穿模你就已经掌握了整套方法的核心。后续再往程序库里加物体类别都只是量变。我的经验是小库上跑通的闭环比大库上跑通一半要值钱得多因为调试成本完全不是一个量级。5.2 评价指标别只看FID给布局和关系留一把尺子如果只用FID来评估场景生成质量很多空间上的错误都会被图像质量的表面光鲜掩盖。实际做评估时我建议至少看三类指标布局质量物体类别与数量的分布是否匹配真实数据物体间的距离分布是否和真实场景的分布一致可以用KL散度衡量关系正确率物体之间的语义关系是否满足程序库里的规则比如支撑关系是否正确茶几在沙发前方是否成立视觉质量FID、人工评估等这部分负责衡量渲染和材质的真实感。实际项目中经常出现视觉质量涨了但关系正确率跌了的对冲局面。这时候我会分阶段看指标先锁定布局质量和关系正确率合格再谈视觉质量优化否则你只是在给自己造一个看起来很真的错误场景。5.3 复现过程中最容易翻车的五个细节以下五个位置是我和身边朋友在类似工作中反复翻车的地方列出来供参考碰撞检测阈值设得太小会导致物体相互穿插设得太大则家具间距明显失真。建议根据物体实际尺寸动态调整而不是全场景用同一个固定值。支撑面判断必须区分地板、桌面、床面、墙面不同支撑面有不同的姿态约束。一套逻辑试图通吃所有支撑面发生器立刻失衡。数据标注噪声半自动标注的关系标签不能直接信任尤其是前方左侧这类相对关系的标注常常错位训练前需要清洗或按置信度加权。程序搜索步数步数太少程序库找不到深度组合的优质解步数太多训练速度大幅下降。需要根据程序树的平均深度做折中。随机种子程序采样的随机性很大不要只跑一次试验就下结论固定种子并多组重复更靠谱。5.4 这个方向真正有价值的地方不只是出图延展一下为什么我认为这类方法值得关注。如果程序库和姿态求解都成熟了它就不只是生成一张好看的室内图而是变成了一套可编辑场景生成器的底层引擎机器人可以在程序生成的各种仿真场景里做策略训练自动驾驶可以用它构建可编辑的场景库游戏和VR可以用它快速生成符合关卡设计的程序化房间。从这个角度看程序库方法的最大价值在于它把生成和模拟连通了。生成的场景自带结构语义可以直接对接物理引擎和决策系统这是纯图像生成模型很难做到的。我在读完这篇论文后最大的体会是它没有试图用一个巨大模型一步到位生成场景而是老老实实地把问题分层——程序库负责抽提规则姿态求解负责落实几何渲染负责视觉真实。每一层都不算复杂但组合起来才能应对真实场景的多重约束。我最近一直在琢磨如果把程序库的检索接口换成大模型让自然语言直接驱动程序树的组装场景生成的自由度应该会再上一个台阶。这大概是这个方向下面最值得持续跟进的一条路。