Read on Omnivore
Read Original

Highlights&&Note

Detectron2 的基本思路就是利用配置文件搭积木。

  • 第一步,将模型拆分为多个模块,每个模块可以叫做一个类型的积木。
  • 第二步,构建配置文件。
  • 第三步,通过配置文件,选择对应的积木。
  • 有一个默认配置文件,即 detectron2/config/default.py 文件。
  • 示例配置文件放在 configs 文件夹中,且使用yaml形式。
  • 所有示例配置文件都是建立在默认配置文件基础上的,即所有示例配置文件中的配置其实都是不全的,缺失的配置需要到默认配置文件中寻找。
  • detectron2 的配置文件比 mmdetection 看起来简洁很多。
  • 有得必有失,虽然简洁,但在看源码的时候经常需要查看默认配置文件,也不是特别方便。
  • 示例配置文件中有一个_BASE_属性,可以将其他示例配置文件作为基础,如果有冲突则用当前配置文件的信息覆盖。

Content

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

参考 Detectron2入门教程 - 云+社区 - 腾讯云

目录

1. 概述

1.1. 自己的源码阅读流程

1.2. 目录结构

1.3. 搭积木过程

1.4. 官方文档阅读

2. 数据处理

2.1. 概述

2.2. 基本流程

2.3. build_detection_train_loader 方法解析

2.4. 其他

3. 模型搭建

3.1. 概述

3.2. 基本流程

3.3. 其他

4. 训练/评估/预测

4.1. 概述

4.2. 训练代码结构


1. 概述

1.1. 自己的源码阅读流程

  • 设定目标:
    • 刚刚从TF转向PyTorch,所以希望进一步熟悉PyTorch。
    • 进一步熟悉目标检测、实例分割、关键点检测等模型。
    • 寻找/研究源码中存在的一些tricks。
    • 后续需要通过detectron2来复现新论文。
  • 总结自己之前的一些步骤
    • 第一步:阅读所有官方文档。
    • 第二步:尝试根据 Getting Started 文档内容,运行 demo 中的脚本。
    • 第三步:从数据处理、模型构建、模型训练/预测/评估三个方面,分别浏览源码。
  • 个人感受:
    • PyTorch代码比TensorFlow代码容易多了。
    • Detectron2源码比TensorFlow Object Detection API源码直观多了,上手容易多了。

