MMDetection-MMDetection のモデル フレームワーク ファイルとパラメーターの解釈 (1)

この記事では、完全な MMDetection に含まれる設定ファイル内のモデル ファイル --model.py を主に紹介します。

次のコードは、モデル ファイルに含まれるコードの意味と使用法を 1 行ずつ詳細に説明しています。

1. 特徴抽出ネットワークバックボーン

 上図に示す SwinTransformer を特徴抽出ネットワークのバックボーンとして使用し、次の構成を実行します。
 他のバックボーン モデルを選択する場合は、「type='新しいモデル名'」を変更し、選択した新しいモデルに応じて新しいパラメーターを定義する必要があります。たとえば、次のバックボーンとしての SwinTransformer の例と、対応するパラメータ

    backbone=dict(
        type='SwinTransformer',     #主干网络(特征提取网络)采用Swin Transformer,以下为关于Swin Transformer网络参数的选取
        embed_dim=96,               #输入Swin Transformer第一层的嵌入维度,整个过程为[96, 192, 384, 768]
        depths=[2, 2, 6, 2],        #Swin Transformer四个阶段W-MSA和SW-MSA的个数
        num_heads=[3, 6, 12, 24],   #Swin Transformer四个阶段分别对应的多头数
        window_size=7,              #Swin Transformer整个阶段采用的窗口大小
        mlp_ratio=4.,               #MPL的词向量嵌入维度,默认为4
        qkv_bias=True,
        qk_scale=None,
        drop_rate=0.,
        attn_drop_rate=0.,
        drop_path_rate=0.2,
        ape=False,
        patch_norm=True,
        out_indices=(0, 1, 2, 3),
        use_checkpoint=False),

2.機能強化されたネックネットワーク 

  上の図に示されている機能ピラミッド ネットワーク (FPN) 機能ピラミッドを特徴抽出ネットワークのバックボーンとして使用し、次の構成を実行します。
 同様に、他のネックを選択したい場合は、「type='新しいモデル名'」を変更し、選択した新しいモデルに応じて新しいパラメータを定義する必要があります。たとえば、次のバックボーンとしてのFPNの例と、その意味対応するパラメータのうち、in_channels は swin トランスフォーマーの 4 段のスケールチャンネル数に対応し、out_channels は各スケールの出力チャンネル数に対応し、num_outs は出力スケール数で、RCNN の出力スケールはさらに 1 つになります。特徴抽出ネットワークよりもスケールが大きいため、num_outs=バックボーンスケール番号+1

    neck=dict(
        type='FPN',                     #neck特征增强采用FPN(特征金字塔)
        in_channels=[96, 192, 384, 768],#每个尺度的输入通道数
        out_channels=256,               #每个尺度的输出通道数,每个尺度都一致
        num_outs=5),                    #输出尺度的数量,RCNN中的输出尺度数量为4+1,其中4为主干网络Swin Transformer的四个尺度

 3. 検出器の第 2 段階

1段階:提案候補ボックスの抽出 - RPN

rpn の正式名は領域提案ネットワークであり、第 2 段階の高品質のターゲット候補フレームを提供するために使用されます。
①アンカー ジェネレーターは

、指定されたスケール、比率、およびストライドに従って異なるアンカーを生成します。
②アンカー ターゲット ジェネレーター アンカー
ターゲット レイヤーは、どのアンカーがポジティブ サンプル (実際のターゲットを含む) でどのアンカーがネガティブ サンプル (背景のみを含む) であるかを区別するタスクを完了します。具体的な方法は、アンカーとグランド トゥルースの IoU を計算することです。
③RPN 損失
rpn には 2 つのタスクがあります: 多数のアンカーから、どのアンカーが正のサンプルでどのアンカーが負のサンプルであるかを判断する (分類タスク)、正のサンプル アンカーについては、回帰によって実際のターゲットを取得する (回帰タスク)。したがって、損失は、分類ブランチの時間関数と回帰ブランチの損失関数の 2 つの部分で構成されます。
④提案ジェネレーター
が候補フレームを取得する目的は、第 2 段階に高品質の ROI フレームを提供することです。

