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

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时计算 Flink 版,5000CU*H 3个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: 本文介绍了改进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文件,有需要可关注私信我。

相关文章
|
7天前
|
存储 安全 网络安全
云计算与网络安全的融合之路
【10月更文挑战第38天】在数字化浪潮中,云计算和网络安全是推动现代企业前进的两个关键因素。本文深入探讨了云计算服务如何影响网络安全策略,并提供了加强云环境下信息安全的实际措施。文章首先概述了云计算的基本概念及其带来的安全挑战,随后分析了当前网络安全的主要威胁,并提出了相应的防护对策。最后,通过一个代码示例,展示了如何在云环境中实现数据加密,以增强信息的安全性。
|
7天前
|
云安全 安全 网络安全
云计算与网络安全:技术融合的未来之路
【10月更文挑战第38天】 在数字化浪潮中,云计算和网络安全成为支撑现代企业和个人数据安全的两大基石。本文将深入探讨云计算服务如何与网络安全技术相结合,保障信息安全,并分析面临的挑战及未来发展趋势。我们将通过实际案例,揭示云安全的最佳实践,为读者提供一条清晰的技术融合路径。
|
7天前
|
安全 网络安全 数据库
云计算与网络安全:技术融合的未来之路
【10月更文挑战第37天】本文将探讨云计算与网络安全的交汇点,揭示它们如何共同塑造信息安全的未来。我们将深入了解云服务的核心组件、网络安全的关键策略以及两者如何相互增强。通过分析当前的挑战和未来的趋势,本文旨在为读者提供一条清晰的路径,以理解并应对这一不断发展的技术领域。
|
10天前
|
存储 安全 网络安全
云计算与网络安全:技术融合与挑战
【10月更文挑战第35天】本文将探讨云计算与网络安全的交叉点,包括云服务、网络安全和信息安全等技术领域。我们将深入了解云计算的基本概念,以及如何通过云服务实现网络安全和信息安全。同时,我们还将讨论云计算面临的安全挑战,并提出相应的解决方案。最后,我们将通过代码示例展示如何在云计算环境中实现网络安全和信息安全。
24 3
|
2月前
|
JSON Kubernetes API
深入理解Kubernetes配置:编写高效的YAML文件
深入理解Kubernetes配置:编写高效的YAML文件
|
5月前
|
存储 运维 Serverless
函数计算产品使用问题之在YAML文件中配置了环境变量,但在PHP代码中无法读取到这些环境变量,是什么原因
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
1月前
|
Kubernetes 应用服务中间件 nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
|
1月前
|
Kubernetes Docker Perl
k8s常见故障--yaml文件检查没有问题 pod起不来(一直处于创建中)
k8s常见故障--yaml文件检查没有问题 pod起不来(一直处于创建中)
|
1月前
ingress相关yaml文件报错且相关资源一切正常解决方法
ingress相关yaml文件报错且相关资源一切正常解决方法
ingress相关yaml文件报错且相关资源一切正常解决方法
|
4月前
|
运维 Kubernetes Serverless
Serverless 应用引擎使用问题之s.yaml文件中如何使用外部环境变量
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。