本文介绍:本专栏第一篇,文章不会讲太复杂的定义,将从小白的角度去进行讲解,为大家节省时间,高效去做实验,文章将会简单介绍一下相关模块(也会附带相关论文链接,有兴趣可以阅读,可以作为论文文献),本专栏主要专注于YOLO改进实战!适用于小白入门也可以水论文,大佬跳过!!!
文章适用人群:研一、准研究生(研0)、少部分本科生、着急毕业水论文的各位
更新时间:每天1~3篇左右,本专栏文章至少50+篇,如果需要单独设计可以联系我,咨询一下
售后:购买专栏后在运行时有问题直接私聊我,大部分都是环境配置问题,我会录教程带大家配置,保证代码畅通无阻!
新专栏福利:帮助入门小白缝合模块,创新模块(先到先得,名额有限,论文从此不缺创新点)!
专栏通知:专栏文章大于20篇时将涨价,早买有优惠,感谢各位读者支持!(更新时间:2024/11/17)
目录
- “CBAM”同学简介
- 一、如何使用CBAM
- 二、将主角“CBAM”加入到YOLO大家庭(代码)中
- 三、模型文件中加入CBAM注意力机制
- 四、直接开跑
- 五、附赠CBAM(改进版)效果好可做创新点
“CBAM”同学简介
个人简介:大家好!我是CBAM模块,中文名是“卷积块注意模块”。别看我名字很长,其实我就是个“智能关注器”,能帮计算机更好地看懂图像。我有两个绝技:一个叫“通道注意力”,能帮助模型选出哪些特征更重要,就像从一堆声音中挑出最悦耳的旋律;另一个叫“空间注意力”,负责搞清楚图像的哪些区域是关键,就像在茫茫人海中锁定目标人物的脸。这样一来,在图像识别和理解的过程中,我能让电脑专注于“精华”,不浪费时间在“没用的细节”上。总之,我的使命是:帮助模型像人类一样,聪明地将注意力放在重要的信息上!
专业版介绍(我知道大家肯定不爱看但可以理解用于写论文):
1、通道注意力模块(Channel Attention Module):
通过利用特征之间的通道关系来生成通道注意力图。每个通道的特征图被视为一个特征探测器,通道注意力关注于给定输入图像中“什么”是有意义的。为了有效地计算通道注意力,CBAM首先对输入特征图的空间维度进行压缩,同时使用平均池化和最大池化操作来捕获不同的空间上下文描述符,这些被送入共享的多层感知机(MLP)以产生通道注意力图。
2、空间注意力模块(Spatial Attention Module):
利用特征之间的空间关系来生成空间注意力图。与通道注意力不同,空间注意力关注于“在哪里”是一个有信息的部分,这与通道注意力是互补的。为了计算空间注意力,CBAM首先沿着通道轴应用平均池化和最大池化操作,然后将它们连接起来生成一个高效的特征描述符。在该描述符上应用一个卷积层来生成空间注意力图。
3、独特优势
(1)、双重注意力机制:
CBAM首次将通道注意力(Channel Attention)和空间注意力(Spatial Attention)顺序结合起来,对输入特征进行两阶段的精炼。这种设计让模型先关注于“哪些通道是重要的”,然后再关注于“空间上哪些位置是重要的”,从而更加全面地捕获特征中的关键信息。
(2)、自适应特征重标定:
通过通道注意力和空间注意力的逐步应用,CBAM能够自适应地调整输入特征图中每个通道和空间位置的重要性。这种自适应重标定机制允许模型根据任务需求和内容上下文动态地关注于最有用的特征,从而提高模型的表征能力和决策准确性。
(3)、灵活性和通用性:
CBAM模块设计简洁,可轻松集成到各种现有的CNN架构中,如ResNet、Inception等,而不需要对原始架构进行大的修改。这种灵活性和通用性使CBAM成为一种有效的插件,可以广泛应用于各种视觉识别任务,包括图像分类、目标检测和语义分割等。
4、计算效率高:
尽管CBAM为模型引入了额外的计算,但其设计考虑了计算效率,如通过全局平均池化和最大池化来简化通道注意力的计算,通过简单的卷积操作来实现空间注意力。这些设计使得CBAM能够在带来性能提升的同时,保持较低的额外计算成本。
5、逐步精炼策略:
CBAM中通道和空间注意力的顺序应用,形成了一种逐步精炼输入特征的策略。这种从通道到空间的逐步细化过程,有助于模型更有效地利用注意力机制,逐渐提取并强调更加有意义的特征,而不是一次性地处理所有信息。
一、如何使用CBAM
CBAM代码展示:
#-----------------------------------ADD----------------------------------#
# 通道注意力模块
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.fc1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False) # 第一个卷积层,降维
self.relu1 = nn.ReLU() # ReLU激活函数
self.fc2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False) # 第二个卷积层,升维
self.sigmoid = nn.Sigmoid() # Sigmoid函数生成最终的注意力权重
def forward(self, x):
avg_out = self.fc2(self.relu1(self.fc1(self.avg_pool(x)))) # 对平均池化的特征进行处理
max_out = self.fc2(self.relu1(self.fc1(self.max_pool(x)))) # 对最大池化的特征进行处理
out = avg_out + max_out # 将两种池化的特征加权和作为输出
return self.sigmoid(out) # 使用sigmoid激活函数计算注意力权重
# 空间注意力模块
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' # 核心大小只能是3或7
padding = 3 if kernel_size == 7 else 1 # 根据核心大小设置填充
# 卷积层用于从连接的平均池化和最大池化特征图中学习空间注意力权重
self.conv1 = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)
self.sigmoid = nn.Sigmoid() # 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) # 使用sigmoid激活函数计算注意力权重
# CBAM模块
class CBAM(nn.Module):
def __init__(self, in_planes, ratio=16, kernel_size=7):
super(CBAM, self).__init__()
self.ca = ChannelAttention(in_planes, ratio) # 通道注意力实例
self.sa = SpatialAttention(kernel_size) # 空间注意力实例
def forward(self, x):
out = x * self.ca(x) # 使用通道注意力加权输入特征图
result = out * self.sa(out) # 使用空间注意力进一步加权特征图
return result # 返回最终的特征图
# 示例使用
if __name__ == '__main__':
block = CBAM(64) # 创建一个CBAM模块,输入通道为64
input = torch.rand(1, 64, 64, 64) # 随机生成一个输入特征图
output = block(input) # 通过CBAM模块处理输入特征图
print(input.size(), output.size()) # 打印输入和输出的
#-----------------------------------ADD----------------------------------#
使用步骤:
- 可自行找位置新建一个"CBAM.py"将上述代码粘贴进去出现下面,不报错说明没问题,否则不可直接用,如图1(提供的代码准确无误)

