五问Nerf | 简单易懂的神经辐射场入门介绍

作者 | lcltopismine3 编辑 | 汽车人

原文链接:zhuanlan.zhihu.com/p/597579341

点击下方卡片,关注“自动驾驶之心”公众号

ADAS巨卷干货,即可获取

点击进入→自动驾驶之心【全栈算法】技术交流群

最近零散时间,翻了一批讲Nerf原理的CSDN/知乎/B站文章和视频,有些讲的还是不错的,但是有些实在是让人感觉,作者本身就没搞懂啥是神经辐射场。所以本文使用自问自答的方式,尝试直击要害的讲清楚Nerf是干什么的。

注A:以下内容里,Nerf和神经辐射场互用。

注B:觉得不全面请直接移步评论区喷作者。

1第一问:不多于三句话说清楚什么是神经辐射场(不要带任何公式或者物理建模反正也看不懂)

【太长不看版本】答:神经辐射场是一种面向三维隐式空间建模的深度学习模型,这种深度学习模型又称全连接神经网络(又称多层感知机)。

【恰好三句话版本】答:神经辐射场是一种面向三维隐式空间建模的深度学习模型,这种深度学习模型又称全连接神经网络(又称多层感知机)。NeRF 所要做的任务是 Novel View Synthesis,一般翻译为新视角合成任务,定义是:在已知视角下对场景进行一系列的捕获 (包括拍摄到的图像,以及每张图像对应的内外参),不需要中间三维重建的过程,仅根据位姿内参和图像,合成新视角下的图像。在基于Nerf的表示方法下,三维空间被表示为一组可学习且连续的辐射场,由输入视角+位置学习后,得到密度+色彩。

2第二问:神经辐射场是如何工作的(物理相关知识含量<10%)?

这里先介绍一下神经辐射场在三维空间渲染对应的物理方程。具体参考下面公式。其中x为当前待分析的三维空间坐标,d为光线照射方向,

9b3fa03af0e9b04087561488b4d3887f.png
经辐射场在三维空间渲染对应的物理方程

这个公式分成两部分。第一部分代表x为光源点时,自身在d方向上的辐射量。第二部分为,该点光源照射到其他表面后,折射在d方向的辐射。第二部分中 (x,d,) 为散射函数, (x,) 为从 方向接收到的辐射, 为 与 d的夹角。

为什么要提这个?因为人眼中的色彩,很大一部分是通过神经辐射场中的辐射来的。人眼会接收到光,而光就是电磁辐射,或者说是振荡的电磁场,光又有波长和频率,其中光的颜色是由频率决定的。如果大家记得初中物理的话,大多数光是不可见的,仅有的很窄的一段人眼可见的光谱称为可见光谱,对应的频率就是我们认为的颜色。

760f70749acd089e30a48588ad3098d4.png
可见光谱,图源来自度娘

因此,我们可以间接认为,建模辐射光即是建模对应的颜色。而Nerf则是一组可以对上面渲染方程近似求解的MLP。这也就是Nerf的工作原理。在基于Nerf的表示方法下,三维场被表示为一组可学习且连续的辐射场。

3第三问:Nerf的输入输出分别是什么?

给定一组连续拍摄的图像+姿态,Nerf尝试使用光线位置、光照方向、对应三维坐标(x,y,z)为输入,输出目标的密度(形体)+颜色。输入共计五变量,也因此被称为“5D辐射场”。具体来说,给定空间点坐标(x,y,z)与观测方向(d_x,d_y,d_z中任意两个,第三个通过叉乘求出,俗称“知二得三”)可求解得该点的密度值(其实是光线在该点终止的概率)与对应的颜色(RGB值)。预测了颜色值,和当前姿态下对应的输入图片求损失,则可进行优化使模型逐步收敛。

4第四问:Nerf模型如何渲染?

Nerf引入了经典的体渲染理论来进行色彩与密度(也就是Nerf输出值)的建模。

相关物理公式如下(实际使用该公式的离散化形式,有兴趣的同学可以看我附录的数学推导):

9d709c0a10e3c5ca77e220c50b0192dc.png
体渲染方程

