作者 | lcltopismine3 编辑 | 汽车人
原文链接:zhuanlan.zhihu.com/p/597579341
点击下方卡片,关注“自动驾驶之心”公众号
ADAS巨卷干货,即可获取
点击进入→自动驾驶之心【全栈算法】技术交流群
最近零散时间,翻了一批讲Nerf原理的CSDN/知乎/B站文章和视频,有些讲的还是不错的,但是有些实在是让人感觉,作者本身就没搞懂啥是神经辐射场。所以本文使用自问自答的方式,尝试直击要害的讲清楚Nerf是干什么的。
注A:以下内容里,Nerf和神经辐射场互用。
注B:觉得不全面请直接移步评论区喷作者。
1第一问:不多于三句话说清楚什么是神经辐射场(不要带任何公式或者物理建模反正也看不懂)
【太长不看版本】答:神经辐射场是一种面向三维隐式空间建模的深度学习模型,这种深度学习模型又称全连接神经网络(又称多层感知机)。
【恰好三句话版本】答:神经辐射场是一种面向三维隐式空间建模的深度学习模型,这种深度学习模型又称全连接神经网络(又称多层感知机)。NeRF 所要做的任务是 Novel View Synthesis,一般翻译为新视角合成任务,定义是:在已知视角下对场景进行一系列的捕获 (包括拍摄到的图像,以及每张图像对应的内外参),不需要中间三维重建的过程,仅根据位姿内参和图像,合成新视角下的图像。在基于Nerf的表示方法下,三维空间被表示为一组可学习且连续的辐射场,由输入视角+位置学习后,得到密度+色彩。
2第二问:神经辐射场是如何工作的(物理相关知识含量<10%)?
这里先介绍一下神经辐射场在三维空间渲染对应的物理方程。具体参考下面公式。其中x为当前待分析的三维空间坐标,d为光线照射方向,
这个公式分成两部分。第一部分代表x为光源点时,自身在d方向上的辐射量。第二部分为,该点光源照射到其他表面后,折射在d方向的辐射。第二部分中 (x,d,) 为散射函数, (x,) 为从 方向接收到的辐射, 为 与 d的夹角。
为什么要提这个?因为人眼中的色彩,很大一部分是通过神经辐射场中的辐射来的。人眼会接收到光,而光就是电磁辐射,或者说是振荡的电磁场,光又有波长和频率,其中光的颜色是由频率决定的。如果大家记得初中物理的话,大多数光是不可见的,仅有的很窄的一段人眼可见的光谱称为可见光谱,对应的频率就是我们认为的颜色。
因此,我们可以间接认为,建模辐射光即是建模对应的颜色。而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输出值)的建模。
相关物理公式如下(实际使用该公式的离散化形式,有兴趣的同学可以看我附录的数学推导):
这个公式看上去极度复杂;里面涉及三组物理量:光线累积量T(x) 、体素密度 (x) 与颜色 C(x)
体素密度 (x) 反映了该模型在该光线的某处的粒子的密度,也就是一个具体的三维坐标上粒子的密度
颜色 C(x) 反应了该具体的三维坐标上,从光线的方向看去,粒子反射的颜色
光线累积量 T(x) 是一个随着光线的路径长度增加,而不断对体素密度积分的量,它的大小是随着光线达到的地方深度的增加而逐渐减小的,也就是说透明度在不断的下降,光线没有碰撞到任何粒子的概率在减小
据此可以设想体渲染方程的物理意义:解决了遮挡问题与无界问题。
举个例子:在追踪某一条光线并在积分的过程中,假设环境是真空的,如果实际的场景中第一个物体遮挡住了第二个物体,那么光线在经过第一个物体的时候,粒子碰撞到物体表面的概率是非常大的。因为对于一个具体的物体而言,它所在的位置的粒子密度肯定是在一定量级上且比较大的。所以当光线通过第一个物体之后,到达第二个物体的时候,T因为穿透前一物体而释放能量,剩余累积量已经很小了,因此按照比例,第一个物体对于颜色的贡献,会大于第二个物体。换句话说,在追踪这根光线上,主要(应该说是几乎全部)呈现的是第一个物体粒子所反射的颜色,而第二个物体粒子的颜色的影响微乎其微。这和实际物理建模的结果是相互呼应的。
了解了如何进行渲染后,我们进一步介绍nerf进行体渲染的方法:分层体素渲染(Hierarchical volume sampling)。
这里还是要先解释一下背景:直接使用上面公式中的体渲染积分,需要控制采样起始点。如果直接对全局采样,所需要的计算消耗过大,且采样区间的点较为稀疏。假设使用均匀分布采样,则直接采样效率低。选择恰当的起始、终止点在这里是非常重要的。选择起始点区间长度太小,则采样点不足,影响训练结果。基于体渲染方程分析,一个合理的采样选择是,最好尽可能的避免在空缺部分以及被遮挡了的部分进行过多的采样,因为这些部分对最好的颜色贡献是很少的。
那么如何采样效率最高呢?Nerf使用两个网络同时进行训练 (后称 coarse 和 fine 网络), coarse 网络输入的点是通过对光线均匀采样得到的,根据 coarse 网络预测的体密度值,对光线的分布进行估计,然后根据估计出的分布进行第二次重要性采样,然后再把所有的采样点一起输入到 fine 网络进行预测。具体过程请见下图。
分层体素渲染的具体流程如下:
先使用粗采样(在起点、终点之间均匀采样)得到 个点,采样通过 coarse 的渲染方程的计算。
之后需要对 进行归一化,得到分段常数概率密度函数,然后通过逆变换采样(inverse transform sampling)获得N_f个点,添加至已有点中,用于fine网络采样。
简单说一下这里为什么用逆变换采样。逆变换采样的作用是,在分布 p 的 CDF 值域上均匀采样,其采样结果与原分布 p 中的采样同分布。因此如果获取当前分布困难,可以通过逆变换采样,简化问题难度。
分层体素渲染公式的数学推导这里不展开,有兴趣的同学请下拉至附录查看。
5第五问:Nerf模型训练是否使用了某些涨点tricks
确实有。实际有两个tricks:
位置编码(positional encoding),注意这里的PE和transformer里面的PE不一样。
层体素渲染,上面已经提过了。
下面重点说一下位置编码。
为什么要引入位置编码:传统的MLP网络不善于学习高频数据信息,但是基于颜色的纹理信息都是高频的,如果直接使用MLP学习,会导致学得纹理的表面相当模糊。因此引入了位置编码,让MLP同时学习高低频信息,提升清晰度。
不多讲公式,直接上图拿来对比,使用了位置编码带来的算法增益。
6体渲染公式的数学推导(可选)
对数学不关心或者看不懂的同学建议跳过这部分。
该部分内容引用Kevin对于Nerf的介绍,数学推导摘录自NeRF原作者Ben Mildenhall在SIGGRAPH 2021的 Courses: Advances in Neural Rendering (Part 1)中的原始数学推导。
设随机变量S,表示当前光线所走到的位置。
我们从T(s)开始介绍。T(s)即为上文提及的光线通过率。物理意义为行进至S处,粒子未撞击到物体的概率。
这里我们定义T(s)为
其物理意义为,当光线到达s处时,光强还剩下百分之多少。按照该模型的解释,也就是有百分之多少的光线没有碰撞到粒子。再从统计学上,换到概率学上的意义,也就是一根光线到达ss处时,没有碰撞到任何粒子的概率。
则物体在位置S撞击到某点的概率F(S)的数学表示为:
求 F(S) 返回颜色的期望即为 E(C) ,则有
计算资源有限,无法穷尽正半球,因此可进一步优化。假定采样起始 、终止点 已知,则可进一步推导得
下面推导体渲染方程的离散化形式
假设光线在走到x的时候,没有碰撞到任何粒子的概率是T(x),也就是光线透过率,那么光线在此三维坐标下继续传播一段距离,给定碰撞到当前粒子的概率为σ,则没撞击的概率为 1-σ, 据此有
求解可得
给定起始点 、终止点 ,进一步可得:
代入E(c)函数的离散形式,此时不再求F(S)的倒数,而是求其差分的期望,则有
此即为体渲染公式的离散形式。
【自动驾驶之心】全栈技术交流群
自动驾驶之心是首个自动驾驶开发者社区,聚焦目标检测、语义分割、全景分割、实例分割、关键点检测、车道线、目标跟踪、3D目标检测、BEV感知、多传感器融合、SLAM、光流估计、深度估计、轨迹预测、高精地图、NeRF、规划控制、模型部署落地、自动驾驶仿真测试、硬件配置、AI求职交流等方向;
添加汽车人助理微信邀请入群
备注:学校/公司+方向+昵称