目录
1介绍
2 What is a NeRF?
3 NeRF Architecture
3.1 Positional Encoder
3.2 Radiance Field Function
3.3 可微分体渲染器(Differentiable Volume Renderer)
3.4 Stratified Sampling
3.5 层次体积采样(Hierarchical Volume Sampling)
4 Training
初始化
训练
5 Conclusion
首页 科技周边 人工智能 NeRF是什么?基于NeRF的三维重建是基于体素吗?

NeRF是什么?基于NeRF的三维重建是基于体素吗?

Oct 16, 2023 am 11:33 AM
模型 视觉

1介绍

神经辐射场(NeRF)是深度学习和计算机视觉领域的一个相当新的范式。ECCV 2020论文《NeRF:将场景表示为视图合成的神经辐射场》(该论文获得了最佳论文奖)中介绍了这项技术,该技术自此大受欢迎,迄今已获得近800次引用[1]。该方法标志着机器学习处理3D数据的传统方式发生了巨大变化。

NeRF是什么?基于NeRF的三维重建是基于体素吗?

神经辐射场场景表示和可微分渲染过程:

通过沿着相机射线采样5D坐标(位置和观看方向)来合成图像;将这些位置输入MLP以产生颜色和体积密度;并使用体积渲染技术将这些值合成图像;该渲染函数是可微分的,因此可以通过最小化合成图像和真实观测图像之间的残差来优化场景表示。

2 What is a NeRF?

NeRF是一种生成模型,以图像和精确姿势为条件,生成给定图像的3D场景的新视图,这一过程通常被称为“新视图合成”。不仅如此,它还将场景的3D形状和外观明确定义为连续函数,可以通过marching cubes生成3D网格。尽管它们直接从图像数据中学习,但它们既不使用convolutional层,也不使用transformer层。

多年来,机器学习应用中表示3D数据的方法很多,从3D体素到点云,再到符号距离(signed distance )函数。他们最大的共同缺点是需要预先假设一个3D模型,要么使用摄影测量或激光雷达等工具来生成3D数据,要么手工制作3D模型。然而,许多类型的物体,如高反射物体、“网格状”物体或透明物体,都无法按比例扫描。3D重建方法通常也具有重建误差,这可能导致影响模型精度的阶梯效应或漂移。

相比之下,NeRF基于射线光场的概念。光场是描述光传输如何在整个3D体积中发生的函数。它描述了光线在空间中的每个x=(x,y,z)坐标和每个方向d上移动的方向,描述为θ和ξ角或单位向量。它们共同形成了描述3D场景中的光传输的5D特征空间。受此表示的启发,NeRF试图近似一个函数,该函数从该空间映射到由颜色c=(R,G,B)和浓度(density)σ组成的4D空间,可以将其视为该5D坐标空间处的光线终止的可能性(例如通过遮挡)。因此,标准NeRF是形式F:(x,d)->(c,σ)的函数。

原始的NeRF论文使用多层感知器将该函数参数化,该感知器基于一组姿势已知的图像上训练得到。这是一类称为generalized scene reconstruction的技术中的一种方法,旨在直接从图像集合中描述3D场景。这种方法具备一些非常好的特性:

  • 直接从数据中学习
  • 场景的连续表示允许非常薄和复杂的结构,例如树叶或网格
  • 隐含物理特性,如镜面性和粗糙度
  • 隐式呈现场景中的照明

此后,一系列的改进论文随之涌现,例如,少镜头和单镜头学习[2,3]、对动态场景的支持[4,5]、将光场推广到特征场[6]、从网络上的未校准图像集合中学习[7]、结合激光雷达数据[8]、大规模场景表示[9]、在没有神经网络的情况下学习[10],诸如此类。

3 NeRF Architecture

总体而言,给定一个经过训练的NeRF模型和一个具有已知姿势和图像维度的相机,我们通过以下过程构建场景:

  • 对于每个像素,从相机光心射出光线穿过场景,以在(x,d)位置收集一组样本
  • 使用每个样本的点和视线方向(x,d)作为输入,以产生输出(c,σ)值(rgbσ)
  • 使用经典的体积渲染技术构建图像

