当前位置:   article > 正文

空间注意力模块与通道注意力模块实现

空间注意力模块

注意力机制(CBAM)论文:1807.06521.pdf (arxiv.org)

参考博文:CBAM实现(pytorch)_cabm pytroch-CSDN博客

1.空间注意力机制(SAB)

强调感兴趣的区域同时抑制不相关的背景区域。感兴趣的区域生成一个较大的权重,不感兴趣的区域生成一个较小的权重,最后将输入特征图F乘以权重。

代码实现:

  1. class SpatialAttention(nn.Module):
  2. # 空间注意力模块实现
  3. def __init__(self, kernel_size=7):
  4. super(SpatialAttention, self).__init__()
  5. self.conv1 = nn.Conv2d(2, 1, kernel_size, padding=kernel_size // 2, bias=False)
  6. self.sigmoid = nn.Sigmoid()
  7. def forward(self, x):
  8. avg_out = torch.mean(x, dim=1, keepdim=True) # 用于计算在第一个维度上的均值,即对每一行进行求平均,keepdim=True表示保持结果的维度与输入的维度一致(即保持行数不变)
  9. max_out, _ = torch.max(x, dim=1, keepdim=True)
  10. out = torch.cat([avg_out, max_out], dim=1) # 将每一行的均值和最大值连接在一起,形成一个新的张量
  11. out = self.conv1(out)
  12. return self.sigmoid(out) * x

2.通道注意力(CAB)

显示不同通道(一个通道是由一个卷积核对输入图像做卷积操作生成的特征图像)之间的相关性和特征图的重要程度。对不同的通道生成一个不一样的权重,权重大说明此通道比较重要。

  1. class ChannelAttention(nn.Module):
  2. # 通道注意力模块实现
  3. def __init__(self, in_planes, ratio=16):
  4. super(ChannelAttention, self).__init__()
  5. self.avg_pool = nn.AdaptiveAvgPool2d(1) # 自适应平均池化
  6. self.max_pool = nn.AdaptiveMaxPool2d(1) # 自适应最大池化
  7. self.fc = nn.Sequential(nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False),
  8. nn.ReLU(),
  9. nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)) # MLP模块由两个卷积乘后再全连接
  10. self.sigmoid = nn.Sigmoid()
  11. def forward(self, x):
  12. avg_out = self.fc(self.avg_pool(x))
  13. max_out = self.fc(self.max_pool(x))
  14. out = avg_out + max_out # 通道合并?
  15. return self.sigmoid(out) * x # 通道注意力模块得到的权重与特征图相乘

3.CBAM注意力机制

将CAB和SAB结合起来。

  1. class CBAM(nn.Module):
  2. def __init__(self, channel):
  3. super(CBAM, self).__init__()
  4. self.channel_attention = ChannelAttentionModule(channel)
  5. self.spatial_attention = SpatialAttentionModule()
  6. def forward(self, x):
  7. out = self.channel_attention(x) * x
  8. print('outchannels:{}'.format(out.shape))
  9. out = self.spatial_attention(out) * out
  10. return out

SE注意力机制

 

 代码实现:

  1. class SELayer(nn.Module):
  2. # SE注意力机制
  3. def __init__(self, channel, reduction=16):
  4. super(SELayer, self).__init__()
  5. self.avg_pool = nn.AdaptiveAvgPool2d(1) # 平局池化操作
  6. self.fc = nn.Sequential(
  7. nn.Linear(channel, channel // reduction, bias=False), # 全连接
  8. nn.ReLU(inplace=True),
  9. nn.Linear(channel // reduction, channel, bias=False), # 全连接
  10. nn.Sigmoid()
  11. )
  12. def forward(self, x):
  13. b, c, _, _ = x.size() # 获取输入特征图 x 的大小,b 表示批次的大小,c 表示输入特征图的通道数
  14. y = self.avg_pool(x).view(b, c)
  15. # 输入特征图 x 经过平均池化层 self.avg_pool 处理,然后使用 view 方法将其形状变为 (b, c)。这一步是为了将特征图转换为向量的形式
  16. y = self.fc(y).view(b, c, 1, 1)
  17. # 特征向量 y 经过全连接层 self.fc 处理,然后使用 view 方法将其形状变为 (b, c, 1, 1)。这一步是为了将特征向量转换为与输入特征图相同的形状
  18. return x * y.expand_as(x)
  19. # 将输入特征图 x 与调整形状后的 y 进行逐元素相乘,得到最终的输出特征图。y.expand_as(x) 将 y 扩展为与 x 相同的形状,以便进行逐元素相乘操作

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/351726
推荐阅读
相关标签
  

闽ICP备14008679号