前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Instant-NGP复现详解

Instant-NGP复现详解

作者头像
Srlua
发布2024-11-30 10:54:36
发布2024-11-30 10:54:36
27900
代码可运行
举报
文章被收录于专栏:CSDN社区搬运CSDN社区搬运
运行总次数:0
代码可运行

图像、3D模型、场景快速参数化为神经网络MLP:Instant-NGP复现详解

一、概述

NGPNeural Graphics Primitives)是一种基于神经网络的图形基元,使用全连接的神经网络进行参数化,其训练和评估成本可能很高。

作者提出了一种多分辨率哈希编码方法,该编码具有自适应性高效性的特点,可用于改善神经网络输入以提高近似质量和训练速度。多分辨率结构允许网络消除哈希冲突的歧义,从而形成一个简单的架构,可以在现代 GPU 上并行化。

作者将多分辨率哈希编码应用到全融合的CUDA内核,使得NGP得以利用其并行性,从而减小带宽和计算上的浪费。最终能够在几秒钟内训练得到高质量的NGP,并在数十毫秒内以1920x1080的分辨率进行渲染,故称Instant-NGP

二、原理介绍

多分辨率哈希编码Multiresolution Hash Encoding)具有自适应和高效的特点:

  • 可以应用在多种场景表示,如 Gigapixel图像sdf(符号距离场)nerf(神经辐射场)
  • 哈希查找的时间复杂度是O(1),无需控制流,在GPU上表现出色,避免了执行分歧和串行指针跟踪;
  • 结合了多个不同分辨率的层次,以捕捉场景中的粗糙精细特征。

具体实现原理如下:

  1. 对于给定的输入坐标x,在不同分辨率级别上找到包围它的体素,并通过对整数坐标进行哈希映射的方式,为这些体素的角(顶点)分配索引。
  2. 对于所有生成的角索引,从哈希表中查找相应的F维特征向量
  3. 根据x在相应体素中的相对位置对这些特征向量进行线性插值
  4. 将每个级别的特征向量以及辅助输入 ?∈ R? 连接起来,得到 MLP 的输入编码 ? ∈ R??+?
  5. 最后,通过反向传播损失梯度(loss gradients)来训练编码,梯度将通过MLP网络(5)、连接(4)、线性插值(3)反向传播,然后累积到查找到的特征向量中(2)。

三、实现细节

作者在CUDA中实现该多分辨率哈希编码,将其与tiny-cuda-nn框架的快速完全融合的MLP相结合,下面是一些具体实现细节:

  • 性能考虑:为了优化推理和反向传播性能,哈希表条目以半精度(每个条目2字节)存储。同时,维护一个全精度副本以稳定混合精度参数更新。
  • 分级计算:作者按级别评估哈希表,在处理一批输入位置时,仅需小部分连续哈希表保留在缓存中,从而充分利用GPU的缓存和并行性。
  • 模型结构:除了NeRF场景之外的任务,MLP的结构包括两个宽度为64个神经元的隐藏层(使用ReLU激活函数)和一个线性输出层。
  • 最大分辨率(Nmax):使用较大的值可以支持在广阔场景中靠近物体时的高质量渲染。
    • 对于NeRFSDF,最大分辨率被设定为场景尺寸的2048倍;
    • 对于gigapixel image(十亿像素图像),最大分辨率被设定为图像宽度的一半;
    • 对于辐射缓存Radiance Cache),最大分辨率被设定为219。
  • 初始化:作者根据相关文献,对神经网络权重进行初始化,为神经网络各层的激活及其梯度提供合理的缩放;使用均匀分布 U(−10−4, 10−4) 对哈希表条目进行初始化,以提供一些随机性。
  • 训练:作者使用Adam方法联合训练神经网络权重和哈希表条目,并在哈希表条目的梯度精确为零时跳过Adam步骤。这节省了约10%的性能,而且在梯度稀疏的情况下没有降低收敛速度。

通过这种实现和优化,多分辨率哈希编码在CUDA中获得了高效的性能和较低的开销。

四、构建Instant-NGP

