当前位置: 首页 > news >正文

gsplat中的3D Gaussian Splatting as Markov Chain Monte Carlo的代码解读

总体

https://github.com/nerfstudio-project/gsplat

simple_trainer_mcmc.py

2个关键点:

  1. 高斯状态转移(每100iter调用)
  2. 高斯随机过程(每1iter调用)

relocate_gs

  • 对 alive gs 进行采样,被采样的 alive gs 将作为 dead gs 的转移目标。
  • 对被采样的 alive gs 进行状态更新,opacities和scales属性会重新计算。
  • 对 dead gs 进行状态转移。

add_new_gs

  • 对 all gs 进行采样
  • 被采样的 gs 进行状态更新,opacities和scales属性会重新计算
  • 再把被采样的 gs 作为 copy,添加到所有 gs 中。

add_noise_to_gs

  • 根据 学习率 和 opacities 控制噪声的大小
  • 根据 quats 和 scales 控制噪声的分布
  • 得到 delt_xyz 噪声
  • 添加到 gs 的 xyz 属性上

代码AI解读

relocate_gs

(add_new_gs 类似)

    @torch.no_grad()def relocate_gs(self, min_opacity: float = 0.005) -> int:dead_mask = torch.sigmoid(self.splats["opacities"]) <= min_opacitydead_indices = dead_mask.nonzero(as_tuple=True)[0]alive_indices = (~dead_mask).nonzero(as_tuple=True)[0]num_gs = len(dead_indices)if num_gs <= 0:return num_gs# Sample for new GSseps = torch.finfo(torch.float32).epsprobs = torch.sigmoid(self.splats["opacities"])[alive_indices]probs = probs / (probs.sum() + eps)sampled_idxs = torch.multinomial(probs, num_gs, replacement=True) # 进行多项式采样,num_gs 是要重新定位的粒子数量,replacement=True 表示允许重复采样。sampled_idxs = alive_indices[sampled_idxs]new_opacities, new_scales = compute_relocation(opacities=torch.sigmoid(self.splats["opacities"])[sampled_idxs],scales=torch.exp(self.splats["scales"])[sampled_idxs],ratios=torch.bincount(sampled_idxs)[sampled_idxs] + 1, # torch.bincount: 这个函数计算输入张量中每个整数值的出现次数。对于 sampled_idxs,torch.bincount 的输出将是一个包含每个索引出现次数的张量。例如,对于 sampled_idxs = [2, 1, 2, 3, 1],torch.bincount(sampled_idxs) 的输出将是 [0, 2, 2, 1]。这里,0 表示索引 0 没有出现,2 表示索引 1 出现了两次,2 表示索引 2 出现了两次,1 表示索引 3 出现了一次。)new_opacities = torch.clamp(new_opacities, max=1.0 - eps, min=min_opacity)self.splats["opacities"][sampled_idxs] = torch.logit(new_opacities)self.splats["scales"][sampled_idxs] = torch.log(new_scales)# Update splats and optimizersfor k in self.splats.keys():self.splats[k][dead_indices] = self.splats[k][sampled_idxs]for optimizer in self.optimizers:for i, param_group in enumerate(optimizer.param_groups):p = param_group["params"][0]name = param_group["name"]p_state = optimizer.state[p]del optimizer.state[p]for key in p_state.keys():if key != "step":p_state[key][sampled_idxs] = 0p_new = torch.nn.Parameter(self.splats[name])optimizer.param_groups[i]["params"] = [p_new]optimizer.state[p_new] = p_stateself.splats[name] = p_newtorch.cuda.empty_cache()return num_gs

compute_relocation

