YOLOv5添加BiFPN

1、修改common.py文件

2、新建一个yaml文件

3、修改yolo.py文件

4、修改train.py并运行

1、修改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、新建yaml文件

新建一个BiFPN-yolov5s.yaml文件:将concat替换为BiFPN_Add2,代码如下:

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
 
# Parameters
nc: 80  # 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.0 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 (P3/8-small)
 
   [-1, 1, Conv, [512, 3, 2]],  # 为了BiFPN正确add,调整channel数
   [[-1, 13, 6], 1, BiFPN_Add3, [256, 256]],  # cat P4 <--- BiFPN change 注意v5s通道数是默认参数的一半
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)
 
   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, BiFPN_Add2, [256, 256]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)
 
   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

3、修改yolo.py文件

在parse_model函数中找到elif m is Concat,在其后面加上BiFPN_Add相关语句:

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

4、修改train.py文件

在cfg参数中,改为models/BiFPN-yolov5s.yaml

def parse_opt(known=False):
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', type=str, default=ROOT / 'yolov5s.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='models/BiFPN-yolov5s.yaml', help='model.yaml path')  # 更改这一行代码
    parser.add_argument('--data', type=str, default=ROOT / 'data/Hat.yaml', help='dataset.yaml path')

5、运行train.py文件

转载自

https://blog.csdn.net/qq_46542320/article/details/131443434?spm=1001.2014.3001.5506

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
对于YOLOv5模型,添加BiFPN(Bilateral Feature Pyramid Network)可以提高其精度和鲁棒性。BiFPN是一种用于目标检测任务的特征金字塔网络结构,通过在不同层级的特征金字塔上引入双向的信息流动,有效地融合多尺度的特征信息,提升目标检测性能。 要在YOLOv5添加BiFPN,可以按照以下步骤进行操作: 1. 导入所需的库和模块: ```python import torch import torch.nn as nn from models.common import Conv ``` 2. 定义BiFPN类: ```python class BiFPN(nn.Module): def __init__(self, num_channels, num_layers): super(BiFPN, self).__init__() self.num_channels = num_channels self.num_layers = num_layers self.up_convs = nn.ModuleList([Conv(num_channels, num_channels, 1) for _ in range(num_layers)]) self.down_convs = nn.ModuleList([Conv(num_channels, num_channels, 1) for _ in range(num_layers)]) self.p6_up = Conv(num_channels, num_channels, 1) self.p7_down = Conv(num_channels, num_channels, 1) self.swish = nn.SiLU() ``` 3. 实现BiFPN的前向传播方法: ```python def forward(self, inputs): p3, p4, p5, p6, p7 = inputs # Bottom-up pathway p7_td = self.p7_down(p7) p6_td = self.p6_up(p6) + nn.functional.interpolate(p7_td, scale_factor=2, mode='nearest') p5_td = self.up_convs[0](p5) + nn.functional.interpolate(p6_td, scale_factor=2, mode='nearest') p4_td = self.up_convs[1](p4) + nn.functional.interpolate(p5_td, scale_factor=2, mode='nearest') p3_out = self.up_convs[2](p3) + nn.functional.interpolate(p4_td, scale_factor=2, mode='nearest') # Top-down pathway p4_out = self.down_convs[0](p4) + nn.functional.interpolate(p3_out, scale_factor=0.5, mode='nearest') p5_out = self.down_convs[1](p5) + nn.functional.interpolate(p4_out, scale_factor=0.5, mode='nearest') p6_out = self.down_convs[2](p6) + nn.functional.interpolate(p5_out, scale_factor=0.5, mode='nearest') p7_out = self.p7_down(p7) + nn.functional.interpolate(p6_out, scale_factor=0.5, mode='nearest') return p3_out, p4_out, p5_out, p6_out, p7_out ``` 4. 在YOLOv5的主干网络中调用BiFPN: ```python class YOLOv5(nn.Module): def __init__(self, num_classes): super(YOLOv5, self).__init__() # Define the backbone network # Add BiFPN to the backbone self.bifpn = BiFPN(num_channels, num_layers) # Define the rest of the YOLOv5 network ... def forward(self, x): # Backbone network forward pass ... # Apply BiFPN p3, p4, p5, p6, p7 = self.bifpn([p3, p4, p5, p6, p7]) # Rest of the YOLOv5 network forward pass ... return outputs ``` 这样,通过在YOLOv5的主干网络中添加BiFPN,可以增强模型对不同尺度目标的检测能力,提高检测精度和鲁棒性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值