【YOLOv5-6.x】设置可学习权重结合BiFPN(Add操作)

修改yaml文件(以yolov5s为例)

本文以 yolov5s.yaml为例进行修改,修改模型配置文件时要注意以下几点:

  • 这里的yaml文件只修改了一处,也就是将19层的Concat换成了BiFPN_Add,要想修改其他层的Concat,可以类比进行修改
  • BiFPN_Add本质是add操作,不是concat操作,因此,BiFPN_Add的各个输入层要求大小完全一致(通道数、feature map大小等),因此,这里要修改之前的参数[-1, 13, 6],来满足这个要求:
  • -1层就是上一层的输出,原来上一层的输出channel数为256,这里改成512
  • 13层就是这里 [-1, 3, C3, [512, False]], # 13
  • 这样修改后,BiFPN_Add各个输入大小都是 [bs,256,40,40]
  • 最后BiFPN_Add后面的参数层设置为 [256, 256]也就是输入输出channel数都是256

nc: 80
depth_multiple: 0.33
width_multiple: 0.50
anchors:
  - [10,13, 16,30, 33,23]
  - [30,61, 62,45, 59,119]
  - [116,90, 156,198, 373,326]

backbone:

  [[-1, 1, Conv, [64, 6, 2, 2]],
   [-1, 1, Conv, [128, 3, 2]],
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],
   [-1, 6, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],
   [-1, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],
  ]

head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],
   [-1, 3, C3, [512, False]],

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],
   [-1, 3, C3, [256, False]],

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 13, 6], 1, BiFPN_Add3, [256, 256]],
   [-1, 3, C3, [512, False]],

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],
   [-1, 3, C3, [1024, False]],

   [[17, 20, 23], 1, Detect, [nc, anchors]],
  ]

nc: 80
depth_multiple: 0.33
width_multiple: 0.50
anchors:
  - [10,13, 16,30, 33,23]
  - [30,61, 62,45, 59,119]
  - [116,90, 156,198, 373,326]

backbone:

  [[-1, 1, Conv, [64, 6, 2, 2]],
   [-1, 1, Conv, [128, 3, 2]],
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],
   [-1, 6, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],
   [-1, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],
  ]

head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, BiFPN_Add2, [256, 256]],
   [-1, 3, C3, [512, False]],

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, BiFPN_Add2, [128, 128]],
   [-1, 3, C3, [256, False]],

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 13, 6], 1, BiFPN_Add3, [256, 256]],
   [-1, 3, C3, [512, False]],

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, BiFPN_Add2, [256, 256]],
   [-1, 3, C3, [1024, False]],

   [[17, 20, 23], 1, Detect, [nc, anchors]],
  ]
                 from  n    params  module                                  arguments
  0                -1  1      3520  models.common.Conv                      [3, 32, 6, 2, 2]
  1                -1  1     18560  models.common.Conv                      [32, 64, 3, 2]
  2                -1  1     18816  models.common.C3                        [64, 64, 1]
  3                -1  1     73984  models.common.Conv                      [64, 128, 3, 2]
  4                -1  2    115712  models.common.C3                        [128, 128, 2]
  5                -1  1    295424  models.common.Conv                      [128, 256, 3, 2]
  6                -1  3    625152  models.common.C3                        [256, 256, 3]
  7                -1  1   1180672  models.common.Conv                      [256, 512, 3, 2]
  8                -1  1   1182720  models.common.C3                        [512, 512, 1]
  9                -1  1    656896  models.common.SPPF                      [512, 512, 5]
 10                -1  1    131584  models.common.Conv                      [512, 256, 1, 1]
 11                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']
 12           [-1, 6]  1     65794  models.common.BiFPN_Add2                [256, 256]
 13                -1  1    296448  models.common.C3                        [256, 256, 1, False]
 14                -1  1     33024  models.common.Conv                      [256, 128, 1, 1]
 15                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']
 16           [-1, 4]  1     16514  models.common.BiFPN_Add2                [128, 128]
 17                -1  1     74496  models.common.C3                        [128, 128, 1, False]
 18                -1  1    295424  models.common.Conv                      [128, 256, 3, 2]
 19       [-1, 13, 6]  1     65795  models.common.BiFPN_Add3                [256, 256]
 20                -1  1    296448  models.common.C3                        [256, 256, 1, False]
 21                -1  1    590336  models.common.Conv                      [256, 256, 3, 2]
 22          [-1, 10]  1     65794  models.common.BiFPN_Add2                [256, 256]
 23                -1  1   1051648  models.common.C3                        [256, 512, 1, False]
 24      [17, 20, 23]  1    229245  models.yolo.Detect                      [80, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [128, 256, 512]]
Model Summary: 278 layers, 7384006 parameters, 7384006 gradients, 17.2 GFLOPs

修改common.py

  • 复制粘贴一下代码:

class BiFPN_Add2(nn.Module):
    def __init__(self, c1, c2):
        super(BiFPN_Add2, self).__init__()

        self.w = nn.Parameter(torch.ones(2, dtype=torch.float32), requires_grad=True)
        self.epsilon = 0.0001
        self.conv = nn.Conv2d(c1, c2, kernel_size=1, stride=1, padding=0)
        self.silu = nn.SiLU()

    def forward(self, x):
        w = self.w
        weight = w / (torch.sum(w, dim=0) + self.epsilon)
        return self.conv(self.silu(weight[0] * x[0] + weight[1] * x[1]))

class BiFPN_Add3(nn.Module):
    def __init__(self, c1, c2):
        super(BiFPN_Add3, self).__init__()
        self.w = nn.Parameter(torch.ones(3, dtype=torch.float32), requires_grad=True)
        self.epsilon = 0.0001
        self.conv = nn.Conv2d(c1, c2, kernel_size=1, stride=1, padding=0)
        self.silu = nn.SiLU()

    def forward(self, x):
        w = self.w
        weight = w / (torch.sum(w, dim=0) + self.epsilon)

        return self.conv(self.silu(weight[0] * x[0] + weight[1] * x[1] + weight[2] * x[2]))

修改yolo.py

  • parse_model函数中找到 elif m is Concat:语句,在其后面加上 BiFPN_Add相关语句:
elif m is Concat:
    c2 = sum(ch[x] for x in f)

elif m in [BiFPN_Add2, BiFPN_Add3]:
    c2 = max([ch[x] for x in f])

修改train.py

  • BiFPN_Add2BiFPN_Add3函数中定义的 w参数,加入 g1
    g0, g1, g2 = [], [], []
    for v in model.modules():

        if hasattr(v, 'bias') and isinstance(v.bias, nn.Parameter):
            g2.append(v.bias)
        if isinstance(v, nn.BatchNorm2d):
            g0.append(v.weight)
        elif hasattr(v, 'weight') and isinstance(v.weight, nn.Parameter):
            g1.append(v.weight)

        elif isinstance(v, BiFPN_Add2) and hasattr(v, 'w') and isinstance(v.w, nn.Parameter):
            g1.append(v.w)
        elif isinstance(v, BiFPN_Add3) and hasattr(v, 'w') and isinstance(v.w, nn.Parameter):
            g1.append(v.w)

References

Original: https://blog.csdn.net/weixin_43799388/article/details/124091648
Author: 嗜睡的篠龙
Title: 【YOLOv5-6.x】设置可学习权重结合BiFPN(Add操作)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/721379/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球