不定期讀一篇Paper之CBAM
前言
本論文針對先前對通道注意力或者空間注意力機制,提出了一個簡單又有效的注意力機制模塊,該模塊既注意關注通道方面,使得網絡知道“what”,又針對空間方面,使得網絡知道"where",兩面進行調整。此外,CBAM是一個輕量化且通用的模塊,它可以被整合到任何CNN架構的網絡中,並且可以進行端對端的訓練。
框架
CBAM有兩個注意力模塊:通道和空間,它們按照次序通道->空間,當然理論上也可以平行或空間->通道的連接方法,但是,作者在實驗上證明通道->空間的次序連接的性能較好。下圖是連接關係圖:
下面首先針對通道和空間子模塊進行分析。
-
通道注意力模塊(what)
首先,由於特徵圖中,不同通道feature map刻畫特徵不同,所以,通道注意力機制關注對於一張圖片中有意義的"what"。在計算方面,輸入一個特徵圖F,分別在空間上進行最大池化和平均池化,保持通道維度不變,然後分別送入一個共享的全連接網絡,,最後把通過共享全連接兩個模塊相加後,送入Sigmoid函數中,得到通道注意力模塊。
Pytorch代碼:
class ChannelAttention(nn.Module): def __init__(self, in_planes, rotio = 16): """ in_planes : 輸入通道 rotio : 縮減率 """ super(ChannelAttention, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.max_pool = nn.AdaptiveMaxPool2d(1) self.shareMLP = nn.Sequential( # 通過縮減,減少優化參數 nn.Conv2d(in_planes, in_planes//16, 1, bias=False), nn.ReLU(), # 返回原來的大小 nn.Conv2d(in_planes//16, in_planes, 1, bias=False) ) self.Sigmoid = nn.Sigmoid() def forward(self, x): avgout = self.shareMLP(self.avg_pool(x)) maxout = self.shareMLP(self.max_pool(x)) return self.Sigmoid(avgout + maxout)
可視化模塊結構:
---------------------------------------------------------------- Layer (type) Output Shape Param # ================================================================ AdaptiveAvgPool2d-1 [1, 256, 1, 1] 0 Conv2d-2 [1, 16, 1, 1] 4,096 ReLU-3 [1, 16, 1, 1] 0 Conv2d-4 [1, 256, 1, 1] 4,096 AdaptiveMaxPool2d-5 [1, 256, 1, 1] 0 Conv2d-6 [1, 16, 1, 1] 4,096 ReLU-7 [1, 16, 1, 1] 0 Conv2d-8 [1, 256, 1, 1] 4,096 Sigmoid-9 [1, 256, 1, 1] 0 ================================================================
-
空間注意力模塊(where)
爲了與通道注意力互補,空間注意力模塊主要關注“where”的部分。爲了計算首先,使用了全局最大池化和全局平均池化在保持H和W不變的情況下,針對通道進行池化,讓後,把兩個結果拼接後,送入一個標準的卷積層,最後,通過sigmoid函數,得到空間注意力模塊。
Pytorch代碼:
class SpatialAttention(nn.Module): def __init__(self, kernel_size = 7): super(SpatialAttention, self).__init__() assert kernel_size in (3, 7) padding = 3 if kernel_size == 7 else 1 self.conv = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False) self.sigmoid = nn.Sigmoid() def forward(self, x): # 平均池化(在通道上進行均值,且保持四個維度) avgout = t.mean(x, dim = 1, keepdim = True) # 最大池化(在通道上進行最大值,且保持四個維度) maxout, _ = t.max(x, dim = 1, keepdim = True) # 拼接 x = t.cat([avgout, maxout], dim=1) x = self.conv(x) return self.sigmoid(x)
可視化模塊結構:
---------------------------------------------------------------- Layer (type) Output Shape Param # ================================================================ Conv2d-1 [1, 1, 224, 224] 98 Sigmoid-2 [1, 1, 224, 224] 0 ===============================================================
實驗
作者在不同的網絡中加入了CBAM模塊,都證明其能有效的提升網絡的性能和準確率,下圖是作者在ResNet50加入SE模塊和CBAM模塊,進行Grad-CAM可視化的結果,其中p值代表所輸入圖像中的目標在最後的softmax中判別爲該類的可能性。由下圖,可以看出,加入CBAM模塊後,網絡注意力更加的全面,並且其判別準確率顯著的提升。
結論
CBAM是一個非常好的注意力模塊,融合空間和通道信息,使我們讓網絡關注輸入圖像的“what”和“where”兩個方面的信息,當然由於其通用性,其可以嵌入任何CNN網絡中,且效果明顯,所以個人認爲這是一篇不錯的paper。最後,本文在表述上難免有不準確的地方,建議感興趣的可以讀原文。
參考
【CV中的Attention機制】易於集成的Convolutional Block Attention Module(CBAM模塊)