知識點回顧:
- 通道注意力模塊復習
- 空間注意力模塊
- CBAM的定義
?
CBAM 注意力模塊介紹
從 SE 到 CBAM:注意力機制的演進
之前我們介紹了 SE(Squeeze-and-Excitation)通道注意力模塊,其本質是對特征進行增強處理。現在,我們進一步探討一種更強大的注意力機制:CBAM(Convolutional Block Attention Module)。
CBAM 的核心目標與價值
CBAM 是一種輕量級、可即插即用的注意力模塊,能夠無縫集成到各種卷積神經網絡(CNN)架構中。它的核心原理是讓模型自動學習特征圖在通道和空間兩個維度上的重要性權重,并據此對特征圖進行自適應的調整——強化關鍵特征,弱化非關鍵特征。這一過程顯著提升了模型的特征表征能力和最終性能。形象地說,CBAM 如同為模型配備了“智能眼鏡”,使其能更精準地聚焦于輸入圖像中最具信息量的部分。
CBAM 的組成結構:通道與空間注意力的結合
CBAM 由兩個順序連接的子模塊構成:
通道注意力模塊(Channel Attention Module):分析并確定哪些特征通道包含更關鍵的信息(例如,識別與特定物體顏色或紋理相關的通道)。
空間注意力模塊(Spatial Attention Module):定位并確定關鍵信息在特征圖空間維度上的具體位置(例如,識別物體在圖像中的區域)。
處理流程為:輸入特征圖 → 通道注意力模塊 → 空間注意力模塊 → 輸出增強后的特征圖。
相較于 SE 模塊的突破
SE 的局限:SE 僅聚焦于學習“哪些通道重要”,而忽略了“重要信息在空間中的具體位置”。
CBAM 的突破:
通過通道注意力明確“關注哪些特征通道”。
通過空間注意力定位“在空間中的哪個位置關注”。
二者協同工作,使模型能夠同時學習“關注什么內容”和“在何處關注”,從而實現了更全面、更強大的特征表達能力提升。
CBAM 的優勢特點
輕量高效:僅通過全局池化操作和少量簡單卷積層實現,計算開銷小。
即插即用:無需改動原有網絡的主體結構,可方便地插入卷積層之間。
雙重優化:同時提升特征在通道維度和空間維度的質量,在處理復雜任務(如小目標檢測、語義分割)時效果尤為顯著。
通用性強:與 SE 等注意力模塊類似,CBAM 也屬于“即插即用”型模塊,適用于廣泛的 CNN 架構(如 ResNet, YOLO 等)。
import torch
import torch.nn as nnclass ChannelAttention(nn.Module):def __init__(self, in_channels, reduction_ratio=16):"""通道注意力機制初始化參數:in_channels: 輸入特征通道數reduction_ratio: 通道壓縮比例,默認16"""super().__init__()# 特征壓縮操作:使用自適應池化獲取通道統計信息self.channel_avg = nn.AdaptiveAvgPool2d(1) # 提取通道均值特征self.channel_max = nn.AdaptiveMaxPool2d(1) # 提取通道峰值特征# 通道關系學習模塊:共享權重的多層感知機self.channel_mlp = nn.Sequential(nn.Linear(in_channels, in_channels // reduction_ratio, bias=False),nn.ReLU(inplace=True), # 原位激活減少內存占用nn.Linear(in_channels // reduction_ratio, in_channels, bias=False))# 權重歸一化層self.weight_activ = nn.Sigmoid()def forward(self, feature_map):"""特征圖通道增強處理參數:feature_map: 輸入特征張量 [B, C, H, W]返回:通道增強后的特征張量"""batch_size, num_channels, _, _ = feature_map.size()# 通道統計信息計算avg_stats = self.channel_avg(feature_map).view(batch_size, num_channels)max_stats = self.channel_max(feature_map).view(batch_size, num_channels)# 雙路特征融合channel_weights = self.channel_mlp(avg_stats) + self.channel_mlp(max_stats)# 生成通道注意力掩碼attention_mask = self.weight_activ(channel_weights).view(batch_size, num_channels, 1, 1)# 應用注意力權重return feature_map * attention_mask # 廣播機制自動擴展維度
import torch
import torch.nn as nnclass SpatialAttention(nn.Module):def __init__(self, kernel_size=7):"""空間注意力機制初始化參數:kernel_size: 卷積核尺寸,控制感受野大小(必須為奇數)"""super().__init__()# 特征融合卷積層:將雙通道特征圖融合為單通道空間權重# 使用奇數卷積核確保對稱填充 (padding=kernel_size//2)self.spatial_conv = nn.Conv2d(in_channels=2, out_channels=1, kernel_size=kernel_size,padding=kernel_size // 2, # 保持特征圖尺寸不變bias=False # 無偏置項)# 空間權重歸一化self.weight_activ = nn.Sigmoid()def forward(self, feature_map):"""特征圖空間增強處理參數:feature_map: 輸入特征張量 [B, C, H, W]返回:空間增強后的特征張量"""# 通道維度壓縮:生成空間顯著性特征# 平均池化:捕獲全局上下文信息 [B, 1, H, W]channel_avg = torch.mean(feature_map, dim=1, keepdim=True)# 最大池化:捕獲顯著局部特征 [B, 1, H, W]channel_max, _ = torch.max(feature_map, dim=1, keepdim=True)# 雙通道特征拼接:融合不同視角的空間信息 [B, 2, H, W]spatial_stats = torch.cat([channel_avg, channel_max], dim=1)# 空間特征學習:通過卷積生成注意力熱圖attention_heatmap = self.spatial_conv(spatial_stats)# 生成空間注意力掩碼 [B, 1, H, W]spatial_mask = self.weight_activ(attention_heatmap)# 應用空間注意力權重return feature_map * spatial_mask # 廣播機制自動擴展通道維度
?
@浙大疏錦行