論文:
-
(DeepLabV1)Semantic image segmentation with deep convolutional nets and fully connected CRFs
-
(DeepLabV3)Rethinking Atrous Convolution for SemanticImage Segmentation
-
(DeepLabV3+)Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation
0.簡介
DeepLab為一系列的工作,從14年到現在跨度也比較久,我會把每篇工作的關鍵點都梳理一下,這四篇工作本身也是一代代改進來的,所以會有一些一直延用並改進的東西,也會有DeepLab放棄了的東西,前者我們深入學習,後者簡單瞭解。
1.DeepLab V1
這裡只簡單說下V1做了什麼,詳細的講解我想放到V2裡開始講,因為那時候的研究已經有更深的認識。這裡就當作個前情提要吧。
2014年,正是DCNN在影像領域爆發後的那段時間,影像分類、目標檢測等領域基於DCNN取得空前進展,語義分割領域當然也會一頭扎進去。但對於語義分割這一需要準確位置資訊的畫素級任務,使用DCNN還需要解決如下問題:
- 重複池化下采樣導致解析度大幅下降,位置資訊難以恢復。
- DCNN的空間不變性,位置資訊丟失會使最後的分割結果粗糙,丟失細節。
所以本文也出一下兩點來解決:
-
空洞卷積。基於VGG-16改造:
- 因為是做分割,所以把全連線層改成卷積層。
- 把最後兩個池化層去掉,後續使用空洞卷積。
-
Fully Connected CRFs(條件隨機場)。
改善DCNN的輸出結果,更好捕捉邊緣細節。
2. DeepLab V2
到了DeepLabV2的時候,多尺度問題已經被研究著們廣泛且深刻的認識到,所以在V2的原文中,把DCNN應用到語義分割需要解決的問題又多了一個多尺度方面的,由原來v1中的兩大問題變成此時的三個:
- 重複池化下采樣導致解析度大幅下降,位置資訊難以恢復。
- 不同尺度物體的存在。
- DCNN的空間不變性,位置資訊丟失會使最後的分割結果粗糙,丟失細節
然後原文給出了對應的三個解決方法:
- 空洞卷積
- ASSP(Atrous Spatial Pyramid Pooling)
- Fully Connected CRF
整體結構
影像輸入,進入到改造過的DCNN(VGG-16或ResNet-101,空洞卷積、ASSP都是在這裡),得到解析度略小的特徵圖,然後進行雙線性插值恢復解析度,使用全連線CRFl來改善分割結果(去噪、平滑、更好的捕捉邊界)。
空洞卷積
DCNN隨著進行,會使feature map變小,得到更high-level的特徵。主要是因為:
- conv的stride>1 —— 為了得到更大感受野
- max pooling操作 —— 為了得到更high-level的特徵
得到這樣high-level的特徵有利於影像分類、目標檢測等任務,但DCNN這樣的特點不能直接用於語義分割這樣的要求高精密的畫素級任務。
對於這一問題,作者強調(卷積+上取樣濾波器)or(空洞卷積)是有力的解決工具,實際使用空洞卷積來解決,空洞卷積由兩個優勢:一是可以控制影像的解析度不至於太小,解決上述問題;二是增加感受野。
首先要明白,通過控制引數,在緊密特徵圖上的空洞卷積可以產生和在係數特徵圖上標準卷積一模一樣的結果;也可以產生更緊密的特徵,即高解析度的特徵圖,如下圖所示:
再結合第三節DeepLabV3串聯結構中講的,應該就完全理解了。
ASSP
影像中存在多種尺度的物體,這是影響視覺檢測、分割等任務精度的一大問題,如果網路抽象能力較強則更容易識別大尺度的物體但會忽略小尺度的物體,如果抽象能力較弱則可以較好識別小物體但抽象大物體的能力勢必較弱,就是這樣一種矛盾,研究者們提出各種方法來解決,本文基於空洞卷積設計了ASSP結構(Atrous Spatial Pyramid Pooling)。
即得到一feature map後,接入一個並行結構,並行結構中的每個分支結構都一樣,唯一不一樣的就是各自卷積的膨脹率。如下圖所示。不同膨脹率的卷積可以得到不同的感受野,膨脹率小的卷積感受野小,對小尺度的物體識別效果較好;膨脹率大的卷積感受野大,對大尺度的物體識別效果好。空洞卷積對於感受野、並行空洞卷積解決多尺度問題,推薦閱讀目標檢測領域的一項工作,原理解釋、實驗非常充實——TridentNet。Scale-Aware Trident Networks for Object Detection
Fully Connected CRF
(這一方法在之後的版本就放棄了,我對此暫時也沒有多大興趣,僅限於跟著論文學習了一遍,這裡就簡單介紹吧,數學及原理就不再梳理了)
條件隨機場(CRF,Conditional Random Field)一般用來處理分割不平滑問題,它只考慮到目標畫素點的附近點,是一個短距離的CRFs。由於網路中得到的結果已經比較光滑了,更希望的是修復一些小的結構,處理邊緣細節,所以用到了全連線CRF模型。能量函式中有一部分高斯核函式,其值由兩點間的位置和顏色決定,位置為主,顏色為輔,算是一句話說一下淺顯的說明一下原理吧。
3.DeepLab V3
串聯結構
基於ResNet。使用標準卷積時,當網路越來越深,output stride越大,feature map越小。每一個block中有三個3×3的卷積,最後一個卷積的stride=2,feature map就是因為這個變小的(除最後一個block的最後一個卷積,它的stride=1)。
低解析度的feature map難以恢復位置資訊得到好的分割結果。解析度變低是因為stride=2,令stride=2的原因是,希望隨著網路的深入,感受野越來越大,越有利於獲得high-level的資訊。
那有沒有什麼辦法既能獲得較大感受野,又能有高解析度(output stride低)的特徵圖呢?就是DeepLab在使用的空洞卷積了!有了第二節DeepLabV2中的空洞卷積介紹基礎,看到這裡應該完全理解了。
作者設計的這一使用空洞卷積的串聯結構,把block4重複了四遍,即block5, block6, block7都是block4的複製品,唯一不同的是其中的膨脹率(rate / dilation),取決於想要的output stride。
作者還考慮了multi-grid方法,即每個block中的三個卷積有各自unit rate,例如Multi Grid = (1, 2, 4),block的dilate rate=2,則block中每個卷積的實際膨脹率=2* (1, 2, 4)=(2,4,8)。
並聯結構
如上圖所示,block4之後連線並聯結構,其中上面四個為ASSP,下面一個為image-level feature,他們的輸入都為前面的feature map,最後這五個結果拼接成一組特徵,看原始碼torch.cat就很好理解了。
ASSP改進
相校對DeepLabV2的ASSP,唯一的區別就是加了BN層...
當想讓output stride=16時,ASSP包括了一個1×1卷積,和rate=(6,12 ,18)的3×3卷積,都是256通道。
image-level feature
用ASSP並列加入image-level feature是因為作者為了解決空洞卷積帶來的一個問題:
隨著空洞卷積的膨脹率(rate/dilation)增大,卷積核有效引數越來越少。是的,這個很容易理解,3×3、rate=1即標準卷積,只有在feature map最外面一圈會有卷積核引數超出邊界而無效,當rate變大,越來越多外圈的位置是有卷積核引數失效的,用極限思想思考一下,如果rate=size(feature map),那麼每次卷積都是卷核中心對應的feature map畫素點被計算了,卷積核引數也只有中心那個點沒有失效,退化成了1×1卷積核。
作者正式為了解決這一問題,才在並聯結構中加入image-level feature。做法是對輸入的feature map全域性平均池化(global average pooling),256通道的1×1卷積層,BN層,最後使用者雙線性插值的方法上取樣到目標大小,即與ASSP輸出的feature map尺寸相同。
4.DeepLab V3+
加入decoder
作者把DeepLavV3作為Encoder部分,加入decoder部分,稱形成了一種融合了SSP和Encoder-Decoder的新方法。
把整個網路DeepLabV3作為Encoder,提取融合多尺度特徵;加入一個簡單的結構作為Decoder,能夠改善分割結構的物體邊界。
圖中的decoder的輸入,即low-level features,並不是和ASSP的輸入一樣,而是backbone的某個中間計算結果,然後通過一個1×1卷積(為了減少通道數),結果與encoder輸出(1×1卷積減少通道數,也上取樣了到原來4倍)融合,再經過3×3卷積,再上取樣4倍(至此16倍,已經恢復到原圖大小)。
深度可分離卷積(depthwise separable convolution)
本作中使用了depthwise separable convolution代替標準卷積,Depthwise separable convolution由depthwise convolution和pointwise convoution兩步完成。因為它能通過將標準卷積運算分為兩步從而減少引數,但實現和標準卷積操作相同的效果。即depthwise separable convolution = depthwise convolution + pointwise convolution(既指流程,也值引數量)。詳細內容和具體引數量計算請見下面的個人獨立部落格,因為我也是學習來的,而且博主寫的很清晰明瞭,所以就不板門弄斧了:https://yinguobing.com/separable-convolution/
當然作者雖然使用了depthwise separable convolution方法來代替標準卷積操作,但依然是還是空洞卷積,看完上面那篇部落格(或者本身就掌握深度可分離卷積),應該很容易就明白這句話。Atrous separable convolution只需要更改第一步為間隔取樣,第二部pointwise convolution無需特別處理。
DeepLab系列,尤其是後面兩作,他們的貢獻除了提出新演算法模型以外,還包括進行了大量的實驗,包括模型中選擇某些小結構、引數的對比實驗,對於後面的研究者提供了寶貴的經驗,節省了大量的實驗資源與時間。
另外,學習時參考的程式碼是第三方pytorch實現的,Github地址放在參考連結裡。
參考及引圖: