社区计算机视觉课程文档
神经辐射场(NeRF)
并获得增强的文档体验
开始使用
神经辐射场(NeRF)
神经辐射场(Neural Radiance Fields, NeRFs)是一种在神经网络中存储3D场景的方式。这种存储和表示场景的方式通常被称为隐式表示,因为场景参数完全由底层的多层感知机(MLP)表示。(相比之下,显式表示将颜色或密度等场景参数明确存储在体素网格中。)这种新颖的场景表示方法在新视角合成任务中展现了非常令人印象深刻的结果,即从训练集中未包含的摄像机视角插值出新视角。此外,它允许我们以比显式表示更小的内存占用存储大型场景,因为我们只需要存储神经网络的权重,而体素网格的内存大小是立方增加的。
简史 📖
NeRF领域相对年轻,Mildenhall等人于2020年首次发表论文。自那时起,大量论文发表,并取得了快速进展。自2020年以来,已有超过620篇预印本和出版物发布,GitHub上有超过250个代码库。(截至2023年12月,数据来自paperswithcode.com)。
由于最初的NeRFs配方需要很长的训练时间(在强大的GPU上长达数天),因此在加快训练和推理方面取得了许多进展。一个重要的飞跃是NVIDIA于2022年发布的Instant-ngp。尽管该方法中使用的模型架构与现有架构相似,但作者引入了一种使用可训练哈希表的新型编码方法。由于这种编码方式,我们可以显著缩小MLP的规模而不会损失重建质量。这种新方法在训练和查询方面更快,同时在质量上与当时的SOTA方法不相上下。同样在2022年发布的Mipnerf-360也值得一提。同样,模型架构与大多数NeRFs相同,但作者引入了一种新颖的场景收缩,使我们能够表示在所有方向上都无限的场景,这对于实际应用非常重要。Zip-NeRF于2023年发布,结合了Instant-ngp的编码和Mipnerf-360的场景收缩等最新进展,以处理真实世界的情况,同时将训练时间缩短到一小时以内。(公平地说,这仍然是在强大的GPU上测量的)。
由于NeRF领域发展迅速,我们在文章末尾添加了一个部分,将介绍NeRF的最新研究和未来可能的发展方向。
但现在历史讲够了,让我们深入了解NeRF的内在机制吧!🚀🚀
基础方法(Vanilla NeRF)📘🔍
NeRF的基本思想是将场景表示为一个连续函数,该函数将一个位置,和一个观察方向,映射到一种颜色和体积密度。由于神经网络可以作为通用函数逼近器,我们可以用一个简单的多层感知机(MLP)来逼近这个表示场景的连续函数。.
一个简单的NeRF流程可以用下图概括:
(a) 沿着摄像机射线采样点和观察方向,并将其通过网络。
(b) 网络输出是每个样本的颜色向量和密度值。
(c) 通过体积渲染将网络输出组合起来,从3D空间中的离散样本生成2D图像。
(d) 计算损失并通过反向传播更新网络梯度以表示场景。
这只是一个非常高层次的概述,为了更好地理解,我们来详细了解体积渲染和所使用的损失函数。
体积渲染
体积渲染过程背后的原理在经典的计算机图形学流程中已经很成熟,并非源于NeRF。对于NeRFs的用例来说,重要的是这一步是可微分的,以便允许反向传播。NeRFs中最简单的体积渲染形式可以表示如下:
在上面的等式中,是相机射线预期的颜色,其中是相机的原点,是作为3D单位向量的观察方向,并且是沿射线的距离。和分别代表射线的近端和远端边界。表示沿射线累积的透射率来自到.
离散化后,上述方程可以计算为以下求和形式:
下方示意图显示了离散化后的相机射线,以便更好地理解上述变量。
损失函数公式
由于离散化的体积渲染方程是完全可微分的,因此可以使用渲染像素的重建损失来训练底层神经网络的权重。许多NeRF方法使用像素级误差项,其公式如下:
,其中是渲染后的像素颜色,以及是真实像素颜色。
补充说明
在一个章节中详细描述整个NeRF流程非常困难。上述解释对于理解基本概念很重要,并且在每个NeRF模型中都相似甚至相同。然而,为了获得一个表现良好的模型,还需要一些额外的技巧。
首先,为了捕捉颜色和几何中的高频变化,对输入信号进行编码是必要的。在将输入通过神经网络之前进行编码的做法并非NeRF领域独有,在其他机器学习领域(例如自然语言处理,NLP)也广泛采用。一个非常简单的编码方式,将输入映射到更高维空间,从而能够捕捉场景参数中的高频变化,可能如下所示:
import torch
import mediapy as media
import numpy as np
def positional_encoding(in_tensor, num_frequencies, min_freq_exp, max_freq_exp):
"""Function for positional encoding."""
# Scale input tensor to [0, 2 * pi]
scaled_in_tensor = 2 * np.pi * in_tensor
# Generate frequency spectrum
freqs = 2 ** torch.linspace(
min_freq_exp, max_freq_exp, num_frequencies, device=in_tensor.device
)
# Generate encodings
scaled_inputs = scaled_in_tensor.unsqueeze(-1) * freqs
encoded_inputs = torch.cat(
[torch.sin(scaled_inputs), torch.cos(scaled_inputs)], dim=-1
)
return encoded_inputs.view(*in_tensor.shape[:-1], -1)
def visualize_grid(grid, encoded_images, resolution):
"""Helper Function to visualize grid."""
# Split the grid into separate channels for x and y
x_channel, y_channel = grid[..., 0], grid[..., 1]
# Show the original grid
print("Input Values:")
media.show_images([x_channel, y_channel], cmap="plasma", border=True)
# Show the encoded grid
print("Encoded Values:")
num_channels_to_visualize = min(
8, encoded_images.shape[-1]
) # Visualize up to 8 channels
encoded_images_to_show = encoded_images.view(resolution, resolution, -1).permute(
2, 0, 1
)[:num_channels_to_visualize]
media.show_images(encoded_images_to_show, vmin=-1, vmax=1, cmap="plasma", border=True)
# Parameters similar to your NeRFEncoding example
num_frequencies = 4
min_freq_exp = 0
max_freq_exp = 6
resolution = 128
# Generate a 2D grid of points in the range [0, 1]
x_samples = torch.linspace(0, 1, resolution)
y_samples = torch.linspace(0, 1, resolution)
grid = torch.stack(
torch.meshgrid(x_samples, y_samples), dim=-1
) # [resolution, resolution, 2]
# Apply positional encoding
encoded_grid = positional_encoding(grid, num_frequencies, min_freq_exp, max_freq_exp)
# Visualize result
visualize_grid(grid, encoded_grid, resolution)
输出应该看起来像下图所示
第二个值得一提的技巧是,大多数方法都使用巧妙的方法来在空间中采样点。本质上,我们希望避免在场景为空的区域进行采样。有各种方法可以将在对最终图像贡献最大的区域集中采样,但最突出的一种是使用第二个网络,通常称为*提议网络(proposal network)*,这样就不会浪费计算资源。如果你对这种*提议网络*的内部工作原理和优化感兴趣,可以深入研究Mipnerf-360的出版物,该网络首次在那里提出。
训练你自己的NeRF
为了获得训练第一个NeRF的完整体验,我建议查看nerfstudio团队的绝佳Google Colab笔记本。在那里,你可以上传你选择的场景图片并训练一个NeRF。例如,你可以建立一个模型来表示你的客厅。🎉🎉
该领域的当前进展
该领域发展迅速,新出版物的数量几乎呈爆炸式增长。在训练和渲染速度方面,VR-NeRF和SMERF展现了非常有前景的结果。我们相信,我们很快就能在边缘设备上实时流式传输真实世界的场景,这是迈向真实*元宇宙*的一大步。然而,NeRF领域的研究不仅关注训练和推理速度,还涵盖了生成式NeRF、姿态估计、可变形NeRF、组合性等多个方向。如果您对精选的NeRF出版物列表感兴趣,请查看Awesome-NeRF。
< > 在 GitHub 上更新