场景坐标回归与DSAC++:端到端可微优化的视觉重定位方法解析 这篇笔记想认真聊一下视觉重定位里非常经典的一条技术路线场景坐标回归Scene Coordinate RegressionSCR以及它在2018年的一个重要改进版本DSAC。视觉重定位是给一张查询图像恢复相机在已知场景中的6自由度位姿位置加朝向这是增强现实、机器人导航、自动驾驶里都绕不开的基础能力。而场景坐标回归的思路很直接不依赖传统特征匹配而是让卷积神经网络把每个像素直接映射到场景坐标系下的3D位置再通过几何优化求解相机位姿。DSAC就是把这个过程做成端到端可训练的代表作之一解决了早期版本采样不可微的问题也把精度和稳定性都往前推了一大截。对于刚开始接触视觉重定位或者想做相机位姿估计方向的人来说这篇论文笔记能帮你弄清楚三件事第一场景坐标回归到底在回归什么第二DSAC相比第一代DSAC改了什么为什么这些改动有效第三实际复现和调参会踩到哪些坑。我不会把全文翻译一遍而是按我自己的理解把关键设计拆开讲尽量给你能直接参考的东西。1. 视觉重定位问题与场景坐标回归的背景1.1 视觉重定位的核心难点在哪里视觉重定位通俗点说就是给定一张图像回答一个问题这张照片是从三维场景的哪个位置朝哪个方向拍的。这里说的“已知场景”不是随便一个室外大马路而是某一个被预先建模过的环境比如一间办公室、一层展厅、一座停车场。系统先离线构建场景模型在线查询时再用单张图像找回当时的相机姿态。这个问题的难点很多人一开始会以为是“图像识别”实际上算法真正要面对的是外观变化和几何一致性的冲突。同一台相机、同一个位置早上和晚上拍出来的像素值可能差很多有人走动、门开开关关场景中还有动态遮挡相机本身的角度稍微偏一点对应关系就完全变了。传统方案喜欢用局部特征点比如SIFT类特征做匹配但在纹理稀疏或者重复纹理很多的环境里特征匹配经常翻车。另一个让重定位变得棘手的原因是尺度。室内小场景几十平方米室外大场景可能覆盖几条街。物体在不同距离下的投影尺度差异很大如果算法不能理解场景的几何结构只凭图像特征很难把姿态约束住。因此近年来的主流思路倾向于让网络直接从图像中回归场景的几何信息而不是单纯识别物体或者检索最相似的图像。场景坐标回归就是这类方法里最有代表性的一个分支。1.2 场景坐标回归的输入输出到底是什么场景坐标回归的思想其实很朴素。标准视觉定位流程里第一步是找到2D像素和3D点之间的对应关系有了足够的对应关系就能通过PnP这类几何算法解出相机位姿。场景坐标回归把找对应关系这件事直接交给了神经网络。网络的输入是一张RGB图像对图像里每个有意义的像素输出那个像素对应的3D点在场景坐标系下的坐标 ( (x, y, z) )。换句话说网络把“图像内容”翻译成了“场景三维结构”输出不是标签而是一张和输入图像分辨率相关的场景坐标图。比如输入图像被缩放到 ( H \times W )网络输出 ( H \times W \times 3 ) 的张量每一个位置对应场景坐标的 ( x, y, z )。由于可以同时对很多像素做预测最后能得到大量的2D-3D对应点。然后在这些对应点上做RANSAC类的抽样、PnP求解就能得到稳定的6自由度位姿。这种方法的好处是网络学到的是场景本身的几何先验可以容忍一定程度的外观变化和局部遮挡。坏处也很明显如果场景更换了网络通常需要重新训练因为输出坐标的参考系变了。所以它更适合地图相对固定、覆盖范围有限、但需要长期稳定定位的应用场景。1.3 DSAC在整个技术脉络里处于什么位置场景坐标回归的想法并不是2018年才有的。更早的工作已经把CNN用于密集坐标预测但难点在于后端的几何优化不可微导致网络无法端到端训练只能先用真实场景坐标做监督。DSAC的核心价值是它把“随机采样一致性”RANSAC过程进行了可微化改造让网络可以通过位姿误差来微调自己。也就是说网络不再只是学着把像素变成坐标点而是学着“如何生成更容易解算出正确位姿的坐标点”。2018年的DSAC在思路上延续了第一代DSAC但它重点做了三件事替换成更强的骨干网络结构、简化并改进了置信度加权方式、加入自监督域适应机制。网上很多论文笔记只关注前两点但我个人认为自监督域适应才是它在工程落地中最值得研究的部分因为它直接关系到模型在新场景或者新采集数据上的生命力。理解DSAC的这些细节也就理解了视觉重定位里“几何优化深度学习”结合的主要技术路径。2. DSAC的核心设计思路与关键创新2.1 端到端可微优化的整体架构DSAC的完整流程可以拆成三块前端的场景坐标回归网络、中间的假设生成模块、后端的位姿假设评估与选择。前端使用一个全卷积网络输入图像输出密集的场景坐标图同时还可以输出每个像素的置信度。中间模块参考RANSAC的思路从预测出的2D-3D对应关系里随机抽取固定数量的最小子集每个子集通过PnP解出一个候选相机位姿。后端对每个候选位姿计算一个评分评分高的假设被认为是最终位姿。这里面最关键的设计是“假设评分”的方式。传统RANSAC里评分是离散的比如数一下有多少内点内点数量最多的那个假设获胜这个过程不可微。DSAC把内点判定替换成了软加权每个像素根据重投影误差被赋予一个平滑的权值权值越大表示这个像素越支持当前假设。这样整个评分函数对网络输出就是连续可微的梯度能顺利从最终的位姿误差回流到场景坐标图的每一个像素上。为了更本质地理解这个设计可以把传统的RANSAC类比成“海选”候选人各讲各的投票人只能投赞成或反对最后赢家不一定是真的最优。DSAC则更像是“评委打分”每个像素不仅展示自己的观点还要给出支持程度而且打分函数是光滑的。正因为打分过程可微网络才知道怎样调整自己的预测能让最终位姿更准而不是仅仅预测出“看起来正确”的坐标。2.2 置信度设计与损失函数的细节DSAC里对置信度的使用很巧妙。第一代DSAC对每个像素输出一个独立置信度权重但这种方式容易退化网络倾向于给背景像素很高的置信度因为它可以让训练损失降低却不一定能提升位姿精度。DSAC改成了根据重投影残差来计算权重形式上更接近鲁棒核函数的作用。具体来说给定一个候选位姿 ( \theta )某个像素 ( i ) 的2D位置 ( p_i )网络预测出的场景坐标 ( y_i )那么把 ( y_i ) 投影回图像平面可以得到一个重投影位置 ( \hat{p}_i )。差值的模长 ( ||\hat{p}_i - p_i|| ) 就是重投影误差。以这个误差为基础用一个带带宽参数 ( \alpha ) 的核函数把它映射成 ( [0,1] ) 之间的软内点权重。误差越小权重越接近1误差越大权重趋近0。这样的设计让评分完全落在几何一致性上网络为了降低最终损失只能让每个像素预测的3D坐标更加精确而不是靠刷置信度来投机取巧。损失函数方面DSAC采用可微的期望损失或者软最小化损失。由于每个位姿假设都会产生一个重投影误差而每个假设又有自己的评分权重网络最终优化的目标可以看成是所有假设误差的加权平均或者只取最高评分假设的误差。前者梯度更平滑后者更接近推理阶段的行为论文实验里两者差距不大。实际中我也建议训练初期使用加权平均后期切到软最小化这样既能稳定收敛又能让网络适应推理阶段的真实选择方式。2.3 骨干网络与训练策略的升级DSAC与第一代DSAC相比在骨干网络上做了明显升级。更深的残差结构比早期的VGG类结构收敛更快特征表达能力也更强。尤其是在重复纹理和弱纹理区域残差网络的感受野和恒等映射设计能更好地保持边界和几何结构信息。论文里提到的做法是先用简单图像分类任务预训练骨干网络再把末尾的全连接层换成卷积层输入图像经过归一化后直接得到一个较粗糙的坐标图输出。训练过程通常分两阶段。第一阶段网络在带有真实场景坐标标注的合成图像上训练用L1或者L2损失直接监督坐标回归。这个阶段让网络先学会大致把像素放到正确的位置附近。第二阶段启动端到端训练不再直接算坐标误差而是用前面提到的可微几何优化模块计算最终位姿损失对整个网络进行微调。这样网络不仅知道“坐标该落在哪”还知道“怎样让坐标在几何求解时更有用”。实践中第二种阶段的迭代次数不需要太多但学习率要调小否则容易破坏第一阶段学好的特征。数据增强在两阶段都很重要。颜色抖动、随机裁剪、水平翻转、模拟镜头模糊这些手段能提升网络的泛化能力。DSAC还特别强调了合成数据与真实数据之间的分布差异这也是它引入自监督域适应的直接动机。如果没有域适应模块网络在合成数据上成绩很好一上真实采集图像精度可能立刻掉一截。2.4 自监督域适应的独特思路DSAC提出的自监督域适应策略简单说就是利用未标注的真实图像来微调网络。没有标注怎么产生监督信号它的思路是这样的先用合成数据训练出一个初始模型用这个模型在真实图像上推断出场景坐标图再通过可微的RANSAC模块解算出相机位姿然后把真实图像中的场景坐标投影回去得到重投影误差。误差越小说明这个样本越可靠误差大的样本被当作噪声丢弃。通过反复迭代网络逐渐适应真实图像的外观分布。这个机制听起来很像师生训练但它的关键区别在于“伪标签质量评估”是几何一致的。不是拿网络自己的置信度去筛选而是看整个位姿假设是否一致。因此即便网络在单张图像上对自己的输出有盲目自信最终的几何验证仍会惩罚它。我在复现这类自监督流程时体会比较深伪标签的门槛不能设太死设太高会浪费大量样本设太低会把噪声导进去。论文给出的做法是根据重投影误差动态调整阈值我在实践里也习惯于每轮迭代后重新统计误差分位数来更新阈值效果确实稳定不少。3. 实操过程中的关键步骤与复现要点3.1 环境准备与网络输入输出设计复现DSAC之前先把工具链理顺。我建议用主流的深度学习框架配合CUDA环境显存至少保证在8GB以上因为密集场景坐标图的输出和批量采样假设都会占不少显存。如果显存紧张可以把输入分辨率调低比如最多让图像的短边保持在300到480像素之间对应的输出坐标图可以很粗比如 ( 49 \times 37 \times 3 ) 这样的规模这在实际项目中已经能提供足够的对应点数。网络结构上前端可以使用残差网络作为编码器后面接若干卷积层和上采样层输出维度是 ( H \times W \times 3 ) 的场景坐标图。如果你想让网络额外输出每个像素的置信度也可以在最后一层分出两个头但基于前面提到的原因我更多时候不显式让网络输出置信度而是依靠后端的重投影残差核函数来做软加权。这样设计更简单也避免置信度头发生过拟合。数据组织方面每个训练样本是“一张RGB图对应的场景坐标图标签”。如果场景已经用SFM或者RGB-D重建得到了稠密点云可以通过渲染把每个像素对应到点云坐标。没有现成标签的场景可以考虑用合成数据渲染器自动生成图像和坐标标签这也是很多团队实际采用的路线。3.2 两阶段训练的实操流程先做坐标回归预训练。将输入图像归一化到合适的尺寸按比例缩放同时将标签场景坐标相应变换。损失函数用平均绝对误差或者平滑L1都可以我倾向平滑L1对大坐标残差不那么敏感。这个阶段通常需要跑几万步学习率从 ( 1 \times 10^{-4} ) 起步配合余弦衰减或者阶梯下降。观测训练损失的同时应该出一个粗略的中位数位姿误差指标而不是只看坐标误差因为坐标误差低并不代表位姿误差一定低。接着做端到端微调。此时要加载预训练权重关闭坐标直接监督换用可微RANSAC模块的位姿损失。每次迭代随机抽取固定数量的候选位姿假设比如32或者64个对每个假设都做一次PnP求解。这里需要注意所有操作都要在可微的框架内实现例如使用基于SVD分解的PnP实现或者把对应的姿态表示成旋转矩阵加平移向量的形式。学习率降到 ( 1 \times 10^{-5} ) 量级避免大幅破坏特征分布。我在实操中遇到的第一个大坑是端到端训练很容易因为不同批次的位姿尺度方差太大而不稳定。解决办法是对场景坐标做归一化。比如预先统计场景点云的均值与方差将坐标值减去均值再除以标准差网络输出再反变换回真实尺度。这个归一化同时还能帮助收敛因为所有场景的输出空间都变成了相对统一的分布。3.3 推理阶段的位姿求解流程推理阶段不再需要取均值所有梯度计算都可以关掉但随机抽样过程仍然保留。输入一张图像网络给出场景坐标图然后执行一个轻量化但充足的RANSAC循环。每轮随机抽取三组2D-3D对应点用PnP求一个候选位姿接着用所有对应点验证这个位姿统计在某个重投影误差阈值内的内点数量重复几百到上千次取内点最多的位姿再做一次非线性优化得到最终结果。实际操作时阈值到底取几个像素很影响定位精度。室内场景、工作距离不大阈值可以设在2到4像素室外大场景重投影误差天然会偏大阈值放到8到10像素可能更合适。还有一个细节是有些像素预测的场景坐标不可靠比如天空、动态物体、远距离背景。推理时可以先用一个简单的语义过滤去掉这些区域也可以根据重投影残差自动判断不需要参与终选。伪代码大致如下for i in range(num_iterations): idx sample_minimal_set(correspondences) pose solve_pnp(correspondences[idx]) inliers count_inliers(pose, correspondences, threshold) if inliers best_inliers: best_pose pose best_inliers inliers final_pose refine(best_pose, correspondences, inlier_mask)这段逻辑和传统RANSAC非常像只是对应关系来自网络预测而不是特征匹配。正因为对应关系密集且覆盖全图即使单点预测有误差在大量采样和几何一致性筛选之后最终位姿依然非常稳。3.4 关键参数设置与硬件资源参考关于参数选择我整理了一个在多数室内场景里可用的初始配置供参考。采样数量是第一个要调的参数训练时建议32到64个假设再多梯度计算开销明显增大推理时建议500到1000轮采样再多对精度提升就很有限了。重投影误差阈值依据场景尺寸来定一般情况下3像素起步不行就往上放宽。学习率从 ( 1 \times 10^{-4} ) 和 ( 1 \times 10^{-5} ) 两阶段分别设置Batch Size通常取8到16。显存方面是一笔很现实的账输入图像 ( 640 \times 480 )输出坐标图大约 ( 80 \times 60 \times 3 )再加上32个候选假设的反向传播单卡16GB基本能用如果Batch Size放大或者采样数增多建议使用梯度累积或者混合精度训练。对于自监督域适应阶段需要额外保存每次推理结果作为伪标签磁盘空间要预留充足别等到训练跑了一半才发现装不下。下表是我在不同配置下的直观体会仅供参考配置项训练阶段建议值推理阶段建议值输入短边300~480像素480像素左右候选假设采样数32~64500~1000重投影阈值3~5像素动态调整学习率预训练1e-4微调1e-5-Batch Size8~16-4. 复现过程中的常见问题与调试技巧4.1 训练不收敛时先查标定与数据问题很多人遇到端到端训练不收敛第一反应是调学习率其实更应该先检查数据链路。场景坐标标签里的3D坐标是否和图像对齐相机内参是否准确如果合成渲染时分辨率、焦距设置和推理阶段不一致网络学到的几何映射就是错的。另一个容易踩的坑是图像缩放后忘了同步缩放相机内参这会导致重投影误差系统性地偏大网络怎么调都救不回来。我排查的顺序一般是先固定网络权重手算几个像素的投影误差确认数据流没有歧义然后用一个小批量样本只做坐标预训练看损失能否降到合理范围最后再开端到端微调。如果坐标预训练本身就不收敛大概率是标签对齐问题而不是网络问题。不要跳过这些检查直接端到端浪费时间也不容易定位问题。4.2 采样数对精度和显存的真实影响采样数是DSAC里非常敏感的超参数。采样太少候选假设覆盖不到真实位姿附近最终选择的位姿可能差很远采样太多训练时反向传播计算量巨大显存压力直线上升。我在实践中的经验是训练阶段64个假设基本够用继续翻倍精度提升不到1%训练时间却翻了倍。推理阶段则可以放宽到1000次采样因为不需要回传梯度计算开销可控。如果显存实在不够可以做的折中是减少Batch Size而不是减少采样数。因为采样数直接影响假设空间覆盖度减少它对精度的伤害更大。混合精度训练也可以把显存占用压下去不少尤其是在候选假设张量比较大的情况下收益非常明显。4.3 场景坐标范围差异导致的尺度问题不同场景的坐标范围差异很惊人。一个小卧室的点云坐标可能只落在几十厘米到几米的范围一个停车场可能横跨几百米。如果不做坐标归一化同一套网络在不同场景之间迁移时输出激活值会被拉得很开训练过程极不稳定。DSAC论文里虽然没有花大篇幅强调这一点但实际复现几乎绕不开。我的做法是对每个场景统计三维坐标的均值和标准差网络输出朝向归一化坐标推理时再反变换回来。这样不仅训练更稳还能让网络更专注于几何结构而不是被迫记忆不同场景的绝对尺度。也不要忘记在归一化时记录标量参数否则导出模型给其他模块用的时候坐标映射会完全错乱。4.4 自监督域适应中的伪标签噪声控制自监督域适应的最大风险是模型在错误伪标签上自我强化。一旦某张真实图像被网络解出错误位姿而这个位姿又能让大部分像素形成一致重投影它就可能被当成高质量样本后续训练反而巩固了错误。为了防止这种自我欺骗我建议对伪标签样本进行多级筛选。第一级看重投影误差的中位数太高的整图丢弃第二级看内点比例低于某个经验值就丢掉第三级如果同一个场景有几张连续帧图像比较相邻帧解出的位姿是否连贯不连贯的也丢掉。用连续帧做位姿一致性检查是很多实际项目里非常有效的一招因为正常相机运动在短时间内的位姿变化是平滑的突然的跳变大概率对应错误解算。这个额外的过滤步骤代码量很小但能显著提升自监督训练的稳定性。另一个小技巧是每次迭代只用“伪标签损失”微调网络的浅层特征而保持深层几何解码层的权重相对固定也可以降低噪声传播速度。5. 效果分析、适用场景与方法边界5.1 在典型室内基准上的直观表现DSAC在当年的公开室内基准上表现很突出几个典型场景里都能达到厘米级的位置精度和几度以内的朝向精度。相比第一代DSAC中位数误差进一步下降最难场景里也能保持稳定不崩。这种提升一部分来自更强的骨干网络另一部分来自可微优化模块的稳健性增强。可以说DSAC是那一阶段“端到端可微几何优化”路线里最有说服力的作品之一。很多读者会问室外大场景能不能直接用。标准设置下DSAC更适应场景模型明确、覆盖范围有限的环境。如果室外覆盖范围特别大网络无法在有限参数里记住整个场景的几何细节性能会明显下降。这时候可以考虑把场景分块处理每块单独训练一个网络或者用层级式场景坐标回归的思路把全局场景先分区块再进行局部精修。5.2 适合哪些实际应用如果从实际应用的角度看DSAC比较适合三类场景。第一类是增强现实希望用户在已知室内环境里稳定放置虚拟物体环境地图可以提前建模位置精度和实时性要求都很高。第二类是移动机器人在室内仓库、展厅里的重定位地图相对固定但光照、货架上的物体可能会变化。第三类是视觉导航中失败后的恢复当一个移动设备的里程计或视觉SLAM跟踪丢失时用单帧图像重新找回全局位姿DSAC比纯图像检索给出更精确的位姿初值。在这些场景里DSAC相对来说比较省心因为推理时只需要单张RGB图不需要维护局部特征库也不需要深度传感器。这也意味着它可以跑在常见的相机和嵌入式设备上只要网络规模压到合适程度实时性是完全可以满足的。5.3 和其他主流方案的取舍视觉重定位领域还有两条重要路线一条是图像检索一条是直接位姿回归。图像检索的优势是简单粗暴通过相似图片给出一个大致位姿但它无法达到很高的精度因为检索结果本身就有离散误差。直接位姿回归即让网络直接输出 ( x, y, z ) 和朝向训练容易、速度快但精度上限低而且对旋转的建模能力较弱。DSAC代表的是“结构先验几何优化”这一派它比图像检索精度高又比直接回归更稳健。代价是训练复杂度和标注成本更高。如果场景不固定、地图频繁变化传统特征点匹配加局部地图的方案可能更灵活因为不需要重新训练网络。所以我的判断是选择哪种方法取决于你的地图更新频率、精度要求和算力限制没有绝对的好坏。DSAC的好是好在它把几何优化和深度学习粘合得很自然退了可以当普通坐标回归网络用进可以做端到端精调。5.4 后续扩展方向与现实提醒DSAC之后这个方向又延伸出很多变体比如把场景模型参数化和网络一起优化、用更复杂的图神经网络做对应关系推理、或者把时间序列信息融入定位。不管后续怎么发展核心思路仍然是“让网络学会生成有利于几何求解的中间表示”。它的可解释性比直接回归位姿好很多出错了也容易定位是哪一部分像素拖了后腿。在实际项目中我还会提醒两点第一场景坐标回归模型绑定的是特定场景换场景必须重训工程上要预留模型迭代的空间第二网络学习的是稠密几何对应关系如果场景出现大量非刚性变化比如人群密集、桌椅大幅移动它的性能还是会受到较大影响。理解这些边界才能真正用好DSAC。结尾我个人一开始复现场景坐标回归时总觉得端到端可微优化很玄跑通之后才发现真正决定效果的不是那个精巧的可微模块而是数据质量、坐标归一化和采样参数这些看似基础的东西。DSAC给我最大的启发是深度学习不一定非要输出最终答案也可以输出一个“中间几何表示”再交给传统几何算法去求解。只要你让整个链路可微网络自然会学会怎么配合后端的算法。建议你在做自己的定位任务时先别急着魔改网络结构先照着这套流程把基准跑通再根据你的场景特点去调整采样、阈值和归一化方式。踩过几次坑之后你会对视觉重定位里几何信息和外观信息的关系有更直观的理解。