mmdetection 选用自定义 backbone训练

学习率

lr = (base_lr / 8) x num_gpus x (img_per_gpu/2)

其中 base_lr 是源码中给定的 学习率,这是在 8张GPU上面,每张GPU上面放2张图片得到的学习率,所以当对应的GPU数目和每张GPU上的图片数目发生改变时,学习率成正比例变化。

选用新的backbone来训练

这里选用 res2net_26w_6s 作为backbone;
以cascade_rcnn_r50_fpn_1x.py 作为config文件

  • mmdetection-mastermmdetmodelsackbones中新建一个 res2net.py文件,并将模型代码复制进去 https://github.com/Res2Net/Res2Net-PretrainedModels/blob/master/res2net.py

  • 由于这里需要多尺度特征图,可参考 原有的 resnet.py,返回的是stage1,stage2,stage3,stage4组成的list,因此新增的 res2net.py的代码需要进行修改

    • 1). 源码:
      class Res2Net(nn.Module):
         def __init__(self, block, layers, baseWidth = 26, scale = 4, num_classes=1000):
    

    修改:添加一个register;需要再import from ..registry import BACKBONES; 同时把block中的参数先写上默认参数,不然后面的config文件中传 block名字时比较麻烦

      @BACKBONES.register_module
      class Res2Net(nn.Module):
         def __init__(self, block=Bottle2neck, layers=[3,4,6,3], baseWidth=26, scale=6, num_classes=1000):
    
    • 2). 源码:class Res2Net下面的 forward

          def forward(self, x):
          x = self.conv1(x)
          x = self.bn1(x)
          x = self.relu(x)
          x = self.maxpool(x)
      
          x = self.layer1(x)
          x = self.layer2(x)
          x = self.layer3(x)
          x = self.layer4(x)
      
          x = self.avgpool(x)
          x = x.view(x.size(0), -1)
          x = self.fc(x)
      
          return x
      

      修改:返回stage1, stage2,stage3,stage4

          def forward(self, x):
          x = self.conv1(x)
          x = self.bn1(x)
          x = self.relu(x)
          x = self.maxpool(x)
      
          x1 = self.layer1(x)
          x2 = self.layer2(x1)
          x3 = self.layer3(x2)
          x4 = self.layer4(x3)
      
          #x = self.avgpool(x)
          #x = x.view(x.size(0), -1)
          #x = self.fc(x)
      
          return [x1,x2,x3,x4]
      
    • 3). 增加一个 init_weights函数(这边是不添加就报错,所以就直接从 resnet.py 中复制过来了),如resnet.py中一样,修改对应的block名称

        def init_weights(self, pretrained=None):
          if isinstance(pretrained, str):
              from mmdet.apis import get_root_logger
              logger = get_root_logger()
              load_checkpoint(self, pretrained, strict=False, logger=logger)
          elif pretrained is None:
              for m in self.modules():
                  if isinstance(m, nn.Conv2d):
                      kaiming_init(m)
                  elif isinstance(m, (_BatchNorm, nn.GroupNorm)):
                      constant_init(m, 1)
    
              if self.dcn is not None:
                  for m in self.modules():
                      if isinstance(m, Bottle2neck) and hasattr(
                              m, 'conv2_offset'):
                          constant_init(m.conv2_offset, 0)
    
              if self.zero_init_residual:
                  for m in self.modules():
                      if isinstance(m, Bottle2neck):
                          constant_init(m.norm3, 0)
                      # elif isinstance(m, BasicBlock):
                      #     constant_init(m.norm2, 0)
          else:
              raise TypeError('pretrained must be a str or None')
    
  • 修改 config 文件,cascade_rcnn_r50_fpn_1x.py
    源码:

# model settings
model = dict(
    type='CascadeRCNN',
    num_stages=3,
    pretrained='torchvision://resnet50',
    backbone=dict(
        type='ResNet',
        depth=50,
        num_stages=4,
        out_indices=(0, 1, 2, 3),
        frozen_stages=1,
        style='pytorch'),

修改:

model = dict(
    type='CascadeRCNN',
    num_stages=3,
    #pretrained='torchvision://resnet50',
    pretrained='/media/mtc/dac70756-6922-445c-9cbe-58847ebdc56f/zql/mmdetection/pretrained_models/res2net50_26w_6s-19041792.pth',
    backbone=dict(
        type='Res2Net',
        layers=[3,4,6,3], baseWidth=26, scale=6, num_classes=1000,
        ),
原文地址:https://www.cnblogs.com/qiulinzhang/p/12252033.html