训练越久越差:两个无人机小样本,把 3DGS 正射 TDOM 的边界跑出来了

0. 先说结论

这个项目最初的目标很直接:把无人机原始照片喂进去,直接产出一张可浏览的正射 TDOM(True Digital Ortho Map)。框架借的是 Tortho-Gaussian,先做曲线展馆,再做低层村落。结果不漂亮:展馆在 3k 迭代后测试集全面退化,7k 时 TDOM 出现大片孔洞;村落在 3k 见顶,7k 掉到 20.26 dB。

但这次不漂亮的结果,最后收敛出一条比 PSNR 更有用的判断:

在小样本、固定正射产品视角下,3DGS 的失败通常不是训练不足,而是自由度超出了观测能偿付的范围。3k 是这本账的破产点。

我把它叫作"可观测性预算"。它不是新算法,而是一个审计顺序:先查真实观测,再查几何证据,再查高斯表示的自由度,最后才查渲染和产品语义。按这个顺序,我把两个场景、2×2 因子实验、一次被代码推翻的归因、以及 70.6% 零视锥覆盖的诊断串成了一条证据链。

这篇文章不卖"生产级 TDOM"。它只回答三个小问题:

  1. 为什么小样本 3DGS 会在 3k 后越训越差?
  2. 孔洞到底该怪谁:球谐、opacity reset,还是尺度剪枝?
  3. 如果你也在做固定视角的正射产品,哪些自由度可以删,哪些观测必须先补?

三条能直接拿走的结论:

  1. 3k 先停:不要默认 30k;先同时看 test PSNR、TDOM 覆盖和各向异性。训练 PSNR 还在涨,不代表产品在变好。
  2. 孔洞先查剪枝和掩膜 :3000 后的 size_threshold=20 与被掩膜排除的覆盖相机,比 SH 阶数更值得先查。
  3. 三本账分开算:覆盖、形状、辐射各有各的干预;在 70% 网格零覆盖时,加正则/加先验是负资产。

1. 两个样本,和一张固定的产品视角

先说数据。两个样本都不是"大场景",而是小样本可行性验证。

项目 A 曲线展馆 B 低层村落
原始影像 5744 张,6000×4000,21.4 GB,无 EXIF/GPS 392 张,5472×3648,3.4 GB,带 GPS
实际使用 41 个种子 → 123 张,5 个相机组 100 张核心子集,3 个航次
稀疏重建 123/123 配准,0.545 px,118,946 点 100/100 配准,0.888 px,102,223 点
3k 测试 PSNR 16.22 dB,TDOM 覆盖 100% 24.22 dB,TDOM 覆盖 100%
7k 测试 PSNR 15.52 dB,TDOM 覆盖 62.2% 20.26 dB,TDOM 覆盖 69.0%
主要难点 曲线屋面、玻璃幕墙、弱纹理、强反射 低层建筑、道路、农田,纹理足但边界杂

这两个样本的差别,不是简单的"难/易"。展馆是光度可观测性 差:曲面和玻璃把同一个表面在不同视角下变成不同的颜色,固定方向的正射产品很难"偿付"这种方向自由度。村落是几何可观测性更友好:屋顶、道路、院子、农田都是哑光、有纹理、近似平面,同样的 3DGS 在 3k 就能到 24.22 dB。

TDOM 的产品形态是固定正射方向、可浏览的影像;它不是自由视角 3DGS。这里还有一个容易被忽略的设定:训练用透视相机,产品是正交 TDOM。训练时模型看到的是多方向透视视图,输出时只取一个正交方向。这个"训练视角"和"产品视角"的错位,是后面所有自由度问题的源头。

项目中途我整理了 23 份资料:知识组 11 份/92 页,技术专题 6 份/52 页,增强组 6 份/40 页。它们没有变成"方法堆叠"。我先建立五层证据链,再把每份资料的主张放回它对应的层。结果很直接:多数方法在几何证据/高斯优化/可见性渲染层加能力,而我的瓶颈在最前面的"观测"层。在观测不足时,继续加方法不是增益,是 confounding。

2. 可观测性预算:一个审计顺序,不是新算法

我先把"预算"拆成三个可操作的概念:

  • 预算:观测能提供的独立约束。包括视角数、交会角、纹理、非反射表面、有效掩膜、真实覆盖。
  • 支出:表示的自由度。包括高斯数量、各向异性、不透明度变化、球谐方向维数。
  • 破产:训练损失还在下降,但测试辐射质量、覆盖或几何稳定性同时恶化。

