3DGS-学习版
环境搭建
由于目前笔记本是amd架构,安装Ubuntu Windows双系统后,Ubuntu系统十分不稳定,容易系统崩坏。故此处使用wsl+docker+cuda+vscode进行环境部署以及搭建;
WSL:WSL通过Windows内核直接翻译Linux系统调用,无需虚拟硬件支持,文件系统与Windows深度融合,支持快速访问Windows文件和进程交互。虚拟机则完全模拟硬件环境,运行独立的Linux内核,资源隔离性强,但需要手动配置文件共享;
- wsl安装:
https://learn.microsoft.com/zh-cn/windows/wsl/install
- docker vscode ssh wsl配置可见:
https://zhuanlan.zhihu.com/p/618014395
export http_proxy="http://172.29.64.1:7890"
export https_proxy="http://172.29.64.1:7890"
export socks_proxy="socks5://172.29.64.1:7890"
export no_proxy="localhost,127.0.0.1"
尽量搞个服务器,我的是3050ti笔记本有点费劲,训练很慢;
原理学习
1. 核心论文阅读
- 原始论文:《3D Gaussian Splatting for Real-Time Radiance Field Rendering》(Kerbl et al., 2023)
- 理解3DGS的核心思想:用大量3D高斯分布代替体素或神经辐射场
- 掌握高斯点的表示方法:位置、缩放、旋转、颜色特征、透明度
- 学习高斯光栅化的原理:如何将3D高斯投影到2D图像平面
- 理解优化策略:损失函数、学习率调度、点云增密/剪枝机制
2. 相关背景知识
-
计算机图形学基础:3D变换、相机模型、光栅化原理
- 相机模型:
https://blog.csdn.net/m0_68926749/article/details/154545705
- 针孔相机
https://zhuanlan.zhihu.com/p/154808198
- 双目相机
https://zhuanlan.zhihu.com/p/698620367
-
鱼眼相机
-
RGBD相机
-
光栅化原理: 总结就是将三角面投影至像素块,并按照一定规律填充三角型内部的像素块颜色;
https://www.bilibili.com/video/BV1tF411x7Cp?t=0.0
-
点云渲染技术:体渲染、点渲染
-
点云渲染:将离散点云数据直接渲染成二维图像;核心技术在于处理离散点带来的空洞;
-
关键技术:
- 点大小优化:根据点与相机的距离动态调整点的大小,近处的点较大,远处的点较小,避免空洞;
- 点插值:在点之间进行插值,生成连续的表面;
- 法线估计:从点云中估计表面法线,用于光照计算;
- 层次化渲染:使用八叉树等数据结构组织点云,实现LOD(细节层次)渲染;
-
-
体渲染技术:直接对体数据(体素+密度+颜色+透明度等信息)进行渲染;核心技术为ray casting(光线追踪、光线投影):从每个像素发射一条光线穿过体数据,沿光线路径采样体素,通过传输函数将体素属性转换为颜色和透明度,然后沿光线进行体绘制积分,累加颜色和透明度,得到最终像素颜色。
-
关键技术:
- 传输函数设计:将体素密度映射到颜色和透明度;
- 光线采样优化:自适应采样、空体素跳过;
- 加速结构:使用八叉树、k-d树等加速光线求交;
- 梯度计算:从体数据中计算梯度,用于光照计算;
- 多分辨率渲染:对大规模体数据使用多分辨率表示;
-
-
点渲染技术:将三维空间中的离散点集直接渲染成二维图像的技术。每个点通常包含位置、颜色、法线等信息,渲染时将这些点投影到图像平面,通过着色计算得到最终像素颜色;
-
关键技术:
- 点大小优化:根据点与相机的距离动态调整点的大小,近处的点较大,远处的点较小,避免空洞;
- 点插值:在点之间进行插值,生成连续的表面;
- 法线估计:从点云中估计表面法线,用于光照计算;
- 层次化渲染:使用八叉树等数据结构组织点云,实现LOD(细节层次)渲染;
-
-
-
深度学习优化:Adam优化器、学习率调度、损失函数设计
-
Adam优化器:Adaptive Moment Estimation,一种自适应学习率的优化算法,结合了动量法(Momentum)和RMSProp的优点;核心技术在于通过维护梯度的一阶矩和二阶矩估计,为每个参数自适应调整学习率,实现快速稳定的收敛。
-
算法原理:
- 动量法(Momentum):利用历史梯度的指数加权平均来加速收敛,减少震荡;
- RMSProp:自适应调整每个参数的学习率,对频繁更新的参数使用较小的学习率,对稀疏更新的参数使用较大的学习率;
-
数学公式:
Adam算法维护两个移动平均参数:
\[\begin{aligned} m_t &= \beta_1 \cdot m_{t-1} + (1-\beta_1) \cdot g_t \\ v_t &= \beta_2 \cdot v_{t-1} + (1-\beta_2) \cdot g_t^2 \\ \hat{m}_t &= m_t / (1-\beta_1^t) \quad \text{(偏差修正)} \\ \hat{v}_t &= v_t / (1-\beta_2^t) \quad \text{(偏差修正)} \\ \theta_{t+1} &= \theta_t - \alpha \cdot \hat{m}_t / (\sqrt{\hat{v}_t} + \epsilon) \end{aligned} \]其中:
- \(\beta_1\)(通常为0.9):一阶矩估计的指数衰减率;
- \(\beta_2\)(通常为0.999):二阶矩估计的指数衰减率;
- \(\alpha\):学习率;
- \(\epsilon\)(通常为1e-8):防止除零的小常数;
-
优缺点:
优点:
- 自适应学习率,适合处理稀疏数据;
- 对超参数选择不敏感;
- 收敛速度快,计算效率高;
- 内存占用相对较小;
缺点:
- 可能会导致过拟合;
- 学习率可能会变得非常小,导致训练停滞;
- 在某些任务上可能不如SGD with Momentum泛化性好;
-
-
学习率调度:在训练过程中动态调整学习率的策略,目的是加速早期收敛、防止训练后期震荡、帮助模型跳出局部最小值、提高泛化性能。
-
常见策略:
- 恒定学习率:整个训练过程使用固定的学习率;
- 阶梯式衰减:在特定迭代次数时将学习率乘以一个衰减因子;
- 指数衰减:学习率随迭代次数指数下降;
- 余弦退火:学习率随迭代次数按照余弦函数下降;
- 线性衰减:学习率随迭代次数线性下降;
- 多项式衰减:学习率随迭代次数按照多项式函数下降;
- 带预热的学习率:初始阶段缓慢增加学习率,然后再逐渐下降;
-
3DGS中的带预热策略:
技术特点与挑战:3DGS使用大量3D高斯点云表示场景,具有高维度参数空间、动态点云密度(densification机制)、位置参数敏感性等特点;
预热策略的优势:
- 避免初始阶段参数剧烈震荡:位置参数初始学习率仅为正常学习率的1%(
position_lr_delay_mult=0.01),防止高斯点云在优化初期出现不合理分布; - 配合动态点云密度调整:从第500次迭代开始,每100次迭代执行一次增密操作,直到第15,000次迭代,预热机制为动态点云密度调整提供稳定的优化环境;
- 实现平滑的学习率过渡:采用类似反余弦衰减的平滑过渡,比线性预热更能有效避免训练震荡;
- 不同参数组的差异化优化:位置参数使用预热+指数衰减,颜色特征、不透明度、尺度和旋转使用固定学习率;
实现代码:
delay_rate = lr_delay_mult + (1 - lr_delay_mult) * np.sin( 0.5 * np.pi * np.clip(step / lr_delay_steps, 0, 1) )与其他调度模式的对比:
- 固定学习率:无法适应训练后期需要更精细调整的需求;
- 简单衰减:缺乏对初始阶段训练稳定性的保护;
- 余弦退火:可能在训练早期阶段学习率过高,导致位置参数震荡;
- 自适应学习率(如AdaGrad):对梯度历史的累积可能导致学习率过早过小;
- 避免初始阶段参数剧烈震荡:位置参数初始学习率仅为正常学习率的1%(
-
-
损失函数设计:用于衡量模型预测结果与真实标签之间的差异,设计时需考虑任务类型、数据分布特点、模型特性、训练稳定性和收敛性。
-
常见损失函数:
- L1损失(Mean Absolute Error):
loss = torch.mean(torch.abs(pred - target)),对异常值不敏感,梯度稳定,收敛速度较慢; - L2损失(Mean Squared Error):
loss = torch.mean(torch.square(pred - target)),对异常值敏感,梯度变化大,收敛速度快; - Huber损失:结合L1和L2损失的优点,对异常值不太敏感,梯度相对稳定;
- DSSIM损失(结构相似性损失):衡量图像的结构相似性,更符合人类视觉感知,常用于图像生成任务;
- 交叉熵损失:用于分类任务,衡量两个概率分布之间的差异;
- L1损失(Mean Absolute Error):
-
3DGS中的损失函数设计:
- L1颜色损失:衡量渲染图像与真实图像之间的像素级差异,
img_loss = l1_loss(rendered_image, gt_image); - DSSIM损失:衡量渲染图像与真实图像之间的结构相似性;
if FUSED_SSIM_AVAILABLE: ssim_loss = 0.84 * (-1.0 * fused_ssim(rendered_image, gt_image, data_range=1.0)) else: ssim_loss = 0.84 * (1.0 - ssim(rendered_image, gt_image, data_range=1.0)) - 深度L1损失:衡量渲染深度与真实深度之间的差异,
depth_loss = depth_l1_weight(iteration) * l1_loss(depth, gt_depth); - 总损失:
loss = (1.0 - opt.lambda_dssim) * img_loss + opt.lambda_dssim * ssim_loss + depth_loss,其中opt.lambda_dssim默认值为0.2;
- L1颜色损失:衡量渲染图像与真实图像之间的像素级差异,
-
设计考量:
- 多损失组合:结合像素级损失(L1)和结构级损失(DSSIM),既保证像素准确性,又注重整体结构相似性;
- 深度信息利用:引入深度损失,利用多视图几何信息提高3D重建质量;
- 损失权重调度:深度损失权重随迭代进程动态调整,早期注重深度信息,后期更多依赖颜色信息;
- 人类视觉感知:使用DSSIM损失,更符合人类对图像质量的评判标准;
- 数值稳定性:使用合适的权重平衡不同损失,避免某一损失主导训练过程;
-
-
-
球面谐波函数:用于表示3D高斯的颜色特征,通过球面基函数的加权和来模拟视角相关的颜色变化。
-
核心概念:
- 直接光:从光源直接发出,照射到物体表面,直接进入摄像机/人眼的那部分光线;定义物体的基本亮度、本影(阴影)以及最清晰的高光;
- 间接光:光线从光源发出后,在场景中至少经过一次反射(或折射),然后再进入摄像机/人眼的光线;定义场景的真实感、氛围和色彩融合;
球谐函数(SH)主要目的就是计算间接光漫反射这一部分的贡献;
-
技术原理:
如同傅里叶级数可以用一系列正弦余弦波的组合来表示任意一维函数,球谐函数是在球面上定义的一组标准正交基函数。任何定义在球面上的二维函数(例如,从各个方向看一个点的颜色),都可以用这些"基波"的加权和来近似:
- 0阶:一个正球,表示平均颜色/环境光;
- 1阶:三个"哑铃"形状,近似主要光照方向;
- 2阶及更高阶:更复杂的形状,能表示高频细节,如锐利的高光和阴影;
-
阶数与性能:
SH的阶数直接决定了它能表示的视角依赖效果的复杂度和质量,也决定了存储开销:
- SH 0阶:1个系数,颜色是常数,完全没有视角变化,适合漫反射表面或对质量要求极低的场景;
- SH 1阶:4个系数,能表示粗略的、线性变化的颜色梯度,可以模拟基础的方向光效果,开销很小;
- SH 2阶:9个系数,能捕捉中等频率的照明变化,可以开始呈现基本的高光形状,是质量和开销的常见折中点;
- SH 3阶:16个系数(3DGS原论文默认使用),能很好地表示清晰的高光、菲涅尔效应和大部分环境光照效果,视觉上已相当丰富真实;
- SH 4/5阶:25/36个系数,能编码非常高频的细节,如极其锐利的镜面高光、复杂的反射图案,但存储和计算开销显著增加,且可能引入噪声(过拟合训练视角);
-
参考资源:
-

浙公网安备 33010602011771号