rpn_head=dict(
        type='RPNHead',                 #采用RPN提取proposal候选框
        in_channels=256,                #输入特征图中的通道数
        feat_channels=256,              #特征图的通道数
        anchor_generator=dict(
            type='AnchorGenerator',     #anchor生成器的配置
            scales=[8],                 #就是放缩的尺度,要将宽和高按照各个scale的值放大。scales*strides
            ratios=[0.5, 1.0, 2.0],     #长短边比例
            strides=[4, 8, 16, 32, 64]),#anchor_strides代表感受野的大小,以配置文件中,anchor_strides=[4, 8, 16, 32, 64]为例。
                                        #具体来说,anchor_strides[0]就是指P2层feature map上的一个点对应到原图上的4个像素;
                                        # anchor_strides[1]就是指P3层feature map上的一个点对应到原图上的8个像素;
                                        # 以此类推……正是由于这个特性,anchor_strides也刚好代表了每一个levlel的anchor对应于原图中的基础大小。
                                        # 因此,在AnchorGenerator中,传入的anchor_strides参数被命名为base_size。
        bbox_coder=dict(
            type='DeltaXYWHBBoxCoder', #训练过程中对anchor框进行编码和解码,采用'DeltaXYWHBBoxCoder' 的框编码器
            target_means=[.0, .0, .0, .0],      #用于编码和解码框的目标均值
            target_stds=[1.0, 1.0, 1.0, 1.0]),  #用于编码和解码框的标准方差
        loss_cls=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),#分类分支的损失函数配置,采用CrossEntropyLoss损失,在RPN中通常用于二分类吗,仅分类目标和背景,因此基本上使用sigmoid函数
        loss_bbox=dict(type='L1Loss', loss_weight=1.0)),                #回归分支的损失函数配置,采用L1Loss损失,给损失权重赋值

第 2 段階: 候補領域の特徴を抽出し、それを分類器に送信してカテゴリを識別します—ROI

ROI の正式名称は、Region of Interest で、画像の「関心領域」を指します。
①提案ターゲット生成者は、
rpn によって生成された提案に基づいて一定量を選択します (min_batch: 通常、画像ごとに 256 個の提案を選択します。または、 512件の提案)のROIをトレーニングの第2段階のサンプルとして、min_batch内の陽性サンプルと陰性サンプルの比率を設定します。 ②特徴量クロップと
プーリング
第1段階で得られたROIに対して、ROIの大きさに応じて、トリミングする適切なフィーチャ レイヤーを選択する必要があり、Pooling によって固定サイズのフィーチャ マップが取得されます。このプロセスは ROI Align (ROI アライメント) と呼ばれます。バイリニア補間を使用してピクセル値を取得し、ROI Align が実現されます。

 roi_head=dict(                                                      #作为检测器的第二步
        type='StandardRoIHead',
        bbox_roi_extractor=dict(                                        #Bbox感兴趣区域的特征提取器
            type='SingleRoIExtractor',
            roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),#roi层的配置,采用的ROI对齐,特征图输出大小为7,sampling_ratio指提取ROI特征时的采样率
            out_channels=256,                                                #特征的输出通道数
            featmap_strides=[4, 8, 16, 32]),                                 #多尺度特征图的步幅,应该与主干的架构保持一致,具体可参考RPN中的strides前四个
        bbox_head=dict(                                                 #RoIHead 中 box head 的配置
            type='Shared2FCBBoxHead',
            in_channels=256,                                            #bbox_head的输入通道,与bbox_roi_extractor的输出通道大小一致
            fc_out_channels=1024,                                       #全连接FC层的输出特征通道数
            roi_feat_size=7,                                            #候选区域(Region of Interest)特征的大小
            num_classes=80,                                             #分类的类别数,和你自己的数据集相匹配
            bbox_coder=dict(
                type='DeltaXYWHBBoxCoder',
                target_means=[0., 0., 0., 0.],                          #用于编码和解码框的目标均值
                target_stds=[0.1, 0.1, 0.2, 0.2]),                      #编码和解码的标准方差。因为框更准确,所以值更小,常规设置时 [0.1, 0.1, 0.2, 0.2]。
            reg_class_agnostic=False,                                   #回归是否与类别无关
            loss_cls=dict(
                type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),#分类分支的损失函数配置,采用CrossEntropyLoss损失,是否使用sigmoid函数
            loss_bbox=dict(type='L1Loss', loss_weight=1.0)),                 #回归分支的损失函数配置,采用L1Loss损失,给损失权重赋值

4. モデルのトレーニングとテストのためのハイパーパラメーター構成