光射场(很多文献翻译为"辐射场",但译者认为"光射场"更直观)函数只是几个组件中的一个,一旦组合起来,就可以创建之前看到的视频中的视觉效果。总体而言,本文包括以下几个部分:

  • 位置编码(Positional encoding)
  • 光射场函数近似器(MLP)
  • 可微分体渲染器(Differentiable volume renderer)
  • 分层(Stratified)取样层次(Hierarchical)体积采样

为了最大限度地清晰讲述,本文将每个组件的关键元素以尽可能简洁的代码展示。参考了bmild的原始实现和yenchenlin和krrish94的PyTorch实现。

3.1 Positional Encoder

就像2017年推出的transformer模型[11]一样,NeRF也受益于位置编码器作为其输入。它使用高频函数将其连续输入映射到更高维的空间,以帮助模型学习数据中的高频变化,从而产生更清晰的模型。这种方法避开(circumvent)了神经网络对低频函数偏置(bias),使NeRF能够表示更清晰的细节。作者参考了ICML 2019上的一篇论文[12]。

如果熟悉transformerd的位置编码,NeRF的相关实现是很标准的,它具有相同的交替正弦和余弦表达式。位置编码器实现:

# pyclass PositionalEncoder(nn.Module):# sine-cosine positional encoder for input points.def __init__( self,d_input: int,n_freqs: int,log_space: bool = False ):super().__init__()self.d_input = d_inputself.n_freqs = n_freqs # 是不是视线上的采样频率?self.log_space = log_spaceself.d_output = d_input * (1 + 2 * self.n_freqs)self.embed_fns = [lambda x: x] # 冒号前面的x表示函数参数,后面的表示匿名函数运算# Define frequencies in either linear or log scaleif self.log_space:freq_bands = 2.**torch.linspace(0., self.n_freqs - 1, self.n_freqs)else:freq_bands = torch.linspace(2.**0., 2.**(self.n_freqs - 1), self.n_freqs)# Alternate sin and cosfor freq in freq_bands:self.embed_fns.append(lambda x, freq=freq: torch.sin(x * freq))self.embed_fns.append(lambda x, freq=freq: torch.cos(x * freq))def forward(self, x) -> torch.Tensor:# Apply positional encoding to input.return torch.concat([fn(x) for fn in self.embed_fns], dim=-1)
登录后复制

思考:这个位置编码,是对输入点(input points)进行编码,这个输入点是视线上的采样点?还是不同的视角位置点?self.n_freqs是不是视线上的采样频率?由此理解,应该就是视线上的采样位置,因为如果不对视线上的采样位置进行编码,就无法有效表示这些位置,也就无法对它们的RGBA进行训练。

3.2 Radiance Field Function

在原文中,光射场函数由NeRF模型表示,NeRF模型是一种典型的多层感知器,以编码的3D点和视角方向作为输入,并返回RGBA值作为输出。虽然本文使用的是神经网络,但这里可以使用任何函数逼近器(function approximator)。例如,Yu等人的后续论文Plenoxels使用球面谐波(spherical harmonics)实现了数量级的更快训练,同时获得有竞争力的结果[10]。

NeRF是什么?基于NeRF的三维重建是基于体素吗?图片

NeRF模型有8层深,大多数层的特征维度为256。剩余的连接被放置在层4处。在这些层之后,产生RGB和σ值。RGB值用线性层进一步处理,然后与视线方向连接,然后通过另一个线性层,最后在输出处与σ重新组合。NeRF模型的PyTorch模块实现:

