CBAM: Convolutional Block Attention Module论文解读和算法原理解析笔记---注意力模型

 

前言

这是去年ECCV2018的一篇文章,主要贡献为提出一个新的网络结构。之前有一篇论文提出了SENet,在feature map的通道上进行attention生成,然后与原来的feature map相乘。这篇文章指出,该种attention方法只关注了通道层面上哪些层会具有更强的反馈能力,但是在空间维度上并不能体现出attention的意思。CBAM作为本文的亮点,将attention同时运用在channel和spatial两个维度上,CBAM与SE Module一样,可以嵌入了目前大部分主流网络中,在不显著增加计算量和参数量的前提下能提升网络模型的特征提取能力。  近几年,随着CNN的兴起,很多结构新颖、有效的网络结构被提出,比如ResNet、ResNext等;最近,大部分论文证明了在网络结构中引入attention机制可以提升网络模型的特征表达能力。attention不止能告诉网络模型该注意什么,同时也能增强特定区域的表征。本文的CBAM在channel和spatial两个维度上引入了attention机制。

贡献 

1.我们提出了一种简单而有效的注意力模块(CBAM),可以广泛应用于提高CNN的表示能力。  

2.我们通过广泛的消融研究验证了我们注意力模块的有效性。

 3.我们通过插入轻量级模块,验证多个基准(ImageNet-1K,MS COCO和VOC 2007)的各种网络性能得到了极大提升。

思想原理

根据近年的深度学习的深入研究调查了网络的三个重要因素:深度,宽度和基数。

当然除了这些因素之外,该论文还研究了架构设计的一个不同方面,即注意力。虽然在之前的文献中,已经有很多的相关研究关于注意力的重要性。所谓的注意力不仅要告诉重点在哪里,还要提高兴趣点的代表性。此论文的目标是通过使用注意机制来增加表现力:关注重要特征并抑制不必要的特征。

核心思想

由于卷积运算通过将多通道和空间信息混合在一起来提取信息特征,而在论文中采用他们的模块来强调沿着这两个主要维度的有意义的特征:通道和空间轴。这样每个分支都可以分别在通道和空间轴上学习到"what"和"where"。

主要的公式:

F是input feature map作为输入,其中⊗表示逐元素乘法

Mc表示在channel维度上做attention提取的操作

Ms表示的是在spatial维度上做attention提取的操作

下图便是具体的处理过程图:

 

Channel Attention Module算法原理

算法公式:

 

为了有效地计算通道注意力,我们压缩输入特征图谱的空间维度。为了聚集空间信息首先将feature map在spatial维度上进行压缩,得到一个一维矢量以后再进行操作。对输入feature map进行spatial维度压缩时,a使用的是average pooling(平均池化)和max pooling(最大值池化),通过两个pooling函数以后总共可以得到两个一维矢量,这样做的好处是:average pooling有效地学习目标物体,而最大池化收集了关于独特对象特征的另一个重要线索,以推断出通道方面的注意力。此外,我在网上学习时看到过另一种说法:average pooling对feature map上的每一个像素点都有反馈,而 max pooling在进行梯度反向传播计算只有feature map中响应最大的地方有梯度的反馈,能作为GAP的一个补充。

在得到两个一维矢量后,将其放入一个共享网络中,共享网络是由一个隐藏层和多层感知机(MLP)组成。为了减少参数开销,隐藏的激活大小设置为,其中r是压缩率。在将共享网络应用于矢量之后,我们使用逐元素求和来合并输出特征向量。其中σ表示Sigmoid函数,即再经过激活函数后最后得到的结果

值得注意的是,多层感知机模型中W0和W1之间的feature需要使用ReLU作为激活函数去处理。代码如下:

