三维点云深度网络 PointNeXt 源码阅读 (IV) —— PointNeXt-B

news2024/9/24 3:27:31

Title: 三维点云深度网络 PointNeXt 源码阅读 (IV) —— PointNeXt-B


文章目录

  • I. PointNeXt-B 与其他版本的区别
  • II. PointNeXt-B 自动生成的网络
  • III. PointNeXt-B 编码部分的结构
  • IV. 显存溢出的规避
  • 总结


关联博文
[1] 三维点云深度网络 PointNeXt 的安装配置与测试

[2] 三维点云深度网络 PointNeXt 源码阅读 (I) —— 注册机制与参数解析

[3] 三维点云深度网络 PointNeXt 源码阅读 (II) —— 点云数据集构造与预处理

[4] 三维点云深度网络 PointNeXt 源码阅读 (III) —— 骨干网络模型

[5] 三维点云深度网络 PointNeXt 源码阅读 (IV) —— PointNeXt-B ⇐ \qquad \Leftarrow 本篇


本篇博文只是前面博文的补充, 做个记录.

感谢原作者 Guocheng Qian 开源 PointNeXt 供我们学习 !


I. PointNeXt-B 与其他版本的区别

前面的博文都是针对 PointNeXt-S 版本网络, 该版本网络是 PointNeXt 系列网络模型中最简单的一种.

而 PointNeXt 中第二简单的 PointNeXt-B 相对于 PointNeXt-S 的最主要区别在于 “是否调用 InvResMLP 模块”, 及 “SetAbstraction 模块中是否使用残差”.

所谓 “InvResMLP” 是指 “inverted bottleneck design + Residual MLP”.

因为 InvResMLP 本身自带残差计算, 所以当编码器 encoder[i] 中附加了 InvResMLP 模块时, 该编码器中的 SetAbstraction 内部就不再需要残差结构了.

PointNeXt-B 中解码器 decoder[i]、head 等部分和 PointNeXt-S 中没有区别.

PointNeXt 中更复杂的网络模型, 如 PointNeXt-L 和 PointNeXt-XL, 比起 PointNeXt-B 只是在编码部分四个阶段中累加 InvResMLP 模块数量的区别.


II. PointNeXt-B 自动生成的网络

自动构建的 PointNeXt-B 网络模型如下.