class NeRF(nn.Module):# Neural radiance fields module.def __init__( self,d_input: int = 3,n_layers: int = 8,d_filter: int = 256,skip: Tuple[int] = (4,), # (4,)只有一个元素4的元组 d_viewdirs: Optional[int] = None): super().__init__()self.d_input = d_input# 这里是3D XYZ,?self.skip = skip# 是要跳过什么?为啥要跳过?被遮挡?self.act = nn.functional.reluself.d_viewdirs = d_viewdirs# d_viewdirs 是2D方向?# Create model layers# [if_true 就执行的指令] if [if_true条件] else [if_false]# 是否skip的区别是,训练输入维度是否多3维,# if i in skip =if i in (4,),似乎是判断i是否等于4# self.d_input=3 :如果层id=4,网络输入要加3维,这是为什么?第4层有何特殊的?self.layers = nn.ModuleList([nn.Linear(self.d_input, d_filter)] +[nn.Linear(d_filter + self.d_input, d_filter) if i in skip else \ nn.Linear(d_filter, d_filter) for i in range(n_layers - 1)])# Bottleneck layersif self.d_viewdirs is not None:# If using viewdirs, split alpha and RGBself.alpha_out = nn.Linear(d_filter, 1)self.rgb_filters = nn.Linear(d_filter, d_filter)self.branch = nn.Linear(d_filter + self.d_viewdirs, d_filter // 2)self.output = nn.Linear(d_filter // 2, 3) # 为啥要取一半?else:# If no viewdirs, use simpler outputself.output = nn.Linear(d_filter, 4) # d_filter=256,输出是4维RGBAdef forward(self,x: torch.Tensor, # ?viewdirs: Optional[torch.Tensor] = None) -> torch.Tensor: # Forward pass with optional view direction.if self.d_viewdirs is None and viewdirs is not None:raise ValueError('Cannot input x_direction')# Apply forward pass up to bottleneckx_input = x# 这里的x是几维?从下面的分离RGB和A看,应该是4D# 下面通过8层MLP训练RGBAfor i, layer in enumerate(self.layers):# 8层,每一层进行运算x = self.act(layer(x)) if i in self.skip:x = torch.cat([x, x_input], dim=-1)# Apply bottleneckbottleneck 瓶颈是啥?是不是最费算力的模块?if self.d_viewdirs is not None:# 从网络输出分离A,RGB还需要经过更多训练alpha = self.alpha_out(x)# Pass through bottleneck to get RGBx = self.rgb_filters(x) x = torch.concat([x, viewdirs], dim=-1)x = self.act(self.branch(x)) # self.branch shape: (d_filter // 2)x = self.output(x) # self.output shape: (3)# Concatenate alphas to outputx = torch.concat([x, alpha], dim=-1)else:# Simple outputx = self.output(x)return x
登录后复制

思考:这个NERF类的输入输出是什么?通过这个类发生了啥?从__init__函数参数看出,主要是对神经网络的输入、层次和维度等进行设置,输入了5D数据,也就是视点位置和视线方向,输出的是RGBA。问题,这个输出的RGBA是一个点的?还是视线上一串的?如果是一串的,没有看到位置编码如何确定每个采样点的RGBA?

也没看到采样间隔之类的说明;如果是一个点,那这个RGBA是视线上哪个点的?是不是眼睛看到的视线采样点集合成后的点RGBA?从NERF类代码可以看出,主要是根据视点位置和视线方向进行了多层前馈训练,输入5D的视点位置和视线方向,输出4D的RGBA。

3.3 可微分体渲染器(Differentiable Volume Renderer)

RGBA输出点位于3D空间中,因此要将它们合成图像,需要应用论文第4节中方程1-3中描述的体积积分。本质上,沿着每个像素的视线对所有样本进行加权求和,以获得该像素的估计颜色值。每个RGB采样都按其透明度alpha值进行加权:α值越高,表示采样区域不透明的可能性越高,因此沿射线更远的点更有可能被遮挡。累积乘积运算确保了这些进一步的点被抑制。

原始NeRF模型输出的体绘制:

