3D高斯泼溅重建中,训练后期经常出现训练视角指标和测试视角指标明显背离的情况:训练损失持续下降,测试视角却出现漂浮高斯点、边缘拉伸和纹理模糊。不要急着怀疑数据量,这通常是显式点集对有限相机位姿过拟合的直接表现。本文围绕早停和正则化两个方向,给出可以落地到训练脚本的调整方法。

一、理解3DGS过拟合的成因
3DGS使用一组可微分的3D高斯原语表示场景,每个原语包含位置、旋转四元数、缩放、不透明度和球谐系数。优化目标是对训练图像做光栅化重建,通过梯度反向传播更新这些参数。由于高斯点是显式几何体,优化自由度远高于NeRF那种MLP隐式表示,当训练视角覆盖不足时,优化器会倾向于生成一些仅对特定训练视角负责的细长高斯或高不透明度点。它们能显著降低训练像素误差,却在新视角上形成针状伪影和半透明漂浮物。
另一个被忽略的因素是密度控制策略。原始3DGS在梯度累积较大的区域分裂或克隆高斯,同时周期性剪除不透明度低于阈值的高斯。这个机制在训练早期有助于增加几何细节,但在训练后期如果学习率没有同步下降,新生成的高斯会继续对训练误差过度响应,加剧对训练视角的记忆。此时验证指标往往已经停滞甚至变差,所以单纯观察训练损失会产生模型仍在变好的错觉。
二、早停策略:从验证集到停止条件
早停的前提是有一个可信的验证集。3DGS训练通常把全部输入图像都当作训练视角,这不利于发现过拟合。可以在每5到10帧中留出一帧作为验证集,或者按相机位置随机划分,确保验证视角与训练视角在空间上有一定间隔。物体级重建可以围绕物体圆周每隔N帧抽一帧作为验证,场景级重建则应该优先保留不同高度和不同朝向的相机。
监控指标比损失更可靠。PSNR对整体亮度误差敏感,SSIM对结构相似性敏感,LPIPS更接近人类感知。建议以LPIPS为主、PSNR为辅。每训练200到500步在验证集上评估一次,记录验证LPIPS。如果连续K次评估没有改善,且训练损失仍在下降,说明模型开始记忆训练视角,可以触发早停。K值一般设置3到5,太小容易过早停止,太大可能错过最佳检查点。下面是一个简化的早停回调逻辑。
class EarlyStopping:
def __init__(self, patience=5, min_delta=0.0005):
self.patience = patience
self.min_delta = min_delta
self.best_score = None
self.counter = 0
self.best_state = None
def step(self, val_lpips, model):
score = -val_lpips
if self.best_score is None:
self.best_score = score
self.best_state = {k: v.clone() for k, v in model.state_dict().items()}
return False
if score < self.best_score + self.min_delta:
self.counter += 1
if self.counter >= self.patience:
model.load_state_dict(self.best_state)
return True
else:
self.best_score = score
self.best_state = {k: v.clone() for k, v in model.state_dict().items()}
self.counter = 0
return False
上面代码中,每次评估后调用step方法,val_lpips越低越好,因此内部取负值作为分数。当验证LPIPS连续多个周期没有明显下降时,返回True并回滚到最佳权重。实际使用时还要结合学习率调度,例如原始3DGS在7k步和15k步附近会做学习率衰减,早停检查频率可以放在每次衰减前和衰减后各多评估一次,因为衰减本身会带来验证指标的短期波动。
另一种更温和的做法是不直接停止,而是在检测到过拟合倾向后降低高斯增删频率,甚至冻结一部分已经稳定的高斯参数。这样既能保留已有几何结构,又避免新生成的点继续追踪训练噪声。若验证指标在后续窗口内重新改善,则恢复正常的密度控制。
三、正则化参数:控制高斯点行为的显式约束
原始3DGS主要依赖剪枝和密度控制来保持几何合理性,并没有显式的正则化损失项。为了抑制过拟合,可以在训练损失中加入若干约束。位置偏移惩罚是最容易实施的一种:记录每次迭代前后高斯中心的变化量,对超过一定阈值的位移施加L2损失。它会让优化过程更平稳,防止单个高斯点为了补偿某个训练视角而大幅移动。
# 位置偏移正则化示例 delta_pos = (new_pos - old_pos).norm(dim=-1) pos_reg = torch.mean(delta_pos * delta_pos) total_loss = image_loss + 0.01 * pos_reg
缩放矩阵约束同样重要。3DGS的协方差由缩放向量和旋转四元数组成,训练后期某些高斯会被拉成极细的针状,以便在特定视图上遮挡误差。可以直接对缩放向量的最小值和最大值做惩罚,例如希望尺度保持在0.0005到0.05之间,超出范围的部分产生损失。更稳定的做法是对数尺度惩罚,因为尺度通常在对数空间更新,直接使用线性惩罚在极小尺度下梯度不均衡。
不透明度稀疏正则化能减少漂浮物。对高斯不透明度做L1惩罚,会推动大量低不透明度点趋近于零,再通过已有的剪枝逻辑删除它们。注意权重不能给得太大,否则会把有效的高斯也削掉,导致重建表面出现孔洞。建议从很小的系数,比如1e-5到1e-4开始,配合验证集观察。
下表汇总了几种常用正则化及其影响。
| 正则化类型 | 作用 | 建议起始权重 | 过度使用的副作用 |
|---|---|---|---|
| 位置偏移L2 | 稳定训练,防止大幅移动 | 0.001-0.01 | 几何更新缓慢,细节收敛不足 |
| 缩放范围惩罚 | 抑制针状高斯和超大高斯 | 0.001-0.005 | 表面模糊,丢失细小结构 |
| 不透明度L1 | 减少漂浮点半透明噪点 | 1e-5-1e-4 | 表面出现孔洞,重建不完整 |
| 方差一致性正则 | 约束协方差矩阵的极端形状 | 0.0005-0.002 | 高频纹理损失 |
这些正则项不应同时全部开启,而是先选择一个最贴合当前问题的。如果测试视角主要是漂浮物,优先使用不透明度L1;如果边缘有很多针状拉伸,使用缩放范围惩罚;如果训练过程不稳定、损失曲线剧烈抖动,则加位置偏移L2。每一种都需要在加入后重新微调学习率,因为正则化会改变梯度的整体量级。
四、联合调试流程与常见坑
推荐的流程是:先跑一遍没有任何显式正则项的基线,记录训练损失、训练PSNR、验证PSNR和验证LPIPS。若训练损失在后期快速下降而验证LPIPS同步上升,基本可以确认过拟合。此时不要急着同时加多个正则项,而是先加入一个温和的不透明度L1或缩放约束,再观察验证曲线是否止跌。若仍无改善,再逐步加入第二项。
早停策略要和正则化配合,不能只靠早停。正则化改变了解空间,可能让模型在更早阶段就达到稳定的验证指标,也可能因为权重过大抑制了所有高频细节。调试时建议固定随机种子,每次只改变一个变量。一个常见的坑是把早停阈值设得过严,例如验证PSNR只要连续两次没有提升就停止,但3DGS在密度控制阶段本来就会有波动,更容易出现假性早停。另一个坑是正则化只加在训练损失里,却不调整密度控制的梯度阈值,导致新增高斯仍然不受约束。最好在新增高斯的克隆和分裂前,也检查其父高斯的尺度与不透明度,以减少坏点的传播。
总的来说,解决3DGS训练过拟合不能只寄希望于更多训练步数,而要建立起验证集监控、早停止损和显式正则化三位一体的控制机制。通过监控验证LPIPS而不是只看训练损失,配合合理的patience和温和的几何约束,通常可以在不明显牺牲细节的情况下抑制漂浮物和针状伪影。若仍然出现过拟合,再考虑增加视角数量、使用预训练深度先验或对球谐系数做低阶截断,这些都是更进一步的调整方向。