train_cfg と test_cfg の一部の設定は、RPN と RCNN のサンプル部分のハイパーパラメータ設定に関連しており、具体的なパラメータについては次のように説明されます。

 train_cfg=dict(                                         #rpn 和 rcnn 训练超参数的配置
        rpn=dict(
            assigner=dict(                                  #分配正负样本分配器的配置
                type='MaxIoUAssigner',                      #选用MaxIoUAssigner
                pos_iou_thr=0.7,                            #IOU >= 0.7 作为正样本
                neg_iou_thr=0.3,                            #IOU <= 0.3 作为负样本
                min_pos_iou=0.3,                            #作为正样本的最小IOU阈值
                match_low_quality=True,                     #是否匹配低质量的框
                ignore_iof_thr=-1),                         #忽略 bbox 的 IoF 阈值
            sampler=dict(                                   #正负采样器的配置
                type='RandomSampler',                       #选用RandomSampler采样器
                num=256,                                    #需要提取样本的数量
                pos_fraction=0.5,                           #正样本占总样本数的比例
                neg_pos_ub=-1,                              #基于正样本数量的负样本上限,超出上限的忽略,-1表示不忽略
                add_gt_as_proposals=False),                 #采样后是否添加 GT 作为 proposal
            allowed_border=-1,                              #对有效anchor进行边界填充,-1表示不填充
            pos_weight=-1,                                  #训练期间正样本权重,-1代表不更改
            debug=False),                                   #是否设置调试(debug)模式
        rpn_proposal=dict(                                  #在训练期间生成 proposals 的配置
            nms_pre=2000,                                   #做非极大值抑制(NMS)前box的数量
            max_per_img=1000,                               #做NMS后要保留的box的数量
            nms=dict(type='nms', iou_threshold=0.7),        #NMS,其阈值为0.7
            min_bbox_size=0),                               #允许的最小 box 尺寸
        rcnn=dict(
            assigner=dict(                                  #RCNN分配正负样本
                type='MaxIoUAssigner',
                pos_iou_thr=0.5,                            #IOU >= 0.5 作为正样本
                neg_iou_thr=0.5,                            #IOU < 0.5 作为负样本
                min_pos_iou=0.5,                            # 将 box 作为正样本的最小 IoU 阈值
                match_low_quality=True,                     #是否匹配低质量的框
                ignore_iof_thr=-1),                         #忽略 bbox 的 IoF 阈值,-1表示不忽略
            sampler=dict(                                   #正负采样器的配置
                type='RandomSampler',                       #选用RandomSampler采样器
                num=512,                                    #需要提取样本的数量
                pos_fraction=0.25,                          #正样本占总样本数的比例
                neg_pos_ub=-1,                              #基于正样本数量的负样本上限,超出上限的忽略,-1表示不忽略
                add_gt_as_proposals=True),                  #采样后是否添加 GT 作为 proposal
            mask_size=28,                                   #mask的大小
            pos_weight=-1,                                  #训练期间正样本权重,-1代表不更改
            debug=False)),                                  #是否设置调试(debug)模式
    test_cfg=dict(                                          #rpn 和 rcnn 测试超参数的配置
        rpn=dict(
            nms_pre=1000,                                   #做非极大值抑制(NMS)前box的数量
            max_per_img=1000,                               #做NMS后要保留的box的数量
            nms=dict(type='nms', iou_threshold=0.7),        #NMS,其阈值为0.7
            min_bbox_size=0),                               #允许的最小 box 尺寸
        rcnn=dict(
            score_thr=0.05,                                 #bbox的分数阈值
            nms=dict(type='nms', iou_threshold=0.5),        #NMS,其阈值为0.5
            max_per_img=100,                                #做NMS后要保留的box的数量
            mask_thr_binary=0.5)))                          #mask预处的阈值

以下は、完全なモデル ファイルのコードとパラメーターの紹介です。mask_rcnn_swin_fpn.py

