YOLOV5中添加CBAM模块详解——原理+代码

YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制 Python、PyTorch、YOLOv5、注意力机制 阅读详情
AI摘要

文章介绍了卷积神经网络中的注意力模块CBAM,包括通道注意力模块CAM和空间注意力模块SAM的工作原理、计算过程、代码实现和流程图。CBAM通过通道和空间两个维度提升特征学习,可以作为即插即用的模块加入到现有的网络架构如YOLOv5中,以提高模型性能。

目录

  • 一、前言
  • 二、CAM
        • 1. CAM计算过程
        • 2. 代码实现
        • 3. 流程图
  • 三、SAM
        • 1. SAM计算过程
        • 2. 代码实现
        • 3. 流程图
  • 四、YOLOv5中添加CBAM模块
  • 参考文章

一、前言

  由于卷积操作通过融合通道和空间信息来提取特征(通过 N × N N×N N×N的卷积核与原特征图相乘,融合空间信息;通过不同通道的特征图加权求和,融合通道信息),论文提出的Convolutional Block Attention Module(CBAM)沿两个独立的维度(通道和空间)依次学习特征,然后与学习后的特征图与输入特征图相乘,进行自适应特征细化。

在这里插入图片描述

图1-1 CBAM结构图

  上图可以看到,CBAM包含CAM(Channel Attention Module)和SAM(Spartial Attention Module)两个子模块,分别进行通道和空间上的Attention。这样不只能够节约参数和计算力,并且保证了其能够做为即插即用的模块集成到现有的网络架构中去。

二、CAM

1. CAM计算过程

在这里插入图片描述

图2-1 CAM结构图

  输入特征图 F F F首先经过两个并行的MaxPool层和AvgPool层,将特征图的维度从 C × H × W C×H×W C×H×W变为 C × 1 × 1 C×1×1 C×1×1,然后经过Shared MLP模块。在该模块中,它先将通道数压缩为原来的 1 / r 1/r 1/r倍,再经过ReLU激活函数,然后扩张到原通道数。将这两个输出结果进行逐元素相加,再通过一个sigmoid激活函数得到Channel Attention的输出结果,然后将这个输出结果与原图相乘,变回 C × H × W C×H×W C×H×W的大小。

  上述过程的计算公式如下:

M c ( F ) = σ ( M L P ( A v g P o o l ( F ) ) + M L P ( M a x P o o l ( F ) ) ) M_{c}(F)=\sigma (MLP(AvgPool(F))+MLP(MaxPool(F))) Mc​(F)=σ(MLP(AvgPool(F))+MLP(MaxPool(F)))
= σ ( W 1 ( W 0 ( F a v g c ) ) + W 1 ( W 0 ( F m a x c ) ) ) =\sigma (W_{1}(W_{0}(F^{c}_{avg}))+W_{1}(W_{0}(F^{c}_{max}))) =σ(W1​(W0​(Favgc​))+W1​(W0​(Fmaxc​)))

  其中, σ \sigma σ代表sigmoid激活函数, W 0 ∈ R C / r × C W_{0}\in R^{C/r\times C} W0​∈RC/r×C, W 1 ∈ R C × C / r W_{1}\in R^{C\times C/r} W1​∈RC×C/r,且MLP的权重 W 0 W_{0} W0​和 W 1 W_{1} W1​对于输入来说是共享的,ReLU激活函数位于 W 0 W_{0} W0​之后, W 1 W_{1} W1​之前。

2. 代码实现
class ChannelAttention(nn.Module):
    def __init__(self, in_planes, ratio=16):
        super(ChannelAttention, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.max_pool = nn.AdaptiveMaxPool2d(1)

        self.f1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False) # 上面公式中的W0
        self.relu = nn.ReLU()
        self.f2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False) # 上面公式中的W1

        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = self.f2(self.relu(self.f1(self.avg_pool(x))))
        max_out = self.f2(self.relu(self.f1(self.max_pool(x))))
        out = self.sigmoid(avg_out + max_out)
        return torch.mul(x, out)
3. 流程图

  CAM过程的详细流程如下图所示:

在这里插入图片描述

图2-2 CAM流程图

三、SAM

1. SAM计算过程

在这里插入图片描述

图3-1 SAM结构图

  将Channel Attention的输出结果通过最大池化和平均池化得到两个 1 × H × W 1×H×W 1×H×W的特征图,然后经过Concat操作对两个特征图进行拼接,再通过 7 × 7 7×7 7×7卷积将特征图的通道数变为 1 1 1(实验证明 7 × 7 7×7 7×7效果比 3 × 3 3×3 3×3好),再经过一个sigmoid得到Spatial Attention的特征图,最后将输出结果与原输入特征图相乘,变回CHW大小。

  上述过程的计算公式如下:

