概要
NeRF(Neural Radiance Fields)是一种基于神经网络的三维图像生成技术,通过一组从不同角度拍摄的2D图片,生成一个3D场景,并且能够渲染出该场景在任意视角下的图像。这项技术的核心思想是利用神经网络的强大建模能力来预测三维空间中每一点的光照和颜色。
Instant-NGP 为NERF引入了多分辨率哈希编码。原始的 NVIDIA 实现主要基于 C++/CUDA,基于 tiny-cuda-nn,可以使 NeRF 训练速度提高 100 倍!该项目是 Instant-NGP 的 纯 PyTorch 实现,旨在帮助 AI 研究人员进一步探索和创新此方法。
官方代码:https://github.com/yashbhalgat/HashNeRF-pytorch/
本人已打包好数据可直接运行代码: https://pan.baidu.com/s/1gJecCah5UGP1yRu-X1_G4A?pwd=yrqf 提取码: yrqf
NERF原理
NeRF的工作流程大致可以分为以下几个步骤:
-
输入数据
NeRF需要从场景的不同角度获取一组2D图像及其对应的相机视角。通常,这些图像用于训练神经网络,让它学习如何从不同视角渲染场景。
-
神经网络模型
NeRF使用一个深度神经网络来建模三维场景。这个网络的输入是空间中的位置(即三维坐标)和视角(即相机的方向),网络会输出该位置的颜色和密度(透明度)。这个过程本质上是通过神经网络来逼近场景的光学特性。
神经网络的具体结构通常包括多个全连接层(MLP)。每个网络输出的颜色值是基于输入位置和视角信息进行计算的,而每个位置的密度决定了光线在该位置的穿透程度。
-
体积渲染(Volumetric Rendering)
NeRF使用的是体积渲染方法,它可以通过沿着光线的路径来计算颜色和透明度。体积渲染的基本思想是:当光线通过一个包含物体的体积时,物体的密度会影响光的传播,最终改变图像的亮度和颜色。神经网络的任务是预测这些密度值和颜色值,从而计算出每一条光线的最终颜色。
在渲染过程中,NeRF会将场景划分成若干小体素,模拟光线通过每个体素时的变化,计算出每个体素对最终图像的贡献。通过对所有体素的计算,NeRF能够渲染出图像中每个像素的最终颜色。
-
训练神经网络
为了让神经网络能够准确地模拟场景的光学特性,NeRF需要使用输入的2D图像和相机视角进行训练。训练过程中,网络会调整其内部参数,以最小化渲染图像与真实图像之间的差异。
训练过程通常是一个时间较长的过程,因为NeRF需要处理大量的三维坐标数据并进行细致的光线追踪。训练完成后,网络可以根据输入的新视角来渲染场景,生成新的图像。
HashNeRF优势
相较于 Vanilla NeRF 的收敛速度,HashNeRF-pytorch(左)与 NeRF-pytorch(右):
神经辐射场训练效果
仅仅训练了 5000 次迭代(大约 10 分钟,使用单个 1050Ti),你就开始看到清晰的椅子渲染效果了。😃
代码训练
从这里下载 nerf-synthetic 数据集:Google Drive(https://drive.google.com/drive/folders/1JDdLGDruGNXWnM1eqY1FNL9PlStjaKWi),百度云打包代码中已内置。
训练一个 chair HashNeRF 模型的命令:
python
python run_nerf.py --config configs/chair.txt --finest_res 512 --log2_hashmap_size 19 --lrate 0.01 --lrate_decay 10
可直接在pycharm中运行run_nerf.py,训练过程示例:
- 注意!若使用打包好的云盘代码,需先删除logs文件夹内已经训练好的文件。
代码库还额外支持:用于平滑嵌入的全变差损失(启用时使用 --tv-loss-weight);对光线权重的稀疏诱导损失(启用时使用 --sparse-loss-weight)。
parser参数说明
1、网络深度与宽度
python
netdepth=8:定义粗网络的隐藏层数,对应论文中的8层MLP结构
netwidth=256:每层神经元的通道数,决定模型容量
netdepth_fine=8:精细网络深度(当N_importance>0时启用)
2、特征嵌入策略
python
i_embed=1 # 1:哈希编码 0:标准位置编码 2:球面编码
i_embed_views=2 # 观察方向编码方案
multires=10 # 空间坐标频带数(2^10=1024个频段)
multires_views=4 # 视角方向编码频带
3、训练优化器
参数 | 默认值 | 作用机制 | 说明 |
---|---|---|---|
lrate | 1e-2 | 初始学习率 | 配合指数衰减使用 |
lrate_decay | 10 | 每1000步衰减系数 | 复杂场景建议设为20 |
N_rand | 32x32x4 | 每批光线数量 | 根据GPU显存调整 |
chunk | 32K | 并行处理光线数 | 显存不足时降至8K |
precrop_frac | 0.5 | 中心区域训练比例 | 加速初期收敛 |
4、 体渲染核心参数
渲染方程
python
N_samples=64:粗采样点数(每条光线)
N_importance=128:精细采样点数(需配合精细网络)
perturb=1.0:加入随机抖动,打破网格伪影
raw_noise_std=0:噪声注入标准差(推荐1e-2应对过平滑)
5、数据集适配参数
python
dataset_type='llff' # 支持三种模式:
# 'llff':真实场景(默认forward-facing)
# 'blender':合成物体(需白背景)
# 'deepvoxels':特殊数据集
# LLFF数据集专属
factor=8 # 图像下采样因子(8→原始分辨率1/8)
no_ndc=True # 非归一化设备坐标(全景场景启用)
spherify=True # 360°球面场景标记
6、优化策略
实验数据:联合使用可使PSNR提升0.8dB
python
tv-loss-weight=1e-6:全变分损失约束颜色场平滑度
sparse-loss-weight=1e-10:稀疏损失促进空间利用率
即时渲染加速
python
render_factor=4 # 渲染分辨率降采样(4→1/4尺寸)
finest_res=512 # 哈希表最大分辨率
log2_hashmap_size=19 # 哈希表尺寸(2^19=524,288条目)
7、训练监控与调试
监控参数 | 频率 | 可视化工具 | 关键指标 |
---|---|---|---|
i_print=100 | 每100步 | 控制台 | 损失值/PSNR |
i_img=500 | 每500步 | TensorBoard | 渲染快照 |
i_testset=1000 | 每1000步 | 测试集目录 | 泛化能力 |
i_video=5000 | 每5000步 | MP4视频 | 视角连贯性 |
结果示例
logs文件夹内每5k次生成一次结果:
NERF生成效果示例:
神经辐射场训练结果示例