图1(上图)
二、将主角“CBAM”加入到YOLO大家庭(代码)中
使用步骤:
- 找到并打开“YOLOv8\ultralytics-main\ultralytics\nn\modules\block.py”文件,在箭头位置添加CBAM模块,如图2
- 复制提供的CDAM代码粘贴进block.py的52行(你们的不一定是52行,注意附近内容),如图3
- 在包结构中导入CBAM类,注意看,这步最容易错,图中有详解,如图4和图5
- 找到task.py导入你的新模块,task.py位置和模块导入方法,如图6
- 编写parse_model函数,首先你需要按住Ctrl和F,搜索def parse_model并跳转到这个函数的定义,然后开始往下滑找到如图7所示的位置(行数不一定相同,注意周围内容),并且输入解析函数,解析函数如下:
#注意事项:将这部分代码放入图中位置,我的是第957行,各位看看附近的内容一样再去添加 #-----------------------------------------ADD------------------------------------------------# elif m is CBAM: c1 = ch[f] args =[c1] #-----------------------------------------ADD------------------------------------------------#图示教学过程:

图2(上图)

图3(上图)

图4(上图)

图5(上图)

图6(上图)


图7(上图)
三、模型文件中加入CBAM注意力机制
步骤:
1.如图8所示,在相应位置创建ADD文件夹(用于存放新建的模型文件)和yolov8-CBAM.yaml模型文件
2.复制yolov8-CBAM.yaml文件内容到新建的yolov8-CBAM.yaml文件中并保存。