它不是一个可以直接计算的物理量,而是一个审计顺序。顺序错了,就会把"观测不足"误判成"模型不够强",然后不断加正则、加先验、加训练时长。

层 要回答的问题 本项目怎么查 本项目看到什么
1 观测 真实影像是否真的看到目标区域? 7048 个网格、z=4 平面的视锥覆盖、掩膜排除 70.64% 网格零相机;12 台覆盖相机被掩膜排除
2 几何证据 轨迹和位姿是否可靠? 8055 个缺失区稀疏点、支持相机、交会角、残差 66.15% 可靠、30.50% 待复核、3.35% 孤立;中位误差 0.347 px
3 高斯优化 表示是否用了过多自由度? 各向异性>10 比例、尺度分布、不透明度 未正则组 3k→7k 约 1.1--1.2%→8.0--8.2%;尺度正则压到 0.064%,但不修孔洞
4 可见性渲染 正确表面是否按正确顺序合成? 视角微扰、排序稳定性、Alpha 覆盖 ±0.1° 无全局 popping;局部排序仍未排除
5 产品证据 哪些是测量、推断、未知? Alpha、NoData、Q_all/Q_valid 双分母 Alpha 是累积不透明度,不是观测置信度
flowchart LR A["1 观测:真实覆盖"] --> B["2 几何证据:轨迹/位姿"] B --> C["3 高斯优化:自由度"] C --> D["4 可见性渲染:排序"] D --> E["5 产品证据:Alpha/NoData"] C -.->|反馈:补观测/减自由度| A

这张表最重要的作用,是阻止"方法堆叠"。如果第 1 层是零覆盖,第 3/4 层的正则、排序、生成先验都不会把观测变出来。在观测不足时,方法叠加是负资产。

3. 3k 悬崖:训练损失还在降,测试集已经转身

先读表说明:本文所有数字都带协议。P3 是 llffhold=83 的两视角 holdout;P4 是 13 视角交错 holdout;2×2 是 116 视角/11 个固定 holdout;村落是独立样本。不同协议之间的绝对值不能直接相减,我只在同一协议内做因果比较。

场景 3k test 7k test 3k train 7k train 3k 覆盖 7k 覆盖
A 曲线展馆(P4 E0) 16.216 dB 15.522 dB 19.86 dB 21.61 dB 100% 62.19%
B 低层村落 24.225 dB 20.258 dB 25.53 dB 28.78 dB 100% 69.00%

这张表里最值得看的是两列 train 和两列 test 的反向运动:训练 PSNR 从 19.86 涨到 21.61,测试 PSNR 从 16.22 掉到 15.52;村落的训练 PSNR 从 25.53 涨到 28.78,测试从 24.22 掉到 20.26。与此同时,展馆 TDOM 的非空覆盖从 100% 掉到 62.19%,村落从 100% 掉到 69.00%。

这不是"训练日程没调好"。3k 附近恰好是这套代码启用尺度剪枝的时间点:size_threshold=20 在 3000 后生效。从日志和代码路径看,3k 是尺度剪枝启用前的最后一个完整检查点。后面会看到,剪枝删掉的不只是"冗余大高斯",还包括支撑覆盖的必要大高斯。

所以"3k 悬崖"有两个层面:

  • 统计层面:测试集过拟合,训练损失继续下降,泛化指标转身。
  • 机制层面:尺度剪枝开始删除大高斯,覆盖和几何稳定性同时受损。

只看到第一层,会得出"早停"的结论;看到第二层,才会去改剪枝策略、补观测,而不是盲目加到 30k。

4. 2×2 因子实验:覆盖、形状、辐射是三本账

为了把"剪枝"和"尺度正则"分开,我做了 2×2 因子实验:

  • 数据集:116 视角,11 个固定 holdout,7 个获批的 A 组恢复视角。
  • 因子:是否启用尺度剪枝 × 是否启用尺度正则。
  • 终点:7k;同时回看 3k 检查点。
组 剪枝 尺度正则 3k PSNR 7k PSNR 7k 覆盖 7k 各向异性>10
A 是 否 17.785 16.815 83.21% 8.21%
B 否 否 17.821 16.963 100% 8.00%
C 是 是 17.978 16.696 81.53% 0.064%
D 否 是 17.698 16.844 100% 0.068%