这个公式看上去极度复杂;里面涉及三组物理量:光线累积量T(x)  、体素密度 (x) 与颜色 C(x)

  • 体素密度 (x) 反映了该模型在该光线的某处的粒子的密度,也就是一个具体的三维坐标上粒子的密度

  • 颜色 C(x) 反应了该具体的三维坐标上,从光线的方向看去,粒子反射的颜色

  • 光线累积量 T(x) 是一个随着光线的路径长度增加,而不断对体素密度积分的量,它的大小是随着光线达到的地方深度的增加而逐渐减小的,也就是说透明度在不断的下降,光线没有碰撞到任何粒子的概率在减小

据此可以设想体渲染方程的物理意义:解决了遮挡问题与无界问题。

举个例子:在追踪某一条光线并在积分的过程中,假设环境是真空的,如果实际的场景中第一个物体遮挡住了第二个物体,那么光线在经过第一个物体的时候,粒子碰撞到物体表面的概率是非常大的。因为对于一个具体的物体而言,它所在的位置的粒子密度肯定是在一定量级上且比较大的。所以当光线通过第一个物体之后,到达第二个物体的时候,T因为穿透前一物体而释放能量,剩余累积量已经很小了,因此按照比例,第一个物体对于颜色的贡献,会大于第二个物体。换句话说,在追踪这根光线上,主要(应该说是几乎全部)呈现的是第一个物体粒子所反射的颜色,而第二个物体粒子的颜色的影响微乎其微。这和实际物理建模的结果是相互呼应的。

了解了如何进行渲染后,我们进一步介绍nerf进行体渲染的方法:分层体素渲染(Hierarchical volume sampling)。

这里还是要先解释一下背景:直接使用上面公式中的体渲染积分,需要控制采样起始点。如果直接对全局采样,所需要的计算消耗过大,且采样区间的点较为稀疏。假设使用均匀分布采样,则直接采样效率低。选择恰当的起始、终止点在这里是非常重要的。选择起始点区间长度太小,则采样点不足,影响训练结果。基于体渲染方程分析,一个合理的采样选择是,最好尽可能的避免在空缺部分以及被遮挡了的部分进行过多的采样,因为这些部分对最好的颜色贡献是很少的。

那么如何采样效率最高呢?Nerf使用两个网络同时进行训练 (后称 coarse 和 fine 网络), coarse 网络输入的点是通过对光线均匀采样得到的,根据 coarse 网络预测的体密度值,对光线的分布进行估计,然后根据估计出的分布进行第二次重要性采样,然后再把所有的采样点一起输入到 fine 网络进行预测。具体过程请见下图。

59663b946391e0355e6cb8434c197692.png
左图:粗采样 右图:细采样

分层体素渲染的具体流程如下:

先使用粗采样(在起点、终点之间均匀采样)得到 个点,采样通过 coarse 的渲染方程的计算。

cb224d67fd0940568719b315419bb023.png
离散化采样方程

之后需要对 进行归一化,得到分段常数概率密度函数,然后通过逆变换采样(inverse transform sampling)获得N_f个点,添加至已有点中,用于fine网络采样。

简单说一下这里为什么用逆变换采样。逆变换采样的作用是,在分布 p 的 CDF 值域上均匀采样,其采样结果与原分布 p 中的采样同分布。因此如果获取当前分布困难,可以通过逆变换采样,简化问题难度。

分层体素渲染公式的数学推导这里不展开,有兴趣的同学请下拉至附录查看。

5第五问:Nerf模型训练是否使用了某些涨点tricks

确实有。实际有两个tricks:

  1. 位置编码(positional encoding),注意这里的PE和transformer里面的PE不一样。

  2. 层体素渲染,上面已经提过了。

下面重点说一下位置编码。

为什么要引入位置编码:传统的MLP网络不善于学习高频数据信息,但是基于颜色的纹理信息都是高频的,如果直接使用MLP学习,会导致学得纹理的表面相当模糊。因此引入了位置编码,让MLP同时学习高低频信息,提升清晰度。

4a837ecab28c8569161271026aec7a03.png
Nerf位置编码公式

不多讲公式,直接上图拿来对比,使用了位置编码带来的算法增益。

4e3954487ba1c1fcb8ab5667c0ba5bc7.png
使用了位置编码,可以让局部纹理更加清晰

6体渲染公式的数学推导(可选)

