欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mmdetection 中文文档四(由原英文文档翻译)

程序员文章站 2022-06-06 08:38:11
...

四、技术细节
在这一节,我们将介绍训练检测器的主要工具:数据管道,模型和迭代管道。
(一)数据管道
根据标准协议,我们使用Dataset和DataLoader作为多工作数据加载。Dataset返回一个数据字典,数据字典的参数是模型前向算法中的参数。由于被检测的数据对象可能大小不一样(比如图像大小,bbox大小等),我们推荐一个MMCV中新的DataContainer类型,来收集和分发不同大小的数据。点击这个链接来获得更多的细节。
数据预处理管道和数据集是分开进行的。通常一个数据集定义了注释的处理,数据管道定义了所有准备数据字典的步骤。一个数据管道包括一系列的操作。每一个操作将使用一个字典作为输入,同时输出一个字典作为下一次转换的开始。
下图中,我们发布了一个经典的数据管道。蓝色方块是数据管道操作。随着数据管道往后运行,每一个操作可以向字典结果增加新的键值(绿色标志的),或者是更新已出现的键值(橙色标注的)。

                数据管道图

上述操作在数据加载、预处理、格式化和测试时间提高等模块中被分类进行。
下面是Faster R-CNN数据管道的例子。
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
train_pipeline = [
dict(type=‘LoadImageFromFile’),
dict(type=‘LoadAnnotations’, with_bbox=True),
dict(type=‘Resize’, img_scale=(1333, 800), keep_ratio=True),
dict(type=‘RandomFlip’, flip_ratio=0.5),
dict(type=‘Normalize’, **img_norm_cfg),
dict(type=‘Pad’, size_divisor=32),
dict(type=‘DefaultFormatBundle’),
dict(type=‘Collect’, keys=[‘img’, ‘gt_bboxes’, ‘gt_labels’]),
]
test_pipeline = [
dict(type=‘LoadImageFromFile’),
dict(
type=‘MultiScaleFlipAug’,
img_scale=(1333, 800),
flip=False,
transforms=[
dict(type=‘Resize’, keep_ratio=True),
dict(type=‘RandomFlip’),
dict(type=‘Normalize’, **img_norm_cfg),
dict(type=‘Pad’, size_divisor=32),
dict(type=‘ImageToTensor’, keys=[‘img’]),
dict(type=‘Collect’, keys=[‘img’]),
])
]
为每一个操作,我们都列出了added/updated/removed(增加,更新、删除)相关的字典域。
1.数据加载
LoadImageFromFile
增加:img, img_shape, ori_shape
LoadAnnotations
增加:gt_bboxes, gt_bboxes_ignore, gt_labels, gt_masks, gt_semantic_seg, bbox_fields, mask_fields
LoadProposals
增加:proposals
2.预处理
Resize
增加:flip
更新:img, *bbox_fields, *mask_fields, *seg_fields
Pad
增加:pad_fixed_size, pad_size_divisor
更新:img, pad_shape, *mask_fields, *seg_fields
RandomCrop
更新:img, pad_shape, gt_bboxes, gt_labels, gt_masks, *bbox_fields
Normalize
增加:img_norm_cfg
更新:img
SegRescale
更新:gt_semantic_seg
PhotoMetricDistortion
更新:img
Expand
更新:img, gt_bboxes
MinIoURandomCrop
更新:img, gt_bboxes, gt_labels
Corrupt
更新:img
2.格式化
ToTensor
更新:由keys定义
ImageToTensor
更新:由keys定义
Transpose
更新:由keys定义
ToDataContainer
更新:由fields定义
DefaultFormatBundle
更新:img, proposals, gt_bboxes, gt_bboxes_ignore, gt_labels, gt_masks, gt_semantic_seg
Collect
增加:
更新:img_meta(img_meta关键字由meta_keys明确)
删除:除了keys定义过的所有其他值
3.测试时间优化
MultiScaleFlipAug
(二)模型
在MMDetection,我们大体上将模型组件分为四类。
Backbone(主干):通常一个FCN网络来抽出特征图,比如ResNet
Neck(脖子):这个组件介于主干和头之间,比如FPN,ASPP
Head(头):具体工作任务组件。比如bbox预测和mask预测。
Roi extractor(兴趣区提取器):从特征图中提取ROI特征的部分,比如ROI Align
为上面的组件,我们写了一些检测管道的工具,比如SingleStageDetector和TwoStageDetector。
1.使用基本组件建立一个模型
依照这些基本管道(比如二阶检测器),可以很容易的通过config文件来定制模型的结构。
如果我们想要定制一些新的组件,比如在Path Aggregation Network for Instance Segmentation(点击链接获取)中列出的FPN结构,那么有两步要完成:
1)中建立一个新的文件mmdet/models/necks/pafpn.py
from …registry import NECKS

@NECKS.register
class PAFPN(nn.Module):

def __init__(self,
            in_channels,
            out_channels,
            num_outs,
            start_level=0,
            end_level=-1,
            add_extra_convs=False):
    pass

def forward(self, inputs):
    # implementation is ignored
    pass

2)在mmdet/models/necks/init.py导入模型
from .pafpn import PAFPN
3)按照下面所示,将config文件中的
neck=dict(
type=‘FPN’,
in_channels=[256, 512, 1024, 2048],
out_channels=256,
num_outs=5)
修改为:
neck=dict(
type=‘PAFPN’,
in_channels=[256, 512, 1024, 2048],
out_channels=256,
num_outs=5)
我们将为研究目的发布更多的组件(backbones, necks, heads)
2.写一个新的模型
写一个新的检测管道,你需要继承BaseDetector,来定义下面的抽象方法。
extract_feat():给一个图像形状批处理shape(n,c,h,w),抽出特征图。
forward_train():训练模型的前向方法。
simple_test():未加增强的单模检测。
aug_test():增强的检测(比如multi-scale, flip:多尺度,图像增强)
TwoStageDetector将更好的说明如何去做。
(三)管道迭代
我们为单机器和多机器选择了分布式训练。支持上面的服务需要8个GPU,8个进程将同时开始,每一个进程运行在一个GPU上。
每个进程维护了一个独立的模型、数据加载和优化方法。模型参数只是在开始的时候会同步。在前向传播和后向传播结束后,梯度将会在所有的GPU上减少,优化器将更新模型参数。梯度被减少,在所有进程中,在迭代以后的模型参数保持不变。
(四)其他信息
你可以参考我们的技术文档,来获得更多信息。