共计 1767 个字符,预计需要花费 5 分钟才能阅读完成。
在 3D 高斯散射 (3DGS) 技术中,损失函数的选择直接影响着模型的收敛速度和重建质量。作为初学者,最常遇到的坑莫过于梯度消失、收敛不稳定等问题。这些问题往往源于损失函数设计不当,比如单一使用 L2 损失导致过度平滑,或者权重分配不合理引发训练震荡。本文将带你系统梳理 3DGS 中常用的损失函数,并通过 PyTorch 代码实战演示如何避开这些陷阱。

一、L1 vs L2:基础损失函数对比
先说最基础的两种损失函数,它们的数学形式很简单:
-
L1 损失(绝对误差):
$$L_{L1} = \frac{1}{N}\sum_{i=1}^N |y_i – \hat{y}_i|$$
它对异常值更鲁棒,适合存在噪声的数据,但梯度恒定可能导致收敛慢 -
L2 损失(均方误差):
$$L_{L2} = \frac{1}{N}\sum_{i=1}^N (y_i – \hat{y}_i)^2$$
对大误差惩罚更重,容易导致过度平滑,但梯度随着误差减小而减弱,后期训练更稳定
在 3DGS 中,建议对颜色预测用 L1(保留锐利边缘),对几何结构用 L2(平滑表面)
二、SSIM 损失:守护细节的卫兵
当需要保留高频细节(如纹理、边缘)时,结构相似性 (SSIM) 损失是利器。它的核心思想是比较局部窗口内的亮度、对比度和结构信息:
$$SSIM(x,y) = \frac{(2\mu_x\mu_y + C_1)(2\sigma_{xy} + C_2)}{(\mu_x^2 + \mu_y^2 + C_1)(\sigma_x^2 + \sigma_y^2 + C_2)}$$
实际使用时要注意:
- 窗口大小通常设为 11×11
- 计算量较大,建议只在最后 1000 次迭代启用
- 权重建议 0.1-0.3 之间(太大可能导致伪影)
三、多损失组合:平衡的艺术
实战中往往需要组合多种损失。这里给出一个 PyTorch 实现示例,包含显存优化技巧:
class MultiLoss(nn.Module):
def __init__(self, weights={'l1':0.6, 'l2':0.3, 'ssim':0.1}):
super().__init__()
self.weights = weights
# 预计算 SSIM 核节省显存
self.ssim_kernel = self._gaussian_kernel(11, 1.5)
def forward(self, pred, target):
losses = {}
if 'l1' in self.weights:
losses['l1'] = F.l1_loss(pred, target)
if 'l2' in self.weights:
losses['l2'] = F.mse_loss(pred, target)
if 'ssim' in self.weights:
losses['ssim'] = 1 - self._ssim(pred, target)
total_loss = sum(w*losses[k] for k,w in self.weights.items())
return total_loss
def _gaussian_kernel(self, size, sigma):
# 高斯核生成实现...
def _ssim(self, img1, img2):
# SSIM 计算实现...
关键技巧:
- 使用字典配置权重,方便动态调整
- 将 SSIM 核预先计算并缓存
- 对每个损失单独记录以便监控
四、避坑实战指南
梯度爆炸检测
当出现以下情况时可能发生了梯度爆炸:
- loss 突然变成 NaN
- 参数值超过 1e6
- 出现明显颜色伪影
应对方案:
- 添加梯度裁剪:
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) - 调小学习率(特别是 SSIM 部分)
- 暂时移除感知损失等复杂项
学习率敏感度测试
我们实测得到各损失函数的最佳学习率范围:
| 损失类型 | 推荐学习率范围 | 备注 |
|---|---|---|
| L1 | 1e-4 ~ 5e-4 | 对学习率相对不敏感 |
| L2 | 5e-5 ~ 2e-4 | 需要更小的初始值 |
| SSIM | 1e-5 ~ 5e-5 | 必须配合 warmup 使用 |
五、展望:自适应损失的设计
当 3DGS 与 NeRF 结合时,一个开放性问题是如何设计自适应损失函数。可能的思路包括:
- 根据空间位置动态调整权重(如近景用 SSIM,远景用 L2)
- 通过 GAN 判别器自动学习损失权重
- 基于渲染误差的反馈调整
这些方向都值得进一步探索,或许你能找到更优的解决方案。建议从小规模实验开始,逐步验证想法的有效性。
