目录
- 一、注意力机制介绍
- 1、什么是注意力机制?
- 2、注意力机制的分类
- 3、注意力机制的核心
- 二、BAM模块
- 1、BAM模块的原理
- 2、实验结果
- 3、应用示例
- 三、CBAM模块
- 1、CBAM模块的原理
- 2、实验结果
- 3、应用示例
大家好,我是哪吒。
🏆本文收录于,目标检测YOLO改进指南。
本专栏均为全网独家首发,内附代码,可直接使用,改进的方法均是2023年最近的模型、方法和注意力机制。每一篇都做了实验,并附有实验结果分析,模型对比。
在机器学习和自然语言处理领域,随着数据的不断增长和任务的复杂性提高,传统的模型在处理长序列或大型输入时面临一些困难。传统模型无法有效地区分每个输入的重要性,导致模型难以捕捉到与当前任务相关的关键信息。为了解决这个问题,注意力机制(Attention Mechanism)应运而生。
一、注意力机制介绍
1、什么是注意力机制?
注意力机制(Attention Mechanism)是一种在机器学习和自然语言处理领域中广泛应用的重要概念。它的出现解决了模型在处理长序列或大型输入时的困难,使得模型能够更加关注与当前任务相关的信息,从而提高模型的性能和效果。
本文将详细介绍注意力机制的原理、应用示例以及应用示例。
2、注意力机制的分类
类别 | 描述 |
---|---|
全局注意力机制(Global Attention) | 在计算注意力权重时,考虑输入序列中的所有位置或元素,适用于需要全局信息的任务。 |
局部注意力机制(Local Attention) | 在计算注意力权重时,只考虑输入序列中的局部区域或邻近元素,适用于需要关注局部信息的任务。 |
自注意力机制(Self Attention) | 在计算注意力权重时,根据输入序列内部的关系来决定每个位置的注意力权重,适用于序列中元素之间存在依赖关系的任务。 |
Bahdanau 注意力机制 | 全局注意力机制的一种变体,通过引入可学习的对齐模型,对输入序列的每个位置计算注意力权重。 |
Luong 注意力机制 | 全局注意力机制的另一种变体,通过引入不同的计算方式,对输入序列的每个位置计算注意力权重。 |
Transformer 注意力机制 | 自注意力机制在Transformer模型中的具体实现,用于对输入序列中的元素进行关联建模和特征提取。 |
3、注意力机制的核心
注意力机制的核心思想是根据输入的上下文信息来动态地计算每个输入的权重。这个过程可以分为三个关键步骤:计算注意力权重、对输入进行加权和输出。首先,计算注意力权重是通过将输入与模型的当前状态进行比较,从而得到每个输入的注意力分数。这些注意力分数反映了每个输入对当前任务的重要性。对输入进行加权是将每个输入乘以其对应的注意力分数,从而根据其重要性对输入进行加权。最后,将加权后的输入进行求和或者拼接,得到最终的输出。注意力机制的关键之处在于它允许模型在不同的时间步或位置上关注不同的输入,从而捕捉到与任务相关的信息。
YOLOv5/v7 添加注意力机制,30多种模块分析①,SE模块,SK模块
二、BAM模块
1、BAM模块的原理
BAM模块是一种新型的注意力机制,其原理是通过对中间特征图进行通道注意力和空间注意力的双重调整,以提高模型对目标的感知能力。在通道注意力中,BAM模块通过学习一个通道权值向量,来对不同通道的特征进行加权处理;在空间注意力中,则通过计算每个空间位置的重要性,来得到空间权重矩阵。将这两种注意力结合起来,即可得到最终的注意力图,从而引导模型更加关注目标相关的特征。
在实现方面,BAM模块通常被集成到通用CNN架构中,并被放置在网络的每个瓶颈处。多个BAM模块组合起来,形成了一个类似于人类感知过程的分层注意力机制。具体地,在早期阶段,BAM模块会去除低级特征,例如背景纹理特征,随着网络的向前传递,BAM模块会逐渐聚焦于精确的目标,即高级语义。
BAM模块的详细架构如下图所示。给定中间特征图F,该模块通过通道Mc和空间Ms这两个单独的注意分支计算出相应的注意图M(F)。模块有两个超参数:膨胀值(d)和收缩比®。膨胀值决定了接受域的大小,有助于空间分支的上下文信息聚集;而收缩比则控制着两个注意力分支的能力和开销。
BAM模块在目标检测领域中被广泛应用,并且已经被成功地应用于多个重要的目标检测模型中,如YOLOv5、RetinaNet等。以YOLOv5为例,BAM模块被加入到CSPDarknet53的每个瓶颈处,以提高模型对目标的感知能力。实验结果表明,加入BAM模块的CSPDarknet53相比原版CSPDarknet53在COCO数据集上的mAP提高了1.2个点,同时参数量也略有增加。此外,研究者还通过可视化的方式观察到,BAM模块能够使得模型更加关注物体的边缘和细节部分,从而提升模型的准确性和鲁棒性。
2、实验结果
BAM相对于SE 的实验结果。在CIFAR-100数据集上报告了Top-1错误率。
3、应用示例
BAM模块的应用示例:
import torch
from torch import nn
class BAM(nn.Module):
def __init__(self, inplanes):
super(BAM, self).__init__()
# 通道注意力分支
self.channel_attention = nn.Sequential(
nn.AdaptiveAvgPool2d(1),
nn.Conv2d(inplanes, inplanes // 2, 1, padding=0),
nn.ReLU(inplace=True),
nn.Conv2d(inplanes // 2, inplanes, 1, padding=0),
nn.Sigmoid()
)
# 空间注意力分支
self.spatial_attention = nn.Sequential(
nn.Conv2d(inplanes, 1, kernel_size=1, stride=1, padding=0),
nn.Sigmoid()
)
def forward(self, x):
# 通道注意力权重的计算
channel_weight = self.channel_attention(x)
# 将通道注意力权重应用于特征图上
out = x * channel_weight
# 空间注意力权重的计算
spatial_weight = self.spatial_attention(out)
# 将空间注意力权重应用于特征图上
out = out * spatial_weight
return out
以上代码展示了如何在YOLOv5中实现BAM模块。在该实现中,通道注意力分支和空间注意力分支都被定义为nn.Sequential()的形式,并且分别包含一系列卷积、池化、激活等操作。在前向传播时,先计算通道注意力权重,然后将其应用于特征图上,接着计算空间注意力权重,并将其应用于特征图上。最终的输出即为经过BAM模块处理后的特征图。
三、CBAM模块
1、CBAM模块的原理
CBAM是"Convolutional Block Attention Module"的缩写,是一种针对卷积神经网络(CNN)的注意力机制模块。CBAM通过学习的方式自动获取每个特征通道的重要程度和每个特征空间的重要程度。这些重要程度信息可以被用来提升对当前任务有帮助的特征,并抑制对当前任务不重要的特征,从而提高整个模型的性能。
CBAM的结构包含两个子模块:通道注意力模块(channel attention module)和空间注意力模块(spatial attention module)。其中,通道注意力模块主要负责计算每个特征通道的重要程度,空间注意力模块则负责计算每个特征空间的重要程度。这两个子模块可以分别或者同时使用,具体使用哪个子模块由实际任务和数据集决定。
在通道注意力模块中,CBAM使用了一个全局平均池化层(Global Average Pooling),将每个特征图的通道维度进行压缩得到一个全局的特征向量,然后通过一个小型的多层感知机(MLP)来计算每个通道的重要程度。这样,每个通道的重要程度信息就可以被用来对该通道的特征进行加权,从而提升有用的特征并且抑制无用的特征。
在空间注意力模块中,CBAM使用了一个全局最大池化层(Global Max Pooling),将每个特征图所有像素点中的最大值取出,然后同样通过一个小型的MLP计算每个像素点的重要程度。这样,每个像素点的重要程度信息就可以被用来对该像素点所在位置的特征进行加权,从而提升有用的特征并且抑制无用的特征。
CBAM与ResNet中的ResBlock集成。该图显示了我们的模块在ResBlock内部集成的确切位置。我们在每个块中对卷积输出应用CBAM。
2、实验结果
在MS COCO验证集上的目标检测平均精度(mAP,%)。我们采用Faster R-CNN [41]检测框架,并将我们的模块应用到基础网络中。CBAM使得两个基线网络的mAP@[.5, .95]都提高了0.9。
3、应用示例
以下是使用CBAM模块的应用示例:
import torch.nn as nn
class CBAM(nn.Module):
def __init__(self, channels, reduction=16):
super(CBAM, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.max_pool = nn.AdaptiveMaxPool2d(1)
self.fc1 = nn.Conv2d(channels, channels // reduction, kernel_size=1, padding=0, bias=False)
self.relu = nn.ReLU(inplace=True)
self.fc2 = nn.Conv2d(channels // reduction, channels, kernel_size=1, padding=0, bias=False)
self.sigmoid_channel = nn.Sigmoid()
self.conv_after_concat = nn.Conv2d(2, 1, kernel_size=7, stride=1, padding=3, bias=False)
self.sigmoid_spatial = nn.Sigmoid()
def forward(self, x):
avg_out = self.fc2(self.relu(self.fc1(self.avg_pool(x))))
max_out = self.fc2(self.relu(self.fc1(self.max_pool(x))))
channel_out = self.sigmoid_channel(avg_out + max_out)
x = x * channel_out
spatial_out = torch.cat([self.avg_pool(x), self.max_pool(x)], dim=1)
spatial_out = self.conv_after_concat(spatial_out)
spatial_out = self.sigmoid_spatial(spatial_out)
x = x * spatial_out
return x
上述代码中实现了CBAM模块的前向传播过程,包括通道注意力和空间注意力两部分。在YOLOv5中,可以将CBAM模块插入到Darknet53的多个卷积块中,以增强特征提取能力。
参考论文:
- http://arxiv-export-lb.library.cornell.edu/pdf/1807.06514
- https://arxiv.org/pdf/1807.06521.pdf
🏆本文收录于,目标检测YOLO改进指南。
本专栏均为全网独家首发,🚀内附代码,可直接使用,改进的方法均是2023年最近的模型、方法和注意力机制。每一篇都做了实验,并附有实验结果分析,模型对比。
🏆华为OD机试(JAVA)真题(A卷+B卷)
每一题都有详细的答题思路、详细的代码注释、样例测试,订阅后,专栏内的文章都可看,可加入华为OD刷题群(私信即可),发现新题目,随时更新,全天CSDN在线答疑。
🏆哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师。
🏆往期回顾:
1、YOLOv5/v7 添加注意力机制,30多种模块分析①,SE模块,SK模块
2、YOLOv5结合BiFPN,如何替换YOLOv5的Neck实现更强的检测能力?
3、YOLOv5结合BiFPN:BiFPN网络结构调整,BiFPN训练模型训练技巧
4、YOLOv7升级换代:EfficientNet骨干网络助力更精准目标检测
5、YOLOv5改进:引入DenseNet思想打造密集连接模块,彻底提升目标检测性能