M s ( F ) = σ ( f 7 × 7 ( [ A v g P o o l ( F ) ; M a x P o o l ( F ) ] ) ) M_{s}(F)=\sigma (f^{7\times 7}([AvgPool(F);MaxPool(F)])) Ms​(F)=σ(f7×7([AvgPool(F);MaxPool(F)]))

= σ ( f 7 × 7 ( [ F a v g s ; F m a x s ] ) ) =\sigma (f^{7\times 7}([F^{s}_{avg};F^{s}_{max}])) =σ(f7×7([Favgs​;Fmaxs​]))

  其中, σ \sigma σ代表sigmoid激活函数, f 7 × 7 f^{7\times 7} f7×7代表卷积核大小为 7 × 7 7×7 7×7的卷积过程。

2. 代码实现
class SpatialAttention(nn.Module):
    def __init__(self, kernel_size=7):
        super(SpatialAttention, self).__init__()

        assert kernel_size in (3, 7), 'kernel size must be 3 or 7'
        padding = 3 if kernel_size == 7 else 1

        self.conv = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = torch.mean(x, dim=1, keepdim=True)
        max_out, _ = torch.max(x, dim=1, keepdim=True)
        out = torch.cat([avg_out, max_out], dim=1)
        out = self.sigmoid(self.conv(out))
        return torch.mul(x, out)
3. 流程图

  SAM过程的详细流程如下图所示:

在这里插入图片描述

图3-2 SAM流程图

四、YOLOv5中添加CBAM模块

  • 修改common.py
    在common.py中添加下列代码:
class ChannelAttention(nn.Module):
    def __init__(self, in_planes, ratio=16):
        super(ChannelAttention, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.max_pool = nn.AdaptiveMaxPool2d(1)

        self.f1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False)
        self.relu = nn.ReLU()
        self.f2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)

        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = self.f2(self.relu(self.f1(self.avg_pool(x))))
        max_out = self.f2(self.relu(self.f1(self.max_pool(x))))
        out = self.sigmoid(avg_out + max_out)
        return torch.mul(x, out)


class SpatialAttention(nn.Module):
    def __init__(self, kernel_size=7):
        super(SpatialAttention, self).__init__()

        assert kernel_size in (3, 7), 'kernel size must be 3 or 7'
        padding = 3 if kernel_size == 7 else 1

        self.conv = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = torch.mean(x, dim=1, keepdim=True)
        max_out, _ = torch.max(x, dim=1, keepdim=True)
        out = torch.cat([avg_out, max_out], dim=1)
        out = self.sigmoid(self.conv(out))
        return torch.mul(x, out)


class CBAMC3(nn.Module):
    # CSP Bottleneck with 3 convolutions
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion
        super(CBAMC3, self).__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c1, c_, 1, 1)
        self.cv3 = Conv(2 * c_, c2, 1)
        self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])
        self.channel_attention = ChannelAttention(c2, 16)
        self.spatial_attention = SpatialAttention(7)

    def forward(self, x):
   		# 将最后的标准卷积模块改为了注意力机制提取特征
        return self.spatial_attention(
            self.channel_attention(self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1))))
  • 修改yolo.py
    在yolo.py的if m in [Conv, GhostConv, Bottleneck, GhostBottleneck, SPP, DWConv, MixConv2d, Focus, CrossConv, BottleneckCSP, C3, C3TR,......]中添加CBAMC3,即修改后的代码为:
        if m in [Conv, GhostConv, Bottleneck, GhostBottleneck, SPP, DWConv, MixConv2d, Focus, CrossConv, BottleneckCSP,
                 C3, C3TR, ASPP, CBAMC3]:
            c1, c2 = ch[f], args[0]  
            if c2 != no:  
                c2 = make_divisible(c2 * gw, 8)  
            args = [c1, c2, *args[1:]] 
  • 修改yolov5s.yaml
    修改后的yolov5s.yaml如下:
# 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, CBAMC3, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 6, CBAMC3, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, CBAMC3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, CBAMC3, [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, 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)
  ]

参考文章

CBAM——即插即用的注意力模块(附代码)

即插即用的涨点模块之注意力机制(CBAMAttention)详解及代码,可应用于检测、分割、分类等各种算法领域 CE模块通常只注意了通道特征,但在视觉任务中,空间任务通常更为重要,是不可忽略的,因此CBAM将通道注意力机制与空间注意力机制进行串联,充分关注特征信息。什么是空间特征?在深度学习中,空间特征是指描述输入数据在空间维度上的特征信息。对于图像数据而言,空间特征可以涵盖多种信息,包括边缘、角点、纹理、颜色等。这些特征信息可以帮助模型理解图像中不同区域的内容和结构,从而实现诸如目标检测、图像分割、图像分类等任务。 阅读详情

