[YOLOv8/YOLOv7/YOLOv5系列算法改进NO.5]改进特征融合网络PANET为BIFPN(更新添加小目标检测层yaml)

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
大数据开发治理平台 DataWorks,不限时长
简介: 本文介绍了改进YOLOv5以解决处理复杂背景时可能出现的错漏检问题。

前      言:作为当前先进的深度学习目标检测算法YOLOv5,已经集合了大量的trick,但是在处理一些复杂背景问题的时候,还是容易出现错漏检的问题。此后的系列文章,将重点对YOLOv5的如何改进进行详细的介绍,目的是为了给那些搞科研的同学需要创新点或者搞工程项目的朋友需要达到更好的效果提供自己的微薄帮助和参考。

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

image.gif 编辑

image.gif 编辑


2023.1.8更新

有朋友问在添加小目标检测层,四个检测层的基础上如何改进特征融合网络,改进方法其他不变,需要修改yaml文件,有需要可关注私信我。 部分yaml内容如下所示:完整见百度网盘链接:链接:https://pan.baidu.com/s/1Qnn6QtGbZ7H3_h89QYA2vQ
提取码:关注私信后获取——扣扣
2453038530

# parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple
# anchors
anchors:
  - [ 19,27,  44,40,  38,94 ]  # P3/8
  - [ 96,68,  86,152,  180,137 ]  # P4/16
  - [ 140,301,  303,264,  238,542 ]  # P5/32
  - [ 436,615,  739,380,  925,792 ]  # P6/64
