前言
本文章发表在 ACM Transactions on Graphics (ToG) 上,是图形学的顶刊之一。文章的作者都来自于Nvidia。
背景
这篇文章是NeRF方法提出后的一个改进工作(虽然文章提出可以应用于多种三维表示任务,但是主要评测还是在NeRF上)。在vanilla NeRF 的重建过程中,场景训练起来一般比较慢,而且重建质量不是特别高。这主要是vanilla NeRF的架构仅仅基于一个多层的MLP对场景进行建模,模型很难学习到空间中的信息。针对这个问题,也有一些改进方法,比如基于位置编码的方法。最简单的是使用Transformer中的位置编码。或者基于可学习的位置编码,比如空间位置的embedding。基于Transformer位置编码,其实并没有解决问题,多层MLP网络依然需要学习空间连续位置上的颜色和密度的不连续突变。因此可学习的位置编码是一个方法,通过embedding的学习可以比较容易地建模不同位置的非连续特征。但是Embedding的方法也面临着一个艰巨的挑战,就是显存问题。如果我们将空间离散为NxNxN的网格,那么需要占用非常多的显存,而且大部分位置都是非必要的。因此需要找到一种方法来减少显存的消耗。
论文目标
如背景中所述,这篇论文的目标就是解决基于Embedding位置编码的显存问题。这样可以保证NeRF的训练过程可以快速收敛,同时重建的质量也比较高。
实现方法
具体流程
既然我们意识到可学习的位置编码的问题主要在于NxNxN的网格表示方法,那么解决思路可以从表示方法入手。比如采用八叉树的编码方式。这篇文章提出了另一种方法,基于级联哈希表的表示方法。我们可以用二维图像的重建作为一个例子阐述。
假设我们的特征编码长度是
F
\bold{F}
F, 我们创建
L
\bold{L}
L层哈希表。每个哈希表我们用
T
\bold{T}
T个编码单位。最终我们得到的编码结果是
F
⋅
L
\bold{F\cdot L}
F⋅L长度的。在每一层哈希表,我们都需要确定一个分辨率。即每个哈希编码单位所表示的空间大小。如上图所示,可以看到第一层的分辨率(蓝色)是比第二层(粉红)的分辨率粗糙的。我们划分第一层的分辨率,保证第一层的哈希编码单位和分辨率是一一对应的。第二层在同样的编码单位个数下,提高分辨率。这样第二层会有哈希冲突,但是通过第一层的哈希编码,网络仍然可以学习到其位置信息。同时,由于图像有大部分的空白区域,基本上通过第一层的哈希编码,网络就可以推理出其颜色特征。这样也合理地将第二层哈希编码分配给更需要重建细节的位置。
哈希算法
在网络推理的过程中,给定坐标x根据何种哈希算法1对位置编码进行索引呢?
文章中给出的空间哈希算法如下所示:
h
(
x
)
=
(
⨁
i
=
1
d
x
i
π
i
)
m
o
d
T
h(x) = \Big(\bigoplus^d_{i=1} x_i \pi_i\Big)\ {\rm mod}\ T
h(x)=(i=1⨁dxiπi) mod T
其中d是
x
x
x的维度,不如平面就是2维。
⨁
\bigoplus
⨁是 XOR运算符。
π
i
\pi_i
πi 是非常大的素数。通常
π
1
=
1
,
π
2
=
2
654
435
761
,
π
3
=
805
459
861
\pi_1=1, \pi_2 = 2\ 654\ 435\ 761, \pi_3 =805\ 459\ 861
π1=1,π2=2 654 435 761,π3=805 459 861。
如果提供的坐标是浮点数,那么我们可以先计算坐标相邻位置的几个整数位置,通过整数位置的哈希编码结果进行线性插值。
实验结果
在实验结果中,我们关注速度和精度两个方面。如下表所示,通过对空间的哈希编码,只需要几秒钟就可以实现场景的训练。同时最终得到的重建结果精度也比较高。
文中也做了一些不同编码方式的比较,如下所示:
参考文献
Matthias Teschner, Bruno Heidelberger, Matthias Müller, Danat Pomeranets, and Markus Gross. 2003. Optimized Spatial Hashing for Collision Detection of Deformable Objects. In Proceedings of VMV’03, Munich, Germany. 47–54. ↩︎