探索神经辐射场(NeRF)与可控神经特征场
立即解锁
发布时间: 2025-09-05 01:28:13 阅读量: 2 订阅数: 2 AIGC 

### 探索神经辐射场(NeRF)与可控神经特征场
#### 1. 理解NeRF模型架构
在之前的工作中,我们使用了NeRF模型类,但未深入了解其具体结构。接下来,我们将可视化神经网络的样子,并详细剖析代码,理解其实现方式。
该神经网络以空间位置 $(x, y, z)$ 的谐波嵌入和 $(\theta, \phi)$ 的谐波嵌入作为输入,输出预测密度 $\sigma$ 和预测颜色 $(r, g, b)$。以下是我们要实现的网络架构:

需要注意的是,我们要实现的模型架构与原始NeRF模型架构不同,这里实现的是简化版本,该简化架构能使训练更快、更轻松。
下面我们开始定义 `NeuralRadianceField` 类,并逐步分析该类定义的不同部分。完整的类定义可参考GitHub仓库中的代码。
1. **输入映射**:每个输入点是一个5维向量。直接在该输入上训练模型,在表示颜色和几何形状的高频变化时表现不佳,因为神经网络倾向于学习低频函数。解决此问题的有效方法是将输入空间映射到更高维空间进行训练,该映射函数是一组具有固定但独特频率的正弦函数。
2. **谐波嵌入**:将上述函数应用于输入向量的每个分量:
```python
class NeuralRadianceField(torch.nn.Module):
def __init__(self, n_harmonic_functions=60, n_hidden_neurons=256):
super().__init__()
self.harmonic_embedding = HarmonicEmbedding(n_harmonic_functions)
```
3. **MLP主干网络**:神经网络由一个MLP主干组成,它以位置 $(x, y, z)$ 的嵌入作为输入,是一个全连接网络,使用的激活函数是 `softplus`(`softplus` 是 `ReLU` 激活函数的平滑版本),主干网络的输出是一个大小为 `n_hidden_neurons` 的向量:
```python
embedding_dim = n_harmonic_functions * 2 * 3
self.mlp = torch.nn.Sequential(
torch.nn.Linear(embedding_dim, n_hidden_neurons),
torch.nn.Softplus(beta=10.0),
torch.nn.Linear(n_hidden_neurons, n_hidden_neurons),
torch.nn.Softplus(beta=10.0),
)
```
4. **颜色层**:定义一个颜色层,它将MLP主干的输出嵌入与射线方向输入嵌入相结合,输出输入点的RGB颜色。因为颜色输出强烈依赖于点的位置和观察方向,所以将这些输入结合起来很重要:
```python
self.color_layer = torch.nn.Sequential(
torch.nn.Linear(n_hidden_neurons + embedding_dim, n_hidden_neurons),
torch.nn.Softplus(beta=10.0),
torch.nn.Linear(n_hidden_neurons, 3),
torch.nn.Sigmoid(),
)
```
5. **密度层**:定义密度层,点的密度仅与其位置有关:
```python
self.density_layer = torch.nn.Sequential(
torch.nn.Linear(n_hidden_neurons, 1),
torch.nn.Softplus(beta=10.0),
)
self.density_layer[0].bias.data[0] = -1.5
```
6. **预测原始密度**:定义一个函数,根据密度层的输出预测原始密度:
```python
def _get_densities(self, features):
raw_densities = self.density_layer(features)
return 1 - (-raw_densities).exp()
```
7. **获取颜色**:同样,为了根据射线方向获取某点的颜色,首先对射线方向输入应用位置编码函数,然后将其与MLP主干的输出连接起来:
```python
def _get_colors(self, features, rays_directions):
spatial_size = features.shape[:-1]
rays_directions_normed = torch.nn.functional.normalize(
rays_directions, dim=-1
)
rays_embedding = self.harmonic_embedding(
rays_directions_normed
)
rays_embedding_expand = rays_embedding[..., None, :].expand(
*spatial_size, rays_embedding.shape[
```
0
0
复制全文
相关推荐









