【YOLOv5改进系列(12)】高效涨点(强推!!!)----使用BiFPN特征融合方式替换yolov5中的PANet网络

在这里插入图片描述



在这里插入图片描述

👀🎉📜系列文章目录

【YOLOv5改进系列(1)】高效涨点----使用EIoU、Alpha-IoU、SIoU、Focal-EIOU替换CIou
【YOLOv5改进系列(2)】高效涨点----Wise-IoU详细解读及使用Wise-IoU(WIOU)替换CIOU
【YOLOv5改进系列(3)】高效涨点----Optimal Transport Assignment:OTA最优传输方法
【YOLOv5改进系列(4)】高效涨点----添加可变形卷积DCNv2
【YOLOv5改进系列(5)】高效涨点----添加密集小目标检测NWD方法
【YOLOv5改进系列(6)】高效涨点----使用DAMO-YOLO中的Efficient RepGFPN模块替换yolov5中的Neck部分
【YOLOv5改进系列(7)】高效涨点----使用yolov8中的C2F模块替换yolov5中的C3模块
【YOLOv5改进系列(8)】高效涨点----添加yolov7中Aux head 辅助训练头
【YOLOv5改进系列(9)】高效涨点----使用CAM(上下文增强模块)替换掉yolov5中的SPPF模块
【YOLOv5改进系列(10)】高效涨点----将CAM(上下文增强模块)添加到Neck特征融合模块当中
【YOLOv5改进系列(11)】高效涨点----添加soft-nms(IoU,GIoU,DIoU,CIoU,EIoU,SIoU)到yolov5中

🚀🚀🚀前言

BiFPN即“双向特征金字塔网络”,是一种常用于计算机视觉任务,特别是目标检测和实例分割的神经网络架构。它扩展了特征金字塔网络(FPN),通过在金字塔级别之间引入双向连接,使信息能够在网络中同时进行自底向上和自顶向下的流动。

以下是BiFPN的工作原理概述:

  1. 特征金字塔生成:最初,网络通过从骨干网络(通常是ResNet等卷积神经网络)的多个层中提取特征来生成特征金字塔。

  2. 双向连接:与传统FPN不同,BiFPN在特征金字塔相邻级别之间引入了双向连接。这意味着信息可以从更高级别的特征流向更低级别的特征(自顶向下路径),也可以从更低级别的特征流向更高级别的特征(自底向上路径)。

  3. 特征整合:双向连接允许在两个方向上整合来自特征金字塔不同级别的信息。这种整合有助于有效地捕获多尺度特征。

  4. 加权特征融合:BiFPN采用加权特征融合机制,将不同级别的特征进行组合。融合的权重在训练过程中学习,确保了最佳的特征整合。

BiFPN中的双向连接有助于更好地在不同尺度上捕获特征表示,提高了网络处理不同尺寸和复杂度对象的能力。这在目标检测任务中尤为重要,因为图像中的对象大小可能差异显著。

🔥🔥🔥研究表明,BiFPN可以提高模型的效率和性能,特别是对于目标检测、实例分割和其他相关计算机视觉任务。博主在实验的时候在疵点数据上测试结果效果非常好,map@0.5提升了将近7个百分点,而且F1置信分数也提升了10个百分点


一、1️⃣ BiFPN解读

BiFPN是在EfficientDet: Scalable and Efficient Object Detection这篇论文中提出来的,传统的自上而下的 FPN 本质上受到单向信息流的限制。 为了解决这个问题,PANet 添加了一个额外的自下而上的路径聚合网络,如下图(b)所示。 NAS-FPN采用神经架构搜索来搜索更好的跨尺度特征网络拓扑,但在搜索过程中需要数千个GPU小时,并且发现的网络不规则并且难以解释或修改,如下图(c)所示 。
在这里插入图片描述
通过研究这三个网络的性能和效率,我们观察到 PANet 比 FPN 和 NAS-FPN 实现了更好的精度,但代价是更多的参数和计算量加粗样式。为了提高模型效率,论文作者提出了几种跨尺度连接的优化,也就是BiFPN网络,如图(d):

  • 第一,删除那些只有一个输入边的节点。 我们的直觉很简单:如果一个节点只有一个输入边,没有特征融合,那么它对旨在融合不同特征的特征网络的贡献就会较小,这导致了一个简化的双向网络;
  • 第二,如果原始输入和输出节点处于同一水平,我们在原始输入和输出节点之间增加一条额外的边,以便在不增加太多成本的情况下融合更多的特征;
  • 第三,与PANet只有一条自顶向下和一条自底向上的路径不同,我们将每条双向(自顶向下和自底向上)路径视为一个特征网络层,并多次重复同一层,以实现更高级的特征融合。(在yolo当中PANet都是只有一条的,但是在EfficientDet论文中,作者将BiFPN这个特征融合层设置多次重复,可以融合更加高级的特征)
  • 第四,使用了加权特征融合,像P3~P7这几个stage特征融合的时候设置的有不同权重参数,这样可以保证网络集中在目标特征上面,同时这个权重参数也是通过训练得到的。
    在这里插入图片描述