1.2. 目录结构

  • configs示例配置文件合集。
  • datasets:数据集准备工作,主要就是各个数据集的基本结构,以及需要如何预处理。
  • demo:快速体验Detectron2,与Getting Started文档对应。如果想要体验Model ZOO中结果的内容就可以用这个。
  • detectron2:项目主要代码都在这里了。
  • dev:一些开发者会用到的脚本。
  • docker:没啥好介绍的。
  • docs:一些官方文档。
  • projects:基于Detectron2的三个项目,DensePose/TensorMask/TridentNet。
    • Detectron2的开发人员介绍,如果想要利用detectron2直接复现所有论文可能比较困难(我的理解就是直接修改detectron2中的代码),一种比较好的方式就是将detectron2作为一个包来调用来构建新的模型。
  • tests:单元测试类。
  • tools:常用脚本,如训练、benchmark、展示数据集等。
  • ==Detectron2 的基本思路就是利用配置文件搭积木。==
    • ==第一步,将模型拆分为多个模块,每个模块可以叫做一个类型的积木。==
    • ==第二步,构建配置文件。==
    • ==第三步,通过配置文件,选择对应的积木。==
  • 配置文件概述
    • ==有一个====默认配置文件====,即== ==detectron2/====config====/====default====.py== ==文件。==
    • ==示例配置文件====放在== ==configs== ==文件夹中,且使用yaml形式。==
    • ==所有====示例配置文件====都是建立在====默认配置文件====基础上的,即所有====示例配置文件====中的配置其实都是不全的,缺失的配置需要到====默认配置文件====中寻找。==
      * ==detectron2 的配置文件比 mmdetection 看起来简洁很多。==  
      * ==有得必有失,虽然简洁,但在看源码的时候经常需要查看默认配置文件,也不是特别方便。==  
      
    • ==示例配置文件====中有一个====_BASE_====属性,可以将其他====示例配置文件====作为基础,如果有冲突则用当前配置文件的信息覆盖。==
  • 如何使用配置文件搭积木
    • 模型搭建的Registry机制
      * 调用了 [fvcore.common.registry.Registry](https://link.zhihu.com/?target=https%3A//github.com/facebookresearch/fvcore/blob/master/fvcore/common/registry.py "fvcore.common.registry.Registry"),该对象的作用是保存一个字典,key为方法/类的名称,value为方法/类,利用 `@registry_object.register` 修饰目标方法/类,这样可以在导入detectron2的同时将 key/value 保存起来。  
      * 对于每一个类型的积木(如backbone, anchor generator, proposal generator, roi head等)都对应一个Registry对象。更多类型可以看 `detectron2/modeling/__init__.py` 文件。  
      * 一般,一个Registry对应一个`build.py`,主要就是从Registry中通过名称获取方法/类,然后将**示例配置文件**中参数导入目标方法/类中。  
      
    • 数据集的Registry机制
      * 主要使用了 `detectron2/data/catalog.py` 中的 `MetadataCatalog` 与 `DatasetCatalog`,前者保存了数据集的元数据,后者保留了一个方法,该方法用于获取数据集 `list(dict)`。  
      * 使用了Registry机制,但不是通过注解实现的,而是在 `detectron2/data/datasets/buildin.py` 中调用了 `register_all_coco()` 等四个方法,这些方法调用了 `MetadataCatalog` 和 `DatasetCatalog`的注册方法。  
      * 一般建数据集会调用 `build_detection_train_loader` 方法,该方法会调用`DatasetCatalog`中的方法,获取 `list(dict)`。  
      
    • 模型训练/预测/评估的的搭积木不复杂,就是根据配置文件,直接创建对应的对象(如lr, optimizer等)。

1.4. 官方文档阅读

  • 官方文档地址,如果想了解Detectron2的源码,强烈建议先看看。
  • tutorials
    • Installation:安装,没啥好说的。
    • Getting Started with Detectron2:跑个Demo,没啥好说的。
    • Extend Detectron2’s Defaults
      * 谈了谈Detectron2的基本设计思路。一方面要有足够的灵活性(做研究总是要做新东西),一方面要有较好的高层抽象。  
      * 基本设计思路:所有的方法和类都可以从一个配置文件中获取所需要的参数(配置文件中没有的,就使用默认参数)。  
      * 介绍了扩展detectron2的一些相关文档。  
      
    • Use Custom Datasets
      * dataset只是解析数据集,而没有进行数据处理(数据处理在后面dataloader中进行)。  
      * dataset的输出将会作为后续dataloader的输入。  
      * 自定义数据集步骤:  
               * 注册数据集,需要制定数据集名称以及一个 `get_dict` 方法,该方法用于获取一个 `list[dict]` 对象,每个字典就是一条输入数据,具体的key列表可以到文档中自己看。  
               * 可以注册一些自定义 metadata。  
      * 数据集的metadata介绍  
               * 一个记录数据库相关信息的字典,比如primitive information that helps interpret what's in the dataset, e.g., names of classes, colors of classes, root of files, etc.  
               * 可以通过 `MetadataCatalog.get(dataset_name).set(name, value)` 为新数据库添加元数据。  
      
    • Use Custom Dataloaders
      * 介绍数据处理模块,其实就是一系列数据增强等操作,以上述dataset的结果作为输入,并作为后续Model的输入。  
      * 具体过程如下:  
               * 首先,根据数据集名称获取一个已经注册的数据集(就是上面的dataset),获取 `list[dict]` 对象。  
               * 其次,数据增强等其他数据处理流程都内置于 `DatasetMapeer` 中。  
               * 最后,需要batch数据,batch后的数据一般就作为 `model.forward()` 的输入。  
      * 介绍如何自定义Dataloader、使用自定义Dataloader可以参考DensePose的代码。  
      
    • Use Models
      * 主要介绍如何构建模型。  
      * 构建模型方式:通过调用 `build_model`, `build_backbone`,`build_roi_heads` 等方法来构建。  
      * 要导入权重可以使用 `DetectionCheckpointer(model).load(file_path)`。  
      * 使用模型就是 `outputs = model(inputs)`  
      * 模型输入使用的参数通过 `list[dict]` 来实现,即上面dataloader的输出,具体的key形式可以参考这个页面中的内容。  
      * 模型输出也是一个 `list[dict]`,具体的形式可以参考这篇文章中的内容。  
      
    • Write Models
      * 自定义模型相关。  
      * 举了个例子如果自定义backbone该怎么做。  
      
    • Training
      * 就提了下训练相关的代码。  
      * 一般使用 `tools/plain_train_net.py` 来训练模型。  
      * 最简单的训练结构是 `SimpleTrainer().train()`。  
      * 一般使用的类是 `DefaultTrainer().train()`。  
      
    • Use Configs
      * 介绍了配置系统的基本结构,即使用yaml和yacs来配置。  
      * 配置文件的使用,其实就是对 `CfgNode` 对象的使用。  
      * 建议使用配置文件的方式,我比较在意的是 使用`_BASE_`参数来重复配置定义到一个文件中。
      
  • notes
  • API Documentation

2. 数据处理

2.1. 概述

  • 实现的功能:
    • 解析COCO、cityscapes等数据集。
    • 提供数据预处理以及增强的接口。
    • 通过配置文件即可实现数据集解析、预处理、增强等操作。
  • 主要入口: detectron2/data/build.py 中的 build_detection_train_loaderbuild_detection_test_loader 方法。
  • 相关代码:主要位于 detectron2/detectron2/data 目录下。
  • 相关配置:detectron2/config/defaults.py_C.INPUT _C.DATASETS _C.DATALOADER 开头的配置。

2.2. 基本流程

  • 第一步:在导入 detectron2 模块时,通过Register机制注册一些常用的数据集。
    • 注册机制可以参考 1.3. 中的内容。
    • 注册代码在 detectron2/detectron2/data/datasets/builtin.py
  • 第二步:通过数据集名称以及完成注册的 DatasetCatalog 对象以及 MetadataCatalog 对象,解析数据集并获取数据集基本信息。
    • 从源码角度看,就是调用了 DatasetCatalog 中的对应的方法,获取 list[dict] 对象。
  • 第三步:通过mapper函数,对解析完的数据集进行进一步处理,包括数据增强,并将修改数据的结构,使之可以直接作为后续模型的输入。
    • 从源码角度理解就是,从 DatasetCatalog 获取的是 list[dict],mapper函数输出的也是 list[dict],但前后两个字典的形式是不一样的,具体可以参考官方文档,里面都有具体的描述。

2.3. build_detection_train_loader 方法解析

  • 源码位于 detectron2/detectron2/data/build.py 中。
  • 流程:
    • 第一步:获取 list[dict] 对象。先根据数据库名称调用 DatasetCatalog 中的方法,获取原始 list[dict] 对象,再通过一些条件进行筛选。
    • 第二步:构建 DatasetFromList 对象,该类是 torch.utils.data.Dataset 的子类。
    • 第三步:根据mapper对上面的dataset对象进行进一步处理。
      * 浏览了下 `DatasetMapper`的源码,主要工作包括读取图像、resize、crop、flip、转换数据与标签的形式等。  
      
    • 第四步:构建 torch.utils.data.sampler.Sampler 对象,实现的功能好像包括Repeat Sample、shuffle、batch功能。
    • 第五步:根据上面的 dataset, sampler 等对象构建 torch.utils.data.DataLoader 对象。
  • 感想:
    • 好像也没有什么特别的数据增强工作。
    • Detectron2实现的 DatasetFromListMapDataset等,有点 tf.data 的感觉,挺有意思。

2.4. 其他

  • 数据增强
    • 方法主要都在 detectron2/detectron2/data/transforms/transform_gen.py 中定义。
    • 调用的话主要是通过 from detectron2.data import transforms as T 以及 T.ResizeShortestEdge 来实现。
    • 在默认实现中,就没用到什么特别的数据增强。具体的可以到 DatasetMapper 的源码中看。

3.1. 概述

  • 实现的功能:通过配置文件构建模型。
  • 主要入口:detectron2/detectron2/modeling/meta_arch/build.py 中的 def build_model(cfg) 方法。
  • 相关代码:detectron2/detectron2/modeling 目录下。
  • 相关配置:detectron2/config/defaults.py_C.MODEL 开头的配置。

3.2. 基本流程

  • 第一步:根据注册机制,在导入 detectron2 时,将各个类型的积木通过注解的方式保存到 Registry 对象中。
  • 第二步:根据配置文件中 META_ARCHITECTURE 参数,选择基本框架,也就是 meta arch。
    • 基本框架(meta arch)的类型没集中,包括 rcnn, retinanet, semantic seg, panoptic 四种。
    • 每个基本框架(meta arch)中都定义了一系列子部件,也都是用Register机制来管理(即通过配置文件与Register对象来构建)。
    • 基本框架的定义中,就包含了模型如何构建、如何训练、如何预测等相关功能。
  • 第三步:通过配置文件分别构建选中meta arch中各个部件。

3.3. 其他

  • Registry对象列表
    • ANCHOR_GENERATOR_REGISTRY:如何生成anchors。
    • BACKBONE_REGISTRY:主干网络,包括FPN。
    • META_ARCH_REGISTRY:基本网络,总体结构。
    • SEM_SEG_HEADS_REGISTRY:应该是用来做语义分隔的。
    • PROPOSAL_GENERATOR_REGISTRY:Faster RCNN中的Region proposal Network,即如何生成proposals。
    • RPN_HEAD_REGISTRY:第一阶段训练所需的输入。
    • ROI_BOX_HEAD_REGISTRY:ROI Head中的bbox分支。
    • ROI_HEADS_REGISTRY:通过特征图和第一阶段的proposals得到ROI。
    • ROI_KEYPOINT_HEAD_REGISTRY:ROI Head中的keypoint分支。
    • ROI_MASK_HEAD_REGISTRY:ROI Head中的mask分支。
  • 除了通过注册机制管理的部件外,还有一系列模型所需的部件,具体的可以参考 meta_arch 中的相关源码。

4.1. 概述

  • 实现的功能:通过配置文件构建模型。
  • 主要入口:detectron2/detectron2/engine/defaults.py 中的 DefaultTrainer, DefaultPredictor
  • 相关代码:主要在 detectron2/detectron2/enginedetectron2/detectron2/solver
  • 相关配置:detectron2/config/defaults.py_C.SOLVER _C.TEST 开头的配置。
  • 主要包括了:TrainerBase, SimpleTrainer, DefaultTrainer 三个类。
  • TrainerBase
    • 定义在 detectron2/detectron2/engine/train_loop.py 中。
    • 主要功能:
      * 提供了 hooks 机制,可以通过导入 `HookBase` 对象,在训练过程的各个时间点进行自定义处理。  
      * 定义了训练函数为 `train(self, start_iter: int, max_iter: int)`,且维训练提供了一个 `EventStorage` 对象。  
      
    • 这个与TF中的SessionRunHook类似,只不过TF已经实现在源码里,而Detectron2中是自己实现的。
  • SimpleTrainer
    • 定义在 detectron2/detectron2/engine/train_loop.py 中。
    • 主要功能:在 TrainerBase 的基础上添加了训练所需的基本参数以及最基本的训练过程代码。
    • 基本训练参数指的是 model/data_loader/optimizer
    • 基本训练过程包括位于 run_step 函数中,主要包括的功能是:
      * 导入数据。  
      * 计算损失函数(并确保损失函数是有效的)。  
      * 记录一些性能指标(包括损失函数、时间点),保存到 `EventStorage` 对象中。  
      * 进行梯度下降操作。
      
  • DefaultTrainer
    • 定义在 detectron2/detectron2/engine/defaults.py 中。
    • 主要功能:
      * 在 `SimpleTrainer` 的基础上,提供了通过配置文件创建模型、数据集、优化器、学习率等一系列操作。  
      * 提供了 checkpoint 功能。  
      * 使用了一系列常见的 hooks。  
      
    • hooks的定义都在 detectron2/detectron2/engine/hooks.py 中。

文章知识点与官方知识档案匹配,可进一步学习相关知识