图8(上图)
yolov8-CBAM.yaml文件内容如下:
# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect
# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'
# [depth, width, max_channels]
n: [0.33, 0.25, 1024] # YOLOv8n summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPs
s: [0.33, 0.50, 1024] # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients, 28.8 GFLOPs
m: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients, 79.3 GFLOPs
l: [1.00, 1.00, 512] # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs
x: [1.00, 1.25, 512] # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs
# YOLOv8.0n backbone
backbone:
# [from, repeats, module, args]
- [-1, 1, CBAM, [64]] # 在第一个Conv层之前添加CBAM模块,根据输入通道数64初始化 第0层
- [-1, 1, Conv, [64, 3, 2]] # 第1层
- [-1, 1, Conv, [128, 3, 2]] # 第2层
- [-1, 3, C2f, [128, True]]
- [-1, 1, Conv, [256, 3, 2]] # 第4层
- [-1, 1, CBAM, [256]] # 在第5层下采样后添加CBAM模块,通道数256
- [-1, 6, C2f, [256, True]]
- [-1, 1, Conv, [512, 3, 2]] # 7-P4/16
- [-1, 1, CBAM, [512]] # 在P8/16下采样后添加CBAM模块,通道数512
- [-1, 6, C2f, [512, True]]
- [-1, 1, Conv, [1024, 3, 2]] # 10-P5/32
- [-1, 1, CBAM, [1024]] # 在P11/32下采样后添加CBAM模块,通道数1024
- [-1, 3, C2f, [1024, True]]
- [-1, 1, SPPF, [1024, 5]] # 13
# YOLOv8.0n head
head:
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 9], 1, Concat, [1]] # cat backbone P4
- [-1, 1, CBAM, [512]] # 在第一次Upsample和Concat操作后添加CBAM模块,通道数512
- [-1, 3, C2f, [512]] # 17
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 6], 1, Concat, [1]] # cat backbone P3
- [-1, 1, CBAM, [256]] # 在第二次Upsample和Concat操作后添加CBAM模块,通道数256
- [-1, 3, C2f, [256]] # 21 (P3/8-small)
- [-1, 1, Conv, [256, 3, 2]]
- [[-1, 17], 1, Concat, [1]] # cat head P4
- [-1, 1, CBAM, [512]] # 在第三次Upsample和Concat操作后添加CBAM模块,通道数512
- [-1, 3, C2f, [512]] # 25 (P4/16-medium)
- [-1, 1, Conv, [512, 3, 2]]
- [[-1,13 ], 1, Concat, [1]] # cat head P5
- [-1, 1, CBAM, [1024]] # 在第四次Upsample和Concat操作后添加CBAM模块,通道数1024
- [-1, 3, C2f, [1024]] # 29 (P5/32-large)
- [[21, 25, 29], 1, Detect, [nc]] # Detect(P3, P4, P5)
四、直接开跑
步骤:
1.运行train.py出现如图9所示即为运行成功