def raw2outputs(raw: torch.Tensor,z_vals: torch.Tensor,rays_d: torch.Tensor,raw_noise_std: float = 0.0,white_bkgd: bool = False) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:# 将原始的NeRF输出转为RGB和其他映射# Difference between consecutive elements of `z_vals`. [n_rays, n_samples]dists = z_vals[..., 1:] - z_vals[..., :-1]# ?这里减法的意义是啥?dists = torch.cat([dists, 1e10 * torch.ones_like(dists[..., :1])], dim=-1)# 将每个距离乘以其对应方向光线的范数,以转换为真实世界的距离(考虑非单位方向)dists = dists * torch.norm(rays_d[..., None, :], dim=-1)# 将噪声添加到模型对密度的预测中,用于在训练期间规范网络(防止漂浮物伪影)noise = 0.if raw_noise_std > 0.:noise = torch.randn(raw[..., 3].shape) * raw_noise_std# Predict density of each sample along each ray. Higher values imply# higher likelihood of being absorbed at this point. [n_rays, n_samples]alpha = 1.0 - torch.exp(-nn.functional.relu(raw[..., 3] + noise) * dists)# Compute weight for RGB of each sample along each ray. [n_rays, n_samples]# The higher the alpha, the lower subsequent weights are driven.weights = alpha * cumprod_exclusive(1. - alpha + 1e-10)# Compute weighted RGB map.rgb = torch.sigmoid(raw[..., :3])# [n_rays, n_samples, 3]rgb_map = torch.sum(weights[..., None] * rgb, dim=-2)# [n_rays, 3]# Estimated depth map is predicted distance.depth_map = torch.sum(weights * z_vals, dim=-1)# Disparity map is inverse depth.disp_map = 1. / torch.max(1e-10 * torch.ones_like(depth_map),depth_map / torch.sum(weights, -1))# Sum of weights along each ray. In [0, 1] up to numerical error.acc_map = torch.sum(weights, dim=-1)# To composite onto a white background, use the accumulated alpha map.if white_bkgd:rgb_map = rgb_map + (1. - acc_map[..., None])return rgb_map, depth_map, acc_map, weightsdef cumprod_exclusive(tensor: torch.Tensor) -> torch.Tensor:# (Courtesy of https://github.com/krrish94/nerf-pytorch)# Compute regular cumprod first.cumprod = torch.cumprod(tensor, -1)# "Roll" the elements along dimension 'dim' by 1 element.cumprod = torch.roll(cumprod, 1, -1)# Replace the first element by "1" as this is what tf.cumprod(..., exclusive=True) does.cumprod[..., 0] = 1.return cumprod
登录后复制

问题:这里的主要功能是啥?输入了什么?输出了什么?

3.4 Stratified Sampling

相机最终拾取到的RGB值是沿着穿过该像素视线的光样本的累积,经典的体积渲染方法是沿着该视线累积点,然后对点进行积分,在每个点估计光线在不撞击任何粒子的情况下射行的概率。因此,每个像素都需要沿着穿过它的光线对点进行采样。为了最好地近似积分,他们的分层采样方法是将空间均匀地划分为N个仓(bins),并从每个仓中均匀地抽取一个样本。stratified sampling方法不是简单地以相等的间隔绘制样本,而是允许模型在连续空间中采样,从而调节网络在连续空间上学习。

NeRF是什么?基于NeRF的三维重建是基于体素吗?图片

分层采样PyTorch中实现:

def sample_stratified(rays_o: torch.Tensor,rays_d: torch.Tensor,near: float,far: float,n_samples: int,perturb: Optional[bool] = True,inverse_depth: bool = False) -> Tuple[torch.Tensor, torch.Tensor]:# Sample along ray from regularly-spaced bins.# Grab samples for space integration along rayt_vals = torch.linspace(0., 1., n_samples, device=rays_o.device)if not inverse_depth:# Sample linearly between `near` and `far`z_vals = near * (1.-t_vals) + far * (t_vals)else:# Sample linearly in inverse depth (disparity)z_vals = 1./(1./near * (1.-t_vals) + 1./far * (t_vals))# Draw uniform samples from bins along rayif perturb:mids = .5 * (z_vals[1:] + z_vals[:-1])upper = torch.concat([mids, z_vals[-1:]], dim=-1)lower = torch.concat([z_vals[:1], mids], dim=-1)t_rand = torch.rand([n_samples], device=z_vals.device)z_vals = lower + (upper - lower) * t_randz_vals = z_vals.expand(list(rays_o.shape[:-1]) + [n_samples])# Apply scale from `rays_d` and offset from `rays_o` to samples# pts: (width, height, n_samples, 3)pts = rays_o[..., None, :] + rays_d[..., None, :] * z_vals[..., :, None]return pts, z_vals
登录后复制

3.5 层次体积采样(Hierarchical Volume Sampling)

