CBAM ResNet50
时间: 2025-03-15 18:21:25 浏览: 90
### 如何在 ResNet50 中实现 CBAM 注意力机制
CBAM(Convolutional Block Attention Module)是一种轻量级的注意力模块,可以无缝集成到现有的卷积神经网络结构中。它通过通道注意和空间注意两个维度来增强特征表示能力[^1]。
以下是具体方法:
#### 1. **引入 CBAM 的基本概念**
CBAM 主要由两部分组成:**Channel Attention (CA)** 和 **Spatial Attention (SA)**。
- Channel Attention 负责计算不同通道的重要性权重。
- Spatial Attention 则关注于特征图的空间分布。
这两个模块可以通过简单的操作嵌入到现有模型中,而不会显著增加额外参数或计算开销。
#### 2. **修改 ResNet50 架构**
ResNet50 是一种经典的深度残差网络,在其基础架构上加入 CBAM 可以进一步提升性能。通常的做法是在每个残差块之后插入 CBAM 模块。这样可以让每一层提取的特征都经过注意力调整。
下面是一个 Python 实现示例,基于 PyTorch 平台完成 ResNet50 加 CBAM 的构建:
```python
import torch
import torch.nn as nn
class ChannelAttention(nn.Module):
def __init__(self, in_planes, ratio=8):
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 CBAMBlock(nn.Module):
def __init__(self, channel, reduction=8, kernel_size=7):
super(CBAMBlock, self).__init__()
self.channel_attention = ChannelAttention(channel, reduction)
self.spatial_attention = SpatialAttention(kernel_size)
def forward(self, x):
out = self.channel_attention(x) * x
out = self.spatial_attention(out) * out
return out
def add_cbam_to_resnet(resnet_model):
for name, module in resnet_model.named_children():
if isinstance(module, nn.Sequential): # 对应 ResNet 的 layer 层
for basic_block_name, basic_block_module in module.named_children():
cbam_layer = CBAMBlock(basic_block_module.conv1.out_channels)
setattr(basic_block_module, 'cbam', cbam_layer)
def forward_hook(m, x):
identity = x[0]
out = m.cbam(x[0])
out += identity
return out
basic_block_module.register_forward_hook(forward_hook)
```
上述代码定义了一个完整的 CBAM 结构并将其注入到 ResNet50 的每一个 BasicBlock 或 Bottleneck 块中。
#### 3. **加载预训练模型并与 CBAM 集成**
如果希望利用已有的 ResNet50 权重,则可以直接调用 `torchvision.models.resnet50(pretrained=True)` 获取预训练模型,并按照上面的方法对其进行改造。
---
### 总结
通过将 CBAM 添加至 ResNet50 各个阶段中的残差单元后部,能够有效提高模型对于复杂场景下目标识别的能力。此改进不仅适用于 ImageNet 数据集上的分类任务,还可在其他视觉领域如目标检测、语义分割等方面发挥重要作用。
阅读全文
相关推荐


















