圖像語義分割,簡單而言就是給定一張圖片,對圖片上的每一個像素點分類。
圖像語義分割,從FCN把深度學習引入這個任務,一個通用的框架事:前端使用FCN全卷積網絡輸出粗糙的label map,后端使用CRF條件隨機場/MRF馬爾科夫隨機場等優化前端的輸出,最后得到一個精細的分割圖。
前端
為什么需要FCN?
分類網絡通常會在最后連接幾層全連接層,它會將原來二維的矩陣(圖片)壓縮成一維的,從而丟失了空間信息,最后訓練輸出一個標量,這就是我們的分類標簽。
而圖像語義分割的輸出需要是個分割圖,且不論尺寸大小,但是至少是二維的。所以,流行的做法是丟棄全連接層,換上全卷積層,而這就是全卷積網絡了。具體定義請參看論文:《Fully Convolutional Networks for Semantic Segmentation》
FCN結構
在FCN論文中,作者的FCN主要使用了三種技術:
卷積(Convolutional)、上采樣(Upsample)、跳層連接(Skip Layer)
卷積化即是將普通的分類網絡,比如VGG16,ResNet50/101等網絡丟棄全連接層,換上對應的卷積層即可。
上采樣即是反卷積(Deconvolution)。當然關於這個名字不同框架不同,Caffe和Kera里叫Deconvolution,而tensorflow里叫conv_transpose,在《信號與系統》這門課上,我們學過反卷積有定義,不是這里的上采樣。所以叫conv_transpose更為合適。
眾所周知,池化會縮小圖片的尺寸,比如VGG16 五次池化后圖片被縮小了32倍。為了得到和原圖等大的分割圖,我們需要上采樣/反卷積。反卷積和卷積類似,都是相乘相加的運算。只不過后者是多對一,前者是一對多。而反卷積的前向和后向傳播,只用顛倒卷積的前后向傳播即可。所以無論優化還是后向傳播算法都是沒有問題。上池化的實現主要在於池化時記住輸出值的位置,在上池化時再將這個值填回原來的位置,其他位置填0。圖解如下:
雖然文中說是可學習的反卷積,但是作者實際代碼並沒有讓它學習,可能正是因為這個一對多的邏輯關系。代碼如下:
1 layer { 2 name: "upscore" 3 type: "Deconvolution" 4 bottom: "score_fr" 5 top: "upscore" 6 param { 7 lr_mult: 0 8 } 9 convolution_param { 10 num_output: 21 11 bias_term: false 12 kernel_size: 64 13 stride: 32 14 } 15 }
可以看到lr_mult被設置為0。
跳層連接的作用就在於優化結果,因為如果將全卷積之后的結果直接上采樣,得到的結果是很粗糙的,所以作者將不同池化層的結果進行上采樣之后來優化輸出。具體結構如下:
不同上采樣得到的結果對比如下:
當然,你也可以將pool1, pool2的結果輸出,再上采樣輸出。不過,作者說了這樣得到的結果提升並不大。FCN是深度學習應用於圖像語義分割的開山之作,所以得了CVPR2015的最佳論文。但是,還是有一些處理比較粗糙的地方,具體和后面對比就知道了。
FCN-alike
《SegNet: A Deep Convolutional Encoder-Decoder Architecture for Robust Semantic Pixel-Wise Labelling》則是一種結構上更為優雅的網絡,SegNet使用一種概率自編碼模型,這是一種無監督特征生成網絡。當然,他們的label還是需要監督的。
DeepLab
DeepLab是Google提出的一個model,在VOC上的排名要比CRF as RNN的效果好。Deeplab仍然采用了FCN來得到score map,並且也是在VGG網絡上進行fine-tuning。但是在得到score map的處理方式上,要比原FCN處理的優雅很多。
還記得FCN中是怎么得到一個更加dense的score map的嗎? 是一張500x500的輸入圖像,直接在第一個卷積層上conv1_1加了一個100的padding。最終在fc7層勉強得到一個16x16的score map。雖然處理上稍顯粗糙,但是畢竟人家是第一次將圖像分割在CNN上變成end-to-end,並且在當時performance是state-of-the-art。
而怎樣才能保證輸出的尺寸不會太小而又不必加100 padding這樣“粗糙的”做法呢?可能有人會說減少池化層不就行了,這樣理論上是可以的,但是這樣直接就改變了原先可用的結構了,而且最重要的一點是不能用以前的結構參數進行fine-tune了。
所以,Deeplab這里使用了一個非常優雅的做法:將VGG網絡的pool4和pool5層的stride由原來的2改為了1,再加上 1 padding。就是這樣一個改動,使得vgg網絡總的stride由原來的32變成8,進而使得在輸入圖像為514x514時,fc7能得到67x67的score map, 要比FCN確實要dense很多很多。
但是這種改變網絡結果的做法也帶來了一個問題: stride改變以后,如果想繼續利用vgg model進行fine tuning,會導致后面感受野發生變化。這個問題在下圖(a) (b)體現出來了,注意花括號就是感受野的大小:
感受野就是輸出feature map某個節點的響應對應的輸入圖像的區域。比如我們第一層是一個3*3的卷積核,那么我們經過這個卷積核得到的feature map中的每個節點都源自這個3*3的卷積核與原圖像中3*3的區域做卷積,那么我們就稱這個feature map的節點感受野大小為3*3。
具體計算公式為:
其中rn表示第n層layer的輸入的某個區域,sn表示第n層layer的步長,kn表示kernel/pooling size
Deeplab提出了一種新的卷積,帶孔的卷積:Atrous Convolution。來解決兩個看似有點矛盾的問題:
既想利用已經訓練好的模型進行fine-tuning,又想改變網絡結構得到更加dense的score map。
如下圖(a) (b)所示,在以往的卷積或者pooling中,一個filter中相鄰的權重作用在feature map上的位置是連續的。
為了保證感受野不發生變化,某一層的stride由2變為1以后,后面的層需要采用hole算法,具體來講就是將連續的連接關系根據hole size大小變成skip連接。
上圖(C)中使用hole為2的Atrous Convolution則感受野依然為7。(C)中的padding為2,如果再增加padding大小,是不是又變”粗糙”了?當然不會,因為是Atrous Convolution,連接是skip的,所以2個padding不會同時和一個filter相連。
所以,Atrous Convolution能夠保證在這樣的池化后感受野不變,從而可以fine tune,同時也能保證輸出的結果更加精細。即:
后端
DeepLab后面接了一個全連接條件隨機場(Fully-Connected Conditional Random Fields)對分割邊界進行refine。
DeepLab里只是變成了refine label map。CRF經常用於 pixel-wise的label 預測。把像素的label作為隨機變量,像素與像素間的關系作為邊,即構成了一個條件隨機場且能夠獲得全局觀測時,CRF便可以對這些label進行建模。全局觀測通常就是輸入圖像。
在全連接的CRF模型中,標簽x 的能量可以表示為:
精細化的結果如下:
CRF-alike
CRFasRNN
在深度學習中,我們都追求end-to-end的系統,所以Conditional Random Fields as Recurrent Neural Networks 這篇文章的套路更深了……把Mean Field算法嵌入在網絡層中。自己寫了caffe一層,用類似於Conv的操作模擬Mean Field的四步,具體實現細節可以參照論文中所給的代碼。
馬爾科夫隨機場(MRF)
在Deep Parsing Network中使用的是MRF,它的公式具體的定義和CRF類似,只不過作者對二元勢函數進行了修改:
這個結構的優點在於:
- 將Mean fied 構造成CNN
- 聯合訓練並且可以one-pass inference,而不用迭代。
總結
深度學習+概率圖模型(PGM)是一種趨勢。深度學習可以更好的提取特征,而PGM能夠從數學理論很好的解釋事物本質間的聯系。概率圖模型的網絡化也是一種趨勢,我們目標是end-to-end的學習系統。
引用
[1]Fully Convolutional Networks for Semantic Segmentation
[2]Learning Deconvolution Network for Semantic Segmentation
[3]DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs
[4]Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFs
[5]Conditional Random Fields as Recurrent Neural Networks
[6]SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation
原文地址: http://blog.csdn.net/junparadox/article/details/52610744