一文深入浅出cv中的Attention机制
在深度學習領域中,存在很多專業名詞,第一次看的時候總會很懵逼~后面慢慢看得時候才會有那么感覺,但是總覺得差點意思。今天我們要說的一個專業名詞,就叫做Attention機制!
1. 直觀理解Attention
想象一個場景,你在開車(真開車!握方向盤的那種!非彼開車!),這時候下雨了,如下圖。
那你想要看清楚馬路,你需要怎么辦呢?dei !很聰明,打開雨刮器就好!
那我們可以把這個雨刮器刮雨的動作,就是尋找Attention區域的過程!嗯!掌聲鼓勵下自己,你已經理解了Attention機制!
2. 再看Attention機制
首先,我們引入一個概念叫做Key-Value,鍵值對。如在中的類型的數據就是鍵值對存儲的,相當于一對一的概念 (如,我們婚姻法,合法夫妻就是一對一)。
dict?=?{'name'?:?'canshi'}???#name為canshi回憶一下,在中學時期,我們學的眼睛成像!一張圖在眼睛中是一個倒立的縮放圖片,然后大腦把它正過來了。我們開始進行建模,假設這個自然界存在的東西就是Key,同時也叫Value。
套下公式,當下雨的時候,冷冷的冰雨在車窗上狠狠的拍!我們把這個整個正在被拍的車窗叫做Key,同時也叫Value。但是我們看不清路呀,我們這時候就想讓我們可以分得清路面上的主要信息就好,也不需要邊邊角角的信息。那么這個時候,雨刮器出場了,我們把它叫做Query! 我們就能得到一個看清主要路面的圖片了!
那么到底發生了什么了呢?我來拆開下哈:
所以,我們通過雨刮器()來作用于車窗圖(), 得到了一個部分干凈的圖像(類,里面的值是0~1),圖片中白色區域表示擦干凈了,其它部分表示不用管。再用這個生成的 與?圖做乘積,得到部分干凈的生成圖像,顯示在我們的大腦中。
因此,我們會看到一些說的博客會有下面的圖:
這張圖主要是針對于機器翻譯中用的,在翻譯的時候,每一個輸出需要于輸入的各個元素計算相似度,再與 進行加權求和~
對于領域中,我們一般都是用矩陣運算了,不像中的任務,需要按照時刻進行,中的任務,就是一個矩陣運算,一把梭就完事兒了。
比如這個雨刮器刮水的過程。我們把原先帶是雨水的車窗記作,雨刮器來刮雨就是,我們使用相似度來代替刮水的過程,得到一個。再用與原圖像通過計算,得到最后的圖像。
因此,用公式來概括性地描述就是:
劃重點,不同的車有不同的雨刷來進行刮雨,同樣,我們有不同的方法來衡量相似度,這里我們主要有以下幾種方案來衡量相似度:
當有了相似度之后,我們需要對其進行歸一化,將原始計算分值整理成所有元素權重之和為1的概率分布,越重要的部分,越大!越不重要的部分,越小。我們采用為主,當然也有一些使用這樣來進行運算,都是ok的~
因此,這個權重的值可以這么計算:
其中表明將數據進行下縮放,防止過大了。
最后就是得到的輸出了:
因此,像戴眼鏡,也是一種,。對于眼睛里的區域進行進行聚焦,而除此之外的區域,就無所謂了。不需要進行額外處理了。
3. 大腦中的Attention機制
人在成長過程中,可能每一個階段都會對大腦進行訓練,讓我們在大自然界中快速得到我們想要的信息。當前大數據時代,那么多圖片視頻,我們需要快速瀏覽得到信息,比如下面的圖:
網上的圖,侵刪!我可能一開始就會注意到這個大衣是很好的款式,這個紅色的小包也不錯,當然每個人用來訓練的數據集是不一樣的,我也不知道你們第一眼看到的是啥!畢竟這個注意力矩陣,需要海量的數據來進行測試。
哦?還跟我拗?那你也來試試下面的挑戰?
原視頻來自 B站,非P站!
3. CV中常用的Attention
1. Non-local Attention
通過上面的例子,我們就明白了,原來本質就是在一個維度上進行計算權重矩陣。這個維度如果是空間,那么就是Spatial Attention, 如果是通道這個維度,那么就是Channel Attention。所以,如果以后你投稿的時候,再說你不夠,我們就可以搭積木搭出來一個模塊呀!
這里我們使用 來講解下,常用在領域中的Attention。
輸入特征,通過卷積來得到,這里的三個矩陣是不同的,因此上文中是假設 相同。
其中代碼如下:
class?Self_Attn(nn.Module):"""?Self?attention?Layer"""def?__init__(self,in_dim,activation):super(Self_Attn,self).__init__()self.chanel_in?=?in_dimself.activation?=?activationself.query_conv?=?nn.Conv2d(in_channels?=?in_dim?,?out_channels?=?in_dim//8?,?kernel_size=?1)self.key_conv?=?nn.Conv2d(in_channels?=?in_dim?,?out_channels?=?in_dim//8?,?kernel_size=?1)self.value_conv?=?nn.Conv2d(in_channels?=?in_dim?,?out_channels?=?in_dim?,?kernel_size=?1)self.gamma?=?nn.Parameter(torch.zeros(1))self.softmax??=?nn.Softmax(dim=-1)?#def?forward(self,x):"""inputs?:x?:?input?feature?maps(?B?X?C?X?W?X?H)returns?:out?:?self?attention?value?+?input?feature?attention:?B?X?N?X?N?(N?is?Width*Height)"""m_batchsize,C,width?,height?=?x.size()proj_query??=?self.query_conv(x).view(m_batchsize,-1,width*height).permute(0,2,1)?#?B?X?CX(N)proj_key?=??self.key_conv(x).view(m_batchsize,-1,width*height)?#?B?X?C?x?(*W*H)energy?=??torch.bmm(proj_query,proj_key)?#?transpose?checkattention?=?self.softmax(energy)?#?BX?(N)?X?(N)?proj_value?=?self.value_conv(x).view(m_batchsize,-1,width*height)?#?B?X?C?X?Nout?=?torch.bmm(proj_value,attention.permute(0,2,1)?)out?=?out.view(m_batchsize,C,width,height)out?=?self.gamma*out?+?xreturn?out,attention代碼看上去還是比較容易懂得,主要就是函數,它可以將緯度為矩陣與的矩陣相乘的到的矩陣。再使用來得到歸一化之后的矩陣,結合殘差,得到最后的輸出!
2. CBAM
由 與 組合而成。
其中的 模塊,主要是從C x H x w 的緯度,學習到一個C x 1 x 1的權重矩陣。
論文中的圖如下:
代碼示例如下:
class?ChannelAttentionModule(nn.Module):def?__init__(self,?channel,?reduction=16):super(ChannelAttentionModule,?self).__init__()mid_channel?=?channel?//?reductionself.avg_pool?=?nn.AdaptiveAvgPool2d(1)self.max_pool?=?nn.AdaptiveMaxPool2d(1)self.shared_MLP?=?nn.Sequential(nn.Linear(in_features=channel,?out_features=mid_channel),nn.ReLU(inplace=True),nn.Linear(in_features=mid_channel,?out_features=channel))self.sigmoid?=?nn.Sigmoid()def?forward(self,?x):avgout?=?self.shared_MLP(self.avg_pool(x).view(x.size(0),-1)).unsqueeze(2).unsqueeze(3)maxout?=?self.shared_MLP(self.max_pool(x).view(x.size(0),-1)).unsqueeze(2).unsqueeze(3)return?self.sigmoid(avgout?+?maxout)當然,我們可以使用的形式來對它進行修改成一個統一架構,只要我們可以學習到一個在通道緯度上的分布矩陣就好。
如下方偽代碼, 均為卷積生成。
#?key:?(N,?C,?H,?W) #?query:?(N,?C,?H,?W) #?value:?(N,?C,?H,?W) key?=?key_conv(x) query?=?query_conv(x) value?=?value_conv(x)mask?=?nn.softmax(torch.bmm(key.view(N,?C,?H*W),?query.view(N,?C,?H*W).permute(0,2,1))) out?=?(mask?*?value.view(N,?C,?H*W)).view(N,?C,?H,?W)對于 ,如圖所示:
參考代碼如下:
class?SpatialAttentionModule(nn.Module):def?__init__(self):super(SpatialAttentionModule,?self).__init__()self.conv2d?=?nn.Conv2d(in_channels=2,?out_channels=1,?kernel_size=7,?stride=1,?padding=3)self.sigmoid?=?nn.Sigmoid()def?forward(self,?x):avgout?=?torch.mean(x,?dim=1,?keepdim=True)maxout,?_?=?torch.max(x,?dim=1,?keepdim=True)out?=?torch.cat([avgout,?maxout],?dim=1)out?=?self.sigmoid(self.conv2d(out))return?out采用的框架來進行改寫:
key?=?key_conv(x) query?=?query_conv(x) value?=?value_conv(x)b,?c,?h,?w?=?t.size() query?=?query.view(b,?c,?-1).permute(0,?2,?1) key?=?key.view(b,?c,?-1) value?=?value.view(b,?c,?-1).permute(0,?2,?1)att?=?torch.bmm(query,?key)if?self.use_scale:att?=?att.div(c**0.5)att?=?self.softmax(att) x?=?torch.bmm(att,?value)x?=?x.permute(0,?2,?1) x?=?x.contiguous() x?=?x.view(b,?c,?h,?w)3. cgnl
論文分析了下如 與 均不能很好的描述特征之間的關系,這里比較極端得生成了N * 1 * 1 * 1的.
主要關于計算的部分代碼:
def?kernel(self,?t,?p,?g,?b,?c,?h,?w):"""The?linear?kernel?(dot?production).Args:t:?output?of?conv?theatap:?output?of?conv?phig:?output?of?conv?gb:?batch?sizec:?channels?numberh:?height?of?featuremapsw:?width?of?featuremaps"""t?=?t.view(b,?1,?c?*?h?*?w)p?=?p.view(b,?1,?c?*?h?*?w)g?=?g.view(b,?c?*?h?*?w,?1)att?=?torch.bmm(p,?g)if?self.use_scale:att?=?att.div((c*h*w)**0.5)x?=?torch.bmm(att,?t)x?=?x.view(b,?c,?h,?w)return?x4. Cross-layer non-local
論文中分析了,同樣的層之間進行計算,感受野重復,會造成冗余,引入背景噪聲,如左邊的部分圖。而右邊的圖表示不同層間的感受野不同,計算全局會關注到更合理的區域。
這里采用跨層之間的生成。
代碼部分比較有意思:
#?query?:?N,?C1,?H1,?W1 #?key:?N,?C2,?H2,?W2 #?value:?N,?C2,?H2,?W2 #?首先,需要使用1?x?1?卷積,使得通道數相同 q?=?query_conv(query)?#?N,?C,?H1,?W1 k?=?key_conv(key)?#?N,?C,?H2,?W2 v?=?value_conv(value)?#?N,?C,?H2,?W2 att?=?nn.softmax(torch.bmm(q.view(N,?C,?H1*W1).permute(0,?1,?2),?k.view(N,?C,?H2?*?W2)))?#?(N,?H1*W1,?H2*W2) out?=?att?*?value.view(N,?C2,?H2*W2).permute(0,?1,?2)?#(N,?H1?*?W1,?C) out?=?out.view(N,?C1,?H1,?W1)4. 小結
是一個比較適合用來寫文章的知識點,算是一個的點。目前針對中的差不多可以概括為這些,后面會繼續補充,歡迎各位關注!
- END - 往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯溫州大學《機器學習課程》視頻 本站qq群851320808,加入微信群請掃碼:總結
以上是生活随笔為你收集整理的一文深入浅出cv中的Attention机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【NLP】N-LTP:基于预训练模型的中
- 下一篇: 温州大学《机器学习》课程课件(七、决策树