# YOLOv5 backbone
backbone:
  # [from, number, module, args]
  [ [-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
    [ -1, 1, Conv, [ 128, 3, 2 ] ],  # 1-P2/4
    [ -1, 3, C3, [ 128 ] ],
    [ -1, 1, Conv, [ 256, 3, 2 ] ],  # 3-P3/8
    [ -1, 6, C3, [ 256 ] ],  #4
    [ -1, 1, Conv, [ 512, 3, 2 ] ],  # 5-P4/16
    [ -1, 9, C3, [ 512 ] ], #6
    [ -1, 1, Conv, [ 768, 3, 2 ] ],  # 7-P5/32
    [ -1, 3, C3, [ 768 ] ], #8
    [ -1, 1, Conv, [ 1024, 3, 2 ] ],  # 9-P6/64
    [ -1, 3, C3, [ 1024 ] ],
    [ -1, 1, SPPF, [ 1024, 5 ] ], # 11
  ]
# BIFPN garph
#                        
# p6     ----------------- --------Concat_bifpn----> P6(out)
#      /                  \                         \       \
#      /-------------------------------------------->  
#     /                Upsample              Concat_bifpn   Concat_bifpn
#    /                    |                          \      | 
# p5 ---Concat_bifpn---> head 5 ---Concat_bifpn----> P5(out)
#                        \                                  \
#                      Upsample                              Concat_bifpn
#       ----------------  | ----------------------->        /
#     /                   \                         \       \
#    /                    |                  Concat_bifpn   |
#   /                     \                          \     |
# p4 ---Concat_bifpn---> head 4 ---Concat_bifpn--->  P4(out)
#                        \                                 \
#                         ----Upsample---->                Concat_bifpn   
#                                          \               /
# p3 ---Concat_bifpn------------------------------>  P3(out)
  
# YOLOv5 head                                                                       
head:                                                                       
  [ [ -1, 1, Conv, [ 768, 1, 1 ] ],    # 12 head                                  
    [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],                           
    [ [ -1, 8 ], 1, Concat_bifpn, [ 384,384] ],  # cat backbone P5                
    [ -1, 3, C3, [ 768, False ] ],  # 15
    [ -1, 1, Conv, [ 512, 1, 1 ] ],
    [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],
    [ [ -1, 6 ], 1, Concat_bifpn, [ 256,256] ],  # cat backbone P4
    [ -1, 3, C3, [ 512, False ] ],  # 19

image.gif

添加方法(以下改进步骤方法为在三个检测层的基础上)

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

class Concat_bifpn(nn.Module):
    # Concatenate a list of tensors along dimension
    def __init__(self, c1, c2):
        super(Concat_bifpn, self).__init__()
        self.w1 = nn.Parameter(torch.ones(2, dtype=torch.float32), requires_grad=True)
        self.w2 = nn.Parameter(torch.ones(3, dtype=torch.float32), requires_grad=True)
       # self.w3 = nn.Parameter(torch.ones(3, dtype=torch.float32), requires_grad=True)
        self.epsilon = 0.0001
        self.conv = Conv(c1, c2, 1 ,1 ,0 )
        self.act= nn.ReLU()
    def forward(self, x): # mutil-layer 1-3 layers #ADD or Concat 
        #print("bifpn:",x.shape)
        if len(x) == 2:
            w = self.w1
            weight = w / (torch.sum(w, dim=0) + self.epsilon)
            x = self.conv(self.act(weight[0] * x[0] + weight[1] * x[1]))
        elif len(x) == 3: 
            w = self.w2
            weight = w / (torch.sum(w, dim=0) + self.epsilon)
            x = self.conv(self.act (weight[0] * x[0] + weight[1] * x[1] + weight[2] * x[2]))
        # elif len(x) == 4:    
        #     w = self.w3
        #     weight = w / (torch.sum(w, dim=0) + self.epsilon)
        #     x = self.conv(self.act(weight[0] * x[0] + weight[1] * x[1] + weight[2] *x[2] + weight[3]*x[3] ))
        return x

image.gif

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

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

image.gif

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

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

image.gif

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

image.gif

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

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

image.gif

第四步:将train.py中改为本文的yaml文件即可,开始训练

结    果:本人在多个数据集上做了大量实验,针对不同的数据集效果不同,同一个数据集的不同添加位置方法也是有差异,需要大家进行实验。有效果有提升的情况占大多数。

预告一下:下一篇内容分享增加小目标检测层。有兴趣的朋友可以关注一下我,有问题可以留言或者私聊我哦

PS:,不仅仅是可以添加进YOLOv5,也可以添加进任何其他的深度学习网络,不管是分类还是检测还是分割,主要是计算机视觉领域,都可能会有不同程度的提升效果。

最后,四个检测层的基础上改进特征融合网络为BIFPN的话,需要修改yaml文件,有需要可关注私信我。

相关文章
|
2月前
|
编解码 缓存 计算机视觉
改进的yolov5目标检测-yolov5替换骨干网络-yolo剪枝(TensorRT及NCNN部署)-1
改进的yolov5目标检测-yolov5替换骨干网络-yolo剪枝(TensorRT及NCNN部署)-1
126 0
|
2月前
|
算法 PyTorch 计算机视觉
改进的yolov5目标检测-yolov5替换骨干网络-yolo剪枝(TensorRT及NCNN部署)-2
改进的yolov5目标检测-yolov5替换骨干网络-yolo剪枝(TensorRT及NCNN部署)-2
100 1
改进的yolov5目标检测-yolov5替换骨干网络-yolo剪枝(TensorRT及NCNN部署)-2
|
2月前
|
机器学习/深度学习 测试技术 Ruby
YOLOv5改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
YOLOv5改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
130 2
|
2月前
|
计算机视觉
YOLOv5改进 | 主干篇 | 低照度图像增强网络SCINet改进黑暗目标检测(全网独家首发)
YOLOv5改进 | 主干篇 | 低照度图像增强网络SCINet改进黑暗目标检测(全网独家首发)
78 3
|
2月前
|
机器学习/深度学习 测试技术 计算机视觉
YOLOv5改进 | 主干篇 | 低照度增强网络Retinexformer改进黑夜目标检测 (2023.11最新成果,全网独家首发)
YOLOv5改进 | 主干篇 | 低照度增强网络Retinexformer改进黑夜目标检测 (2023.11最新成果,全网独家首发)
60 0
|
3月前
|
存储 IDE 测试技术
玩转数据处理利器:学会使用 YAML 文件轻松处理数据
玩转数据处理利器:学会使用 YAML 文件轻松处理数据
57 0
|
6月前
|
Kubernetes Cloud Native 应用服务中间件
【云原生】使用k8s创建nginx服务—通过yaml文件svc类型暴露
【云原生】使用k8s创建nginx服务—通过yaml文件svc类型暴露
133 0
|
6月前
|
Web App开发 资源调度 JavaScript
SAP Fiori Elements 应用里的 ui5.yaml 文件详解试读版
SAP Fiori Elements 应用里的 ui5.yaml 文件详解试读版
76 0
|
6月前
|
Kubernetes 应用服务中间件 nginx
kubernetes集群命令行工具kubectl介绍&yaml文件介绍-20230208
kubernetes集群命令行工具kubectl介绍&yaml文件介绍-20230208
|
2月前
|
机器学习/深度学习 数据可视化 计算机视觉
YOLOv5改进 | 2023Neck篇 | 轻量级跨尺度特征融合模块CCFM(附yaml文件+添加教程)
YOLOv5改进 | 2023Neck篇 | 轻量级跨尺度特征融合模块CCFM(附yaml文件+添加教程)
149 1