辐射场由两个多层感知器表示:一个是在粗略级别上操作,对场景的广泛结构属性进行编码;另一个是在精细的层面上细化细节,从而实现网格和分支等薄而复杂的结构。此外,他们接收的样本是不同的,粗模型在整个射线中处理宽的、大多是规则间隔的样本,而精细模型在具有强先验的区域中珩磨(honing in)以获得显著信息。

这种“珩磨”过程是通过层次体积采样流程完成的。3D空间实际上非常稀疏,存在遮挡,因此大多数点对渲染图像的贡献不大。因此,对具有对积分贡献可能性高的区域进行过采样(oversample)更有好处。他们将学习到的归一化权重应用于第一组样本,以在光线上创建PDF,然后再将inverse transform sampling应用于该PDF以收集第二组样本。该集合与第一集合相结合,并被馈送到精细网络以产生最终输出。

NeRF是什么?基于NeRF的三维重建是基于体素吗?

分层采样PyTorch实现:

def sample_hierarchical(rays_o: torch.Tensor,rays_d: torch.Tensor,z_vals: torch.Tensor,weights: torch.Tensor,n_samples: int,perturb: bool = False) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:# Apply hierarchical sampling to the rays.# Draw samples from PDF using z_vals as bins and weights as probabilities.z_vals_mid = .5 * (z_vals[..., 1:] + z_vals[..., :-1])new_z_samples = sample_pdf(z_vals_mid, weights[..., 1:-1], n_samples, perturb=perturb)new_z_samples = new_z_samples.detach()# Resample points from ray based on PDF.z_vals_combined, _ = torch.sort(torch.cat([z_vals, new_z_samples], dim=-1), dim=-1)# [N_rays, N_samples + n_samples, 3]pts = rays_o[..., None, :] + rays_d[..., None, :] * z_vals_combined[..., :, None]return pts, z_vals_combined, new_z_samplesdef sample_pdf(bins: torch.Tensor, weights: torch.Tensor, n_samples: int, perturb: bool = False) -> torch.Tensor:# Apply inverse transform sampling to a weighted set of points.# Normalize weights to get PDF.# [n_rays, weights.shape[-1]]pdf = (weights + 1e-5) / torch.sum(weights + 1e-5, -1, keepdims=True) # Convert PDF to CDF.cdf = torch.cumsum(pdf, dim=-1) # [n_rays, weights.shape[-1]]# [n_rays, weights.shape[-1] + 1]cdf = torch.concat([torch.zeros_like(cdf[..., :1]), cdf], dim=-1) # Take sample positions to grab from CDF. Linear when perturb == 0.if not perturb:u = torch.linspace(0., 1., n_samples, device=cdf.device)u = u.expand(list(cdf.shape[:-1]) + [n_samples]) # [n_rays, n_samples]else:# [n_rays, n_samples]u = torch.rand(list(cdf.shape[:-1]) + [n_samples], device=cdf.device) # Find indices along CDF where values in u would be placed.u = u.contiguous() # Returns contiguous tensor with same values.inds = torch.searchsorted(cdf, u, right=True) # [n_rays, n_samples]# Clamp indices that are out of bounds.below = torch.clamp(inds - 1, min=0)above = torch.clamp(inds, max=cdf.shape[-1] - 1)inds_g = torch.stack([below, above], dim=-1) # [n_rays, n_samples, 2]# Sample from cdf and the corresponding bin centers.matched_shape = list(inds_g.shape[:-1]) + [cdf.shape[-1]]cdf_g = torch.gather(cdf.unsqueeze(-2).expand(matched_shape), dim=-1,index=inds_g)bins_g = torch.gather(bins.unsqueeze(-2).expand(matched_shape), dim=-1, index=inds_g)# Convert samples to ray length.denom = (cdf_g[..., 1] - cdf_g[..., 0])denom = torch.where(denom <h3 id="Training">4 Training</h3><p>论文中训练NeRF推荐的每网络8层、每层256维的架构在训练过程中会消耗大量内存。缓解这种情况的方法是将前传(forward pass)分成更小的部分,然后在这些部分上积累梯度。注意与minibatching的区别:梯度是在采样光线的单个小批次上累积的,这些光线可能已经被收集成块。如果没有论文中使用的NVIDIA V100类似性能的GPU,可能必须相应地调整块大小以避免OOM错误。Colab笔记本采用了更小的架构和更适中的分块尺寸。</p><p>我个人发现,由于局部极小值,即使选择了许多默认值,NeRF的训练也有些棘手。一些有帮助的技术包括早期训练迭代和早期重新启动期间的中心裁剪(center cropping)。随意尝试不同的超参数和技术,以进一步提高训练收敛性。</p><h4 id="初始化">初始化</h4><pre class="brush:php;toolbar:false">def init_models():# Initialize models, encoders, and optimizer for NeRF training.encoder = PositionalEncoder(d_input, n_freqs, log_space=log_space)encode = lambda x: encoder(x)# View direction encodersif use_viewdirs:encoder_viewdirs = PositionalEncoder(d_input, n_freqs_views,log_space=log_space)encode_viewdirs= lambda x: encoder_viewdirs(x)d_viewdirs = encoder_viewdirs.d_outputelse:encode_viewdirs = Noned_viewdirs = Nonemodel = NeRF(encoder.d_output,  n_layers=n_layers,  d_filter=d_filter, skip=skip,d_viewdirs=d_viewdirs)model.to(device)model_params = list(model.parameters())if use_fine_model:fine_model = NeRF(encoder.d_output, n_layers=n_layers, d_filter=d_filter, skip=skip,d_viewdirs=d_viewdirs)fine_model.to(device)model_params = model_params + list(fine_model.parameters())else:fine_model = Noneoptimizer= torch.optim.Adam(model_params, lr=lr)warmup_stopper = EarlyStopping(patience=50)return model, fine_model, encode, encode_viewdirs, optimizer, warmup_stopper
登录后复制

