Python训练营打卡Day47-CBAM注意力

知识点回顾:
  1. 通道注意力模块复习
  2. 空间注意力模块
  3. CBAM的定义

作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程
 

CBAM 是一种能够集成到任何卷积神经网络架构中的注意力模块。它的核心目标是通过学习的方式,自动获取特征图在通道和空间维度上的重要性,进而对特征图进行自适应调整,增强重要特征,抑制不重要特征,提升模型的特征表达能力和性能。简单来说,它就像是给模型装上了 “智能眼镜”,让模型能够更精准地看到图像中关键的部分。

CBAM 由两个主要部分组成:通道注意力模块(Channel Attention Module)和空间注意力模块(Spatial Attention Module)。这两个模块顺序连接,共同作用于输入的特征图。

SE 通道注意力的局限:仅关注 “哪些通道重要”,未考虑 “重要信息在空间中的位置”。CBAM 的突破:通道注意力(Channel Attention):分析 “哪些通道的特征更关键”(如图像中的颜色、纹理通道)。空间注意力(Spatial Attention):定位 “关键特征在图像中的具体位置”(如物体所在区域)。二者结合:让模型同时学会 “关注什么” 和 “关注哪里”,提升特征表达能力。

输入特征图 → 通道注意力模块 → 空间注意力模块 → 输出增强后的特征图

轻量级设计:仅增加少量计算量(全局池化 + 简单卷积),适合嵌入各种 CNN 架构(如 ResNet、YOLO)。即插即用:无需修改原有模型主体结构,直接作为模块插入卷积层之间。双重优化:同时提升通道和空间维度的特征质量,尤其适合复杂场景(如小目标检测、语义分割)。

这些模块相较于cnn都属于即插即用。

import torch
import torch.nn as nn

# 定义通道注意力
class ChannelAttention(nn.Module):
    def __init__(self, in_channels, ratio=16):
        """
        通道注意力机制初始化
        参数:
            in_channels: 输入特征图的通道数
            ratio: 降维比例,用于减少参数量,默认为16
        """
        super().__init__()
        # 全局平均池化,将每个通道的特征图压缩为1x1,保留通道间的平均值信息
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        # 全局最大池化,将每个通道的特征图压缩为1x1,保留通道间的最显著特征
        self.max_pool = nn.AdaptiveMaxPool2d(1)
        # 共享全连接层,用于学习通道间的关系
        # 先降维(除以ratio),再通过ReLU激活,最后升维回原始通道数
        self.fc = nn.Sequential(
            nn.Linear(in_channels, in_channels // ratio, bias=False),  # 降维层
            nn.ReLU(),  # 非线性激活函数
            nn.Linear(in_channels // ratio, in_channels, bias=False)   # 升维层
        )
        # Sigmoid函数将输出映射到0-1之间,作为各通道的权重
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        """
        前向传播函数
        参数:
            x: 输入特征图,形状为 [batch_size, channels, height, width]
        返回:
            调整后的特征图,通道权重已应用
        """
        # 获取输入特征图的维度信息,这是一种元组的解包写法
        b, c, h, w = x.shape
        # 对平均池化结果进行处理:展平后通过全
### 如何在 YOLOv8 中实现 CBAM 注意力机制 CBAM(Convolutional Block Attention Module)是一种轻量级的注意力模块,能够显著提升卷积神经网络的表现[^1]。它通过分别计算通道注意力和空间注意力来增强特征图的质量,并将其应用到原始特征图上以完成自适应特征细化[^2]。 要在 YOLOv8 中引入 CBAM 注意力机制,可以通过以下方式实现: #### 1. 定义 CBAM 模块 首先需要定义一个 Python 类 `CBAM` 来封装 CBAM 的逻辑。以下是基于 PyTorch 实现的一个典型 CBAM 模块代码示例: ```python import torch import torch.nn as nn 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() self.fc2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False) self.sigmoid = nn.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) 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.conv1 = 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) x = torch.cat([avg_out, max_out], dim=1) x = self.conv1(x) return self.sigmoid(x) class CBAM(nn.Module): def __init__(self, in_planes, ratio=16, kernel_size=7): super(CBAM, self).__init__() self.channel_attention = ChannelAttention(in_planes, ratio) self.spatial_attention = SpatialAttention(kernel_size) def forward(self, x): out = self.channel_attention(x) * x out = self.spatial_attention(out) * out return out ``` 此代码实现了完整的 CBAM 结构,其中包含了通道注意力和空间注意力两部分。 --- #### 2. 将 CBAM 集成到 YOLOv8 主干网络中 YOLOv8 使用的是 EfficientRep 和 CSP-DPN 等先进的主干结构。为了提高检测性能,可以在这些主干层的关键位置插入 CBAM 模块。通常可以选择在网络中的瓶颈层或下采样层之后加入 CBAM。 假设您正在修改 YOLOv8 的主干网络文件(通常是 `models/yolo.py` 或类似的路径),可以按照如下方式进行调整: ```python from models.common import Conv, BottleneckCSP def add_cbam_to_backbone(model): """ Add CBAM modules to the backbone of a given model. Args: model: The YOLOv8 model instance. Returns: Modified model with CBAM integrated into its backbone layers. """ for i, layer in enumerate(model.model): # Iterate through all layers in the model if isinstance(layer, BottleneckCSP): # Insert after each CSP block cbam_layer = CBAM(in_planes=layer.cv1.out_channels).to(next(model.parameters()).device) setattr(model.model[i], 'cbam', cbam_layer) def custom_forward(self, x): """Override the forward pass to include CBAM.""" outputs = [] for j, module in enumerate(self.model): x = module(x) if hasattr(module, 'cbam'): x = module.cbam(x) # Apply CBAM attention here outputs.append(x) return x model.forward = custom_forward.__get__(model) # Replace original forward method return model ``` 上述代码片段展示了如何动态地向现有的 YOLOv8 模型中注入 CBAM 层。具体来说,在每个 `BottleneckCSP` 块后面添加了一个新的 CBAM 层,并重写了模型的前向传播函数以便调用新增加的 CBAM 操作。 --- #### 3. 训练与评估 一旦完成了对 YOLOv8 的改造,就可以像平常一样对其进行训练并观察其效果变化。由于 CBAM 只增加了少量额外参数,因此不会明显增加推理时间成本。然而,应该注意到实际性能增益取决于目标数据集的特点以及所选架构的具体配置。 --- ### 总结 通过将 CBAM 注意力机制嵌入至 YOLOv8 的骨干网路之中,不仅可以有效强化模型对于复杂场景下的鲁棒性,而且还能进一步优化最终预测精度水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值