YOLOv5改进 | 注意力机制 | 用于增强小目标感受野的RFEM


💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡


专栏目录: 《YOLOv5入门 + 改进涨点》专栏介绍 & 专栏目录 |目前已有40+篇内容,内含各种Head检测头、损失函数Loss、Backbone、Neck、NMS等创新点改进


近年来,基于深度学习的人脸检测算法取得了很大进步。这些算法大致可以分为两类,即类似于Faster R-CNN的两阶段检测器和类似于YOLO的一阶段检测器。由于在一阶段检测器中准确性和速度之间有更好的平衡,因此它们被广泛应用于许多应用中。研究者设计了一个名为RFE的感受野增强模块,用于增强小目标的感受野。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改并将修改后的完整代码放在文章的最后,方便大家一键运行小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。

专栏地址YOLOv5改进+入门——持续更新各种有效涨点方法——点击即可跳转

目录

1. 原理

2. C3RFEM的代码实现

2.1 将C3RFEM添加到YOLOv5中

2.2 新增yaml文件

2.3 注册模块

2.4 执行程序

3. 完整代码分享

4. GFLOPs

5. 进阶

6. 总结


1. 原理

论文地址:YOLO-FaceV2: A Scale and Occlusion Aware Face Detector——点击即可跳转

官方代码:官方代码仓库——点击即可跳转

RFEM(Receptive Field Enhancement Module)是用于增强神经网络中特征图感受野的模块。在深度学习和计算机视觉中,感受野(Receptive Field)是指卷积神经网络中某个神经元能够“看到”或影响输入图像的区域。RFEM的设计目的是为了提升神经网络在处理小目标和多尺度目标时的性能。以下是RFEM的主要原理和功能:

  1. 感受野的扩展:RFEM通过使用扩张卷积(Dilated Convolution)技术来扩大特征图的感受野。扩张卷积能够在不增加参数数量的情况下增加卷积核的感受野,从而能够更好地捕捉到输入图像中的远程依赖关系和上下文信息。

  2. 多尺度特征融合:RFEM不仅仅是简单地扩展感受野,还通过多尺度特征融合来增强特征图的表示能力。在卷积神经网络中,不同层的特征图包含不同尺度的信息,通过融合这些多尺度特征,RFEM能够更有效地处理不同尺度的目标。

  3. 处理小目标和大尺度变化:在许多应用中,例如人脸检测,小目标和尺度变化大的目标检测是一个重要挑战。RFEM通过感受野的扩展和多尺度特征的融合,能够提高对小目标和大尺度变化目标的检测能力。

  4. 集成到现有的检测架构中:RFEM可以很容易地集成到现有的检测架构中,例如YOLO、Faster R-CNN等。通过在这些架构的特定层次上加入RFEM模块,可以显著提升检测性能,特别是在处理复杂场景和小目标时。

总结来说,RFEM通过扩展感受野和多尺度特征融合,提高了神经网络在处理小目标和多尺度目标时的检测能力,并且可以集成到各种现有的检测架构中以提升其性能。这使得RFEM成为一种有效的改进模块,用于提升深度学习模型在复杂场景中的表现。

2. C3RFEM的代码实现

2.1 将C3RFEM添加到YOLOv5中

关键步骤一: 将下面代码粘贴到/yolov5-6.1/models/common.py文件中

*注:代码太长,完整代码请查看下方的完整代码分享

class TridentBlock(nn.Module):
    def __init__(self, c1, c2, stride=1, c=False, e=0.5, padding=None, dilate=None, bias=False):
        super(TridentBlock, self).__init__()
        if padding is None:
            padding = [1, 2, 3]
        if dilate is None:
            dilate = [1, 2, 3]
        self.stride = stride
        self.c = c
        c_ = int(c2 * e)
        self.padding = padding
        self.dilate = dilate
        self.share_weightconv1 = nn.Parameter(torch.Tensor(c_, c1, 1, 1))
        self.share_weightconv2 = nn.Parameter(torch.Tensor(c2, c_, 3, 3))

        self.bn1 = nn.BatchNorm2d(c_)
        self.bn2 = nn.BatchNorm2d(c2)

        self.act = nn.SiLU()

        nn.init.kaiming_uniform_(self.share_weightconv1, nonlinearity="relu")
        nn.init.kaiming_uniform_(self.share_weightconv2, nonlinearity="relu")

        if bias:
            self.bias = nn.Parameter(torch.Tensor(c2))
        else:
            self.bias = None

        if self.bias is not None:
            nn.init.constant_(self.bias, 0)

    def forward_for_small(self, x):
        residual = x
        out = nn.functional.conv2d(x, self.share_weightconv1, bias=self.bias)
        out = self.bn1(out)
        out = self.act(out)

        out = nn.functional.conv2d(out, self.share_weightconv2, bias=self.bias, stride=self.stride,
                                   padding=self.padding[0],
                                   dilation=self.dilate[0])
        out = self.bn2(out)
        out += residual
        out = self.act(out)

        return out

    def forward_for_middle(self, x):
        residual = x
        out = nn.functional.conv2d(x, self.share_weightconv1, bias=self.bias)
        out = self.bn1(out)
        out = self.act(out)

        out = nn.functional.conv2d(out, self.share_weightconv2, bias=self.bias, stride=self.stride,
                                   padding=self.padding[1],
                                   dilation=self.dilate[1])
        out = self.bn2(out)
        out += residual
        out = self.act(out)

        return out

    def forward_for_big(self, x):
        residual = x
        out = nn.functional.conv2d(x, self.share_weightconv1, bias=self.bias)
        out = self.bn1(out)
        out = self.act(out)

        out = nn.functional.conv2d(out, self.share_weightconv2, bias=self.bias, stride=self.stride,
                                   padding=self.padding[2],
                                   dilation=self.dilate[2])
        out = self.bn2(out)
        out += residual
        out = self.act(out)

        return out

    def forward(self, x):
        xm = x
        base_feat = []
        if self.c is not False:
            x1 = self.forward_for_small(x)
            x2 = self.forward_for_middle(x)
            x3 = self.forward_for_big(x)
        else:
            x1 = self.forward_for_small(xm[0])
            x2 = self.forward_for_middle(xm[1])
            x3 = self.forward_for_big(xm[2])

        base_feat.append(x1)
        base_feat.append(x2)
        base_feat.append(x3)

        return base_feat

