mmdetection3d模型框架解读

复现和理解pointpillar算法和VoxelNet之后,下面对mmdetection3d的模型框架进行解读。

该篇文章参考:带你玩转 3D 检测和分割(一):MMDetection3D 整体框架介绍_用mmdetion3d写一个简单的语义分割模型-CSDN博客

以下是本人在学习3D目标检测过程中的一些过程记录和理解,仅供大家参考:

基于kitti数据集的3D目标检测算法复现流程:基于kitti数据集的3D目标检测算法的训练流程_pointpillar训练kitti数据集-CSDN博客

pointpillar文献理解:PointPillars文献理解_pillar feature net-CSDN博客

VoxelNet文献理解:VoxelNet文献理解-CSDN博客


目录

一、前言

(一) configs

(二) mmdet3d

(三) tools

(四)work_dirs

二、任务介绍

三、算法模型支持

(一)点云3D检测(以及多模态3D检测)

(二)纯视觉3D检测

(三)点云3D语义分割

四、数据预处理

五、模块抽象

(一)Pipeline

(二)Model

(1)点云 3D 检测模型

(2)单目 3D 检测模型

(3)多模态 3D 检测模型

(4) 点云 3D 语义分割模型

六、训练和测试流程

(一)train和val流程

(二)test流程


一、前言

由于 3D 本身数据的复杂性和 MMDetection3D 支持任务(点云 3D 检测、单目 3D 检测、多模态 3D 检测和点云 3D 语义分割等)和场景(室内和室外)的多样性,整个框架结构相对复杂,新人用户的上手门槛相对较高。所以我们推出新的系列文章,让各个细分方向的用户都能轻松上手 MMDetection3D,基于框架进行自己的研究和开发。

首先展示整个代码库的目录结构,方便初步认识:

# MMDetection3D 代码目录结构,展示主要部分 
mmdetection3d 
   | 
   |- configs                    # 配置文件 
   |- data                       # 原始数据及预处理后数据文件 
   |- mmdet3d  
   |     |- ops                  # cuda 算子(即将迁移到 mmcv 中) 
   |     |- core                 # 核心组件 
   |     |- datasets             # 数据集相关代码 
   |     |- models               # 模型相关代码 
   |     |- utils                # 辅助工具 
   |     |- ... 
   |- tools 
   |     |- analysis_tools       # 分析工具,包括可视化、计算flops等 
   |     |- data_converter       # 各个数据集预处理转换脚本 
   |     |- create_data.py       # 数据预处理入口 
   |     |- train.py             # 训练脚本 
   |     |- test.py              # 测试脚本 
   |     |- ...                       
   |- ... 

在编辑器上可以看到更为完全的目录结构:

图1.1:完整mmdetection3d目录结构

其中常用的有configs、mmdet3d、tools和work_dirs四个文件夹。其中visualization文件夹是我在进行数据集可视化时创建的,kitti数据集的可视化可以参考这篇博客:

基于kitti数据集的可视化-CSDN博客

(一) configs

configs主要是各类算法的配置文件和代码,其目录结构如下:

图1.2:configs文件夹目录结构

其中可以看到pointpillars和Second两个算法,文件夹下都是算法的各式配置文件:

图1.3:pointpillars和Second算法配置文件

可以看到标注出的两项py文件就是在复现时使用的配置文件。

(二) mmdet3d

mmdet3d主要是存放各类模型文件,这些稍后在代码框架中会着重介绍:

图1.4:mmdet3d文件夹目录结构

我们可以看到backbones(主干网络)、data_preprocessor(数据预处理器)、decode_heads(解码头)、dense_heads(密集头部网络)、detectors(检测器)、layers(网络中各种层)、losses(损失函数)、middle_encoders(中间编码器)和necks(颈部模块)的各种定义。

(三) tools

tools文件夹主要存放各类工具包和训练、测试文件,其目录结构如下:

图1.5:tools文件夹目录结构

在复现中比较重要的事这个train.py文件,我在固定随机种子时就是通过修改train文件,保证实验结果准确一致。之后会写一篇有关随机种子固定的文章。

(四)work_dirs

这个文件夹是用来存放复现结果的,每次运行时都会生成一个文件用于保存每次运行生成的结果文件:

图1.6:work_dirs文件夹目录结构

这里pointpillars算法复现了三遍,Second复现了一遍。复现结果会自动以日期为名创建文件夹,并且会生成一个和配置文件同名的py文件,里面是模型的架构等。

二、任务介绍

3D目标检测按照输入数据的模态可以划分为:点云3D检测、纯视觉3D检测以及多模态的3D检测(即点云与图像融合)。这里直接使用原文章的图:

图2.1:点云3D目标检测

点云3D目标检测主要是基于激光雷达生成的点云图像进行目标检测,直接在点云图中生成3D边界框实现检测。

图2.2:单目3D目标检测

在纯视觉的3D目标检测中,主要是依靠摄像头采集的图像进行检测,图2.2展示的是单目(即只有一个摄像头)相机的检测,其检测精度较低,识别误差较大。相较之下,双目相机检测精度更高。

