【初窥CBAM】实操版即插即用的注意力机制模块

简介: 【初窥CBAM】实操版即插即用的注意力机制模块

前言

  在2018年提出了了卷积块注意力模块(CBAM),提出了一种简单而有效的前馈卷积神经网络注意力模块,它可以对一个中间特征图在CA&SA(通道&空间)上单独进行推理,然后将注意力结果图与输入特征图融合处理。在本文中为大家带来一个简单的小示例,以Alexnet为CNN基础模板,对Alexnet添加CBAM模块,希望对大家有帮助。

理论基础

  我们对卷积网络中添加注意力机制模块希望达到对核心特征进行多注意,对非核心特征过滤进而达到网络的表现能力增强的效果。由于卷积的运算是通过混合了通道和空间信息进行提取信息,那么我们的注意力模块对通道和空间进行“注意”,达到目的。

image.png

通道(CA)模块

  如下图所示,通道子模块利用共享网络的最大池输出和平均池输出;空间子模块利用类似的两个输出,沿通道轴汇集并将它们转发到卷积层。

image.png

python

复制代码

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)
        print("in_planes=", in_planes, "in_planes // ratio = ", in_planes // ratio)
        self.fc = nn.Sequential(nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False),
                                nn.ReLU(),
                                nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False))
        self.sigmoid = nn.Sigmoid()
    def forward(self, x):
        avg_out = self.fc(self.avg_pool(x))
        max_out = self.fc(self.max_pool(x))
        out = avg_out + max_out
        return self.sigmoid(out)

空间(SA)模块

  SA模块利用特征的空间间关系生成空间注意图。与通道注意不同,空间注意所关注的“在哪里”是一个信息部分,与通道注意相呼应。为了计算空间注意力,我们首先沿通道轴应用平均池和最大池操作,这样可以有效地突出显示信息域。

image.png

ini

复制代码