BaseSeg(
  (encoder): PointNextEncoder(
    (encoder): Sequential(
      (0): Sequential(
        (0): SetAbstraction(
          (convs): Sequential(
            (0): Sequential(
              (0): Conv1d(4, 32, kernel_size=(1,), stride=(1,))
            )
          )
        )
      )
      (1): Sequential(
        (0): SetAbstraction(
          (convs): Sequential(
            (0): Sequential(
              (0): Conv2d(35, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
          )
          (grouper): QueryAndGroup()
        )
        (1): InvResMLP(
          (convs): LocalAggregation(
            (convs): Sequential(
              (0): Sequential(
                (0): Conv2d(67, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
                (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
                (2): ReLU(inplace=True)
              )
            )
            (grouper): QueryAndGroup()
          )
          (pwconv): Sequential(
            (0): Sequential(
              (0): Conv1d(64, 256, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
            (1): Sequential(
              (0): Conv1d(256, 64, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
            )
          )
          (act): ReLU(inplace=True)
        )
      )
      (2): Sequential(
        (0): SetAbstraction(
          (convs): Sequential(
            (0): Sequential(
              (0): Conv2d(67, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
          )
          (grouper): QueryAndGroup()
        )
        (1): InvResMLP(
          (convs): LocalAggregation(
            (convs): Sequential(
              (0): Sequential(
                (0): Conv2d(131, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
                (2): ReLU(inplace=True)
              )
            )
            (grouper): QueryAndGroup()
          )
          (pwconv): Sequential(
            (0): Sequential(
              (0): Conv1d(128, 512, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
            (1): Sequential(
              (0): Conv1d(512, 128, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
            )
          )
          (act): ReLU(inplace=True)
        )
        (2): InvResMLP(
          (convs): LocalAggregation(
            (convs): Sequential(
              (0): Sequential(
                (0): Conv2d(131, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
                (2): ReLU(inplace=True)
              )
            )
            (grouper): QueryAndGroup()
          )
          (pwconv): Sequential(
            (0): Sequential(
              (0): Conv1d(128, 512, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
            (1): Sequential(
              (0): Conv1d(512, 128, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
            )
          )
          (act): ReLU(inplace=True)
        )
      )
      (3): Sequential(
        (0): SetAbstraction(
          (convs): Sequential(
            (0): Sequential(
              (0): Conv2d(131, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
          )
          (grouper): QueryAndGroup()
        )
        (1): InvResMLP(
          (convs): LocalAggregation(
            (convs): Sequential(
              (0): Sequential(
                (0): Conv2d(259, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
                (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
                (2): ReLU(inplace=True)
              )
            )
            (grouper): QueryAndGroup()
          )
          (pwconv): Sequential(
            (0): Sequential(
              (0): Conv1d(256, 1024, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
            (1): Sequential(
              (0): Conv1d(1024, 256, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
            )
          )
          (act): ReLU(inplace=True)
        )
      )
      (4): Sequential(
        (0): SetAbstraction(
          (convs): Sequential(
            (0): Sequential(
              (0): Conv2d(259, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
          )
          (grouper): QueryAndGroup()
        )
        (1): InvResMLP(
          (convs): LocalAggregation(
            (convs): Sequential(
              (0): Sequential(
                (0): Conv2d(515, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
                (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
                (2): ReLU(inplace=True)
              )
            )
            (grouper): QueryAndGroup()
          )
          (pwconv): Sequential(
            (0): Sequential(
              (0): Conv1d(512, 2048, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
            (1): Sequential(
              (0): Conv1d(2048, 512, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
            )
          )
          (act): ReLU(inplace=True)
        )
      )
    )
  )
  (decoder): PointNextDecoder(
    (decoder): Sequential(
      (0): Sequential(
        (0): FeaturePropogation(
          (convs): Sequential(
            (0): Sequential(
              (0): Conv1d(96, 32, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
            (1): Sequential(
              (0): Conv1d(32, 32, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
          )
        )
      )
      (1): Sequential(
        (0): FeaturePropogation(
          (convs): Sequential(
            (0): Sequential(
              (0): Conv1d(192, 64, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
            (1): Sequential(
              (0): Conv1d(64, 64, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
          )
        )
      )
      (2): Sequential(
        (0): FeaturePropogation(
          (convs): Sequential(
            (0): Sequential(
              (0): Conv1d(384, 128, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
            (1): Sequential(
              (0): Conv1d(128, 128, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
          )
        )
      )
      (3): Sequential(
        (0): FeaturePropogation(
          (convs): Sequential(
            (0): Sequential(
              (0): Conv1d(768, 256, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
            (1): Sequential(
              (0): Conv1d(256, 256, kernel_size=(1,), stride=(1,), bias=False)
              (1): BatchNorm1d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): ReLU(inplace=True)
            )
          )
        )
      )
    )
  )
  (head): SegHead(
    (head): Sequential(
      (0): Sequential(
        (0): Conv1d(32, 32, kernel_size=(1,), stride=(1,), bias=False)
        (1): BatchNorm1d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): ReLU(inplace=True)
      )
      (1): Dropout(p=0.5, inplace=False)
      (2): Sequential(
        (0): Conv1d(32, 13, kernel_size=(1,), stride=(1,))
      )
    )
  )
)

III. PointNeXt-B 编码部分的结构

直接看图比较清晰, 重点是对 InvResMLP 的理解.

encoder_in_PointNeXt-B

IV. 显存溢出的规避

为了避免 “RuntimeError: CUDA out of memory” 显存溢出问题, 先可以将 cfgs/s3dis/default.yaml 中配置的 batch_size 改小一半为 16.

然后, 通过 vpdb 配置 vscode 调试环境

vpdb CUDA_VISIBLE_DEVICES=0,1 python examples/segmentation/main.py --cfg cfgs/s3dis/pointnext-b.yaml  mode=train

就可以开启 debug 模式了.


总结

到此我们对 PointNeXt 模型的构建和结构有了基本理解.


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2046577.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring IOC 小演示

首先建项目&#xff0c;可参考 https://blog.csdn.net/2303_79008526/article/details/141141114?spm1001.2014.3001.5502 一、spring 环境搭建 &#xff08;一&#xff09;导相关坐标 <?xml version"1.0" encoding"UTF-8"?> <project xmln…

高通AI-让AI触手可及

生成式AI模型&#xff0c;例如大语言模型和大视觉模型&#xff0c;需要大量的计算资源进行推理&#xff0c;这对于传统的CPU和GPU等通用处理器来说是一个挑战。 1 NPU和异构计算的优势 NPU (神经网络处理器): 专门为AI推理设计的处理器&#xff0c;具有高性能、低功耗的特点&…

Eval绕过限制参数限制

PHP Eval函数参数限制在16个字符 PHP代码 <?php$param $_REQUEST[param]; if (strlen($param) < 17 && stripos($param, eval) false && stripos($param, assert) false){eval($param);}?># 部署环境属于ubuntu系统 通过GET传参绕过 由于是…

贪吃蛇+SDL2库【1】(c语言)

小白的学习记录 一、前置知识 注&#xff1a;博主是小白&#xff0c;所以记录的可能是一些无意中看到&#xff0c;但是不清楚的东西&#xff0c;所以大家择需了解。 JSON JSON&#xff08;JavaScript Object Notation&#xff09; 是一种轻量级的数据交换格式&#xff0c;易于…

10690 分面包

### 伪代码 1. 读取输入的 n 和 m&#xff0c;以及 m 个面包的长度 L。 2. 定义一个函数 canDivide(length)&#xff0c;判断是否可以将所有面包分成每人 length 长度的面包。 3. 使用二分法查找每人分得的最长面包长度&#xff1a; - 初始化 low 为 0&#xff0c;high 为所…

前端工程化-04.Vue项目简介

一.Vue项目-创建 1.使用如图两种方式创建Vue项目 2.在此创建新项目 点击创建项目 创建成功&#xff01; 二.Vue项目-目录结构 三.Vue项目-运行 启动后直接在下方找到连接端口 成功启动项目 这个项目即为Vue中的自带项目Vue.app。修改其中的Home为Vue Home。ctals保存发…

数学建模预测类—【一元线性回归】

每日格言&#xff1a;行动是治愈恐惧的良药&#xff0c;而犹豫拖延将不断滋养恐惧. 目录 前言 一、什么是回归分析&#xff1f; 1.概念理解 2.分类和一般步骤 二、一元线性回归&#xff08;Matlab算法&#xff09; 1.利用regress函数 2、例题讲解 总结 前言 在具体讲述线性回归…

如何在 Windows 10 中配置住宅 IP

什么是住宅IP 住宅IP指的是普通家庭网络的 IP 地址。你可以这样想&#xff1a; IP地址&#xff1a;每一个接入互联网的设备都有一个唯一的“地址”&#xff0c;就像每栋房子都有一个唯一的门牌号一样&#xff0c;这个地址就是IP地址。 住宅IP&#xff1a;指的是那些来自家庭用…

vue2父组件向子孙组件响应式传参,provide/inject响应式

provide和inject一起使用&#xff0c;实现将父组件的数据、方法提供给子孙组件使用&#xff0c;不论组件层次有多深。provide和inject绑定并不是可响应的。但如果你传入了一个可监听的对象&#xff0c;那么其对象的property还是可响应的。 API — Vue.js (vuejs.org)https://v…

完美解决html2canvas + jsPDF导出pdf分页内容截断问题

代码地址&#xff1a;https://github.com/HFQ12333/export-pdf.git html2canvas jspdf方案是前端实现页面打印的一种常用方案&#xff0c;但是在实践过程中&#xff0c;遇到的最大问题就是分页截断的问题&#xff1a;当页面元素超过一页A4纸的时候&#xff0c;连续的页面就会…

基于c++的yolov5推理之后处理详解及代码(二)

目录 一、解析yolov5的输出结果 1、对1*25200*85的向量进行解析 2、预测框中心&#xff08;x&#xff0c;y&#xff09;&#xff0c;预测框的高和宽&#xff08;h&#xff0c;w&#xff09;详解 3、解析代码&#xff1a; 二、confidence过滤 1、confidence计算 三、Non-Maxi…

C++笔记-sstream的使用(字符串转其他类型,读取文件时用得多)

在 C 中&#xff0c;std::stringstream 类可以用来进行字符串流的输入输出&#xff0c;将字符串和其他类型的数据进行转换。 #include <iostream> #include <sstream>int main() {// 将整数转换为字符串int num 123;std::stringstream ss;ss << num;std::s…

单元训练10:定时器实现秒表功能-数组方式

蓝桥杯 小蜜蜂 单元训练10&#xff1a;定时器实现秒表功能-数组方式 /** Description:* Author: fdzhang* Email: zfdcqq.com* Date: 2024-08-15 21:58:53* LastEditTime: 2024-08-16 19:07:27* LastEditors: fdzhang*/#include "stc15f2k60s2.h"#define LED(x) …

火语言RPA--手机对象元素库使用方法

使用自动选取工具获得手机中元素的xpath路径。 工具标识 手机 分组下组件若有此标识&#xff0c;则包含选择元素工具&#xff0c;点击此标识会可以选择手机中的元素进行操作。 元素库介绍 ① 根据元素名称筛选元素库中保存的元素 ② 元素库&#xff0c;显示已经保存的元素名称…

算法的学习笔记—链表中倒数第 K 个结点(牛客JZ22)

&#x1f600;前言 在编程过程中&#xff0c;链表是一种常见的数据结构&#xff0c;它能够高效地进行插入和删除操作。然而&#xff0c;遍历链表并找到特定节点是一个典型的挑战&#xff0c;尤其是当我们需要找到链表中倒数第 K 个节点时。本文将详细介绍如何使用双指针技术来解…

48天笔试训练错题——day47

目录 选择题 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 编程题 1. 合唱团 2. 马戏团 选择题 1. 子网掩码是 255.255.255.0&#xff0c;前三个字节都是 1&#xff0c;则表示有 24 位网络号和子网号。又是 B 类 IP 地址&#xff0c;只有 16 位网络号&#xff0c;所有第三个…

聊聊JS中的WebSocket

你好&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏和关注。个人知乎 在JavaScript中&#xff0c;使用WebSocket非常简单直观。通过几行代码&#xff0c;你就可以轻松创建一个WebSocket连接&#xff0c;并监听来自服务器的消息。无论是开发实时聊天应用、在线游戏、实时数据分…

高效录制新选择:2024年Windows录屏软件

录屏能帮助我们捕捉屏幕上的精彩瞬间&#xff0c;作为老师可以用来录制课程&#xff0c;作为会议记录员可以用来录制远程会议。那么有什么软件是适合windows录屏的呢&#xff1f;这次我们一起来探讨一下吧。 1.福昕录屏大师 链接&#xff1a;www.foxitsoftware.cn/REC/ 这款软…

【数据结构】 顺序表的应用 - 通讯录的实现

0. 前言 上一期博客中&#xff0c;我们已经学习了顺序表是什么&#xff0c;以及顺序表相关接口的实现&#xff0c;了解了如何实现顺序表的插入和删除等功能&#xff0c;那么在这期博客&#xff0c;我们可以基于顺序表来实现一个通讯录&#xff0c;在通讯录当中能实现联系人的增…

【代码随想录训练营第42期 Day27打卡 贪心Part1 - LeetCode 455.分发饼干 376. 摆动序列 53. 最大子序和

目录 一、贪心 二、题目与题解 题目一&#xff1a;455.分发饼干 题目链接 题解&#xff1a;排序双指针贪心 题目二&#xff1a;376. 摆动序列 题目链接 题解&#xff1a;贪心 题目三&#xff1a;53. 最大子序和 题目链接 题解1&#xff1a;暴力&#xff08;失败&…