从目前来说,基于纯视觉(例如单目)的 3D 检测方法在性能上和基于点云的 3D 检测方法仍然有比较大的差距,但是其胜在便捷性和低成本;同时,多模态 3D 检测也是一个在学术界和工业界都很火热的方向,对不同模态的数据各取所长,相互配合从而达到更好的检测效果。

上述描述的主要还是室外场景的 3D 检测,最广泛的实际应用场景就是最近火热的自动驾驶领域;而室内场景的 3D 检测同样也有广阔的应用前景,例如室内机器人(扫地机器人)、室内导航等等,而目前室内 3D 检测仍然以点云数据为主。

图2.3:室内点云3D检测

室内点云检测主要应用与扫地机器人和家庭机器人等,使用激光雷达的点云为主。

图2.4:室内点云语义分割

除此以外,MMDetection3D 还拓展到了点云 3D 语义分割领域,目前已经支持了室内点云语义分割,同时会在将来支持室外点云语义分割

三、算法模型支持

所有模型相关代码位于 mmdet3d/models 下,MMDetection3D 支持的各个方向的模型大体可以归类如下:

图3.1:模型分类图

总体来说,由于 MMDetection3D 依赖于 MMDetection 和 MMSegmentation, 所以很多的模型及组件都是直接复用或者继承而来。目前在 MMDetection3D 内,整体模型的构建方式会根据任务类型被划分为三种方式 (PS: 原作者正在进行整体代码的重构,统一所有任务的模型构建方式)。

(一)点云3D检测(以及多模态3D检测)

图3.2:点云3D检测模型构建

对于点云 3D 检测(多模态 3D 检测),我们继承自 MMDetection 中的 BaseDetector 构建了适用于 3D 检测的 Base3DDetector ,再根据检测中的单阶段和二阶段分别构造,需要注意的是不同于 SingleStage3DDetector,为了尽可能的复用已有的代码组件,二阶段检测器TwoStage3DDetector 同时继承自 Base3DDetector 和 TwoStageDetector。而由于多模态任务的特殊性,我们专门为多模态检测方法设计了 MVXTwoStage3DDetector,图中只列出了部分支持的模型算法。

(二)纯视觉3D检测

图3.3:单目3D检测模型结构

这里只展示了单目3D检测的模型结构。

对于单目 3D 检测,考虑到和 2D 检测输入数据的一致性,同时方便做 2D 检测的同学能快速的上手单目 3D 检测,继承自 MMDetection 中的 SingleStageDetector 构建了 SingleStageMono3DDetector,目前所支持的单目 3D 检测算法都是基于该类构建的。

(三)点云3D语义分割

图3.4:点云3D语义分割模型结构

对于点云 3D 语义分割,继承自 MMSegmentation 中的 BaseSegmentor 构建了适用于点云分割的 Base3DSegmentor,而目前所支持的点云分割算法都是遵循 EncoderDecoder3D 模式。

四、数据预处理

该部分对应于 tools/create_data.py ,各个数据集预处理脚本位于 tools/data_converter 目录下。由于 3D 数据集的多样性,MMDetection3D 会对数据集做预处理。我们在官方文档里面介绍了不同的数据集的格式转换方法和命令,在这里我们从整体视角来看一下数据预处理的文件生成过程:
 

图4.1:数据预处理文件生成过程

在 MMDetection3D 中,不同的任务和不同的场景(室内或室外)的数据预处理都会存在一定的区别,如上图所示,会产生不同的预处理后的文件,便于后续训练。

对所有的任务和场景,我们统一使用数据处理脚本转换后的 pkl 文件,该文件包含数据集的各种信息,包括数据集路径、calib 信息和标注信息等等,从而做到各个数据集内部格式尽可能的统一。
对于点云 (多模态)3D 检测,室内和室外数据集生成的文件是不一样的:
对于某些室外数据集,我们会借助 pkl 文件的信息进一步提取 reduced_point_cloud 和gt_database:前者是仅包含前方视野的点云文件,通常存在于 kitti 数据集处理过程中,因为 kitti 数据集仅包含前方视野的标注;后者则是将包含在训练数据集的每个 3D 边界框中的点云数据分别提取出来得到的各个物体的点云文件,常用来在数据增强时使用(copy-paste)。

而对于室内数据集,由于室内点云较为密集的特点,通常会进行点云的下采样处理,保存在points内:对于单目 3D 检测,由于在前面提到,整个模型构建的流程是遵循 2D 检测的,同样的在数据处理的过程中,在生成基本的 pkl 文件后,还需要将其转换为 coco 标注格式的 json 文件,该过程中会对 pkl 的标注信息做相应处理,实际在该任务中,pkl 文件用来提供 data 信息,json 文件提供标注信息;对于点云 3D 语义分割,目前 MMDetection3D 仅支持室内点云分割,相对于检测任务,如图所示需要生成额外的文件:instance_mask 包含每个点云的实例标签,semantic_mask 包含每个点云的语义标签,seg_info 包含额外的辅助训练的信息。

五、模块抽象

模块抽象也可以参考这篇知乎:轻松掌握 MMDetection 整体构建流程(二) - 知乎 (zhihu.com)