主效应很清楚:

  • 关剪枝:7k PSNR +0.148 dB,覆盖从 83.21% 回到 100%;代价是边缘更糊、锐度下降。
  • 尺度正则 :各向异性>10 从 8.21% 压到 0.064%,但 7k PSNR −0.119 dB;它不修孔洞,覆盖仍只有 81.53%。
  • 交互项:−0.0003 dB,约等于 0。覆盖和形状是两本独立的账,不能指望一个开关同时解决。

这里有两个读表细节,值得单独说:

  1. 3k 的数字早于 3100 的尺度正则启动。C 组 3k 的 17.978 不能记在尺度正则头上;3k 的公平比较是 A/B/C/D 的 17.7--18.0 平台。真正能归因于尺度正则的是 7k 的各向异性比例,而不是 3k 的 PSNR。
  2. E1 和 B 组都叫"不剪枝",但不能直接合并。E1 是 123 视角/13 holdout,B 是 116 视角/11 holdout;而且 E1 在 3k 就已经比 E0 低 0.27 dB,说明"不剪枝"本身也改变了优化动力学,不能把 E1 的 7k 差异简单归因于剪枝。B 组才是同一 116 视角协议内的干净比较:不剪枝 +0.148 dB、覆盖 83.21%→100%。这也是我坚持用 2×2 固定协议的原因。

5. 一次被代码推翻的归因:不是 opacity reset

项目早期,我对 7k 孔洞的解释是"3000 迭代时 opacity reset 把高斯删了"。这个解释听起来很合理,因为很多 3DGS 实现确实有这个机制。但它错了。

我把训练路径的代码逐行对了一遍:

text 复制代码
train.py:128-130
  opacity_reset_interval 只参与 size_threshold=20 的选择
scene/gaussian_model.py:526-529
  max_radii2D > 20 或 max scale > 0.1 * camera_extent 时删除
scene/gaussian_model.py:521
  min_opacity = -1e14,opacity prune 的比较实际失效
train_vast.py:152-153
  reset_opacity_features 只在这里出现,不在 E0/E1/E2/B1 的 train.py 路径

修正后的机制是:

3000 后启用的是基于尺度的剪枝,不是 opacity reset。必要的大高斯被删掉,剩下的小而长的高斯继续增密。结果是孔洞 + 各向异性上升,同时训练损失还在下降。

这个纠正很重要,因为错误的标签会导致错误的干预:

  • 如果相信"opacity reset",你会去关 reset,或者调 opacity。
  • 如果相信"尺度剪枝",你会去分离 size_threshold 和尺度正则,或者补覆盖观测。
  • 这两条路的代价完全不同。

这也是我认为这篇文章最"工程"的部分:归因不是写日志,是要回到代码路径。一个听起来顺耳的解释,如果没有代码证据,很容易把后续实验带偏。

6. 缺失区诊断:缺的是观测,不是高斯

7k 的孔洞到底是不是"点云空了"?我做了缺失区诊断:在 z=4 的主平面上铺 7048 个网格,统计每个网格被多少台注册相机看到。

结果:

  • 70.64% 的网格零相机覆盖。
  • Q_all(以全部网格为分母)中,至少 3 台相机覆盖的比例只有 20.81%。
  • Q_valid(以"至少 1 台相机覆盖"的网格为分母)中,至少 3 台相机覆盖的比例是 70.90%。
  • 12 台注册相机其实覆盖缺失区,但被语义掩膜排除了:A 组 7 台、S 组 1 台、X 组 4 台。
  • 缺失区里有 8055 个稀疏点:66.15% 可靠、30.50% 待复核、3.35% 孤立;中位重投影误差 0.347 px;97.63% 至少有一个 B1 观测。

这组数字说明两件事:

  1. 缺失区不是空点云,也不是整体浮空。它有一批可靠的轨迹和点,问题在于相机使用和掩膜排除,而不是"高斯不够多"。
  2. Alpha 覆盖会骗人。TDOM 的非空像素可以到 100%,但那只是累积不透明度,不是"这个像素被真实观测过"。这两个指标必须分开报。

这也是"可观测性预算"的最强证据:当 70.64% 的网格零相机时,继续加高斯、加迭代、加正则,都是在给一个没有观测的区域记假账。

7. SH0 的减法红利,和它的边界

在表示层面,我做了一个反直觉的尝试:把球谐从 SH3 降到 SH0。

