[pytorch] 试验--用CBAM注意力模块进行语义分割

CBAM是IEEE 2018的一篇文章

Convolutional Block Attention Module (CBAM) 表示卷积模块的注意力机制模块。是一种结合了空间(spatial)和通道(channel)的注意力机制模块。相比于senet只关注通道(channel)的注意力机制可以取得更好的效果。

CBAM的结构如下:

通道注意力决定了网络“look what”,因为每个通道所关注的特征是不一样的。空间注意力决定了网络“look where”。

Input Feature F的维度是CxHxW,通道注意力特征Mc的维度是Cx1x1。空间注意力特征Ms的维度是1xHxW。

通道注意力特征的形成如下:

论文作者认为,前人的一些操作表明了用平均池化可以有效地聚集空间信息。而作者认为,最大池化可以更好地获得一些独特物体的特征从而调优注意力模型。通过平均池化和最大池化后的特征会各自通过MLP的两个fc层,得到MLP处理后的平均池化特征和最大池化特征,然后再加到一起,最后通过softmax层,再作为output输出。

公式如下:

\sigma表示softmax操作。

代码如下:

空间注意力特征的形成如下:

输入特征沿着通道的维度方向分别进行最大操作和平均操作,再直接连接在一起,然后再通过卷积操作,达到强调或抑制某些地方的作用。最后通过softmax层得到最终输出。

公式如下:

\sigma表示softmax操作。f^{7\times 7}表示卷积核为7x7的卷积操作。;表示连接。

代码如下:

CBAM注意力模块的应用:

论文中的CBAM模块是嵌入到resnet中的,resnet中的每个block都嵌入了CBAM模块。流程图如下:

公式如下:

用于语义分割:

而怎么看用于语义分割的效果呢?只需要把最后的特征图进行上采样就行了

输入图片:

输出:

可以看出效果其实很不好。

当然也有可能是我代码写得有问题,欢迎讨论。

代码链接:https://github.com/Andy-zhujunwen/pytorch-CBAM-Segmentation-experiment-

论文地址:https://arxiv.org/abs/1807.06521

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
CBAM(Convolutional Block Attention Module)是一种用于卷积神经网络的注意力模块,可以增强模型的表达能力和准确性。下面是一个使用PyTorch实现的CBAM模块的示例代码: ```python import torch import torch.nn as nn import torch.nn.functional as F 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.ca = ChannelAttention(in_planes, ratio) self.sa = SpatialAttention(kernel_size) def forward(self, x): out = x * self.ca(x) return out * self.sa(out) ``` 上述代码中,定义了一个CBAM类,包括了ChannelAttention模块和SpatialAttention模块。其中,ChannelAttention模块用于提取通道信息,SpatialAttention模块用于提取空间信息。在CBAM模块的forward()函数中,先使用ChannelAttention模块提取通道信息,然后再使用SpatialAttention模块提取空间信息。最后将两种信息结合起来得到最终输出。 使用该CBAM模块时,只需在需要使用注意力机制的卷积层后面添加一个CBAM实例即可。例如: ```python class MyModel(nn.Module): def __init__(self): super(MyModel, self).__init__() self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1) self.cbam1 = CBAM(64) self.conv2 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) self.cbam2 = CBAM(128) def forward(self, x): x = self.conv1(x) x = self.cbam1(x) x = F.relu(x) x = self.conv2(x) x = self.cbam2(x) x = F.relu(x) return x ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值