训练

def train():# Launch training session for NeRF.# Shuffle rays across all images.if not one_image_per_step:height, width = images.shape[1:3]all_rays = torch.stack([torch.stack(get_rays(height, width, focal, p), 0) for p in poses[:n_training]], 0)rays_rgb = torch.cat([all_rays, images[:, None]], 1)rays_rgb = torch.permute(rays_rgb, [0, 2, 3, 1, 4])rays_rgb = rays_rgb.reshape([-1, 3, 3])rays_rgb = rays_rgb.type(torch.float32)rays_rgb = rays_rgb[torch.randperm(rays_rgb.shape[0])]i_batch = 0train_psnrs = []val_psnrs = []iternums = []for i in trange(n_iters):model.train()if one_image_per_step:# Randomly pick an image as the target.target_img_idx = np.random.randint(images.shape[0])target_img = images[target_img_idx].to(device)if center_crop and i = rays_rgb.shape[0]:rays_rgb = rays_rgb[torch.randperm(rays_rgb.shape[0])]i_batch = 0target_img = target_img.reshape([-1, 3])# Run one iteration of TinyNeRF and get the rendered RGB image.outputs = nerf_forward(rays_o, rays_d, near, far, encode, model, kwargs_sample_stratified=kwargs_sample_stratified, n_samples_hierarchical=n_samples_hierarchical, kwargs_sample_hierarchical=kwargs_sample_hierarchical, fine_model=fine_model, viewdirs_encoding_fn=encode_viewdirs, chunksize=chunksize)# Backprop!rgb_predicted = outputs['rgb_map']loss = torch.nn.functional.mse_loss(rgb_predicted, target_img)loss.backward()optimizer.step()optimizer.zero_grad()psnr = -10. * torch.log10(loss)train_psnrs.append(psnr.item())# Evaluate testimg at given display rate.if i % display_rate == 0:model.eval()height, width = testimg.shape[:2]rays_o, rays_d = get_rays(height, width, focal, testpose)rays_o = rays_o.reshape([-1, 3])rays_d = rays_d.reshape([-1, 3])outputs = nerf_forward(rays_o, rays_d, near, far, encode, model, kwargs_sample_stratified=kwargs_sample_stratified, n_samples_hierarchical=n_samples_hierarchical, kwargs_sample_hierarchical=kwargs_sample_hierarchical, fine_model=fine_model, viewdirs_encoding_fn=encode_viewdirs, chunksize=chunksize)rgb_predicted = outputs['rgb_map']loss = torch.nn.functional.mse_loss(rgb_predicted, testimg.reshape(-1, 3))val_psnr = -10. * torch.log10(loss)val_psnrs.append(val_psnr.item())iternums.append(i)# Check PSNR for issues and stop if any are found.if i == warmup_iters - 1:if val_psnr <h4 id="训练">训练</h4><pre class="brush:php;toolbar:false"># Run training session(s)for _ in range(n_restarts):model, fine_model, encode, encode_viewdirs, optimizer, warmup_stopper = init_models()success, train_psnrs, val_psnrs = train()if success and val_psnrs[-1] >= warmup_min_fitness:print('Training successful!')breakprint(f'Done!')
登录后复制