对数学不关心或者看不懂的同学建议跳过这部分。

该部分内容引用Kevin对于Nerf的介绍,数学推导摘录自NeRF原作者Ben Mildenhall在SIGGRAPH 2021的 Courses: Advances in Neural Rendering (Part 1)中的原始数学推导。

设随机变量S,表示当前光线所走到的位置。

我们从T(s)开始介绍。T(s)即为上文提及的光线通过率。物理意义为行进至S处,粒子未撞击到物体的概率。

这里我们定义T(s)为

da191c1481e53178feebfe542540df3b.png

其物理意义为,当光线到达s处时,光强还剩下百分之多少。按照该模型的解释,也就是有百分之多少的光线没有碰撞到粒子。再从统计学上,换到概率学上的意义,也就是一根光线到达ss处时,没有碰撞到任何粒子的概率。

则物体在位置S撞击到某点的概率F(S)的数学表示为:

6a0d236f448b5d138c726116d909709d.png

求 F(S) 返回颜色的期望即为 E(C) ,则有

4126927d3d4d684955c553c71cd2e915.png
体渲染方程:连续形式

计算资源有限,无法穷尽正半球,因此可进一步优化。假定采样起始 、终止点 已知,则可进一步推导得

b781f8e0040673ea542777c9f9fdbd9c.png

下面推导体渲染方程的离散化形式

假设光线在走到x的时候,没有碰撞到任何粒子的概率是T(x),也就是光线透过率,那么光线在此三维坐标下继续传播一段距离,给定碰撞到当前粒子的概率为σ,则没撞击的概率为 1-σ, 据此有

00e1216d76da9e805eaf57e4fe50850c.png
上式转换成微分方程

求解可得

1d843d4b5d766d3e5191bb90d969dc43.png

给定起始点 、终止点 ,进一步可得:

9b81694408500adcfb0c49e5dd4fcb60.png

代入E(c)函数的离散形式,此时不再求F(S)的倒数,而是求其差分的期望,则有

d4a5bd17053ef3eb81291def88eecf3f.png
体渲染公式的离散形式

此即为体渲染公式的离散形式。

7e970781025bb5635facaaf8fbbed203.png

自动驾驶之心】全栈技术交流群

自动驾驶之心是首个自动驾驶开发者社区,聚焦目标检测、语义分割、全景分割、实例分割、关键点检测、车道线、目标跟踪、3D目标检测、BEV感知、多传感器融合、SLAM、光流估计、深度估计、轨迹预测、高精地图、NeRF、规划控制、模型部署落地、自动驾驶仿真测试、硬件配置、AI求职交流等方向;

4ca590fe4aefe352609daaa6cc22a785.jpeg

添加汽车人助理微信邀请入群

备注:学校/公司+方向+昵称

  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
nerf-simple是基于PyTorch框架实现的NERF神经辐射)模型的简单版本。NERF是一种用于生成高质量逼真图像的深度学习模型,它通过对景中各个点的辐射值进行建模,从而实现精确的三维重建和渲染。 在NERF模型中,神经辐射是核心概念之一。它是一个由多个隐藏层组成的神经网络,用于估计景中每个点的辐射值。这里的辐射值通常表示像素的RGB颜色值或光强度。 nerf-simple通过使用PyTorch框架的张量操作和自动微分功能来实现NERF模型。首先,我们需要定义一个神经网络模型,包括隐藏层的数量和大小。这个模型可以基于现有的PyTorch模块,如nn.Linear和nn.ReLU,以便构建非线性变换和特征提取。 然后,我们需要定义训练过程,实现数据加载、优化器设置和损失函数计算等步骤。训练数据通常包括一系列景中的图像及其对应的相机和深度信息。 在模型训练完成后,我们可以使用训练好的神经网络来生成逼真的图像。通过对景中每个像素点的辐射值进行预测,我们可以还原出景的三维形状和纹理信息,并最终渲染出高质量的图像。 总结来说,nerf-simple是一个使用PyTorch实现的简单版本NERF模型,它通过神经辐射来估计景中每个像素点的辐射值,从而实现精确的三维重建和渲染。通过定义神经网络模型、训练过程和图像生成过程,我们可以利用这个模型生成逼真的图像。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值