当前位置:   article > 正文

YOLOv5、YOLOv8改进-BIFPN_concat_bifpn

concat_bifpn

目录

1. BiFPN论文简介

 2.YOLOv5改进

2.1第一步:common.py构建Concat_BIFPN模块

2.2第二步:yolo.py中注册Concat_BIFPNt模块

 2.3第三步:修改yaml文件(以修改官方YOLOv5s.yaml为例),需要修改head(特征融合网络)


1. BiFPN论文简介

论文《EfficientDet: Scalable and Efficient Object Detection》地址:https://arxiv.org/abs/1911.09070

BiFPN 全称 Bidirectional Feature Pyramid Network 加权双向(自顶向下 + 自低向上)特征金字塔网络。

加入BIFPN加权双向金字塔结构,提升不同尺度的检测效果。

 

图中蓝色部分为自顶向下的通路,传递的是高层特征的语义信息;红色部分是自底向上的通路,传递的是低层特征的位置信息;紫色部分是同一层在输入节点和输入节点间新加的一条边。

我们删除那些只有一条输入边的节点。这么做的思路很简单:如果一个节点只有一条输入边而没有特征融合,那么它对旨在融合不同特征的特征网络的贡献就会很小。删除它对我们的网络影响不大,同时简化了双向网络;如上图d 的 P7右边第一个节点
如果原始输入节点和输出节点处于同一层,我们会在原始输入节点和输出节点之间添加一条额外的边。思路:以在不增加太多成本的情况下融合更多的特性;
与只有一个自顶向下和一个自底向上路径的PANet不同,我们处理每个双向路径(自顶向下和自底而上)路径作为一个特征网络层,并重复同一层多次,以实现更高层次的特征融合。如下图EfficientNet 的网络结构所示,我们对BiFPN是重复使用多次的。而这个使用次数也不是我们认为设定的,而是作为参数一起加入网络的设计当中,使用NAS技术算出来的。

 Weighted Feature Fusion 带权特征融合:学习不同输入特征的重要性,对不同输入特征有区分的融合。
设计思路:传统的特征融合往往只是简单的 feature map 叠加/相加 (sum them up),比如使用concat或者shortcut连接,而不对同时加进来的 feature map 进行区分。然而,不同的输入 feature map 具有不同的分辨率,它们对融合输入 feature map 的贡献也是不同的,因此简单的对他们进行相加或叠加处理并不是最佳的操作。所以这里我们提出了一种简单而高效的加权特融合的机制。
常见的带权特征融合有三种方法。

 2.YOLOv5改进

2.1第一步:common.py构建Concat_BIFPN模块

  1. class Concat_bifpn(nn.Module):
  2. # Concatenate a list of tensors along dimension
  3. def __init__(self, c1, c2):
  4. super(Concat_bifpn, self).__init__()
  5. self.w1 = nn.Parameter(torch.ones(2, dtype=torch.float32), requires_grad=True)
  6. self.w2 = nn.Parameter(torch.ones(3, dtype=torch.float32), requires_grad=True)
  7. # self.w3 = nn.Parameter(torch.ones(3, dtype=torch.float32), requires_grad=True)
  8. self.epsilon = 0.0001
  9. self.conv = Conv(c1, c2, 1 ,1 ,0 )
  10. self.act= nn.ReLU()
  11. def forward(self, x): # mutil-layer 1-3 layers #ADD or Concat
  12. #print("bifpn:",x.shape)
  13. if len(x) == 2:
  14. w = self.w1
  15. weight = w / (torch.sum(w, dim=0) + self.epsilon)
  16. x = self.conv(self.act(weight[0] * x[0] + weight[1] * x[1]))
  17. elif len(x) == 3:
  18. w = self.w2
  19. weight = w / (torch.sum(w, dim=0) + self.epsilon)
  20. x = self.conv(self.act (weight[0] * x[0] + weight[1] * x[1] + weight[2] * x[2]))
  21. # elif len(x) == 4:
  22. # w = self.w3
  23. # weight = w / (torch.sum(w, dim=0) + self.epsilon)
  24. # x = self.conv(self.act(weight[0] * x[0] + weight[1] * x[1] + weight[2] *x[2] + weight[3]*x[3] ))
  25. return x

2.2第二步:yolo.py中注册Concat_BIFPNt模块

  1. elif m is Concat_bifpn:
  2. c2 = max([ch[x] for x in f])

 2.3第三步:修改yaml文件(以修改官方YOLOv5s.yaml为例),需要修改head(特征融合网络)

  1. # parameters
  2. nc: 80 # number of classes
  3. depth_multiple: 0.33 # model depth multiple
  4. width_multiple: 0.50 # layer channel multiple
  5. # anchors
  6. anchors:
  7. - [10,13, 16,30, 33,23] # P3/8
  8. - [30,61, 62,45, 59,119] # P4/16
  9. - [116,90, 156,198, 373,326] # P5/32
  10. # YOLOv5 backbone
  11. backbone:
  12. # [from, number, module, args]
  13. [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
  14. [-1, 1, Conv, [128, 3, 2]], # 1-P2/4
  15. [-1, 3, C3, [128]],
  16. [-1, 1, Conv, [256, 3, 2]], # 3-P3/8
  17. [-1, 6, C3, [256]],
  18. [-1, 1, Conv, [512, 3, 2]], # 5-P4/16
  19. [-1, 9, C3, [512]],
  20. [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
  21. [-1, 3, C3, [1024]],
  22. [-1, 1, SPPF, [1024, 5]],
  23. ]
  24. # YOLOv5 head
  25. head:
  26. [[-1, 1, Conv, [512, 1, 1]],
  27. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
  28. [[-1,6], 1, Concat_bifpn, [256,256]], # cat backbone P4
  29. [-1, 3, C3, [512, False]], # 13
  30. [-1, 1, Conv, [256, 1, 1]],
  31. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
  32. [[-1, 4], 1, Concat_bifpn, [128,128]], # cat backbone P3
  33. [-1, 3, C3, [256, False]], # 17 (P3/8-small)
  34. [-1, 1, Conv, [512, 3, 2]], # 320, 640 #
  35. [[-1, 6, 13], 1, Concat_bifpn, [256,256]], # cat head P4
  36. [-1, 3, C3, [512, False]], # 20 (P4/16-medium)
  37. [-1, 1, Conv, [1024, 3, 2]], # 640, 1280 #
  38. [[-1, 9], 1, Concat_bifpn, [512, 512]], # cat head P5 cat 20,20 #22
  39. [-1, 3, C3, [1024, False]], # 25 (P5/32-large) # 1280, 1280 #23
  40. [[17, 20, 23], 1, Detect, [nc, anchors]] # Detect(P3, P4, P5)
  41. ]

Model Summary: 290 layers, 8114651 parameters, 8114651 gradients, 17.4 GFLOPs

 如果需要在YOLOv5l.yaml等网络结构进行修改的话,不可直接用以上的yaml文件或者就简单修改depth_multiple为1.0,而是 需要修改Concat_bifpn, [256,256]中的通道数为对应网络实际通道数。具体如下所示:

  1. # parameters
  2. nc: 80 # number of classes
  3. depth_multiple: 1.0 # model depth multiple
  4. width_multiple: 1.0 # layer channel multiple
  5. # anchors
  6. anchors:
  7. - [10,13, 16,30, 33,23] # P3/8
  8. - [30,61, 62,45, 59,119] # P4/16
  9. - [116,90, 156,198, 373,326] # P5/32
  10. # YOLOv5 backbone
  11. backbone:
  12. # [from, number, module, args]
  13. [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
  14. [-1, 1, Conv, [128, 3, 2]], # 1-P2/4
  15. [-1, 3, C3, [128]],
  16. [-1, 1, Conv, [256, 3, 2]], # 3-P3/8
  17. [-1, 6, C3, [256]],
  18. [-1, 1, Conv, [512, 3, 2]], # 5-P4/16
  19. [-1, 9, C3, [512]],
  20. [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
  21. [-1, 3, C3, [1024]],
  22. [-1, 1, SPPF, [1024, 5]],
  23. ]
  24. # YOLOv5 head
  25. head:
  26. [[-1, 1, Conv, [512, 1, 1]],
  27. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
  28. [[-1,6], 1, Concat_bifpn, [512,512]], # cat backbone P4
  29. [-1, 3, C3, [512, False]], # 13
  30. [-1, 1, Conv, [256, 1, 1]],
  31. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
  32. [[-1, 4], 1, Concat_bifpn, [256,256]], # cat backbone P3
  33. [-1, 3, C3, [256, False]], # 17 (P3/8-small)
  34. [-1, 1, Conv, [512, 3, 2]], # 320, 640 #
  35. [[-1, 6, 13], 1, Concat_bifpn, [512,512]], # cat head P4
  36. [-1, 3, C3, [512, False]], # 20 (P4/16-medium)
  37. [-1, 1, Conv, [1024, 3, 2]], # 640, 1280 #
  38. [[-1, 9], 1, Concat_bifpn, [1024, 1024]], # cat head P5 cat 20,20 #22
  39. [-1, 3, C3, [1024, False]], # 25 (P5/32-large) # 1280, 1280 #23
  40. [[17, 20, 23], 1, Detect, [nc, anchors]] # Detect(P3, P4, P5)
  41. ]

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/248809
推荐阅读
相关标签
  

闽ICP备14008679号