图9(上图)
五、附赠CBAM(改进版)效果好可做创新点
代码如下所示:(添加方式与上面相同,不会的私信我!)
# ------------------------------------CBAM增强版(有需要可用增强版)--------------------------------------------#
"""
如果增强版对你的任务map和精度有提高的话可以应用于论文,改进皆为原创!
增强版模块使用前需要注册模块哦!如果想使用增强版可以私聊我,人多的话出教程,人少的话就私聊了!
"""
import torch
from torch import nn
class EnhancedChannelAttention(nn.Module):
def __init__(self, in_planes, ratio=16, act=nn.ReLU, norm_layer=None):
super(EnhancedChannelAttention, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.max_pool = nn.AdaptiveMaxPool2d(1)
self.std_pool = lambda x: torch.std(x, dim=[2, 3], keepdim=True)
self.shared_mlp = nn.Sequential(
nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False),
act(),
nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)
)
self.sigmoid = nn.Sigmoid()
# Use InstanceNorm2d instead of BatchNorm2d
self.norm_layer = norm_layer
if self.norm_layer is not None:
self.bn1 = self.norm_layer(in_planes // ratio)
self.bn2 = self.norm_layer(in_planes)
def forward(self, x):
avg_out = self.shared_mlp(self.avg_pool(x))
max_out = self.shared_mlp(self.max_pool(x))
std_out = self.shared_mlp(self.std_pool(x))
out = avg_out + max_out + std_out
# Only apply normalization if input size is compatible
if self.norm_layer is not None and out.size(0) > 1:
out = self.bn2(out)
return self.sigmoid(out)
class EnhancedSpatialAttention(nn.Module):
def __init__(self, kernel_size=7, norm_layer=None):
super(EnhancedSpatialAttention, self).__init__()
assert kernel_size in (3, 7), 'kernel size must be 3 or 7'
padding = 3 if kernel_size == 7 else 1
self.conv1 = nn.Conv2d(3, 1, kernel_size, padding=padding, bias=False)
self.sigmoid = nn.Sigmoid()
# Use InstanceNorm2d instead of BatchNorm2d
self.norm_layer = norm_layer
if self.norm_layer is not None:
self.bn = self.norm_layer(1)
def forward(self, x):
avg_out = torch.mean(x, dim=1, keepdim=True)
max_out, _ = torch.max(x, dim=1, keepdim=True)
std_out = torch.std(x, dim=1, keepdim=True)
x = torch.cat([avg_out, max_out, std_out], dim=1)
x = self.conv1(x)
# Only apply normalization if input size is compatible
if self.norm_layer is not None and x.size(0) > 1:
x = self.bn(x)
return self.sigmoid(x)
class EnhancedCBAM(nn.Module):
def __init__(self, in_planes, ratio=16, kernel_size=7, act=nn.ReLU, norm_layer=None):
super(EnhancedCBAM, self).__init__()
self.ca = EnhancedChannelAttention(in_planes, ratio, act, norm_layer)
self.sa = EnhancedSpatialAttention(kernel_size, norm_layer)
def forward(self, x):
residual = x
out = self.ca(x) * x
out = self.sa(out) * out
return out + residual # Use residual connection
# 示例使用
if __name__ == '__main__':
# Use InstanceNorm2d instead of BatchNorm2d due to batch size issues
norm_layer = nn.InstanceNorm2d
block = EnhancedCBAM(64, ratio=16, kernel_size=7, norm_layer=norm_layer)
input = torch.rand(1, 64, 64, 64)
output = block(input)
print(input.size(), output.size())
总结:
CBAM的适用范围
CBAM模块的设计初衷是为了提升卷积神经网络在视觉任务中的表现。它主要适用于以下任务:
-
图像分类:
- CBAM能通过关注重要特征通道和关键图像区域,提升网络的分类能力,尤其是在复杂背景的情况下。
-
目标检测:
- 在检测任务中,如YOLO、Faster R-CNN等,CBAM能帮助模型更精确地识别目标边界和位置,提高检测精度。
-
语义分割:
- 在需要对图像进行像素级别的分类时,CBAM能增强模型在区分前景和背景时的表现,例如在人群稠密的场景中找到每个人。
-
图像生成与超分辨率:
- 在需要生成高质量图像或提升图像分辨率的任务中,CBAM通过关注关键信息,提高生成图像的细节和质量。
改进后的CBAM的适用范围
改进后的CBAM扩展了原有模块的能力,适应性更强,适合更复杂或更多样化的任务:
-
复杂背景下的目标检测与分类:
- 由于多种池化策略和残差连接的应用,改进后的CBAM在复杂多变的环境下能够更好地提取和利用重要特征。
-
实时视频分析:
- 在需要快速处理大量视频数据的情况下(如监控系统),改进后的CBAM能帮助模型快速识别和跟踪目标。
-
医疗图像分析:
- 在医学成像领域,如CT或MRI,改进后的CBAM能帮助模型更有效地识别微小病变或器官区域,提高诊断的可靠性。
-
遥感图像处理:
- 对于遥感数据分析任务,如土地分类或变化检测,改进后的CBAM可以提高对细节和变化的敏感度。
-
多模态数据融合:
- 在需要处理和结合来自多种传感器或数据源的信息时(如自动驾驶中的视觉和雷达数据融合),CBAM的灵活性有助于提升整体模型的性能。

7714

被折叠的 条评论
为什么被折叠?



