1. 摘要
作者提出了一個簡單但有效的注意力模塊 CBAM,給定一個中間特征圖,我們沿着空間和通道兩個維度依次推斷出注意力權重,然后與原特征圖相乘來對特征進行自適應調整。
由於 CBAM 是一個輕量級的通用模塊,它可以無縫地集成到任何 CNN 架構中,額外開銷忽略不計,並且可以與基本 CNN 一起進行端到端的訓練。
在不同的分類和檢測數據集上,將 CBAM 集成到不同的模型中后,模型的表現都有了一致的提升,展示了其廣泛的可應用性。
2. 介紹
為了提升 CNN 模型的表現,最近的研究主要集中在三個重要的方面:深度、寬度和基數(cardinality)。ResNet 讓構建非常深的網絡成為可能,而 GoogLeNet 則表明寬度也是提升模型性能的另一個重要的因素。此外,Xception 和 ResNeXt 提出增加網絡的基數,經驗表明,基數不僅可以節省參數總量,還可以產生比深度和寬度更強的表示能力。
除了這些因素,作者則研究了網絡架構設計的另一個不同方向:注意力。注意力不僅要告訴我們重點關注哪里,還要提高關注點的表示。 我們的目標是通過使用注意機制來增加表現力,關注重要特征並抑制不必要的特征。
為了強調空間和通道這兩個維度上的有意義特征,作者依次應用通道和空間注意模塊,來分別在通道和空間維度上學習關注什么、在哪里關注。此外,通過了解要強調或抑制的信息也有助於網絡內的信息流動。
3. 網絡結構
作者將注意力過程分為兩個獨立的部分,通道注意力模塊和空間注意力模塊。這樣不僅可以節約參數和計算力,而且保證了其可以作為即插即用的模塊集成到現有的網絡架構中去。
3.1. 通道注意力模塊
特征的每一個通道都代表着一個專門的檢測器,因此,通道注意力是關注什么樣的特征是有意義的。為了匯總空間特征,作者采用了全局平均池化和最大池化兩種方式來分別利用不同的信息。
如上圖所示,輸入是一個 H×W×C 的特征 F,我們先分別進行一個空間的全局平均池化和最大池化得到兩個 1×1×C 的通道描述。接着,再將它們分別送入一個兩層的神經網絡,第一層神經元個數為 C/r,激活函數為 Relu,第二層神經元個數為 C。注意,這個兩層的神經網絡是共享的。
然后,再將得到的兩個特征相加后經過一個 Sigmoid 激活函數得到權重系數 Mc。最后,拿權重系數和原來的特征 F 相乘即可得到縮放后的新特征。
3.2. 空間注意力模塊
在通道注意力模塊之后,我們再引入空間注意力模塊來關注哪里的特征是有意義的。
與通道注意力相似,給定一個 H×W×C 的特征 F‘,我們先分別進行一個通道維度的平均池化和最大池化得到兩個 H×W×1 的通道描述,並將這兩個描述按照通道拼接在一起。然后,經過一個 7×7 的卷積層,激活函數為 Sigmoid,得到權重系數 Ms。最后,拿權重系數和特征 F’ 相乘即可得到縮放后的新特征。
3.3. CBAM
通道注意力和空間注意力這兩個模塊可以以並行或者順序的方式組合在一起,但是作者發現順序組合並且將通道注意力放在前面可以取得更好的效果。
一個完整的 CBAM 模塊如上圖所示,其 TensorFlow 的一個實現如下所示:
def CBAM(input, reduction):
"""
@Convolutional Block Attention Module
"""
_, width, height, channel = input.get_shape() # (B, W, H, C)
# channel attention
x_mean = tf.reduce_mean(input, axis=(1, 2), keepdims=True) # (B, 1, 1, C)
x_mean = tf.layers.conv2d(x_mean, channel // reduction, 1, activation=tf.nn.relu, name='CA1') # (B, 1, 1, C // r)
x_mean = tf.layers.conv2d(x_mean, channel, 1, name='CA2') # (B, 1, 1, C)
x_max = tf.reduce_max(input, axis=(1, 2), keepdims=True) # (B, 1, 1, C)
x_max = tf.layers.conv2d(x_max, channel // reduction, 1, activation=tf.nn.relu, name='CA1', reuse=True)
# (B, 1, 1, C // r)
x_max = tf.layers.conv2d(x_max, channel, 1, name='CA2', reuse=True) # (B, 1, 1, C)
x = tf.add(x_mean, x_max) # (B, 1, 1, C)
x = tf.nn.sigmoid(x) # (B, 1, 1, C)
x = tf.multiply(input, x) # (B, W, H, C)
# spatial attention
y_mean = tf.reduce_mean(x, axis=3, keepdims=True) # (B, W, H, 1)
y_max = tf.reduce_max(x, axis=3, keepdims=True) # (B, W, H, 1)
y = tf.concat([y_mean, y_max], axis=-1) # (B, W, H, 2)
y = tf.layers.conv2d(y, 1, 7, padding='same', activation=tf.nn.sigmoid) # (B, W, H, 1)
y = tf.multiply(x, y) # (B, W, H, C)
return y
4. 實驗結果
將 CBAM 集成到 ResNet 中的方式如下圖所示。
4.1. Ablation studies
可以看到,在通道注意力模塊中,同時引入最大池化和平均池化可以得到最好的效果。
在空間注意力模塊中,同時引入最大池化和平均池化比利用一個 1×1 的卷積要好,同時,卷積層采用 7×7 的卷積核要優於 3×3 的卷積核。
至於通道注意力和空間注意力的組合方式,則是順序組合通道注意力在前最好。
4.2. 圖像分類
將 CBAM 集成到所有的 ResNet 系列網絡中去,都會降低最終的分類錯誤率,這展示了 CBAM 的通用性和巨大的潛力。
4.3. 可視化
利用 Grad-CAM 對不同的網絡進行可視化后,可以發現,引入 CBAM 后,特征覆蓋到了待識別物體的更多部位,並且最終判別物體的概率也更高,這表明注意力機制的確讓網絡學會了關注重點信息。
4.4. 物體檢測
在物體檢測領域,引入 CBAM 后模型性能的提升效果同樣非常明顯。
獲取更多精彩,請關注「seniusen」!