相关推荐

YOLOv5改进系列(一)添加注意力机制SE、CBAM、ECA、CA

在没有降维的通道全局平均池化之后,ECA使用1D卷积来实现跨通道信息交互,而卷积核的大小 k 则通过函数来自适应计算,k 也可以理解为局部跨通道交互的覆盖范围,即有多少邻居参与了一个通道的注意力预测。激活函数形成空间注意力权重[batch_size,1,H,W],和原来的输入[batch_size,channel,H,W]作哈达玛积。最后,将原始特征图的每个通道与对应的权重相乘,从而得到增强后的特征图。在这一阶段,网络从特征图中提取出每个通道的全局信息,得到一个描述每个通道重要性的特征向量。

m0_55908255的博客 2169

Yolov5 中添加注意力机制 CBAM

从上图中可以看到,前面的卷积神经网络提前特征后,分别进行两个通道注意力计算,两个通道可以并行也可以串行,但是原作者在实验中发现,串行且channel在spatial之前,性能会更好。CBAM将这两个注意力模块嵌入到CNN的卷积层之间,以增强网络对重要特征的关注度。在common.py的尾部添加如下代码,即Channel Attention 模块、Spatial Attention模块、CBAMC3模块。如果运行之后的网络输出中,出现CBAMC3,则说明添加成功,下面就是等待训练的结果。

ruotianxia的博客 5713

YOLOV5添加 ECA CA SE CBAM 等八种注意力机制(小白可用)

⭐欢迎大家订阅我的专栏一起学习⭐。

kay_545 9174

yolov5添加注意力机制(CBAM)

引入CBAM后,YOLOv5在基础骨干网的每个残差单元的最后添加了CBAM模块,并在中间层的SPP(Spatial Pyramid Pooling)层后也添加了CBAM模块。总之,通过引入CBAM注意力机制,YOLOv5改进了网络的基础骨干网、中间层和检测头,使得模型能够更好地捕捉特征之间的依赖关系,提高特征表示能力和检测精度。通过结合通道注意力和空间注意力,CBAM注意力机制能够自适应地调整不同通道和空间位置的重要性,从而提升模型对图像特征的表达能力。,将CBAM添加到我们想添加的位置。

kay_545 1万+

YOLOv5改进系列(1)——添加CBAM注意力机制

例如,在图像分类任务中,模型不需要对整张图像的每一个像素都一视同仁,而是可以专注于那些关键区域,如目标物体的边缘或特征。在句子处理时,模型可以根据句子的上下文,专注于那些对语义理解最为关键的单词或短语,而忽略不太重要的部分。当你听到某些关键字时,比如“你的名字”或者“你感兴趣的话题”,你会自动把注意力从书上转移到他们的谈话上,尽管你并没有完全忽略书本的内容。(7×7比3×3效果更好)操作,降维为1个channel,即叠积核融合通道信息,特征图的shape从b,2,h,w - >b,1,h,w。

vimpirespider的博客 3960

改进YOLOv5:引入CBAM注意力机制的计算机视觉模型

CBAM注意力机制由两个部分组成:通道注意力模块(Channel Attention Module)和空间注意力模块(Spatial Attention Module)。通道注意力模块用于对特征图的通道维度进行建模,以便捕捉通道之间的依赖关系;空间注意力模块则用于对特征图的空间维度进行建模,以捕捉不同空间位置之间的关联。目前,计算机视觉领域的目标检测任务中,YOLOv5是一种非常流行的模型。CBAM注意力机制能够帮助模型更好地聚焦于图像中的关键区域,提高目标检测的准确性和鲁棒性。

LgvrApplescript的博客 723

手把手带你YOLOv5/v7 添加注意力机制

手把手带你YOLOv5/v7 添加注意力机制

qwj的博客 3078

Yolov8有效涨点,添加多种注意力机制,修改损失函数提高目标检测准确率

Ultralytics 推出了最新版本的 YOLO 模型。注意力机制是提高模型性能最热门的方法之一。本次将介绍几种常见的注意力机制,这些注意力机制在大多数的数据集上均能有效的提升目标检测的精度/召回率/准确率。

kay_545 3642

YOLO源码解读:Yolov5的改进方案——注意力模块