RFEM (Receptive Field Enhancement Module) 是一种改进模型的技术,专门针对多尺度目标检测问题进行优化。RFEM的处理流程主要包括以下几个步骤:

特征提取(Backbone)

在YOLO-FaceV2中,采用CSPDarknet53作为骨干网络(Backbone),负责从输入图像中提取多尺度特征。为了扩展感受野并增强多尺度融合能力,P5层的CSP模块被RFEM模块所取代。

感受野增强模块(RFE)

RFEM模块的设计目的是利用扩展卷积(dilated convolution)来捕获多尺度信息。它包括多个分支,每个分支使用不同的扩展率进行卷积操作,以捕获不同范围的依赖关系。然后,通过信息聚合和加权层将这些信息进行整合和平衡,以提高特征图的感受野。

网络结构(Neck)

Neck部分主要由空间金字塔池化(SPP)和路径聚合网络(PAN)组成。SPP用于提取最重要的上下文特征并增加感受野,PAN则从不同骨干层级聚合参数以适应不同的检测层级。此外,通过融合P2层特征,进一步提升目标位置感知能力。

多头注意力网络(SEAM)

为了应对遮挡问题,引入了多头注意力网络(SEAM)。该模块通过深度可分离卷积和残差连接来增强特征之间的关系,并通过指数函数进行归一化处理,最后将SEAM模块的输出作为注意力权重乘以原始特征,以增强模型对遮挡面部的处理能力。

通过上述步骤,RFEM模块在YOLOv8基础上实现了多尺度信息的充分利用和遮挡问题的有效处理,从而提升了模型的检测精度和鲁棒性。

2.2 新增yaml文件

关键步骤二在下/yolov5-6.1/models下新建文件 yolov5_C3RFEM.yaml并将下面代码复制进去

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license

# Parameters
nc: 80  # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # 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
   [-1, 1, C3RFEM, [1024]],
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # 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, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)

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

温馨提示:本文只是对yolov5l基础上添加模块,如果要对yolov5n/l/m/x进行添加则只需要指定对应的depth_multiple 和 width_multiple。


# YOLOv5n
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.25  # layer channel multiple
 
# YOLOv5s
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple
 
# YOLOv5l 
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple
 
# YOLOv5m
depth_multiple: 0.67  # model depth multiple
width_multiple: 0.75  # layer channel multiple
 
# YOLOv5x
depth_multiple: 1.33  # model depth multiple
width_multiple: 1.25  # layer channel multiple

2.3 注册模块

关键步骤三在yolo.py中注册 添加“C3RFEM",

2.4 执行程序

在train.py中,将cfg的参数路径设置为yolov5_C3RFEM.yaml的路径

建议大家写绝对路径,确保一定能找到

🚀运行程序,如果出现下面的内容则说明添加成功🚀

3. 完整代码分享

https://pan.baidu.com/s/10ciB-HSBJ50Y3y27-NFJRg?pwd=8csu

提取码: 8csu 

4. GFLOPs

关于GFLOPs的计算方式可以查看百面算法工程师 | 卷积基础知识——Convolution

未改进的GFLOPs

img

改进后的GFLOPs

5. 进阶

可以和损失函数的修改相结合,效果可能会更好

YOLOv5改进 | 损失函数 | EIoU、SIoU、WIoU、DIoU、FocusIoU等多种损失函数

6. 总结

RFEM(Receptive Field Enhancement Module)模块的主要原理是通过结合空洞卷积和多尺度特征融合技术来扩展神经网络的感受野。具体来说,RFEM使用多个不同扩展率的卷积分支来捕获不同尺度的特征,这些分支的输出通过信息聚合和加权层进行整合,以生成具有更大感受野和更丰富上下文信息的特征图。这一过程不仅提高了网络对小目标和多尺度目标的检测能力,还增强了在复杂场景中处理目标遮挡和形变的性能。通过集成到现有检测架构中,RFEM显著提升了检测模型的整体表现。

  • 19
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kay_545

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

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

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

打赏作者

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

抵扣说明:

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

余额充值