和 MMDetection 一脉相承,整个 MMDetection3D 的模块内部抽象流程也主要包括 Pipeline、DataParallel、Model、Runner 和 Hooks。

(一)Pipeline

具体在 Pipeline 方面由于数据模态的不同,所以在数据处理过程中包含不同的信息。

图5.1:典型3D检测Pipeline

上图展示了三个比较典型的 3D 检测 pipeline, 流程自上而下分别是点云 3D 检测多模态 3D 检测和单目 3D 检测,从上述的流程可以,pipeline 其实是由一系列的按照插入顺序运行的数据处理模块组成,接受数据字典,输出经过处理后的数据字典,MMDetection3D 对于点云 3D 检测提供了很多常用的 pipeline 模块,比如GlobalRotScaleTrans(点云的旋转缩放)、PointsRangeFilter / ObjectRangeFilter(限定了点云和物体的范围)、PointShuffle(打乱点云数据);而对于单目 3D 检测基本就是直接调用 MMDetection 的数据处理模块,比如 Resize (图片缩放)、Normalize (正则化)、Pad (图片填充);多模态检测则兼用两者。我们可以看到其实这些任务共享了部分的 pipeline 模块,比如 LoadAnnotations3D (标签载入)、RandomFlip3D(会对点云和图片同时进行翻转)、DefaultFormatBundle3D(数据格式化)、Collect3D (选取需要用于训练的数据和标签),这些代码都在 mmdet3d/datasets/pipeline 目录下。

(二)Model

在该部分我们按照任务类型分类,对于整个模型内部做抽象介绍。和 2D 检测类似, 3D 检测器通常也包含了几个核心组件:Backbone 用于提取特征、Neck 进行特征融合和增强、Head 用于输出需要的结果。

(1)点云 3D 检测模型

目前点云目标检测按照对点云数据的处理方式,可以分为体素处理方法 (Voxel-based) 原始点云处理方法 (Point-based),这两种方法其实在构建模型的时候会有一定的区别,整体的模型构建按照下图流程所示:

图5.2:点云3D检测模型

1、基于体素的模型通常需要 Encoder 来对点云体素化,如 HardVFE 和 PointPillarScatter等,采用的稀疏卷积或者 Pillars 的方法从点云中生成 2D 特征图,然后基本可以套用 2D 检测流程进行 3D 检测。
2、基于原始点云模型通常直接采用 3D Backbone (Pointnet / Pointnet++ 等) 提取点的特征,再针对提取到的点云特征采用 RoI 或者 Group 等方式回归 3D bounding box。有关的具体内容我们会在后续的文章中针对典型的方法进行分析介绍。

(2)单目 3D 检测模型

图5.3:单目3D检测模型

由于单目 3D 检测的输入是图片,输出是 3D bounding box, 所以整体的检测流程和模型组成来说基本和 2D 检测保持一致。

(3)多模态 3D 检测模型

多模态的检测模型从组成来看可以看成 2D 检测模型和点云检测模型的拼接。

(4) 点云 3D 语义分割模型

图5.4:点云3D语义分割模型

MMDetection3D 内部支持的 3D 分割模型都是符合 EncoderDecoder 结构的,需要 backbone 来 encode feature, decode_head 用来预测每个点云的类别的进行分割,目前主要只支持室内场景的 3D 语义分割。

六、训练和测试流程

首先我们训练和验证调用的是 tools/train.py 脚本,先进行 Dataset、Model 等相关类初始化,然后我们构建了一个 runner,最终模型的训练和验证过程是发生在 runner 内部的,而训练和验证的时候实际上是 runner 调用了 model 内部的 train_step 和 val_step 函数。

对如何从 tools/train.py 脚本开始到调用 train_step 和 val_step 函数的细节过程可以参考前述文章的【第三层代码抽象】部分,而理解了这两个函数调用流程就理解了 MMDetection3D 训练和测试流程。这里主要以 PointPillars 为例分析 MMDetection3D 中 Model 的训练和测试代码:

(一)train和val流程

图6.1:train和val流程

1、调用runner中的train_step或者val_step:

可以发现,在调用 model 本身的 train_step 前,需要额外调用 scatter 函数,前面说过该函数的作用是处理 DataContainer 格式数据,使其能够组成 batch,否则程序会报错。

如果是分布式训练,则调用的实际上是 mmcv/parallel/distributed.py/MMDistributedDataParallel,最终调用的依然是 model 本身的 train_step 或者 val_step。

2、调用Model中的train_step或者val_step:

其中,forward_train 和 forward_test 需要在不同的算法子类中实现,输出是 Loss 或者 预测结果。

3、调用子类中的forward_train方法:

PointPillars 采用的是 VoxelNet 检测器,核心逻辑还是比较通用的。

4、调用Model中的_parse_losses方法。

(二)test流程

图6.2:test流程

可以看见在 test 的时候流程相比 train / val 更为简单,没有调用 runner 对象。

1、调用Model中的forward_test;

2、调用子类的simple_test或aug_test;

以上分析了整体的框架流程。之后会详细介绍pointpillars代码的框架。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值