5 Conclusion

辐射场标志着处理3D数据的方式发生了巨大变化。NeRF模型和更广泛的可微分渲染正在迅速弥合图像创建和体积场景创建之间的差距。虽然我们的组件可能看起来非常复杂,但受vanilla NeRF启发的无数其他方法证明,基本概念(连续函数逼近器+可微分渲染器)是构建各种解决方案的坚实基础,这些解决方案可用于几乎无限的情况。

原文:NeRF From Nothing: A Tutorial with PyTorch | Towards Data Science

原文链接:https://mp.weixin.qq.com/s/zxJAIpAmLgsIuTsPqQqOVg

以上是NeRF是什么?基于NeRF的三维重建是基于体素吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

全球最强开源 MoE 模型来了,中文能力比肩 GPT-4,价格仅为 GPT-4-Turbo 的近百分之一 全球最强开源 MoE 模型来了,中文能力比肩 GPT-4,价格仅为 GPT-4-Turbo 的近百分之一 May 07, 2024 pm 04:13 PM

想象一下,一个人工智能模型,不仅拥有超越传统计算的能力,还能以更低的成本实现更高效的性能。这不是科幻,DeepSeek-V2[1],全球最强开源MoE模型来了。DeepSeek-V2是一个强大的专家混合(MoE)语言模型,具有训练经济、推理高效的特点。它由236B个参数组成,其中21B个参数用于激活每个标记。与DeepSeek67B相比,DeepSeek-V2性能更强,同时节省了42.5%的训练成本,减少了93.3%的KV缓存,最大生成吞吐量提高到5.76倍。DeepSeek是一家探索通用人工智

超越ORB-SLAM3!SL-SLAM:低光、严重抖动和弱纹理场景全搞定 超越ORB-SLAM3!SL-SLAM:低光、严重抖动和弱纹理场景全搞定 May 30, 2024 am 09:35 AM

写在前面今天我们探讨下深度学习技术如何改善在复杂环境中基于视觉的SLAM(同时定位与地图构建)性能。通过将深度特征提取和深度匹配方法相结合,这里介绍了一种多功能的混合视觉SLAM系统,旨在提高在诸如低光条件、动态光照、弱纹理区域和严重抖动等挑战性场景中的适应性。我们的系统支持多种模式,包括拓展单目、立体、单目-惯性以及立体-惯性配置。除此之外,还分析了如何将视觉SLAM与深度学习方法相结合,以启发其他研究。通过在公共数据集和自采样数据上的广泛实验,展示了SL-SLAM在定位精度和跟踪鲁棒性方面优

替代MLP的KAN,被开源项目扩展到卷积了 替代MLP的KAN,被开源项目扩展到卷积了 Jun 01, 2024 pm 10:03 PM

本月初,来自MIT等机构的研究者提出了一种非常有潜力的MLP替代方法——KAN。KAN在准确性和可解释性方面表现优于MLP。而且它能以非常少的参数量胜过以更大参数量运行的MLP。比如,作者表示,他们用KAN以更小的网络和更高的自动化程度重现了DeepMind的结果。具体来说,DeepMind的MLP有大约300,000个参数,而KAN只有约200个参数。KAN与MLP一样具有强大的数学基础,MLP基于通用逼近定理,而KAN基于Kolmogorov-Arnold表示定理。如下图所示,KAN在边上具

你好,电动Atlas!波士顿动力机器人复活,180度诡异动作吓坏马斯克 你好,电动Atlas!波士顿动力机器人复活,180度诡异动作吓坏马斯克 Apr 18, 2024 pm 07:58 PM