实验 3k test 7k test 运行时间 7k 覆盖
E0:SH3 + 剪枝 16.216 dB 15.522 dB 1625 s 62.19%
E2:SH0 + 剪枝 16.206 dB 15.888 dB 1515 s 61.84%

3k 基本打平(16.206 vs 16.216),7k 反而高 0.366 dB,运行时间少 110 秒。但 SH0 没有修掉孔洞:7k 覆盖仍然是 61.84%。这说明方向自由度不是孔洞的根因,孔洞的根因还是尺度剪枝和观测不足。

这个实验的边界必须说清楚:E2 是"颜色+不透明度"的 FAGK(球谐参数化)打包消融,不是只改 SH 的干净单变量实验;而且是单次运行。它只能算假设生成级证据,不能写成"SH0 一定更好"。

但它背后的理论值得记下来:

固定正交方向下,完整的方向颜色/不透明度函数是不可辨识的;高阶 SH 不是被恢复出来的物理 BRDF。对一个只输出单一方向的正射产品,方向维度的自由度没有被产品偿付。

这句话是本文最"反潮流"的地方。很多工作默认 SH3 更强,但在固定正射产品里,SH3 的额外自由度可能只是在拟合训练视角,而不是在描述表面。SH0 是一个值得验证的减法,不是 universal winner。

8. 产品边界:GeoTIFF 不是"一张图"

最后落到产品。当前输出是局部北向的 RGBA GeoTIFF,1600×1000,Alpha 作为 NoData。展馆的局部单位/像素约 0.0188,村落约 0.0180。它没有 EPSG,没有绝对尺度,也没有 POS/GCP 支撑。

我坚持把边界写进产品,而不是藏在 README 里:

  • 坐标系:局部任意 COLMAP 坐标,无 EPSG、无绝对尺度。
  • Alpha:累积高斯不透明度,NoData 语义;不是观测置信度。
  • 评估:Q_all 与 Q_valid 双分母;覆盖、几何、完整、重复性四轴分开报。
  • 重复性:没有做独立 A/B 子集重建,所以不声明 repeatability。
  • 精度:没有 GCP/POS,不声明测绘级精度;13 视角 holdout 只是探索性泛化评估,不是独立空间精度评估。

这些边界不是"免责声明",而是产品的一部分。把"测量、推断、未知"分开,别人才敢复用你的结果。

工程实现上,这套流水线是 Docker CUDA 11.8 + 双 venv(透视训练/正交渲染,同名 CUDA 扩展必须隔离)+ 25 个 Python 脚本 + 6 个回归测试;上游 commit 用 SHA256 锁定。双 venv 不是洁癖:同名扩展混用会静默加载错的 rasterizer,表现为黑图或尺度异常。

9. 如果你也要做:一页纸止损清单

症状 先查什么 不要做什么
3k 后 test PSNR 下降、train 上升 是否过拟合;coverage 是否同时下降 不要直接加到 30k
TDOM 出现孔洞 3000 后 size_threshold=20 是否启用;覆盖相机是否被掩膜排除 不要先怪 SH 或 opacity reset
各向异性>10 比例上升 尺度正则是否开启;代价是否可接受 不要指望尺度正则修孔洞
覆盖不足 视锥覆盖、≥3 相机支持、掩膜 不要用 Alpha 当观测完整度
边缘模糊 是否关剪枝;是否尺度正则 不要用"更久训练"换清晰度
固定正射产品 SH 阶数、方向自由度 不要默认 SH3 一定更好
小样本配准差 种子连通性、相邻帧、跨航线边 不要先降匹配阈值
想上生产 GCP/POS、独立检查点、重复性 不要拿单次运行当精度报告

如果只能记一条:先补观测,再减自由度,最后才加方法。

10. 边界与下一步

这篇文章的结论有明确的边界:

  • 两个样本都是小样本,不能外推到大规模城市级重建。
  • 展馆与村落是不同协议,绝对值不可直接比较;2×2 只在 116 视角/11 holdout 内做因果比较。
  • E2 的 SH0 是打包消融、单次运行,属于假设生成,不是定论。
  • 没有独立 A/B 重复性重建,没有绝对地理精度,没有测绘级结论。
  • 23 份资料是二手主题报告,正文的引用优先回到一手论文与官方仓库。

