目錄
前言
一、CBAM結(jié)構(gòu)
二、CBAM計算流程
三、CBAM參數(shù)
四、代碼詳解
前言
????????CE模塊通常只注意了通道特征,但在視覺任務(wù)中,空間任務(wù)通常更為重要,是不可忽略的,因此CBAM將通道注意力機(jī)制與空間注意力機(jī)制進(jìn)行串聯(lián),充分關(guān)注特征信息。
????????什么是空間特征?在深度學(xué)習(xí)中,空間特征是指描述輸入數(shù)據(jù)在空間維度上的特征信息。對于圖像數(shù)據(jù)而言,空間特征可以涵蓋多種信息,包括邊緣、角點(diǎn)、紋理、顏色等。這些特征信息可以幫助模型理解圖像中不同區(qū)域的內(nèi)容和結(jié)構(gòu),從而實(shí)現(xiàn)諸如目標(biāo)檢測、圖像分割、圖像分類等任務(wù)。在深度學(xué)習(xí)模型中,通常通過卷積神經(jīng)網(wǎng)絡(luò)(CNN)等結(jié)構(gòu)來提取和學(xué)習(xí)空間特征,這些特征對于模型的表現(xiàn)和性能具有重要的影響。
????????什么是空間注意力機(jī)制?空間注意力機(jī)制是一種注意力機(jī)制,用于在深度學(xué)習(xí)模型中對輸入數(shù)據(jù)的不同空間位置進(jìn)行加權(quán),以便模型能夠更加關(guān)注重要的空間位置,從而提高模型的性能和泛化能力??臻g注意力機(jī)制通常應(yīng)用在圖像處理或自然語言處理等任務(wù)中,能夠有效地捕捉輸入數(shù)據(jù)在空間維度上的相關(guān)性。
????????在空間注意力機(jī)制中,模型會學(xué)習(xí)到針對輸入數(shù)據(jù)中不同空間位置的權(quán)重,以確定哪些位置對于任務(wù)是最重要的。這些權(quán)重可以根據(jù)輸入數(shù)據(jù)的內(nèi)容和上下文來自適應(yīng)地調(diào)整,從而實(shí)現(xiàn)對不同空間位置的加權(quán)組合。通過引入空間注意力機(jī)制,模型可以更好地捕捉數(shù)據(jù)的局部特征和全局結(jié)構(gòu),從而提高模型的性能和泛化能力。
通道注意力機(jī)制 |
空間注意力機(jī)制 |
|
關(guān)注對象 |
關(guān)注于不同特征通道的重要性 |
關(guān)注于輸入數(shù)據(jù)中不同位置的重要性 |
操作對象 |
輸入數(shù)據(jù)的通道維度 |
輸入數(shù)據(jù)的空間維度 |
應(yīng)用范圍 |
處理具有多個特征通道的數(shù)據(jù) |
處理具有空間結(jié)構(gòu)的數(shù)據(jù) |
一、CBAM結(jié)構(gòu)
????????CBAM 是由Channel Attention Moduel和Spatial Attention Module構(gòu)成,結(jié)構(gòu)如圖1所示。Channel Attention Moduel,結(jié)構(gòu)如圖2所示。對輸入的特征圖分別同時進(jìn)行最大池化和平均池化,通過對輸入形狀為(B,C,H,W)的特征圖進(jìn)行最大池化或平均池化操作,將每個通道(C)在空間維度上的信息進(jìn)行壓縮,最終得到形狀為(B,C,1,1)的輸出,在這個過程中,對于每個通道而言,它的空間信息被最大池化或者平均池化操作壓縮為一個單獨(dú)的值,從而實(shí)現(xiàn)了對全局空間信息的壓縮和提取。這一步旨在將特征圖上的信息集中在通道上,從而更好的在通道上捕捉到輸入的特征圖的特征信息,利用這兩個特征可以大大提高網(wǎng)絡(luò)的表示能力。共享網(wǎng)絡(luò)由兩個卷積和一個Relu激活函數(shù)構(gòu)成,先降維再升維,這一步旨在減少參數(shù)開銷,其中MLP中的權(quán)重是共享的,所用的輸入都用相同的W0和W1權(quán)重矩陣進(jìn)行計算處理,將共享網(wǎng)絡(luò)應(yīng)用于每個特征描述子后,使用元素求和(+)來合并輸出特征向量,再將輸出的特征向量通過sigmoid函數(shù)生成權(quán)重向量,確保它們的總和為1。Spatial Attention Module,結(jié)構(gòu)如圖3所示。對輸入的特征圖沿通道軸應(yīng)用平均池化和最大池化,通過平均池化和最大池化操作,可以將輸入張量的通道維度(C)壓縮為1,從而將全局通道信息整合為一個單一的通道特征圖,形狀為(B,1,H,W)。在這個過程中,對于每個樣本(B),模型會對該樣本在通道上的特征進(jìn)行平均池化,從而實(shí)現(xiàn)對全局通道信息的壓縮合并。這種操作有助于減少參數(shù)數(shù)量、減小計算復(fù)雜度,同時保留重要的通道特征信息。將獲得的兩個矩陣在通道上拼接起來(torch.cat),并通過一個卷積層,將通道數(shù)再次變成1,使獲得的特征信息全部分布在一個通道上,再將通過卷積層的輸出通過sigmoid函數(shù)生成權(quán)重向量。CBAM則是將在Channel Attention Module得到的通道注意力權(quán)重乘以輸入的原始特征圖。這一步用于調(diào)整每個通道的特征值,強(qiáng)調(diào)重要通道的信息,抑制不重要通道的信息。再將之前在Spatial Attention Module得到的空間注意力權(quán)重乘以通過通道注意力機(jī)制得到的特征圖,最終即得到最終輸出結(jié)果。(通道和空間注意力機(jī)制可以并行或者順序放置,發(fā)現(xiàn)順序排列比平行排列產(chǎn)生更好結(jié)果,我們實(shí)驗(yàn)結(jié)果表明,通道優(yōu)先順序略優(yōu)于空間優(yōu)先順序)
圖1 CBAM結(jié)構(gòu)
圖2 通道注意力機(jī)制
????????
圖3 空間注意力機(jī)制
精讀:CBAM(Convolutional Block Attention Module)是一個集成在卷積神經(jīng)網(wǎng)絡(luò)中的注意力模塊,目的是增強(qiáng)模型的特征表達(dá)能力,通過強(qiáng)調(diào)重要的特征并抑制不重要的特征。CBAM 通過兩個主要部分工作:Channel Attention Module 和 Spatial Attention Module。下面詳細(xì)解釋這兩部分的工作原理及其互動方式。
Channel Attention Module (CAM)的核心目的是強(qiáng)調(diào)那些對當(dāng)前任務(wù)更重要的特征通道。它通過以下步驟實(shí)現(xiàn):
1.特征壓縮:對輸入的特征圖X,形狀為(B,C,H,W),進(jìn)行最大池化和平均池化。這兩種池化操作都在空間維度H×W 上進(jìn)行,輸出的結(jié)果是兩個形狀為(B,C,1,1)的特征圖,即每個通道壓縮成一個單獨(dú)的值,分別代表了該通道的最大值和平均值。通過以下步驟實(shí)現(xiàn):
2.維度轉(zhuǎn)換:通過一個小型神經(jīng)網(wǎng)絡(luò)(通常是兩層MLP),首先將通道數(shù)降維以減少參數(shù)量,然后再升維恢復(fù)到原始通道數(shù)。這個小網(wǎng)絡(luò)包括兩個全連接層和一個ReLU激活函數(shù)。
3.特征融合與激活:將最大池化和平均池化得到的兩個特征圖通過共享的MLP處理后,結(jié)果相加并通過sigmoid函數(shù),得到每個通道的權(quán)重系數(shù)。
Spatial Attention Module (SAM) 的目的是在空間上強(qiáng)調(diào)更為關(guān)鍵的區(qū)域。它的步驟包括:
1.通道壓縮:將處理后的特征圖X 進(jìn)行最大池化和平均池化,但這次是沿著通道軸 C,從而壓縮所有通道信息到一個單通道圖像中。操作結(jié)果是兩個形狀為(B,1,H,W)的特征圖。
2. 特征拼接與卷積:將上述兩個特征圖在通道維度上拼接,然后通過一個卷積層將通道數(shù)變?yōu)?,最終通過sigmoid函數(shù)得到每個空間位置的權(quán)重系數(shù)。
整合與順序
1.特征圖權(quán)重調(diào)整:首先,通過Channel Attention Module得到的通道權(quán)重乘以原始的特征圖X,調(diào)整每個通道的重要性。然后,將這個調(diào)整后的特征圖輸入到Spatial Attention Module,進(jìn)一步調(diào)整每個位置的重要性。
2. 順序優(yōu)化:實(shí)驗(yàn)顯示,首先應(yīng)用Channel Attention(通道注意力)后再應(yīng)用Spatial Attention(空間注意力)通常效果更好。這是因?yàn)椋坏┪覀兇_定了最重要的特征通道,再去調(diào)整這些通道中各個位置的重要性,能夠更精確地強(qiáng)化有用的信息,抑制不必要的信息。
二、CBAM計算流程
?如圖 1所示,給定一個輸入,
為CBAM通過 Channel Attention Moduel獲得,在Channel Attention Moduel中,先通過全局平均池化和全局最大池化分別獲得
和
,其中
為Sigmoid函數(shù),MLP結(jié)構(gòu)為Conv-ReLU-Conv,
,
,
,
為MLP的權(quán)重。
? ? ? ? ? ? ?? ? ? ? ? ? ? ?
為CBAM通過Spatial Attention Module獲得,在Spatial Attention Module中,先通過全局平均池化和全局最大池化分別獲得
和
,其中
為Sigmoid函數(shù),
表示濾波器為7*7的卷積運(yùn)算。
將F通過Channel Attention Moduel得到的通道注意力權(quán)重乘以輸入的原始特征圖F,以獲得
,再將
通過Spatial Attention Module得到的空間注意力權(quán)重
乘以通過通道注意力機(jī)制得到的特征圖
,其中
為元素乘法,
為最終輸出
三、CBAM參數(shù)
利用thop庫的profile函數(shù)計算FLOPs和Param。Input:(512,7,7)。
Module |
FLOPs |
Param |
CBAM |
95938.0 |
32866.0文章來源:http://www.zghlxwxcb.cn/news/detail-861118.html |
四、代碼詳解
?文章來源地址http://www.zghlxwxcb.cn/news/detail-861118.html
import torch
from torch import nn
from torch.nn import init
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.mlp=nn.Sequential(
nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False),
nn.ReLU(),
nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)
)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
avg_out = self.mlp(self.avg_pool(x)) # 通過平均池化壓縮全局空間信息: (B,C,H,W)--> (B,C,1,1) ,然后通過MLP降維升維:(B,C,1,1)
max_out = self.mlp(self.max_pool(x)) # 通過最大池化壓縮全局空間信息: (B,C,H,W)--> (B,C,1,1) ,然后通過MLP降維升維:(B,C,1,1)
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) # 通過平均池化壓縮全局通道信息:(B,C,H,W)-->(B,1,H,W)
max_out, _ = torch.max(x, dim=1, keepdim=True) # 通過最大池化壓縮全局通道信息:(B,C,H,W)-->(B,1,H,W)
x = torch.cat([avg_out, max_out], dim=1) # 在通道上拼接兩個矩陣:(B,2,H,W)
x = self.conv1(x) # 通過卷積層得到注意力權(quán)重:(B,2,H,W)-->(B,1,H,W)
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 init_weights(self):
for m in self.modules():
if isinstance(m, nn.Conv2d):
init.kaiming_normal_(m.weight, mode='fan_out')
if m.bias is not None:
init.constant_(m.bias, 0)
elif isinstance(m, nn.BatchNorm2d):
init.constant_(m.weight, 1)
init.constant_(m.bias, 0)
elif isinstance(m, nn.Linear):
init.normal_(m.weight, std=0.001)
if m.bias is not None:
init.constant_(m.bias, 0)
def forward(self, x):
out = x * self.ca(x) # 通過通道注意力機(jī)制得到的特征圖,x:(B,C,H,W),ca(x):(B,C,1,1),out:(B,C,H,W)
result = out * self.sa(out) # 通過空間注意力機(jī)制得到的特征圖,out:(B,C,H,W),sa(out):(B,1,H,W),result:(B,C,H,W)
return result
if __name__ == '__main__':
from torchsummary import summary
from thop import profile
model = CBAM(in_planes=512)
# summary(model, (512, 7, 7), device='cpu', batch_size=1)
flops, params = profile(model, inputs=(torch.randn(1, 512, 7, 7),))
print(f"FLOPs: {flops}, Params: {params}")
到了這里,關(guān)于即插即用的漲點(diǎn)模塊之注意力機(jī)制(CBAMAttention)詳解及代碼,可應(yīng)用于檢測、分割、分類等各種算法領(lǐng)域的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!