def channel_attention(input_feature, name, ratio=8):
  
  kernel_initializer = tf.contrib.layers.variance_scaling_initializer()
  bias_initializer = tf.constant_initializer(value=0.0)
  
  with tf.variable_scope(name):
    
    channel = input_feature.get_shape()[-1]
    avg_pool = tf.reduce_mean(input_feature, axis=[1,2], keepdims=True)
        
    assert avg_pool.get_shape()[1:] == (1,1,channel)
    avg_pool = tf.layers.dense(inputs=avg_pool,
                                 units=channel//ratio,
                                 activation=tf.nn.relu,
                                 kernel_initializer=kernel_initializer,
                                 bias_initializer=bias_initializer,
                                 name='mlp_0',
                                 reuse=None)   
    assert avg_pool.get_shape()[1:] == (1,1,channel//ratio)
    avg_pool = tf.layers.dense(inputs=avg_pool,
                                 units=channel,                             
                                 kernel_initializer=kernel_initializer,
                                 bias_initializer=bias_initializer,
                                 name='mlp_1',
                                 reuse=None)    
    assert avg_pool.get_shape()[1:] == (1,1,channel)

    max_pool = tf.reduce_max(input_feature, axis=[1,2], keepdims=True)    
    assert max_pool.get_shape()[1:] == (1,1,channel)
    max_pool = tf.layers.dense(inputs=max_pool,
                                 units=channel//ratio,
                                 activation=tf.nn.relu,
                                 name='mlp_0',
                                 reuse=True)   
    assert max_pool.get_shape()[1:] == (1,1,channel//ratio)
    max_pool = tf.layers.dense(inputs=max_pool,
                                 units=channel,                             
                                 name='mlp_1',
                                 reuse=True)  
    assert max_pool.get_shape()[1:] == (1,1,channel)

    scale = tf.sigmoid(avg_pool + max_pool, 'sigmoid')
    
  return input_feature * scale

Spatial attention module

算法公式:

首先沿通道轴应用平均池化和最大池化操作(此处注意点:这里的压缩变成了通道层面上的压缩,不再是最开始的feature map,这里面的F=Mc),接着对输入特征分别在通道维度上做了avg和max操作。最后得到了两个二维的feature,将其按通道维度拼接在一起得到一个通道数为2的feature map,之后使用一个包含单个卷积核的隐藏层对其进行卷积操作,要保证最后得到的feature在spatial维度上与输入的feature map一致。

其中σ表示sigmoid函数,f7×7表示卷积操作,卷积核大小为7×7。代码如下:

def spatial_attention(input_feature, name):
  kernel_size = 7
  kernel_initializer = tf.contrib.layers.variance_scaling_initializer()
  with tf.variable_scope(name):
    avg_pool = tf.reduce_mean(input_feature, axis=[3], keepdims=True)
    assert avg_pool.get_shape()[-1] == 1
    max_pool = tf.reduce_max(input_feature, axis=[3], keepdims=True)
    assert max_pool.get_shape()[-1] == 1
    concat = tf.concat([avg_pool,max_pool], 3)
    assert concat.get_shape()[-1] == 2
    
    concat = tf.layers.conv2d(concat,
                              filters=1,
                              kernel_size=[kernel_size,kernel_size],
                              strides=[1,1],
                              padding="same",
                              activation=None,
                              kernel_initializer=kernel_initializer,
                              use_bias=False,
                              name='conv')
    assert concat.get_shape()[-1] == 1
    concat = tf.sigmoid(concat, 'sigmoid')
    
  return input_feature * concat

当然论文作者也说明了注意力模块的安排。给定输入图像,两个注意力模块,通道和空间,计算互补注意力,分别关注“什么”和“何处”。 考虑到这一点,可以以并行或顺序方式放置两个模块。我们发现顺序排列比并行排列能得到更好的结果。对于顺序过程的安排,我们的实验结果表明,通道的第一顺序略好于空间第一顺序。

def cbam_block(input_feature, name, ratio=8):
  """Contains the implementation of Convolutional Block Attention Module(CBAM) block.
  As described in https://arxiv.org/abs/1807.06521.
  """
  
  with tf.variable_scope(name):
    attention_feature = channel_attention(input_feature, 'ch_at', ratio)
    attention_feature = spatial_attention(attention_feature, 'sp_at')
    print ("CBAM Hello")
  return attention_feature

 

### 回答1: CBAM是卷积块注意力模块的缩写,是一种用于交替堆叠到深度卷积神经网络(CNNs)中的模块。它包含两个子模块:通道注意力模块和空间注意力模块。通道注意力模块用来对每个通道进行加权,确定哪些通道最重要。空间注意力模块在每个通道中对所有空间位置进行加权,可以捕捉不同位置的重要性,从而更好地定位物体。 CBAM的优点在于,它能够提高CNNs的性能,减少了过度拟合的情况。CBAM结构的输入任意大小、任意通道数、任意深度,因此可以适用于各种计算机视觉任务,包括图像分类,物体检测和语义分割等。 总之,CBAM是一种具有高灵活性和高性能的卷积块注意力模块,能够极大地增强CNNs的表达能力,提高计算机视觉任务的准确性。 ### 回答2: CBAMConvolutional Block Attention Module),是一种用于图像分类的Attention模块,它主要是用于增强卷积神经网络(CNN)的特征表达能力,使得CNN能够更好地区分不同种类的图像。 CBAM结构由两部分组成,分别是CBAM-Channel和CBAM-Spatial。在CBAM-Channel中,它通过引入注意力机制,对每个通道的特征进行加权求和,并且使用全局平均池化操作,计算其重要性参数,进而对特征进行修正,从而提升模型的表达能力。CBAM-Spatial则通过空间注意力机制对图像中的区域进行注意力分配权重,进一步优化模型的性能。 CBAM在图像分类方面的性能表现非常卓越。实验证明,在对比原始ResNet和ResNeXt网络,以及加入CBAM的ResNet和ResNext网络进行图像分类时,加入CBAM的ResNet和ResNeXt网络具有更强的表达能力和更高的分类准确性,同时,它在训练过程中的收敛速度也有所提升。 总的来说,CBAM是一种非常有效的图像分类模块,利用注意力机制对CNN的特征进行增强,为图像分类任务提供了更好的性能表现。随着人工智能的迅速发展,CBAM在图像识别、物体检测等领域将具有广阔的应用前景。 ### 回答3: CBAM是卷积块注意力模块的缩写,它是一种用于图像分类和目标检测的神经网络模型CBAM模块通过将通道和空间注意力机制组合在一起,从而有效地提高了模型的性能。 CBAM模块分为两个部分:通道注意力机制和空间注意力机制。通道注意力机制是针对图像特征中的通道信息进行关注,它可以基于每个通道的特征图来计算权重,然后对于每个通道进行信息的调整和加权。这样,在网络中的每个层次上都能更好地利用有用的通道信息,减少无用信息对网络性能的影响。 空间注意力机制是针对图像特征中的空间信息进行关注。它能够自适应地计算每个像素点的权重,然后对于每个像素点进行信息的调整和加权。这样,网络中的每个空间位置都能更好地利用有用的空间信息,提高目标检测和分类的准确率。 通过组合这两种注意力机制,CBAM模块能够区分有用和无用的特征,从而在图像分类和目标检测任务中取得更好的性能。CBAM模块通常被用在深度卷积神经网络中,例如ResNet以及MobileNet等,以提高整个网络中的特征提取能力和分类性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值