如果读者使用的是Windows环境,可根据自己的显卡直接下载下面的发行版:

如果读者使用的是Linux环境,抑或是想通过Python bindings进行更多对照实验,则需要自己构建Instant-NGP,下面是构建的过程:

1. 安装环境
  • 硬件要求:英伟达显卡(对于NeRF模型的渲染,尽量保证8GB以上的显存,最好能达到16GB)
  • 支持C++14的编译器(以下是官方推荐的环境)
    • Windows:Visual Studio 2019 或 2022
    • Linux:GCC/G++ 8 及以上
  • CMake工具(3.21及以上)
  • CUDA
    • Windows:CUDA11.5 及以上
    • Linux:CUDA 10.2 及以上

读者首先要确保已配备英伟达显卡,并自行配置满足上述版本要求的C++14编译器CMake工具,以及CUDA工具包(建议安装在/usr/local下)。

安装依赖包

若使用基于 Debian 的 Linux 发行版(如Ubuntu),安装以下依赖包:

代码语言:javascript
代码运行次数:0
复制
sudo apt-get install build-essential git python3-dev python3-pip libopenexr-dev libxi-dev libglfw3-dev libglew-dev libomp-dev libxinerama-dev libxcursor-dev

若使用 Arch 相关的Linux环境,安装以下依赖包:

代码语言:javascript
代码运行次数:0
复制
sudo pacman -S cuda base-devel cmake openexr libxi glfw openmp libxinerama libxcursor
安装CUDA

官方建议将CUDA安装到/usr/local目录下并配置环境变量。例如,如果已经在/usr/local下安装了CUDA11.4,编辑~/.bashrc文件,添加以下代码,重启终端或使用source ~/.bashrc命令使之生效。

代码语言:javascript
代码运行次数:0
复制
export PATH="/usr/local/cuda-11.4/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH"

正确配置后,在命令行输入nvcc --version应当正常输出cuda工具包的版本信息。

2. 编译源码

下载附件压缩包

  • 解压附件压缩包并进入项目目录
  • 根据重要说明.txt文档中的链接,下载dependencies并解压到项目根目录

使用CMake构建项目

代码语言:javascript
代码运行次数:0
复制
cmake . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build --config RelWithDebInfo -j
3. 启动
直接启动可执行文件

可直接启动可执行文件

代码语言:javascript
代码运行次数:0
复制
./instant-ngp
通过python bindings调用接口启动

先使用conda创建并配置虚拟环境

代码语言:javascript
代码运行次数:0
复制
# 创建虚拟环境(python版本>=3.7)
conda create --name instant-ngp python=3.7
# 激活环境
conda activate instant-ngp
# 安装最新版的pip工具
conda install pip
pip install --upgrade pip
# 使用pip安装依赖库
pip install -r requirements.txt

启动项目

代码语言:javascript
代码运行次数:0
复制
python scripts/run.py

五、使用Instant-NGP

1. 基本操作介绍
  • 键盘操作:W S A D 在场景中前后左右移动,space(空格)和c分别实现上升下降
  • 鼠标操作:左键拖拽旋转视角,中键拖拽平移视图,滚轮缩放视图

其他快捷键可查阅README.md文档

2. 使用源码data目录下的模型

项目源码中已经有data文件夹,其中包括了三种类型的文件:

exr格式的image文件

.exr格式的文件常用于制作贴图,用图片来实现动态的3D效果。 想要了解更多,可以阅读本文:EXR贴图究竟有多牛B?将要颠覆整个CG绘图行业! - 知乎 (zhihu.com)

我们只需要将.exr格式文件拖入窗口内,或者在启动时带上文件路径(如下)即可。

代码语言:javascript
代码运行次数:0
复制
./instant-ngp data/image/albert.exr

sdf文件

sdf(signed distance field)即符号距离场,通过记录每个点到模型边界的距离,在模型内侧的点数值为负,外侧的点数值为正,在边界上的点数值为0,所有距离为0的点构成了模型的表面,从而可以表示出一个2D或3D模型。 想要了解更多,可以阅读本文:SDF(signed distance field)基础理论和计算 - 知乎 (zhihu.com)

