原始文檔 https://www.yuque.com/lart/papers/onk4snpython
在本文中,咱們經過 基於自我約束機制捕獲豐富的上下文依賴關係來解決場景分割任務。
與以前經過多尺度特徵融合捕獲上下文的工做不一樣,咱們提出了一種雙重注意網絡(DANet)來自適應地集成局部特徵及其全局依賴性。
具體來講,咱們在傳統的擴張FCN之上附加兩種類型的注意力模塊,它們分別對空間和通道維度中的語義相互依賴性進行建模。git
咱們將兩個注意模塊的輸出相加以進一步改進特徵表示,這有助於更精確的分割結果。github
場景分割是一個基本且具備挑戰性的問題,其目標是將場景圖像分割和解析到與語義類別相關聯的不一樣圖像區域,包括填充物(例如天空,道路,草地)和離散物體(例如人,汽車,自行車)。 該任務的研究可應用於潛在的應用,例如自動駕駛,機器人傳感和圖像編輯。 爲了有效地完成場景分割任務,咱們須要區分一些使人困惑的類別,並將不一樣外觀的對象分解。 例如,「田地」和「草地」的區域一般是難以區分的,而且一般難以區分的「汽車」可能具備不一樣的尺度,遮擋和照明。 所以,有必要提升像素級識別特徵表示的辨別能力。網絡
最近,已經提出了基於徹底卷積網絡(FCN)的最早進方法來解決上述問題。app
雖然上下文融合有助於捕獲不一樣比例的對象,但它沒法利用全局視圖中對象或東西之間的關係,這對於場景分割也是必不可少的。框架
另外一種類型的方法使用遞歸神經網絡來利用長程依賴性,從而提升分割精度。提出了基於2DLSTM網絡的方法來捕獲標籤上覆雜的空間依賴性。工做[DAGRNN]使用有向無環圖構建一個遞歸神經網絡,以捕獲局部特徵上豐富的上下文依賴性。然而,這些方法使用遞歸神經網絡隱含地捕捉全局關係,其有效性在很大程度上依賴於長期記憶的學習結果。dom
爲了解決上述問題,在本文中,咱們提出了一種新的框架,稱爲雙注意網絡(DANet),用於天然場景圖像分割,如圖所示。它引入了一種自注意力機制來分別捕捉空間和通道尺寸中的視覺特徵依賴性。學習
具體來講,咱們在傳統的_擴張FCN_之上添加了兩個並行的注意模塊。一個是位置注意力模塊(position attention module),另外一個是通道注意模塊(channel attention module)。測試
最後,這兩個注意模塊的輸出被融合以進一步加強特徵表示。編碼
值得注意的是,在處理複雜多樣的場景時,咱們的方法比之前的方法[Rethinking atrous convolution for semantic image segmentation, PSPNet]更有效,更靈活。走圖中的街景。以圖1爲例。
咱們的主要貢獻可概括以下:
除了第一步以外,捕獲通道關係的過程相似於位置注意力模塊,其中在通道維度中計算通道注意力矩陣。最後,咱們彙總了兩個注意模塊的輸出特徵,以得到更好的像素級預測特徵表示。
對於場景理解, 判別特徵表示是必不可少的,能夠經過捕獲遠程上下文信息來得到。然而,許多做品代表傳統FCN產生的局部特徵表示可能致使objects和stuff的錯誤分類。
爲了在局部特徵表示之上建模豐富的上下文關係,咱們引入了一個位置注意力模塊。位置注意力模塊將更普遍的上下文信息編碼到局部特徵中,從而加強其表示能力。
如圖:
這樣一來, 每一個算出來的特徵E的每一個位置都是來自全部位置的特徵和原始特徵的加權和. 所以能夠得到一個全局的上下文信息, 而且能夠根據空間注意力圖來有選擇的集成上下文信息. 類似的特徵會互相得到增益, 所以能夠提高類間對比度和語義一致性.
利用矩陣乘法來實現對於全局上下文信息的利用與融合, 實際上和全鏈接是同樣的. 全鏈接確實能夠更爲全面的利用全部位置的信息, 可是會破壞空間結構, 這也是相互矛盾的, 因此, 不能徹底的利用全鏈接. 還得想辦法保留更多的空間結構信息. 這裏使用這個全鏈接的結果用在原始數據信息上, 互相利用, 互相促進.
高級特徵的每一個通道映射能夠被從新看做特定於類的響應,而且不一樣的語義響應彼此相關聯。經過利用通道映射之間的相互依賴關係,咱們能夠強調相互依賴的特徵映射,並改進特定語義的特徵表示。所以,咱們創建了一個通道注意力模塊, 以顯式的建模通道之間的相互依賴性。
結構以下:
公式4顯示 每一個通道的最終特徵是全部通道和原始特徵的特徵的加權數據,其建模特徵映射之間的遠程語義依賴性。它 強調依賴於類的特徵映射並有助於提升特徵可辨性。
咱們在計算兩個通道的關係以前,咱們不使用卷積層來嵌入特徵,由於能夠維持不一樣通道映射之間的關係。此外,與最近經過全局池化或者編碼層探索通道關係的工做[26]不一樣,咱們利用全部相應位置的空間信息來建通道相關性。
爲了充分利用遠程上下文信息的優點, 咱們集成來自兩個注意力模塊的特徵. 特別地, 咱們經過一個卷積層和元素級加法來聚合兩個注意力模塊的輸出, 以實現特徵融合.
在最後緊跟着一個用來生成最終預測圖的卷積層. 咱們不採用級聯操做, 由於它須要更多的 GPU 內存.
注意到咱們的注意力模塊很簡單, 能夠直接插入現有的 FCN流程中。 它們不會增長太多的參數, 卻又能有效地加強特徵表示。
# https://github.com/junfu1115/DANet/blob/master/encoding/nn/attention.py ########################################################################### # Created by: CASIA IVA # Email: jliu@nlpr.ia.ac.cn # Copyright (c) 2018 ########################################################################### import numpy as np import torch import math from torch.nn import (Module, Sequential, Conv2d, ReLU, AdaptiveMaxPool2d, AdaptiveAvgPool2d, NLLLoss, BCELoss, CrossEntropyLoss, AvgPool2d, MaxPool2d, Parameter, Linear, Sigmoid, Softmax, Dropout, Embedding) from torch.nn import functional as F from torch.autograd import Variable class PAM_Module(Module): """ Position attention module""" # Ref from SAGAN def __init__(self, in_dim): super(PAM_Module, self).__init__() self.query_conv = Conv2d(in_channels=in_dim, out_channels=in_dim // 8, kernel_size=1) self.key_conv = Conv2d(in_channels=in_dim, out_channels=in_dim // 8, kernel_size=1) self.value_conv = Conv2d(in_channels=in_dim, out_channels=in_dim, kernel_size=1) self.gamma = Parameter(torch.zeros(1)) self.softmax = Softmax(dim=-1) def forward(self, x): """ inputs : x : input feature maps( N X C X H X W) returns : out : attention value + input feature attention: N X (HxW) X (HxW) """ m_batchsize, C, height, width = x.size() # B => N, C, HW proj_query = self.query_conv(x).view(m_batchsize, -1, width * height) # B' => N, HW, C proj_query = proj_query.permute(0, 2, 1) # C => N, C, HW proj_key = self.key_conv(x).view(m_batchsize, -1, width * height) # B'xC => N, HW, HW energy = torch.bmm(proj_query, proj_key) # S = softmax(B'xC) => N, HW, HW attention = self.softmax(energy) # D => N, C, HW proj_value = self.value_conv(x).view(m_batchsize, -1, width * height) # DxS' => N, C, HW out = torch.bmm(proj_value, attention.permute(0, 2, 1)) # N, C, H, W out = out.view(m_batchsize, C, height, width) out = self.gamma * out + x return out class CAM_Module(Module): """ Channel attention module""" def __init__(self): super(CAM_Module, self).__init__() self.gamma = Parameter(torch.zeros(1)) self.softmax = Softmax(dim=-1) def forward(self, x): """ inputs : x : input feature maps( N X C X H X W) returns : out : attention value + input feature attention: N X C X C """ m_batchsize, C, height, width = x.size() proj_query = x.view(m_batchsize, C, -1) proj_key = x.view(m_batchsize, C, -1).permute(0, 2, 1) # N, C, C, bmm 批次矩陣乘法 energy = torch.bmm(proj_query, proj_key) # 這裏實現了softmax用最後一維的最大值減去了原始數據, 得到了一個不是太大的值 # 沿着最後一維的C選擇最大值, keepdim保證輸出和輸入形狀一致, 除了指定的dim維度大小爲1 energy_new = torch.max(energy, -1, keepdim=True) energy_new = energy_new[0].expand_as(energy) # 複製的形式擴展到energy的尺寸 energy_new = energy_new - energy attention = self.softmax(energy_new) proj_value = x.view(m_batchsize, C, -1) out = torch.bmm(attention, proj_value) out = out.view(m_batchsize, C, height, width) out = self.gamma * out + x return out if __name__ == '__main__': module = CAM_Module() in_data = torch.randint(0, 255, (2, 3, 7, 7), dtype=torch.float32) print(module(in_data).size())
位置注意力模塊的效果在圖4中可視化, 一些細節和對象邊界在使用位置注意力模塊時更加清晰, 例如第一行中的 "杆子" 和第三行的 "人行道"。對局部特徵的選擇性融合加強了對細節的區分。
同時, 圖5證實, 利用咱們的信道注意模塊, 一些錯誤分類的類別如今被正確地分類, 如第一行和第三行中的 "公交車"。 通道映射之間的選擇性集成有助於捕獲上下文信息。 語義一致性獲得了明顯的改善。
Following [Rethinking atrous convolution for semantic image segmentation], we adopt the same strategies to improve peformance further.