YOLOv5改进 | 注意力机制 | 轻量级的空间组增强模块SGE【全网独家】

秋招面试专栏推荐 深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 


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


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


卷积神经网络(CNN)通过收集复杂对象的分层和不同部分的语义子特征来生成特征表示。这些子特征通常在每个层的特征向量中以分组形式分布,代表各种语义实体。然而,这些子特征的激活往往受到相似模式和噪声背景的空间影响,导致错误的定位和识别。一个空间组增强(SGE)模块可以为每个语义组中每个空间位置生成一个注意力因子,从而调整每个子特征的重要性,以便每个组可以自主地增强其学习的表达并抑制可能的噪声。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改,并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。

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

目录

1. 原理

2. 将SGE添加到YOLOv5中

2.1 代码实现

 2.2 新增yaml文件

2.3 注册模块

2.4 执行程序

3. 完整代码分享

4. GFLOPs

 5. 进阶

6. 总结


1. 原理

论文地址:Spatial Group-wise Enhance: Improving Semantic Feature Learning in Convolutional Networks——点击即可跳转

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

空间分组增强 (SGE) 模块旨在通过解决特征图中的空间错位和噪声来改进卷积神经网络 (CNN) 中的语义特征学习。以下是 SGE 模块的主要原理和机制:

分组特征

  • 特征沿卷积特征图的通道维度分组。这意味着将特征图分成几个组,每个组包含通道的子集。

注意机制

  • 在每个组中,根据全局特征和局部特征之间的相似性生成注意掩码。全局特征是组内所有特征的平均值,局部特征是该组内特定空间位置的特征。

  • 注意掩码用于缩放每个空间位置的特征向量,增强重要特征并抑制噪声。这有助于确保语义特征在图像的空间维度上分布良好且稳健。

轻量级设计

  • SGE 模块的设计具有计算效率,几乎不需要额外的参数或计算。这是通过使用点积和归一化等简单操作来生成注意掩码来实现的。

归一化和缩放

  • 计算基于相似性的系数(注意分数)后,对其进行归一化,以确保不同样本之间的缩放一致。这涉及减去平均值并除以每个组内系数的标准差。

  • 然后使用可学习的参数对归一化的分数进行缩放和移位,确保网络可以在训练期间灵活调整 SGE 模块的影响。

性能提升

  • 事实证明,SGE 模块可以提高各种 CNN 架构在图像识别任务上的性能。它可以提高 ImageNet 基准测试中的 Top-1 准确率,并提高 COCO 基准测试中物体检测任务的平均准确率 (AP)。

总体而言,SGE 模块增强了每个组内语义特征的空间分布,从而使 CNN 中的特征表示更加准确和稳健。

2. 将SGE添加到YOLOv5中

2.1 代码实现

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

from torch.nn import init

class SpatialGroupEnhance(nn.Module):
    def __init__(self, groups=8):
        super().__init__()
        self.groups = groups
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.weight = nn.Parameter(torch.zeros(1, groups, 1, 1))
        self.bias = nn.Parameter(torch.zeros(1, groups, 1, 1))
        self.sig = nn.Sigmoid()
        self.init_weights()

    def init_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                init.kaiming_normal_(m.weight, mode='fan_out')
                if m.bias is not None:
                    init.constant_(m.bias, 0)
            elif isinstance(m, nn.BatchNorm2d):
                init.constant_(m.weight, 1)
                init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                init.normal_(m.weight, std=0.001)
                if m.bias is not None:
                    init.constant_(m.bias, 0)

    def forward(self, x):
        b, c, h, w = x.shape
        x = x.view(b * self.groups, -1, h, w)  # bs*g,dim//g,h,w
        xn = x * self.avg_pool(x)  # bs*g,dim//g,h,w
        xn = xn.sum(dim=1, keepdim=True)  # bs*g,1,h,w
        t = xn.view(b * self.groups, -1)  # bs*g,h*w

        t = t - t.mean(dim=1, keepdim=True)  # bs*g,h*w
        std = t.std(dim=1, keepdim=True) + 1e-5
        t = t / std  # bs*g,h*w
        t = t.view(b, self.groups, h, w)  # bs,g,h*w

        t = t * self.weight + self.bias  # bs,g,h*w
        t = t.view(b * self.groups, 1, h, w)  # bs*g,1,h*w
        x = x * self.sig(t)
        x = x.view(b, c, h, w)
        return x

 SGE 模块的核心思想是在每个特征组内部进行空间增强,以提升特征学习的精度和鲁棒性。 具体步骤如下

  1. 特征分组: 将特征图沿通道维度分成多个组,每个组包含代表特定语义的子特征。

  2. 全局特征提取: 对每个组内的所有特征进行全局平均池化,得到一个全局特征向量,代表该组学习的语义信息。

  3. 注意力权重生成: 计算全局特征向量与组内每个位置的特征向量之间的相似度,生成注意力权重向量。相似度越高,注意力权重越大。

  4. 特征增强: 将注意力权重向量通过 sigmoid 函数进行非线性变换,并与原始特征向量相乘,得到增强后的特征向量。 SGE 模块的优点

  • 轻量级: 仅引入少量参数,几乎没有额外的计算量。

  • 高效: 有效提升特征学习的精度和鲁棒性,尤其是在识别具有高级语义的区域时。

  • 可解释性强: 通过可视化注意力权重,可以直观地理解每个组学习的语义信息。

SGE 模块在图像分类和目标检测任务中都取得了显著的性能提升,证明了其在实践中的有效性

 2.2 新增yaml文件

关键步骤二在下/yolov5-6.1/models下新建文件 yolov5_SGE.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
  ]

# 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, SpatialGroupEnhance, [512]],

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

   [[17, 21, 25], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

温馨提示:本文只是对yolov5基础上添加模块,如果要对yolov8n/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中注册 添加“SpatialGroupEnhance",

elif m in [SpatialGroupEnhance]:
            c1, c2 = ch[f], args[0]
            if c2 != no:  # if not output
                c2 = make_divisible(c2 * gw, 8)
            args = [c1, *args[1:]]

2.4 执行程序

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

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

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

3. 完整代码分享

https://pan.baidu.com/s/197WEIC_kHJNMNJxTacNFQg?pwd=m76n

提取码: m76n 

4. GFLOPs

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

未改进的GFLOPs

img

改进后的GFLOPs

5. 进阶

可以与其他的注意力机制或者损失函数等结合,进一步提升检测效果

6. 总结

空间分组增强 (SGE) 模块通过解决特征图中的空间错位和噪声问题,改进了卷积神经网络中的语义特征学习。它沿通道维度对特征进行分组,并在每个组中使用注意机制,根据全局特征和局部特征之间的相似性生成注意掩码。这些掩码增强了重要特征,同时抑制了噪声,确保了语义特征的稳健性和分布性。SGE 模块具有计算效率,只需要极少的附加参数,并使用可学习的参数对注意力分数进行归一化和缩放。这种方法提高了 CNN 在图像识别和物体检测任务上的性能,提高了准确率和精确度。

  • 63
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kay_545

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

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

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

打赏作者

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

抵扣说明:

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

余额充值