波士顿动力Atlas,正式进入电动机器人时代!昨天,液压Atlas刚刚「含泪」退出历史舞台,今天波士顿动力就宣布:电动Atlas上岗。看来,在商用人形机器人领域,波士顿动力是下定决心要和特斯拉硬刚一把了。新视频放出后,短短十几小时内,就已经有一百多万观看。旧人离去,新角色登场,这是历史的必然。毫无疑问,今年是人形机器人的爆发年。网友锐评:机器人的进步,让今年看起来像人类的开幕式动作、自由度远超人类,但这真不是恐怖片?视频一开始,Atlas平静地躺在地上,看起来应该是仰面朝天。接下来,让人惊掉下巴

谷歌狂喜:JAX性能超越Pytorch、TensorFlow!或成GPU推理训练最快选择 谷歌狂喜:JAX性能超越Pytorch、TensorFlow!或成GPU推理训练最快选择 Apr 01, 2024 pm 07:46 PM

谷歌力推的JAX在最近的基准测试中性能已经超过Pytorch和TensorFlow,7项指标排名第一。而且测试并不是在JAX性能表现最好的TPU上完成的。虽然现在在开发者中,Pytorch依然比Tensorflow更受欢迎。但未来,也许有更多的大模型会基于JAX平台进行训练和运行。模型最近,Keras团队为三个后端(TensorFlow、JAX、PyTorch)与原生PyTorch实现以及搭配TensorFlow的Keras2进行了基准测试。首先,他们为生成式和非生成式人工智能任务选择了一组主流

AI颠覆数学研究!菲尔兹奖得主、华裔数学家领衔11篇顶刊论文|陶哲轩转赞 AI颠覆数学研究!菲尔兹奖得主、华裔数学家领衔11篇顶刊论文|陶哲轩转赞 Apr 09, 2024 am 11:52 AM

AI,的确正在改变数学。最近,一直十分关注这个议题的陶哲轩,转发了最近一期的《美国数学学会通报》(BulletinoftheAmericanMathematicalSociety)。围绕「机器会改变数学吗?」这个话题,众多数学家发表了自己的观点,全程火花四射,内容硬核,精彩纷呈。作者阵容强大,包括菲尔兹奖得主AkshayVenkatesh、华裔数学家郑乐隽、纽大计算机科学家ErnestDavis等多位业界知名学者。AI的世界已经发生了天翻地覆的变化,要知道,其中很多文章是在一年前提交的,而在这一

FisheyeDetNet:首个基于鱼眼相机的目标检测算法 FisheyeDetNet:首个基于鱼眼相机的目标检测算法 Apr 26, 2024 am 11:37 AM

目标检测在自动驾驶系统当中是一个比较成熟的问题,其中行人检测是最早得以部署算法之一。在多数论文当中已经进行了非常全面的研究。然而,利用鱼眼相机进行环视的距离感知相对来说研究较少。由于径向畸变大,标准的边界框表示在鱼眼相机当中很难实施。为了缓解上述描述,我们探索了扩展边界框、椭圆、通用多边形设计为极坐标/角度表示,并定义一个实例分割mIOU度量来分析这些表示。所提出的具有多边形形状的模型fisheyeDetNet优于其他模型,并同时在用于自动驾驶的Valeo鱼眼相机数据集上实现了49.5%的mAP

特斯拉机器人进厂打工,马斯克:手的自由度今年将达到22个! 特斯拉机器人进厂打工,马斯克:手的自由度今年将达到22个! May 06, 2024 pm 04:13 PM

特斯拉机器人Optimus最新视频出炉,已经可以在厂子里打工了。正常速度下,它分拣电池(特斯拉的4680电池)是这样的:官方还放出了20倍速下的样子——在小小的“工位”上,拣啊拣啊拣:这次放出的视频亮点之一在于Optimus在厂子里完成这项工作,是完全自主的,全程没有人为的干预。并且在Optimus的视角之下,它还可以把放歪了的电池重新捡起来放置,主打一个自动纠错:对于Optimus的手,英伟达科学家JimFan给出了高度的评价:Optimus的手是全球五指机器人里最灵巧的之一。它的手不仅有触觉

See all articles