在本项目中,他的作用是提取原始特征维度中的信息,并将其映射到更高的维度,从而增强模型的表达能力和分类精度,但似乎并没有用到所谓的share,作用相当于一般的MLP模块,即特征转换、特征提取。通道域旨在显示的建模出不同通道之间的相关性,通过网络学习的方式来自动获取到每个特征通道的重要程度,最后再为每个通道赋予不同的权重系数,从而来强化重要的特征抑制非重要的特征。3.对压缩后的特征图,进行通道特征学习,实现: 通过FC全连接层操作学习,得到具有通道注意力的特征图,它的维度还是1。该模块关注的是目标的位置信息。

wusuoweiieq的博客 1336

在yolov5的网络结构中添加注意力机制模块

会点就总结

XingshiXu 4万+

YOLOv5改进系列(一) YOLOv5添加注意力机制SE CBAM ECA CA SimAM S2-MLPv2 NAMAttention Criss-CrossAttention等

注意力机制(Attention Mechanism)源于对人类视觉的研究。在认知科学中,由于信息处理的瓶颈,人类会选择性地关注所有信息的一部分,同时忽略其他可见的信息。为了合理利用有限的视觉信息处理资源,人类需要选择视觉区域中的特定部分,然后集中关注它。例如,人们在阅读时,通常只有少量要被读取的词会被关注和处理。综上,注意力机制主要有两个方面:决定需要关注输入的哪部分;分配有限的信息处理资源给重要的部分。

专注于人工智能学习,总结 1723

优化改进YOLOv5算法之添加SE、CBAM、CA模块(超详细)

本文主要是在YOLOv5算法中加入SE、CBAM和CA注意力机制模块,通过实验验证对比,加入CBAM和CA注意力机制后的效果均有所提升

qq_40716944的博客 1万+

改进YOLOv5 | 在 C3 模块中添加【SE】【CBAM】【 ECA 】【CA】注意力机制 | 附详细结构图

在 C3 模块中添加【SE】【CBAM】【 ECA 】【CA】注意力机制 | 附详细结构图

Coding... 1万+

改进YOLOv5、YOLOv8系列:21.添加CBAM注意力机制

目标检测科研Trick改进推荐 | 包括Backbone、Neck、Head、注意力机制、IoU损失函数、NMS、Loss计算方式、自注意力机制、数据增强部分、激活函数

包括YOLOv5、YOLOv7、YOLOv8等模型改进 2万+

【YOLOv5/v7 添加注意力机制】 模块八 CBAM模块在YOLOv5/v7中的应用

CBAM(Convolutional Block Attention Module)是一种卷积块注意力模块,它通过通道注意力机制(Channel Attention)和空间注意力机制(Spatial Attention)来增强特征表示能力。CBAM模块可以有效地捕捉特征图中的重要信息,提高模型的性能。

u010117029的博客 173

YOLOv5改进(一) 本文(7万字) | 添加注意力机制 | SE | CBAM | ECA | CA | SimAM | S2-MLPv2 | NAMAttention | 等 | 共计二十种 |

《人工智能专栏》 Python与Python | 机器学习 | 深度学习 | 目标检测 | YOLOv5及其改进 | YOLOv8及其改进 | 关键知识点 | 各种工具教程获取添加完成的注意力机制代码:注意力机制(Attention Mechanism)源于对人类视觉的研究。在认知科学中,由于信息处理的瓶颈,人类会选择性地关注所有信息的一部分,同时忽略其他可见的信息。为了合理利用有限的视觉信息处理资源,人类需要选择视觉区域中的特定部分,然后集中关注它。

专注于人工智能学习,总结 4510

Yolov5--从模块解析到网络结构修改(添加注意力机制)

文章目录1.模块解析(common.py)01. Focus模块02. CONV模块03.Bottleneck模块:04.C3模块05.SPP模块2.为yolov5添加CBAM注意力机制 最近在进行yolov5的二次开发,软件开发完毕后才想着对框架进行一些整理和进一步学习,以下将记录一些我的学习记录。 1.模块解析(common.py)   01. Focus模块 作用:下采样 输入:data( 3×640×640 彩色图片) Focus模块的作用是对图片进行切片,类似于下采样,先将图片变为320

Mr_Clutch的博客 5万+

番外篇 | 20+ 种注意力机制及代码 适用于YOLOv5/v7/v8(新增5种v7模板)

番外篇 | 20+ 种注意力机制及代码 适用于YOLOv5/v7

Coding... 2万+
上一篇: YOLOv8之C2f模块——与YOLOv5的C3模块对比
下一篇: Pytorch语义分割网络的详细训练过程——以NYUv2数据集为例
晓shuo
晓shuo 优质创作者: 人工智能技术领域 优质创作者: 人工智能技术领域
博客等级 码龄6年 4万+粉丝 113原创
评论 12
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

晓shuo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值