下一步我会做四件事:

  1. 用交错 A/B 子集做独立重复性重建,补上 repeatability 这一轴。
  2. 在可信轨迹上做小规模 joint BA,把几何证据层和高斯优化层分开。
  3. 对缺失区做 per-ray 排序/深度诊断,区分"没观测""没高斯""排序错"。
  4. 如果目标是测绘级产品,先上 GCP/POS,再谈绝对精度;否则就守住局部产品的边界。

这套框架是可证伪的:如果补了覆盖视角,覆盖和 PSNR 仍然不涨;或者 SH0 在第二个场景上明显更差;或者 2×2 的结论在独立重复中消失------那"可观测性预算"就需要修正。至少现在,它能解释我手上的全部证据,并且给出了下一步实验的优先级。

11. 结语:失败不是资产,可复用的失败才是

这个项目没有跑出一个生产级 TDOM,但它跑出了一条止损线:

先算观测账,再谈模型容量;先分开覆盖、形状、辐射,再谈调参;先回到代码路径,再给现象起名字。

如果你也在做小样本无人机 3DGS、正射 TDOM、或者任何"训练用透视、产品用固定视角"的重建任务,希望这套审计顺序能帮你少走一段弯路。

参考资料

只列一手论文/官方仓库;项目整理的 23 份二手主题资料不单独列,避免把二手总结当一手证据。

  1. Kerbl, B., et al. 3D Gaussian Splatting for Real-Time Radiance Field Rendering. SIGGRAPH 2023. arXiv:2308.04079.
  2. Tortho-Gaussian. arXiv:2411.19594. DOI: 10.1080/10095020.2026.2622788.
  3. REUrbanGS. arXiv:2507.23006.
  4. GloSplat. arXiv:2603.04847.
  5. SparseSplat. arXiv:2604.03069. CVPR 2026.
  6. SalientGS. arXiv:2607.11285.
  7. VoxelTTO. arXiv:2609.21498.
  8. CalibAnyView. arXiv:2605.14615.
  9. GSM-GS. arXiv:2602.12796.
  10. FilterGS. arXiv:2603.23891.

数据与复现

  • 代码、配置、结果 JSON 与图:https://atomgit.com/lucia-lee-geo/tdom-observability-budget(发布前确认仓库可访问)。
  • 原始影像不公开:展馆 21.4 GB、村落 3.4 GB,含场地信息;仓库只保留脚本、配置、结果和小样本说明。
  • 结果图来自项目输出;合成图与封面由脚本排版,发布前已剥离 EXIF;村落位置在文中做脱敏处理。
  • 关键结果文件:p2_validation.json、p3_validation.json、p4_validation.json、factorial_validation.json、four_axis_baseline.json、train_event_audit.json、missing_region_summary.json、village_validation.json。

作者:LUCIA LEE(李镜馨)|空间数据 × 实体行业 · 智能化技术栈

写作说明:本文的框架与文字经 AI 辅助整理,实验数据、代码审计与结论由作者复核;文中所有数字可在仓库 results/ 中复算。

相关推荐
陈嘿萌5 小时前
ECCV 2026 | CausalDrive:澳门大学×小米汽车,面向自动驾驶的实时因果世界模型
图像处理·人工智能·深度学习·计算机视觉·自动驾驶·学术研究与理论基础
song150265372981 天前
小型零部件外观检测难?AI机器视觉检测设备,适配全行业小件质检
人工智能·计算机视觉·视觉检测
xsd202411181 天前
AI 智能美甲推荐系统技术全解析
人工智能·计算机视觉
原子延迟1 天前
批量压缩视频会变大?HandBrake等3款(2026)
图像处理·人工智能·计算机视觉·音视频
apple_692658851 天前
基于 Qwen-Image-2.1 的人物替换 LoRA 模型及部署工作流 人物替换的效果 吊打闭源
人工智能·计算机视觉
qq_25294131681 天前
日本道路病害检测数据集 | 道路病害 裂缝检测 坑洼识别 市政巡检9287期
人工智能·深度学习·yolo·目标检测·计算机视觉·道路检测
Qianxueban1 天前
如果卷积核大小固定,步长固定,那经过i次卷积,它一个像素的感受野是多大?
人工智能·深度学习·计算机视觉
qq_25294131681 天前
伊蚊检测数据集 | 伊蚊检测 病媒生物 公共卫生 目标检测9304期
人工智能·yolo·目标检测·计算机视觉·蚊子·尹蚊
闭包不眠1 天前
批量压缩视频先分组,HandBrake等3种方法(2026)
图像处理·人工智能·计算机视觉·音视频