@
0. 論文鏈接
FCN(https://arxiv.org/abs/1411.4038)
1. 概述
語義分割(semantic segmentation)其實就是對每個像素點進行預測分類(dense prediction)。這也應該是第一個訓練對像素進行預測並且采用了有監督預訓練的端到端FCN網絡,可以對任意尺寸的輸入利用現有的網絡對其進行密集預測(dense prediction)。學習和推理能在全圖通過密集的前饋計算和反向傳播一次執行(whole-image-ata-time)。網內上采樣層能在像素級別預測和通過下采樣池化學習。作者提出了一種利用了結合深、粗層的語義(semantic)信息和淺、細層的表征(appearance)信息的特征譜的跨層網絡結構(skip architecture)。
2. Adapting classifiers for dense prediction
因為之前的分類網絡通常只能固定輸入圖片尺寸,然后輸出概率,並沒有空間信息。但是全連接層同樣用卷積層進行表示,具體就是在用與輸入分類網絡FC層尺度大小相同卷積核從而獲得與FC層相同維度的輸出(比較經典也比較簡單,不細舉例了),換成全卷積層就可以接受任意尺度的輸入並且輸出一個分類圖(classification map),具體可以看下圖:

值得注意的是全卷積層最后輸出的classification map相當於原來網絡在某些特定patch上進行預測(可以想象成一個滑動窗口),但是很多計算都在這些patch的overlap上,浪費很多計算資源與時間,而全卷積層的效率是很高的。
3. upsampling
之前的對分類網絡的改動,還是有一個問題的,比如output map相比原圖維度是減少了很多的,因為在網絡過程中通常會做一些 subsample來讓卷積核變得更小,讓計算量相對合理,所以我們需要通過一些手段使coarse output維度增加獲得dense prediction的分割輸出,文章中說了一句 感受野的步長等於輸入尺寸與輸出尺寸的系數比。接下來文章中介紹了三種upsample的方法。
3.1 Shift-and-stitch
這里首先推薦這位中科大學長的一篇博客,講解的很不錯,我也加了他的微信,為人也很好呢~在這我就簡述一下Shift-and-stitch。
Shift-and-stitch是從coarse outputs到dense predictions的一種trick,文章在《Overfeat: Integrated recognition, localization and detection using convolutional networks》中被提到。他的方法為(直接看英文原版更清晰一些):

這里注意,通常需要在輸入加相應的padding,來讓他進行“shift”,引用上面中科大學長的文章內容:

為表述簡潔,用 “ 像素 i ” 表示“ 值為 i 的像素 ”
紅色 output中的像素1對應shifted input(0,0) 的紅色部分, 而對應 original image 的部分,也即receptive field僅僅為像素[1], 所以 receptive field 的中心為像素[1], 該位置填上紅色output中像素 1 的值。
黃色 output 中的像素4 對應 shifted input (1,0)的黃色部分, 而對應 original image 的部分,也即receptive field為像素 [3,4] , 所以 receptive field 的中心為像素 [4], 該位置填上黃色output中像素 4 的值。
以此類推..注意: 我們注意到黃色 output 中的像素 5 與紅色 output 中的像素5對應的receptive field 中心是重疊的,所以將黃色 output 中的像素 5 標為灰色,表示不予考慮。同理其他ouput 中的灰色區域也代表 receptive field中心重疊的像素。
這里需要說明一下的是, 感受野的中心可以簡單的理解成:給定一個矩形,求他的中心, 小數需要向上/下取整,所以上圖2x2的感受野,在其實四個值都可以作為“中心”, 在論文《RECURRENT CONVOLUTIONAL NEURAL NETWORKS FOR SCENE PARSING》中,他舉得例子是沒有上圖中“灰色塊”的,如果按照灰色塊里的數值計算,會發現他對“感受野中心”定義是不同的,有的是左下有的是右下,而在論文中,他則是忽略了灰色塊, 我的理解是論文里是按照右下的規則,在灰色地方,感受野的中心成了padding的0,不是原圖的像素,因此需要去掉,因此這樣恰好可以拼成原圖大小,不會多像素也不會少像素,如下圖。

(關於中科大學長的觀點目前還不知道他從哪得到的,也沒看FCN中的源碼,以后補充)
3.2 decreasing subsampling
上述采用的shift-and-stitch方案,需要反復計算 \(f*f\) 個輸入,造成計算效率的降低。而 decreasing subsampling 方法提供了另外的一種思路,減小傳統網絡中降采樣操作,從而實現 coarse output 的 dense prediction。
考慮其中某一層具有stride = s,后面卷積層具有卷積核權重 fij。現在我們設置原本stride = 1避免降采樣的出現,形成上采樣結果。然而直接對這樣的上采樣結果進行按照原本卷積核操作並不能得到相等於 shift-and-stitch的結果。因為這樣的卷積核僅僅能看到上采樣結果的一小部分,所以我們擴大原本的卷積核:

值得注意的是,這樣的操作方式會造成一種 trade-off:卷積核如果需要看到更精細的信息,往往需要較小的感受野且需要更多的操作。這樣的一種方式,使得感受野固定成一種較大的 input size,不能完成精細的定位分割信息。
3.3 Deconvolution(backwards strided convolution)
所謂的Deconvolution在操作上其實就是簡單的把卷積forward與backward交換過來,因此上采樣可以通過計算所有像素(pixel-wise)的loss反向傳播達到in-network for end-to-end learning。值得注意的是,反卷積核並不是固定的,而是可以學習的,一些堆疊的反卷積層跟激活函數可以學一個非線性上采樣(upsampling),作者采用了Deconvolution + skip的網絡結構。
4. Segmentation Architecture
作者訓練了一個per-pixel multinomial logistic loss,用VGG16跟GooLeNet做backbone,其中GoogLeNet只用最后的loss layer 並且把最后的average pooling layer去掉。作者把每個網絡去掉最后的分類層,把全連接層變成全卷積層,另外,在每個coarse output locations加了一個21維通道的1x1卷積,然后接着一層deconv層來把coarse output 轉換成 pixel-dense outputs。從classification 到 segmentation 的Fine-tuning很重要,通過BP來fine-tuning整個網絡,如果只fine-tuning分類器只有70%的性能,作者提出一個skip architecture來結合finer與coarse的特征,如下圖:

每個網絡的效果圖跟結果:

轉自:https://www.jianshu.com/p/0beea071b9b1
網絡框架如下:
-
整體的網絡框架基於正常的CNN,將最后的全連接網絡改為了卷積。
這樣做的效果是:
1)網絡得以接受任意維度的輸入,不需要變成224x224了;
2)最后本該是1000x1x1維的特征變成了1000xWxH維,這個w和h就是熱點圖的尺寸。關於這個熱點圖,應該是有1000張熱點圖,可以看出整張圖片的不同區域都激活了哪種分類的輸出。 -
在上述結構的基礎上,將1000維變成21維(20種分類+背景類),再接一個反卷積層。
這樣做的效果就是:
1)輸出了21張熱點圖,然后通過反卷積網絡變成了21張大小等於原圖的Mask;
2)21張Mask出來之后就可以和真實數據做逐像素的損失函數了,進行訓練。
這樣做還有一些缺點:
1)先得到的熱點圖的尺寸和最后一層卷積的特征圖尺寸是相當的,在作者采用的VGG16中,尺寸為原圖的1/32,這就讓一層反卷積網絡實現32倍的放大,結果可想而知是粗糙(coarse)的。作者后來采用了skip的方法做了精細化,但或許直接采用多層的反卷積就可以有不錯的效果。
2)這一段寫的過程中被刪掉了,因為寫着寫着發現了問題,我把刪掉的放到后面,可以作為思路記錄。訓練的時候每個點的預測值就是一個21維的向量,做交叉熵損失函數。最后預測結果采用max算法。嗯這是一個提醒自己訓練和測試不同的好例子。
其實21張Mask出來之后他有采用一個最大值算法,使得最后輸出的MAsk就一張,包括了每個點最可能的預測。這種方式有個缺陷就是它相當於把每個點的非極大預測值變成了0。之后loss具體是交叉熵還是單純的3-2(這個不太可能)不太清楚,就以交叉熵來說,他的損失函數就是不合理的,因為可能本身該點像素預測第二名就是對的,但這下又要推倒重來。 -
接下來是Skip結構,是將pool3和pool4層的特征引到輸出。
具體來說,pool3和pool4層特征圖的大小是pool5層的4、2倍,所以最后的熱點圖要先反卷積擴大為2倍、4倍再相加,然后再反卷積擴大為16倍、8倍。得到原圖尺寸。
這樣做是為了讓Mask更加精細,之前說過這個方法或許可以被替代。
接下來是訓練過程:
其實上面說的比較清楚了,就是利用FCN得到圖像的熱點圖,然后通過反卷積的方式得到與原圖像尺寸相同的Mask,每個像素均包含21類的預測值,然后利用這個進行訓練。測試方式是取21預測值的最大為結果。
但是還有一些細節需要說明:
- 作者采用了VGG網絡,默認大小是224x224,在pool5層后輸出尺寸變為1/32,為7x7,之后進行7x7的卷積,可以得出,最后熱點圖的大小並不是原圖尺寸/32,而是\(h_1 = (h-192)/32\)。這就有2個問題:
1)圖像尺寸不能小於224,否則輸出不足1.
2)skip結構中,fc7與pool4層之間不是2倍關系。
對於這一問題的解決方式是:
1)圖像在輸入過程中被pad了100,最終尺寸變為\(h_1 = (h+6)/32\),從而可以接受任意尺寸圖像。
2)對fc7反卷積x2后進行crop裁剪。(因為他多了6)
5. Metric
轉自:https://blog.csdn.net/mieleizhi0522/article/details/81914000