// Equation (9) in "3D Gaussian Splatting as Markov Chain Monte Carlo"
__global__ void compute_relocation_kernel(int N, float *opacities, float *scales,int *ratios, float *binoms, int n_max,float *new_opacities, float *new_scales) {int idx = threadIdx.x + blockIdx.x * blockDim.x;if (idx >= N)return;int n_idx = ratios[idx];float denom_sum = 0.0f;// compute new opacitynew_opacities[idx] = 1.0f - powf(1.0f - opacities[idx], 1.0f / n_idx);// compute new scalefor (int i = 1; i <= n_idx; ++i) {for (int k = 0; k <= (i - 1); ++k) {float bin_coeff = binoms[(i - 1) * n_max + k];float term = (pow(-1.0f, k) / sqrt(static_cast<float>(k + 1))) *pow(new_opacities[idx], k + 1);denom_sum += (bin_coeff * term);}}float coeff = (opacities[idx] / denom_sum);for (int i = 0; i < 3; ++i)new_scales[idx * 3 + i] = coeff * scales[idx * 3 + i];
}
  1. 计算新的透明度(Opacity)

    • 使用公式 new_opacities[idx]=1.0−(1.0−opacities[idx])1.0/n_idx\text{new\_opacities}[idx] = 1.0 - (1.0 - \text{opacities}[idx])^{1.0 / n\_idx}new_opacities[idx]=1.0(1.0opacities[idx])1.0/n_idx 来计算新的透明度。这个公式是基于论文中的公式 (9) 推导出来的。

  2. 计算新的尺度(Scale)

    • 通过一个嵌套的循环来计算新的尺度。这个过程涉及到二项式系数(binoms)和一些数学运算,包括幂运算和平方根运算。

    • 具体来说,内核函数计算了一个系数 coeff,然后用这个系数来调整原始的尺度值,得到新的尺度值。

add_noise_to_gs

    @torch.no_grad()def add_noise_to_gs(self, last_lr):opacities = torch.sigmoid(self.splats["opacities"])scales = torch.exp(self.splats["scales"])actual_covariance, _ = quat_scale_to_covar_preci(self.splats["quats"],scales,compute_covar=True,compute_preci=False,triu=False,)def op_sigmoid(x, k=100, x0=0.995):return 1 / (1 + torch.exp(-k * (x - x0)))noise = (torch.randn_like(self.splats["means3d"])* (op_sigmoid(1 - opacities)).unsqueeze(-1)* cfg.noise_lr* last_lr)noise = torch.bmm(actual_covariance, noise.unsqueeze(-1)).squeeze(-1)self.splats["means3d"].add_(noise) # 只改变xyz

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python面试题:在 Python 中,如何使用 `functools` 模块?
  • JS常用正则校验大全
  • 算法的时间复杂度(C语言)
  • 什么是 VueQuill(前端的富文本编辑器)?
  • Linux-磁盘空间不足的清理步骤(详细版本)
  • Qt QSettings 使用详解:跨平台的配置管理
  • 【多媒体】Java实现MP4和MP3音视频播放器【JavaFX】【更多功能的播放器】【音视频播放】
  • 基于SpringBoot的网上书城管理系统
  • vue 点击获取元素的css属性
  • @Slf4j idea标红Cannot resolve symbol ‘log‘
  • 【多线程】wait()和notify()
  • 【mybatis】mybatisX插件概述
  • npm证书过期问题
  • uniapp内置组件uni.navigateTo跳转后页面空白问题解决
  • 警钟!电池储能安全事故频发!物联网技术如何加强储能安全排查?
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 【面试系列】之二:关于js原型
  • android图片蒙层
  • Hibernate【inverse和cascade属性】知识要点
  • Java小白进阶笔记(3)-初级面向对象
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • linux学习笔记
  • 日剧·日综资源集合(建议收藏)
  • 使用 QuickBI 搭建酷炫可视化分析
  • 提醒我喝水chrome插件开发指南
  • 微信支付JSAPI,实测!终极方案
  • 优秀架构师必须掌握的架构思维
  • 正则表达式
  • kubernetes资源对象--ingress
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #define、const、typedef的差别
  • #include
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #如何使用 Qt 5.6 在 Android 上启用 NFC
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (9)目标检测_SSD的原理
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (k8s)Kubernetes本地存储接入
  • (Note)C++中的继承方式
  • (二)fiber的基本认识
  • (二)JAVA使用POI操作excel
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (七)Appdesigner-初步入门及常用组件的使用方法说明
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (四)opengl函数加载和错误处理
  • (四)库存超卖案例实战——优化redis分布式锁
  • (五)IO流之ByteArrayInput/OutputStream
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转)Linux下编译安装log4cxx
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .net 反编译_.net反编译的相关问题
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .net的socket示例