只需将sdf文件夹下的.obj格式的文件拖入到窗口中,或者在启动时带上文件路径(如下)即可。

代码语言:javascript
代码运行次数:0
复制
./instant-ngp data/sdf/armadillo.obj

nerf模型

NeRF(Neural Radiance Fields)即神经辐射场,基于神经网络构建一个连续的5D函数来表示3D场景,并使用少量的输入视图来优化这个函数以生成复杂场景的新视角。 上一期我介绍了一种mip-NeRF模型,就是对NeRF的一种改进,有兴趣的可以阅读本文:【mip-NeRF】使用一组二维图像渲染3D场景视频(mip-NeRF论文复现)-CSDN博客

只需将nerf文件夹下的场景文件夹(如fox场景)拖入窗口内,或在启动时带上场景目录路径(如下)即可。

代码语言:javascript
代码运行次数:0
复制
./instant-ngp data/nerf/fox

渲染效果图(在RTX 4090显卡上):

image(albert.exr)

SDF模型(armadillo.obj)

nerf模型(fox)

3. 使用任意NeRF数据集

如果读者有自己的NeRF数据集,也可以使用Instant-NGP进行快速渲染,例如我们可以使用谷歌最原始的NeRF数据集,对legochairhotdog这三个场景进行,下载数据集后,将场景文件夹拖入到窗口内即可。下面是渲染效果图:

lego场景

chair场景

hotdog场景

4. 制作自己的NeRF数据集

NeRF数据集通常由一组图片和对应的相机位姿(通常存储在transforms.json文件中)组成。想要制作一组NeRF数据集有很多方法,通常需要一些专业的相机设备。

但是,如果你是ios用户,那幸运的是,你可以从苹果app store下载一个叫NeRF Capture的app(不清楚安卓是否有类似的app),它可以将图像及坐标(大概用到了ARKit)传输给Instant-NGP,并通过Instant-NGP提供的脚本快速制作NeRF数据集。

操作说明如下:

首先需要安装下面的依赖

代码语言:javascript
代码运行次数:0
复制
pip install cyclonedds

用流(stream)传输

打开 NeRF Capture app

运行python脚本(启用stream模式)

代码语言:javascript
代码运行次数:0
复制
python scripts/nerfcapture2nerf.py --stream

等待app与脚本连接,这会在app上显示

在app上点击 send 按钮,捕获到的场景将会发送到Instant-NGP

开始训练

保存数据集

打开 NeRF Capture app

运行python脚本,--save_path指定保存路径,n_frames指定保存数据集前要捕获多少帧

代码语言:javascript
代码运行次数:0
复制
python scripts/nerfcapture2nerf.py --save_path "dir1/dir2" --n_frames 20

等待app与脚本连接,这会在app上显示

在app上点击 send 按钮,捕获到的场景将会保存到指定的目录

六、总结

论文主要提出了一种多分辨率哈希编码,优化了NGP的输入特征编码,并将其融合CUDA内核进行实现,可以适应图像、模型、NeRF等多种场景的渲染。通过复现实验,Instant-NGP的收敛速度之快、渲染质量之高不禁令人称奇!但是Hash编码是一种以空间换时间的数据结构,因此这种方法对显存的要求也比较高。

七、参考资料

论文地址:[2201.05989] Instant Neural Graphics Primitives with a Multiresolution Hash Encoding (arxiv.org)

​​​

希望对你有帮助!加油!

若您认为本文内容有益,请不吝赐予赞同并订阅,以便持续接收有价值的信息。衷心感谢您的关注和支持!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 图像、3D模型、场景快速参数化为神经网络MLP:Instant-NGP复现详解
    • 一、概述
    • 二、原理介绍
    • 三、实现细节
    • 四、构建Instant-NGP
      • 1. 安装环境
      • 2. 编译源码
      • 3. 启动
    • 五、使用Instant-NGP
      • 1. 基本操作介绍
      • 2. 使用源码data目录下的模型
      • 3. 使用任意NeRF数据集
      • 4. 制作自己的NeRF数据集
    • 六、总结
    • 七、参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档