通过不同特征网络的比较实验数据对比可以看出,论文中的的加权BiFPN以更少的参数和FLOPs达到了最好的精度。

二、2️⃣ BiFPN添加方式

2.1 🎓 在common.py中添加BiFPN模块

📌📌📌将下面BiFPN模块的代码复制粘贴到common.py文件的末尾。

# BiFPN 
# 两个特征图add操作
class BiFPN_Add2(nn.Module):
    def __init__(self, c1, c2):
        super(BiFPN_Add2, self).__init__()
        # 设置可学习参数 nn.Parameter的作用是:将一个不可训练的类型Tensor转换成可以训练的类型parameter
        # 并且会向宿主模型注册该参数 成为其一部分 即model.parameters()会包含这个parameter
        # 从而在参数优化的时候可以自动一起优化
        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]))
 
 
# 三个特征图add操作
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)  
        # Fast normalized fusion
        return self.conv(self.silu(weight[0] * x[0] + weight[1] * x[1] + weight[2] * x[2]))

2.2 ✨在yolo.py文件中加入BiFPN

📌在yolo.py文件的parse_model网络解析函数中找到 elif m is Concat: 语句,在其后面加上下列语句:

# 添加bifpn_add结构
elif m in [BiFPN_Add2, BiFPN_Add3]:
    c2 = max([ch[x] for x in f])

在这里插入图片描述

2.3 ⭐️自定义yolov5s_BiFPN.yaml文件

📌将head配置文件中的所有concat连接都替换成BiFPN_Add2模块还有BiFPN_Add3模块,配置文件如下:

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license

# Parameters
nc: 6  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple
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 v6.0 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]],  # 9
  ]

# YOLOv5 v6.1 BiFPN head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, BiFPN_Add2, [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, BiFPN_Add2, [128, 128]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 13, 6], 1, BiFPN_Add3, [256, 256]],  #v5s通道数是默认参数的一半
   [-1, 3, C3, [512, False]],  # 20

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, BiFPN_Add2, [256, 256]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

2.4 🎯添加yolov5s_BiFPN.yaml

在yolo.py文件里找到DetectionModel函数,将我们刚才定义好的yolov5s_BiFPN.yaml添加进去,同时在main函数里面将默认配置文件也替换成yolov5s_BiFPN.yaml;
在这里插入图片描述
在这里插入图片描述
这个时候我们其实可以直接运行yolo.py文件,查看网络配置结构,由运行结果可以看到,所有Concat已被换成了BiFPN_Add。

在这里插入图片描述

☀️2.5修改train.py文件

📌在train.py文件中找到Optimizer优化器设置这一部分,添加下面这段代码;

    g0, g1, g2 = [], [], []  # optimizer parameter groups
    for v in model.modules():
        if hasattr(v, 'bias') and isinstance(v.bias, nn.Parameter):  # bias
            g2.append(v.bias)
        if isinstance(v, nn.BatchNorm2d):  # weight (no decay)
            g0.append(v.weight)
        elif hasattr(v, 'weight') and isinstance(v.weight, nn.Parameter):  # weight (with decay)
            g1.append(v.weight)
        # BiFPN_Concat
        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)

在这里插入图片描述
📌注意,需要提前在train.py文件中导入我们刚刚的BiFPN_Add2模块还有BiFPN_Add3模块。

from models.common import BiFPN_Add2
from models.common import BiFPN_Add3

将上述步骤完成后,在train.pymain函数里面添加yolov5s_BiFPN.yaml文件即可开始训练
在这里插入图片描述

三、3️⃣ 实验结果

➤yolov5基准模型:F1置信度分数为0.71、map@0.5=0.779;
在这里插入图片描述
➤替换BiFPN:F1置信度分数为0.81、map@0.5=0.856;
在这里插入图片描述


在这里插入图片描述

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Yolov7-tiny系列是一种用于目标检测网络结构,它在物体检测任务具有较高的效率和准确率。为了进一步提升其性能,我们可以对其进行改进,引入bifpn结构的特征融合网络Bifpn结构是一种特征融合网络,它在多个尺度上进行特征融合,可以有效地提取目标的多尺度信息。我们将其与Yolov7-tiny结构进行结合,以获得更多有效的特征。 首先,我们在Yolov7-tiny的每个火箭头后面添加一层bifpn结构。这样,每个火箭头都可以从多个尺度的特征图获取信息,并将其融合到一起。这种特征融合可以提高目标检测的准确性和鲁棒性。 其次,我们可以对bifpn结构进行一些改进。例如,我们可以引入注意力机制来控制特征的重要程度。注意力机制可以根据目标的重要性自适应地调整特征图的权重,从而提高关键目标的检测准确率。 此外,我们还可以利用多尺度的特征进行级联式的检测。即将不同尺度的特征图输入到级联式的分类器,以进一步提升目标检测的性能。级联式的分类器可以对不同尺度的目标进行更准确的判断。 通过以上的改进改进Yolov7-tiny系列可以更好地融合更多有效的特征,提高目标检测的准确率。这将使该系列在实际应用更加可靠和高效。当然,具体的改进方式还需要进一步的实验和验证,以确保其有效性和可行性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕溪同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值