注意力模型CBAM

论文:CBAM: Convolutional Block Attention Module 

 

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

 

基于传统VGG结构的CBAM模块。需要在每个卷积层后面加该模块。

基于shortcut结构的CBAM模块。例如resnet50,该模块在每个resnet的block后面加该模块。

 

Channel attention module:

 

将输入的featuremap,分别经过基于width和height的global max pooling 和global average pooling,然后分别经过MLP。将MLP输出的特征进行基于elementwise的加和操作,再经过sigmoid激活操作,生成最终的channel attention featuremap。将该channel attention featuremap和input featuremap做elementwise乘法操作,生成Spatial attention模块需要的输入特征。

其中,seigema为sigmoid操作,r表示减少率,其中W0后面需要接RELU激活。

 

Spatial attention module:

 

将Channel attention模块输出的特征图作为本模块的输入特征图。首先做一个基于channel的global max pooling 和global average pooling,然后将这2个结果基于channel 做concat操作。然后经过一个卷积操作,降维为1个channel。再经过sigmoid生成spatial attention feature。最后将该feature和该模块的输入feature做乘法,得到最终生成的特征。

其中,seigema为sigmoid操作,7*7表示卷积核的大小,7*7的卷积核比3*3的卷积核效果更好。

 

The code:

def cbam_module(inputs,reduction_ratio=0.5,name=""):
    with tf.variable_scope("cbam_"+name, reuse=tf.AUTO_REUSE):
        batch_size,hidden_num=inputs.get_shape().as_list()[0],inputs.get_shape().as_list()[3]

        maxpool_channel=tf.reduce_max(tf.reduce_max(inputs,axis=1,keepdims=True),axis=2,keepdims=True)
        avgpool_channel=tf.reduce_mean(tf.reduce_mean(inputs,axis=1,keepdims=True),axis=2,keepdims=True)
        
        maxpool_channel = tf.layers.Flatten()(maxpool_channel)
        avgpool_channel = tf.layers.Flatten()(avgpool_channel)
        
        mlp_1_max=tf.layers.dense(inputs=maxpool_channel,units=int(hidden_num*reduction_ratio),name="mlp_1",reuse=None,activation=tf.nn.relu)
        mlp_2_max=tf.layers.dense(inputs=mlp_1_max,units=hidden_num,name="mlp_2",reuse=None)
        mlp_2_max=tf.reshape(mlp_2_max,[batch_size,1,1,hidden_num])

        mlp_1_avg=tf.layers.dense(inputs=avgpool_channel,units=int(hidden_num*reduction_ratio),name="mlp_1",reuse=True,activation=tf.nn.relu)
        mlp_2_avg=tf.layers.dense(inputs=mlp_1_avg,units=hidden_num,name="mlp_2",reuse=True)
        mlp_2_avg=tf.reshape(mlp_2_avg,[batch_size,1,1,hidden_num])

        channel_attention=tf.nn.sigmoid(mlp_2_max+mlp_2_avg)
        channel_refined_feature=inputs*channel_attention

        maxpool_spatial=tf.reduce_max(inputs,axis=3,keepdims=True)
        avgpool_spatial=tf.reduce_mean(inputs,axis=3,keepdims=True)
        max_avg_pool_spatial=tf.concat([maxpool_spatial,avgpool_spatial],axis=3)
        conv_layer=tf.layers.conv2d(inputs=max_avg_pool_spatial, filters=1, kernel_size=(7, 7), padding="same", activation=None)
        spatial_attention=tf.nn.sigmoid(conv_layer)

        refined_feature=channel_refined_feature*spatial_attention

    return refined_feature

 

### CBAM注意力机制概述 CBAM(Convolutional Block Attention Module)是一种轻量级的注意力模块,旨在通过通道注意和空间注意来增强卷积神经网络中的特征表示能力[^2]。它能够动态调整不同位置的重要性权重,从而提高模型性能。 #### 实现细节 CBAM的核心思想在于分别计算 **通道注意力** 和 **空间注意力** 并将其组合起来应用到输入特征图上。以下是具体实现过程: 1. **通道注意力 (Channel Attention)** 首先通过对输入特征图 $F$ 进行全局平均池化(Global Average Pooling, GAP)和全局最大池化(Global Max Pooling, GMP),得到两个一维向量。随后将这两个向量送入共享权值的多层感知机(MLP)结构中处理,最终通过逐元素相加并经过 Sigmoid 函数生成通道注意力掩码 $M_c$[^3]。 2. **空间注意力 (Spatial Attention)** 对于空间维度上的关注,则利用先前获得的通道注意力结果作为新的输入。同样采用 GAP 和 GMP 的方式提取信息,并沿通道方向连接这些统计量形成二维张量。接着通过一个 $7 \times 7$ 卷积操作学习空间关系,最后经由 Sigmoid 得到空间注意力掩码 $M_s$[^4]。 3. **融合与输出** 将上述两部分的结果依次作用于原始特征图之上,即先乘以通道注意力再乘以空间注意力完成整个流程。 ```python 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 CBAM(nn.Module): def __init__(self, channel_in, reduction_ratio=8, kernel_size=7): super(CBAM, self).__init__() self.channel_attention = ChannelAttention(channel_in, reduction_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 ``` 以上代码展示了如何构建基于 PyTorch 的 CBAM 模块[^5]。 #### 使用场景 CBAM 可广泛应用于图像分类、目标检测以及语义分割等领域。其主要优势体现在无需额外增加大量参数的情况下显著提升模型表现力。例如,在 ResNet 或 DenseNet 等基础架构基础上加入此模块即可轻松获取更优的效果。 ---
评论 77
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值