NeRF从入门到放弃2:InstantNGP

2024-06-22 14:12
文章标签 入门 放弃 nerf instantngp

本文主要是介绍NeRF从入门到放弃2:InstantNGP,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原始的NeRF每条光线上的点都要经过MLP的查询,才能得到其密度和颜色值,要查询的点非常多,而MLP的推理是比较耗时的。

InstantNGP将空间划分成多个层级的体素(voxels),并且在每个体素内部使用神经网络来预测feature。

而Plenoxels则干脆就不使用神经网络了,它直接在体素中存储场景的辐射亮度和密度信息。通过使用球谐函数(Spherical Harmonics)来近似每个体素内的光照分布,Plenoxels能够有效地压缩存储需求,同时保持高质量的渲染效果。这种方法避免了复杂的神经网络计算,显著提升了渲染速度。Tesla用的就是这种方法。

Direct Voxel Grid也是类似的想法。

现在比较常调用的是InstantNGP,所以我们重点看这个方法。

算法解读

在这里插入图片描述

Given a fully connected neural network 𝑚(y; Φ), we are interested in an encoding of its inputs y = enc(x; 𝜃 ) that improves the approximation quality and training speed across a wide range of applications without incurring a notable performance overhead

InstantNGP把空间划分成多个分辨率,具体查询某个点的feature时,利用hash表查询到这个点附近的四个角点,这四个角点的feature是已知的,通过三线性插值的方法,得到该点在该分辨率下的feature。

最终的feature是多个分辨率下的feature concate起来,作为最终的feature。

也就是说,原始的NeRF是输入(x,y,z),经过mlp,输出feature;而InstantNGP是输入(x,y,z),查询其4个邻域的feature(事先编码好的,所以很快),插值得到feature。

参数意义

在这里插入图片描述
在这里插入图片描述

5个参数,根据最小、最大分辨率和层数,计算出每一层的放大系数,也就是等比数列的公比(也就是b)。算出公比后每一层的分辨率就是Nmin * b的l次方,l是层的序号。

F是要编码成的向量的维度。

T表示hash表的最大容量,如果超过了这个最大容量,就会出现hash冲突。

如第一张图中编码的feature是2维,有2个层级(L),那最后的特征向量就是这两个层级的特征向量concate起来,是4维度。

代码实例

# nerfstudio/field_components/encodings.py
class HashEncoding(Encoding):"""Hash encodingArgs:num_levels: Number of feature grids.min_res: Resolution of smallest feature grid.max_res: Resolution of largest feature grid.log2_hashmap_size: Size of hash map is 2^log2_hashmap_size.features_per_level: Number of features per level.hash_init_scale: Value to initialize hash grid.implementation: Implementation of hash encoding. Fallback to torch if tcnn not available.interpolation: Interpolation override for tcnn hashgrid. Not supported for torch unless linear.n_input_dims: Number of input dimensions (typically 3 for x,y,z)"""def __init__(self,num_levels: int = 16,min_res: int = 16,max_res: int = 1024,log2_hashmap_size: int = 19,features_per_level: int = 2,hash_init_scale: float = 0.001,implementation: Literal["tcnn", "torch"] = "tcnn",interpolation: Optional[Literal["Nearest", "Linear", "Smoothstep"]] = None,n_input_dims: int = 3,) -> None:super().__init__(in_dim=3)self.num_levels = num_levelsself.min_res = min_resself.features_per_level = features_per_levelself.hash_init_scale = hash_init_scaleself.log2_hashmap_size = log2_hashmap_sizeself.hash_table_size = 2**log2_hashmap_sizeself.min_res = min_resself.hash_init_scale = hash_init_scalelevels = torch.arange(num_levels)self.growth_factor = np.exp((np.log(max_res) - np.log(min_res)) / (num_levels - 1)) if num_levels > 1 else 1.0self.register_buffer("scalings", torch.floor(min_res * self.growth_factor**levels))self.hash_offset = levels * self.hash_table_sizeself.tcnn_encoding = Noneself.hash_table = torch.empty(0)if implementation == "torch":self.build_nn_modules()elif implementation == "tcnn" and not TCNN_EXISTS:print_tcnn_speed_warning("HashEncoding")self.build_nn_modules()elif implementation == "tcnn":encoding_config = self.get_tcnn_encoding_config(num_levels=self.num_levels,features_per_level=self.features_per_level,log2_hashmap_size=self.log2_hashmap_size,min_res=self.min_res,growth_factor=self.growth_factor,interpolation=interpolation,)self.tcnn_encoding = tcnn.Encoding(n_input_dims=n_input_dims,encoding_config=encoding_config,)if self.tcnn_encoding is None:assert (interpolation is None or interpolation == "Linear"), f"interpolation '{interpolation}' is not supported for torch encoding backend"def build_nn_modules(self) -> None:"""Initialize the torch version of the hash encoding."""self.hash_table = torch.rand(size=(self.hash_table_size * self.num_levels, self.features_per_level)) * 2 - 1self.hash_table *= self.hash_init_scaleself.hash_table = nn.Parameter(self.hash_table)

这篇关于NeRF从入门到放弃2:InstantNGP的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1084511

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al

MySQL-CRUD入门1

文章目录 认识配置文件client节点mysql节点mysqld节点 数据的添加(Create)添加一行数据添加多行数据两种添加数据的效率对比 数据的查询(Retrieve)全列查询指定列查询查询中带有表达式关于字面量关于as重命名 临时表引入distinct去重order by 排序关于NULL 认识配置文件 在我们的MySQL服务安装好了之后, 会有一个配置文件, 也就

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非

MySQL入门到精通

一、创建数据库 CREATE DATABASE 数据库名称; 如果数据库存在,则会提示报错。 二、选择数据库 USE 数据库名称; 三、创建数据表 CREATE TABLE 数据表名称; 四、MySQL数据类型 MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串类型 4.1 数值类型 数值类型 类型大小用途INT4Bytes整数值FLOAT4By

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是