class SpatialAttention(nn.Module):
    def __init__(self, kernel_size=7):
        super(SpatialAttention, self).__init__()
        self.conv1 = nn.Conv2d(2, 1, kernel_size, padding=kernel_size // 2, 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)
        x = torch.cat([avg_out, max_out], dim=1)
        x = self.conv1(x)
        return self.sigmoid(x)

实操简介

  综上所述,我们已经知道了CA&SA模块的应用位置,我们在本文中采用的卷积模板为较为经典的Alexnet网络,大家可自行参考【基础实操】借用torch自带网络进行训练自己的图像数据中介绍到的训练方法,这里我们将延续该篇中的方式,仅对Alexnet部分进行修改匹配。

  在Alexnet中定义ca&sa模块,对self.features中的最后两层注释,便于由卷积层接CA&SA模块。具体的添加如下所示:

ini

复制代码

class AlexNet(nn.Module):
    def __init__(self, num_classes: int = 1000, planes=256, downsample=None) -> None:
        super(AlexNet, self).__init__()
        self.ca = ChannelAttention(in_planes=256)
        self.sa = SpatialAttention()
        self.downsample = downsample
        self.bn2 = nn.BatchNorm2d(planes)
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            # nn.ReLU(inplace=True),
            # nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        out = self.features(x)
        out = self.bn2(out)
        out = self.ca(out) * out
        out = self.sa(out) * out
        out = self.avgpool(out)
        out = torch.flatten(out, 1)
        out = self.classifier(out)
        return out

结语

  使用CBMA模块可以保持较小的计算开销,能够得到显著的性能提升,这是我们在学习和工程上愿意看到的结果,也是推动项目进展的有利方法。由于本次写的匆忙,本文中还有阐述不清楚的地方,望各位路过的大神,不吝啬赐教!


相关文章
|
7月前
|
机器学习/深度学习 Java 网络架构
YOLOv5改进 | TripletAttention三重注意力机制(附代码+机制原理+添加教程)
YOLOv5改进 | TripletAttention三重注意力机制(附代码+机制原理+添加教程)
371 0
|
机器学习/深度学习 编解码 数据可视化
【即插即用】涨点神器AFF:注意力特征融合(已经开源,附论文和源码链接)
【即插即用】涨点神器AFF:注意力特征融合(已经开源,附论文和源码链接)
3093 1
|
3月前
|
机器学习/深度学习 PyTorch 算法框架/工具
CNN中的注意力机制综合指南:从理论到Pytorch代码实现
注意力机制已成为深度学习模型的关键组件,尤其在卷积神经网络(CNN)中发挥了重要作用。通过使模型关注输入数据中最相关的部分,注意力机制显著提升了CNN在图像分类、目标检测和语义分割等任务中的表现。本文将详细介绍CNN中的注意力机制,包括其基本概念、不同类型(如通道注意力、空间注意力和混合注意力)以及实际实现方法。此外,还将探讨注意力机制在多个计算机视觉任务中的应用效果及其面临的挑战。无论是图像分类还是医学图像分析,注意力机制都能显著提升模型性能,并在不断发展的深度学习领域中扮演重要角色。
125 10
|
6月前
|
机器学习/深度学习 自然语言处理 并行计算
YOLOv8改进 | 注意力机制 | 在主干网络中添加MHSA模块【原理+附完整代码】
Transformer中的多头自注意力机制(Multi-Head Self-Attention, MHSA)被用来增强模型捕捉序列数据中复杂关系的能力。该机制通过并行计算多个注意力头,使模型能关注不同位置和子空间的特征,提高了表示多样性。在YOLOv8的改进中,可以将MHSA代码添加到`/ultralytics/ultralytics/nn/modules/conv.py`,以增强网络的表示能力。完整实现和教程可在提供的链接中找到。
|
6月前
|
机器学习/深度学习 计算机视觉
【保姆级教程|YOLOv8添加注意力机制】【2】在C2f结构中添加ShuffleAttention注意力机制并训练
【保姆级教程|YOLOv8添加注意力机制】【2】在C2f结构中添加ShuffleAttention注意力机制并训练
|
7月前
|
机器学习/深度学习 自然语言处理 并行计算
一文搞懂Transformer架构的三种注意力机制
一文搞懂Transformer架构的三种注意力机制
708 1
|
7月前
|
机器学习/深度学习 算法 计算机视觉
YOLOv8 | 卷积模块 | 提高网络的灵活性和表征能力的动态卷积【附代码+小白可上手】
本教程介绍了如何在YOLOv8中使用动态卷积提升网络性能和灵活性。动态卷积利用注意力机制动态选择和组合卷积核,适应输入数据特征,解决了轻量级CNN的局限。文中提供了详细步骤教读者如何添加和修改代码,包括在`conv.py`中添加`Dynamic_conv2d`模块,更新`init.py`、`task.py`和`yaml`配置文件。此外,还分享了完整代码和进阶技巧,帮助深度学习初学者实践目标检测。参考[YOLOv8改进](https://blog.csdn.net/m0_67647321/category_12548649.html)专栏获取更多详情。
|
7月前
|
机器学习/深度学习 算法 计算机视觉
YOLOv8改进 | 注意力机制 | 添加全局注意力机制 GcNet【附代码+小白必备】
本文介绍了如何在YOLOv8中集成GcNet,以增强网络对全局上下文的捕获能力。GcNet通过全局上下文模块、通道和空间注意力机制提升CNN对全局信息的利用。教程详细阐述了GcNet的原理,并提供了将GcNet添加到YOLOv8的代码实现步骤,包括创建ContextBlock类、修改init.py、task.py以及配置yaml文件。此外,还提供了训练和运行示例代码。完整代码和更多进阶内容可在作者的博客中找到。
|
7月前
|
机器学习/深度学习 算法 计算机视觉
YOLOv8改进 | 注意力机制 | 添加双重注意力机制 DoubleAttention【附完整代码+小白必备】
在这个教程中,作者介绍了如何在YOLOv8图像识别模型中集成DoubleAttention模块,以提升模型捕捉长距离关系的效率。DoubleAttention通过全局和局部注意力模块捕获图像的全局和局部信息。教程详细阐述了DoubleAttention的工作原理,并提供了相应的代码实现。读者将学习到如何在YOLOv8的网络结构中添加这一组件,并给出了完整的代码示例。此外,还分享了GFLOPs的计算,以及鼓励读者尝试在不同位置添加注意力机制作为进阶练习。完整代码和更多详情可在提供的链接中获取。
|
7月前
|
机器学习/深度学习 算法 PyTorch
【SAHI】即插即用| SAHI操作可有效解决小目标检测过程中的难点!实现涨点
【SAHI】即插即用| SAHI操作可有效解决小目标检测过程中的难点!实现涨点
442 1