YOLOv5改进 | 注意力机制 | 通道和空间的双重作用的CBAM注意力机制

2024-05-12 18:20

本文主要是介绍YOLOv5改进 | 注意力机制 | 通道和空间的双重作用的CBAM注意力机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在深度学习目标检测领域,YOLOv5成为了备受关注的模型之一。本文给大家带来的是通道和空间的双重作用的CBAM注意力机制。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改,并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。


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

目录

1.原理 

2.YOLOv5添加CBAM注意力机制

2.1 CBAM注意力机制代码

2.2新增yaml文件

2.3 注册模块

2.4 执行程序

3.总结 


1.原理 

论文地址:CBAM: Convolutional Block Attention Module点击即可跳转

实现代码:CBAM代码实现点击即可跳转

CBAM(Convolutional Block Attention Module)是一种引入了注意力机制的卷积神经网络模块,旨在增强CNN模型的表征能力和性能。它由两个关键组件组成:通道注意力模块(Channel Attention Module)和空间注意力模块(Spatial Attention Module)。

1. 通道注意力模块(CAM):
   CAM主要用于建模特征图在通道维度上的关系。它的目标是学习每个通道的重要性,并对不同通道的特征进行加权,以提升有用特征的影响力,抑制无用特征的干扰。
   CAM首先对输入的特征图进行全局平均池化(Global Average Pooling),将每个通道的特征图压缩成一个标量,然后通过全连接层(FC)学习得到每个通道的权重。这些权重用于对每个通道的特征图进行加权,得到加权后的特征表示。

2. 空间注意力模块(SAM):
   SAM用于捕捉特征图在空间维度上的重要性。它的目标是学习不同空间位置的权重,使网络能够更好地关注图像中的重要区域。
   SAM首先对特征图进行两种池化操作:最大池化和平均池化。这两种池化操作分别用于捕捉特征图中的局部显著性和全局分布信息。然后,将两种池化结果结合,并通过全连接层学习得到每个空间位置的权重,以产生最终的空间注意力图。
   
通过结合通道注意力和空间注意力,CBAM可以使网络更好地理解输入数据中的关键信息,并提高模型在各种视觉任务上的性能。这种注意力机制的引入使得网络能够自适应地调整特征图中不同通道和空间位置的重要性,从而有效地提升了模型的表现力和泛化能力。CBAM已经被成功应用于图像分类、目标检测、语义分割等多个计算机视觉任务中,取得了显著的性能提升。

CBAM结构简图

2.YOLOv5添加CBAM注意力机制

2.1 CBAM注意力机制代码

关键步骤一:将下面代码添加到 yolov5/models/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 outclass 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# (特征图的大小-算子的size+2*padding)/步长+1self.conv = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)self.sigmoid = nn.Sigmoid()def forward(self, x):# 1*h*wavg_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)#2*h*wx = self.conv(x)#1*h*wreturn self.sigmoid(x)class CBAM(nn.Module):# CSP Bottleneck with 3 convolutionsdef __init__(self, c1, c2, ratio=16, kernel_size=7):  # ch_in, ch_out, number, shortcut, groups, expansionsuper(CBAM, self).__init__()self.channel_attention = ChannelAttention(c1, ratio)self.spatial_attention = SpatialAttention(kernel_size)def forward(self, x):out = self.channel_attention(x) * x# c*h*w# c*h*w * 1*h*wout = self.spatial_attention(out) * outreturn out

 CBAM(Convolutional Block Attention Module)注意力机制的流程可以总结如下:

1. 输入特征图:接收来自上一层或输入图像的特征图作为输入。

2. 通道注意力模块(Channel Attention Module,CAM):
   对输入特征图进行全局平均池化(Global Average Pooling),将每个通道的特征进行降维,得到每个通道的全局描述。
   通过全连接层(Fully Connected Layer)学习得到每个通道的权重向量,这些权重用于衡量每个通道的重要性。
   将学习到的权重与原始特征图相乘,以加权增强有用特征和抑制无用特征。

3. 空间注意力模块(Spatial Attention Module,SAM):
   对输入特征图进行最大池化(Max Pooling)和平均池化(Average Pooling),分别捕获局部显著性和全局分布信息。
   将两种池化结果进行组合(如相加),得到综合的空间注意力图。
   通过激活函数(如sigmoid)对空间注意力图进行归一化,得到每个空间位置的权重。

4. 结合通道和空间注意力:
   将通道注意力加权后的特征图与空间注意力加权后的特征图进行逐元素相乘,得到最终的注意力增强特征图。

5. 输出:最终的注意力增强特征图作为模块的输出,传递给下一层网络进行后续的处理,如分类、检测或分割等任务。

整个CBAM注意力机制的流程是将通道注意力和空间注意力相结合,使得网络能够自适应地调整不同通道和空间位置的重要性,从而提升模型的性能和泛化能力。

2.2新增yaml文件

关键步骤二:在 /yolov5/models/ 下新建文件 yolov5_cbam.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, 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, CBAM, [1024]],[-1, 1, SPPF, [1024, 5]],  # 10]# 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]],  # 14[-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]],  # 18 (P3/8-small)[-1, 1, Conv, [256, 3, 2]],[[-1, 15], 1, Concat, [1]],  # cat head P4[-1, 3, C3, [512, False]],  # 21 (P4/16-medium)[-1, 1, Conv, [512, 3, 2]],[[-1, 11], 1, Concat, [1]],  # cat head P5[-1, 3, C3, [1024, False]],  # 24 (P5/32-large)[[18, 21, 24], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)]

温馨提示:因为本文只是对yolov5s基础上添加CBAM模块,如果要对yolov5n/l/m/x进行添加则只需要修改对应的depth_multiple 和 width_multiple。


yolov5n/l/m/x对应的depth_multiple 和 width_multiple如下:

# YOLOv5n
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.25  # 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 注册模块

关键步骤三:在yolov5/models/yolo.py中注册,大概在250行左右添加 ‘CBAM’

2.4 执行程序

在train.py中,将cfg的参数路径设置为yolov5_cbam.yaml的路径,如下图所示

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

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

我修改后的代码:链接: https://pan.baidu.com/s/1qoLGhu7t4noFMxvi7t0rzA?pwd=92im 提取码: 92im

3.总结 

CBAM(Convolutional Block Attention Module)是一种用于增强卷积神经网络(CNN)性能的注意力机制。它由两个子模块组成:通道注意力模块和空间注意力模块。通道注意力模块通过全局平均池化和全连接层学习通道间的关系,并利用学到的权重对每个通道的特征图进行加权,以增强有用的特征并抑制无用的特征。空间注意力模块则通过对特征图在空间维度上进行最大池化和平均池化操作,结合两种池化结果通过全连接层学习得到每个空间位置的权重,使得网络能够更好地关注图像中的重要区域。CBAM的引入可以帮助网络更好地理解输入数据中的关键信息,从而提高了模型在各种视觉任务上的性能,如图像分类、目标检测和语义分割等。

这篇关于YOLOv5改进 | 注意力机制 | 通道和空间的双重作用的CBAM注意力机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/983383

相关文章

MySQL启动报错:InnoDB表空间丢失问题及解决方法

《MySQL启动报错:InnoDB表空间丢失问题及解决方法》在启动MySQL时,遇到了InnoDB:Tablespace5975wasnotfound,该错误表明MySQL在启动过程中无法找到指定的s... 目录mysql 启动报错:InnoDB 表空间丢失问题及解决方法错误分析解决方案1. 启用 inno

Jvm sandbox mock机制的实践过程

《Jvmsandboxmock机制的实践过程》:本文主要介绍Jvmsandboxmock机制的实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景二、定义一个损坏的钟1、 Springboot工程中创建一个Clock类2、 添加一个Controller

在Java中基于Geotools对PostGIS数据库的空间查询实践教程

《在Java中基于Geotools对PostGIS数据库的空间查询实践教程》本文将深入探讨这一实践,从连接配置到复杂空间查询操作,包括点查询、区域范围查询以及空间关系判断等,全方位展示如何在Java环... 目录前言一、相关技术背景介绍1、评价对象AOI2、数据处理流程二、对AOI空间范围查询实践1、空间查

MySQL表空间结构详解表空间到段页操作

《MySQL表空间结构详解表空间到段页操作》在MySQL架构和存储引擎专题中介绍了使用不同存储引擎创建表时生成的表空间数据文件,在本章节主要介绍使用InnoDB存储引擎创建表时生成的表空间数据文件,对... 目录️‍一、什么是表空间结构1.1 表空间与表空间文件的关系是什么?️‍二、用户数据在表空间中是怎么

Dubbo之SPI机制的实现原理和优势分析

《Dubbo之SPI机制的实现原理和优势分析》:本文主要介绍Dubbo之SPI机制的实现原理和优势,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Dubbo中SPI机制的实现原理和优势JDK 中的 SPI 机制解析Dubbo 中的 SPI 机制解析总结Dubbo中

Java 的 Condition 接口与等待通知机制详解

《Java的Condition接口与等待通知机制详解》在Java并发编程里,实现线程间的协作与同步是极为关键的任务,本文将深入探究Condition接口及其背后的等待通知机制,感兴趣的朋友一起看... 目录一、引言二、Condition 接口概述2.1 基本概念2.2 与 Object 类等待通知方法的区别

CentOS7增加Swap空间的两种方法

《CentOS7增加Swap空间的两种方法》当服务器物理内存不足时,增加Swap空间可以作为虚拟内存使用,帮助系统处理内存压力,本文给大家介绍了CentOS7增加Swap空间的两种方法:创建新的Swa... 目录在Centos 7上增加Swap空间的方法方法一:创建新的Swap文件(推荐)方法二:调整Sww

macOS Sequoia 15.5 发布: 改进邮件和屏幕使用时间功能

《macOSSequoia15.5发布:改进邮件和屏幕使用时间功能》经过常规Beta测试后,新的macOSSequoia15.5现已公开发布,但重要的新功能将被保留到WWDC和... MACOS Sequoia 15.5 正式发布!本次更新为 Mac 用户带来了一系列功能强化、错误修复和安全性提升,进一步增

$在R语言中的作用示例小结

《$在R语言中的作用示例小结》在R语言中,$是一个非常重要的操作符,主要用于访问对象的成员或组件,它的用途非常广泛,不仅限于数据框(dataframe),还可以用于列表(list)、环境(enviro... 目录1. 访问数据框(data frame)中的列2. 访问列表(list)中的元素3. 访问jav

Kotlin运算符重载函数及作用场景

《Kotlin运算符重载函数及作用场景》在Kotlin里,运算符重载函数允许为自定义类型重新定义现有的运算符(如+-…)行为,从而让自定义类型能像内置类型那样使用运算符,本文给大家介绍Kotlin运算... 目录基本语法作用场景类对象数据类型接口注意事项在 Kotlin 里,运算符重载函数允许为自定义类型重