# model settings
model = dict(
    type='MaskRCNN',                #你所采用的检测器类型
    pretrained=None,
    backbone=dict(
        type='SwinTransformer',     #主干网络(特征提取网络)采用Swin Transformer,以下为关于Swin Transformer网络参数的选取
        embed_dim=96,               #输入Swin Transformer第一层的嵌入维度,整个过程为[96, 192, 384, 768]
        depths=[2, 2, 6, 2],        #Swin Transformer四个阶段W-MSA和SW-MSA的个数
        num_heads=[3, 6, 12, 24],   #Swin Transformer四个阶段分别对应的多头数
        window_size=7,              #Swin Transformer整个阶段采用的窗口大小
        mlp_ratio=4.,               #MPL的词向量嵌入维度,默认为4
        qkv_bias=True,
        qk_scale=None,
        drop_rate=0.,
        attn_drop_rate=0.,
        drop_path_rate=0.2,
        ape=False,
        patch_norm=True,
        out_indices=(0, 1, 2, 3),
        use_checkpoint=False),
    neck=dict(
        type='FPN',                     #neck特征增强采用FPN(特征金字塔)
        in_channels=[96, 192, 384, 768],#每个尺度的输入通道数
        out_channels=256,               #每个尺度的输出通道数,每个尺度都一致
        num_outs=5),                    #输出尺度的数量,RCNN中的输出尺度数量为4+1,其中4为主干网络Swin Transformer的四个尺度
    rpn_head=dict(
        type='RPNHead',                 #采用RPN提取proposal候选框
        in_channels=256,                #输入特征图中的通道数
        feat_channels=256,              #特征图的通道数
        anchor_generator=dict(
            type='AnchorGenerator',     #anchor生成器的配置
            scales=[8],                 #就是放缩的尺度,要将宽和高按照各个scale的值放大。scales*strides
            ratios=[0.5, 1.0, 2.0],     #长短边比例
            strides=[4, 8, 16, 32, 64]),#anchor_strides代表感受野的大小,以配置文件中,anchor_strides=[4, 8, 16, 32, 64]为例。
                                        #具体来说,anchor_strides[0]就是指P2层feature map上的一个点对应到原图上的4个像素;
                                        # anchor_strides[1]就是指P3层feature map上的一个点对应到原图上的8个像素;
                                        # 以此类推……正是由于这个特性,anchor_strides也刚好代表了每一个levlel的anchor对应于原图中的基础大小。
                                        # 因此,在AnchorGenerator中,传入的anchor_strides参数被命名为base_size。
        bbox_coder=dict(
            type='DeltaXYWHBBoxCoder', #训练过程中对anchor框进行编码和解码,采用'DeltaXYWHBBoxCoder' 的框编码器
            target_means=[.0, .0, .0, .0],      #用于编码和解码框的目标均值
            target_stds=[1.0, 1.0, 1.0, 1.0]),  #用于编码和解码框的标准方差
        loss_cls=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),#分类分支的损失函数配置,采用CrossEntropyLoss损失,在RPN中通常用于二分类吗,仅分类目标和背景,因此基本上使用sigmoid函数
        loss_bbox=dict(type='L1Loss', loss_weight=1.0)),                #回归分支的损失函数配置,采用L1Loss损失,给损失权重赋值
    roi_head=dict(                                                      #作为检测器的第二步
        type='StandardRoIHead',
        bbox_roi_extractor=dict(                                        #Bbox感兴趣区域的特征提取器
            type='SingleRoIExtractor',
            roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),#roi层的配置,采用的ROI对齐,特征图输出大小为7,sampling_ratio指提取ROI特征时的采样率
            out_channels=256,                                                #特征的输出通道数
            featmap_strides=[4, 8, 16, 32]),                                 #多尺度特征图的步幅,应该与主干的架构保持一致,具体可参考RPN中的strides前四个
        bbox_head=dict(                                                 #RoIHead 中 box head 的配置
            type='Shared2FCBBoxHead',
            in_channels=256,                                            #bbox_head的输入通道,与bbox_roi_extractor的输出通道大小一致
            fc_out_channels=1024,                                       #全连接FC层的输出特征通道数
            roi_feat_size=7,                                            #候选区域(Region of Interest)特征的大小
            num_classes=80,                                             #分类的类别数,和你自己的数据集相匹配
            bbox_coder=dict(
                type='DeltaXYWHBBoxCoder',
                target_means=[0., 0., 0., 0.],                          #用于编码和解码框的目标均值
                target_stds=[0.1, 0.1, 0.2, 0.2]),                      #编码和解码的标准方差。因为框更准确,所以值更小,常规设置时 [0.1, 0.1, 0.2, 0.2]。
            reg_class_agnostic=False,                                   #回归是否与类别无关
            loss_cls=dict(
                type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),#分类分支的损失函数配置,采用CrossEntropyLoss损失,是否使用sigmoid函数
            loss_bbox=dict(type='L1Loss', loss_weight=1.0)),                 #回归分支的损失函数配置,采用L1Loss损失,给损失权重赋值
        mask_roi_extractor=dict(
            type='SingleRoIExtractor',
            roi_layer=dict(type='RoIAlign', output_size=14, sampling_ratio=0),
            out_channels=256,
            featmap_strides=[4, 8, 16, 32]),
        mask_head=dict(
            type='FCNMaskHead',
            num_convs=4,
            in_channels=256,
            conv_out_channels=256,
            num_classes=80,
            loss_mask=dict(
                type='CrossEntropyLoss', use_mask=True, loss_weight=1.0))),
    # model training and testing settings
    train_cfg=dict(                                         #rpn 和 rcnn 训练超参数的配置
        rpn=dict(
            assigner=dict(                                  #分配正负样本分配器的配置
                type='MaxIoUAssigner',                      #选用MaxIoUAssigner
                pos_iou_thr=0.7,                            #IOU >= 0.7 作为正样本
                neg_iou_thr=0.3,                            #IOU <= 0.3 作为负样本
                min_pos_iou=0.3,                            #作为正样本的最小IOU阈值
                match_low_quality=True,                     #是否匹配低质量的框
                ignore_iof_thr=-1),                         #忽略 bbox 的 IoF 阈值
            sampler=dict(                                   #正负采样器的配置
                type='RandomSampler',                       #选用RandomSampler采样器
                num=256,                                    #需要提取样本的数量
                pos_fraction=0.5,                           #正样本占总样本数的比例
                neg_pos_ub=-1,                              #基于正样本数量的负样本上限,超出上限的忽略,-1表示不忽略
                add_gt_as_proposals=False),                 #采样后是否添加 GT 作为 proposal
            allowed_border=-1,                              #对有效anchor进行边界填充,-1表示不填充
            pos_weight=-1,                                  #训练期间正样本权重,-1代表不更改
            debug=False),                                   #是否设置调试(debug)模式
        rpn_proposal=dict(                                  #在训练期间生成 proposals 的配置
            nms_pre=2000,                                   #做非极大值抑制(NMS)前box的数量
            max_per_img=1000,                               #做NMS后要保留的box的数量
            nms=dict(type='nms', iou_threshold=0.7),        #NMS,其阈值为0.7
            min_bbox_size=0),                               #允许的最小 box 尺寸
        rcnn=dict(
            assigner=dict(                                  #RCNN分配正负样本
                type='MaxIoUAssigner',
                pos_iou_thr=0.5,                            #IOU >= 0.5 作为正样本
                neg_iou_thr=0.5,                            #IOU < 0.5 作为负样本
                min_pos_iou=0.5,                            # 将 box 作为正样本的最小 IoU 阈值
                match_low_quality=True,                     #是否匹配低质量的框
                ignore_iof_thr=-1),                         #忽略 bbox 的 IoF 阈值,-1表示不忽略
            sampler=dict(                                   #正负采样器的配置
                type='RandomSampler',                       #选用RandomSampler采样器
                num=512,                                    #需要提取样本的数量
                pos_fraction=0.25,                          #正样本占总样本数的比例
                neg_pos_ub=-1,                              #基于正样本数量的负样本上限,超出上限的忽略,-1表示不忽略
                add_gt_as_proposals=True),                  #采样后是否添加 GT 作为 proposal
            mask_size=28,                                   #mask的大小
            pos_weight=-1,                                  #训练期间正样本权重,-1代表不更改
            debug=False)),                                  #是否设置调试(debug)模式
    test_cfg=dict(                                          #rpn 和 rcnn 测试超参数的配置
        rpn=dict(
            nms_pre=1000,                                   #做非极大值抑制(NMS)前box的数量
            max_per_img=1000,                               #做NMS后要保留的box的数量
            nms=dict(type='nms', iou_threshold=0.7),        #NMS,其阈值为0.7
            min_bbox_size=0),                               #允许的最小 box 尺寸
        rcnn=dict(
            score_thr=0.05,                                 #bbox的分数阈值
            nms=dict(type='nms', iou_threshold=0.5),        #NMS,其阈值为0.5
            max_per_img=100,                                #做NMS后要保留的box的数量
            mask_thr_binary=0.5)))                          #mask预处的阈值
MMDetection-MMDetection のデータセット ファイル、トレーニング プラン ファイル、実行情報ファイル、および特定のパラメーターの解釈を使って遊ぶ (2) 
MMDetection-MMDetection を使って独自の設定ファイルを作成して遊ぶ (3)

おすすめ

転載: blog.csdn.net/weixin_42715977/article/details/130003440