截止目前,CNN已經在圖像分類分方面取得了巨大的成就,涌現出如VGG和Resnet等網絡結構,并在ImageNet中取得了好成績。CNN的強大之處在于它的多層結構能自動學習特征,并且可以學習到多個層次的特征:
較淺的卷積層感知域較小,學習到一些局部區域的特征;
較深的卷積層具有較大的感知域,能夠學習到更加抽象一些的特征。
這些深層抽象特征對物體的大小、位置和方向等敏感性更低,從而有助于分類性能的提高。這些抽象的特征對分類很有幫助,可以很好地判斷出一幅圖像中包含什么類別的物體,也就是說圖像分類是圖像級別任務(參考圖像語義分割入門)。
與分類不同的是,語義分割需要判斷圖像每個像素點的類別,進行精確分割,圖像語義分割是像素級別的任務,但是由于CNN在進行convolution和pooling過程中丟失了圖像細節,即feature map size逐漸變小,所以不能很好地指出物體的具體輪廓、指出每個像素具體屬于哪個物體,無法做到精確的分割。針對這個問題,Jonathan Long等人提出了Fully Convolutional Networks(FCN)用于圖像語義分割。自從提出后,FCN已經成為語義分割的基本框架,后續算法其實都是在這個框架中改進而來。
注意,本文僅對基于深度學習的經典語義分割成果進行梳理,之所以說是經典,是因為本文幾乎沒有涉及18年及之后的最新進展,故標題也說了:只是入門基于深度學習的語義分割。
一、FCN
對于一般的分類CNN網絡,如VGG和Resnet,都會在網絡的最后加入一些全連接層,經過softmax后就可以獲得類別概率信息。但是這個概率信息是1維的,即只能標識整個圖片的類別,不能標識每個像素點的類別,所以這種全連接方法不適用于圖像分割。而FCN提出可以把后面幾個全連接都換成卷積,這樣就可以獲得一張2維的feature map,后接softmax獲得每個像素點的分類信息,從而解決了分割問題。
1、網絡特點
全卷積(Convolutional)
上采樣(Upsample)
跳躍結構(Skip Layer)
2、網絡結構
3、原理說明
全卷積
FCN將傳統CNN中的全連接層轉化成一個個的卷積層。如下圖所示,在傳統的CNN結構中,前5層是卷積層,第6層和第7層分別是一個長度為4096的一維向量,第8層是長度為1000的一維向量,分別對應1000個類別的概率。FCN將這3層表示為卷積層,卷積核的大小(通道數,寬,高)分別為(4096,1,1)、(4096,1,1)、(1000,1,1)。所有的層都是卷積層,故稱為全卷積網絡。
上采樣——轉置卷積
可以發現,經過多次卷積(還有pooling)以后,得到的圖像越來越小,分辨率越來越低(粗略的圖像),那么FCN是如何得到圖像中每一個像素的類別的呢?為了從這個分辨率低的粗略圖像恢復到原圖的分辨率,FCN使用了上采樣。例如經過5次卷積(和pooling)以后,圖像的分辨率依次縮小了2,4,8,16,32倍。對于最后一層的輸出圖像,需要進行32倍的上采樣,以得到原圖一樣的大小。這個上采樣是通過反卷積(deconvolution)實現的。
另外補充一句,上采樣(upsampling)一般包括2種方式:
Resize,如雙線性插值直接縮放,類似于圖像縮放(這種方法在原文中提到)
Deconvolution,也叫Transposed Convolution
一張更為形象的說明如下:
跳躍結構
對第5層的輸出(32倍放大)反卷積到原圖大小,得到的結果還是不夠精確,一些細節無法恢復。于是Jonathan將第4層的輸出和第3層的輸出也依次反卷積,分別需要16倍和8倍上采樣,結果就精細一些了。
其卷積過程類似:
image經過多個conv和+一個max pooling變為pool1 feature,寬高變為1/2
pool1 feature再經過多個conv+一個max pooling變為pool2 feature,寬高變為1/4
pool2 feature再經過多個conv+一個max pooling變為pool3 feature,寬高變為1/8
......
直到pool5 feature,寬高變為1/32。
相對應的:
對于FCN-32s,直接對pool5 feature進行32倍上采樣獲得32x upsampled feature,再對32x upsampled feature每個點做softmax prediction獲得32x upsampled feature prediction(即分割圖)。
對于FCN-16s,首先對pool5 feature進行2倍上采樣獲得2x upsampled feature,再把pool4 feature和2x upsampled feature逐點相加,然后對相加的feature進行16倍上采樣,并softmax prediction,獲得16x upsampled feature prediction。
對于FCN-8s,首先進行pool4+2x upsampled feature逐點相加,然后又進行pool3+2x upsampled逐點相加,即進行更多次特征融合。具體過程與16s類似,不再贅述。
下圖是這個卷積和反卷積上采樣的過程:
下圖是32倍,16倍和8倍上采樣得到的結果的對比,可以看到它們得到的結果越來越精確:
4、優點(貢獻)和不足
優點和貢獻
1.為深度學習解決語義分割提供了基本思路,激發了很多優秀的工作
2.輸入圖像大小沒有限制,結構靈活
3.更加高效,節省時間和空間
不足
1.結果不夠精細,邊界不清晰
2.沒有充分考慮到語義間的上下文關系
3.padding操作可能會引入噪聲
二、SegNet
基于FCN的一項工作,修改VGG-16網絡得到的語義分割網絡,有兩種SegNet,分別為正常版與貝葉斯版,同時SegNet作者根據網絡的深度提供了一個basic版(淺網絡)。
1、網絡結構
作者提供了幾種網絡結構,上圖就是通用結構:對稱的encode-decode結構,想了解更為具體的實現建議查看開源實現。
2、創新點
SegNet的最大池化層和上采樣層不同于通常的處理,SegNet 中使用最大池化,并且同時輸出最大點的 index。同一層次的上采樣根據 index 確定池化前 max 值的點的位置,并對其他丟失的點做插值。
補充一點,tensorflow對于SegNet的上采樣方式并不支持(也許只是沒有封裝好而已,可以手動實現,不確定),所以我查到的實現一般就直接用普通的上采樣了,這樣tf版本的SegNet結構相較U-Net簡單了不少(個人感覺兩者還是很相似的)。有趣的是帶索引最大池化tf是有封裝好的接口的,在nn包中。
作為對比,下左為SegNet,下右為FCN中的上采樣實現(FCN的上采樣相較現在成熟的上采樣方案也略有不同,多加了一個根據原始編碼得來并保存的y,這需要消耗額外的內存):
此外還有貝葉斯SegNet變種,不太懂,就不畫蛇添足了。
三、U-Net
U-Net是原作者參加ISBI Challenge提出的一種分割網絡,能夠適應很小的訓練集(大約30張圖)。U-Net與FCN都是很小的分割網絡,既沒有使用空洞卷積,也沒有后接CRF,結構簡單。
卷積網絡被大規模應用在分類任務中,輸出的結果是整個圖像的類標簽。然而,在許多視覺任務,尤其是生物醫學圖像處理領域,目標輸出應該包括目標類別的位置,并且每個像素都應該有類標簽。另外,在生物醫學圖像往往缺少訓練圖片。所以,Ciresan等人訓練了一個卷積神經網絡,用滑動窗口提供像素的周圍區域(patch)作為輸入來預測每個像素的類標簽。這個網絡有兩個優點:第一,輸出結果可以定位出目標類別的位置;第二,由于輸入的訓練數據是patches,這樣就相當于進行了數據增廣,解決了生物醫學圖像數量少的問題。 ?? 但是,這個方法也有兩個很明顯缺點。 ?? 第一,它很慢,因為這個網絡必須訓練每個patch,并且因為patch間的重疊有很多的冗余(冗余會造成什么影響呢?卷積核里面的W,就是提取特征的權重,兩個塊如果重疊的部分太多,這個權重會被同一些特征訓練兩次,造成資源的浪費,減慢訓練時間和效率,雖然說會有一些冗余,訓練集大了,準確率不就高了嗎?可是你這個是相同的圖片啊,重疊的東西都是相同的,舉個例子,我用一張相同的圖片訓練20次,按照這個意思也是增大了訓練集啊,可是會出現什么結果呢,很顯然,會導致過擬合,也就是對你這個圖片識別很準,別的圖片就不一定了)。 ?? 第二,定位準確性和獲取上下文信息不可兼得。大的patches需要更多的max-pooling層這樣減小了定位準確性(為什么?因為你是對以這個像素為中心的點進行分類,如果patch太大,最后經過全連接層的前一層大小肯定是不變的,如果你patch大就需要更多的pooling達到這個大小,而pooling層越多,丟失信息的信息也越多;小的patches只能看到很小的局部信息,包含的背景信息不夠。
和SegNet格式極為相近,不過其添加了中間的center crop和concat操作實現了不同層次特征的upsample,目的同樣是使上采樣的層能夠更多的參考前面下采樣中間層的信息,更好的達到還原的效果。
U-Net的格式也不復雜,形狀如下,參看github開源實現不難復現,注意用好相關張量操作API即可(如concet、slice等)。值得注意的是U-Net采用了與FCN完全不同的特征融合方式:拼接!與FCN逐點相加不同,U-Net采用將特征在channel維度拼接在一起,形成更“厚”的特征。所以:
語義分割網絡在特征融合時也有2種辦法:
FCN式的逐點相加,對應caffe的EltwiseLayer層,對應tensorflow的tf.add()
U-Net式的channel維度拼接融合,對應caffe的ConcatLayer層,對應tensorflow的tf.concat()
(1) 使用全卷積神經網絡。(全卷積神經網絡就是卷積取代了全連接層,全連接層必須固定圖像大小而卷積不用,所以這個策略使得,你可以輸入任意尺寸的圖片,而且輸出也是圖片,所以這是一個端到端的網絡。) ?? (2) 左邊的網絡是收縮路徑:使用卷積和maxpooling。 ?? (3) 右邊的網絡是擴張路徑:使用上采樣產生的特征圖與左側收縮路徑對應層產生的特征圖進行concatenate操作。(pooling層會丟失圖像信息和降低圖像分辨率且是不可逆的操作,對圖像分割任務有一些影響,對圖像分類任務的影響不大,為什么要做上采樣?因為上采樣可以補足一些圖片的信息,但是信息補充的肯定不完全,所以還需要與左邊的分辨率比較高的圖片相連接起來(直接復制過來再裁剪到與上采樣圖片一樣大?。@就相當于在高分辨率和更抽象特征當中做一個折衷,因為隨著卷積次數增多,提取的特征也更加有效,更加抽象,上采樣的圖片是經歷多次卷積后的圖片,肯定是比較高效和抽象的圖片,然后把它與左邊不怎么抽象但更高分辨率的特征圖片進行連接)。 ?? (4) 最后再經過兩次反卷積操作,生成特征圖,再用兩個1X1的卷積做分類得到最后的兩張heatmap,例如第一張表示的是第一類的得分,第二張表示第二類的得分heatmap,然后作為softmax函數的輸入,算出概率比較大的softmax類,選擇它作為輸入給交叉熵進行反向傳播訓練。
四、空洞卷積
『計算機視覺』空洞卷積
池化操作增大了感受野,有助于實現分類網絡,但是池化操作在分割過程中也降低了分辨率,空洞卷積層則可以在不降低空間維度的前提下增大了相應的感受野指數。
五、DeepLab
v1
面臨問題:
在DCNN進行分割任務時,有兩個瓶頸:
一個是下采樣所導致的信息丟失,通過帶孔卷積的方法解決;
另一個是CNN空間不變性所導致的邊緣不夠準確,通過全連接的CRF解決(CRF是可以通過底層特征進行分割的一個方法) 核心工作:空洞卷積 (計算的特征映射更加密集)+ 如何降低計算量 + CRF作為后處理(知乎文章:FCN(3)——DenseCRF) Deeplab: ??? 使用帶孔算法(空洞卷積)進行特征提取:將VGG16的全連層轉換為卷積層,將最后兩個最大池化層的后的下采樣去掉,中間的卷積替換為帶孔卷積 ??? 對于空洞卷積,作者提到了兩個實現方法:在卷積核中間加0/ 先降采樣然后過正常卷積,第二種方法計算速度快。最后三個卷積層使用2倍的步長,第一個全連層使用4倍步長,這樣做的好處是不需要引入額外的近似算法。 ??? 感受野控制、加速卷積網絡的密集計算:將VGG16轉換為全卷積層后計算量變得非常大,為了降低運算,將第一個全連層進行降采樣。這個做法降低了感受野的大小 不是很懂CRF的具體做法,簡單的原文的圖貼上來,感受一下框架的pipline,
v2
相較于v1,簡單來說:
空洞卷積+全連接CRF+ASPP模塊
主干網絡從預訓練的VGG變成了ResNet
首先在三個尺度上訓練和測試(在給定的輸入上以不同采樣率的空洞卷積并行采樣,相當于以多個比例捕捉圖像的上下文,稱為 ASPP (atrous spatial pyramid pooling) 模塊),得到的概率是輸入圖片的八分之一大小,然后是將概率圖進行雙線性插值到原始輸入圖片大小,將三個尺度的概率圖進行融合,融合策略是最簡單的取最大值,最后將融合之后的和原始輸入一樣大小的概率圖輸入到全連接條件隨機場中細化邊緣細節得到最終的分割結果。訓練的時候將GT降采樣了8倍和CNN直接輸出的概率圖同樣的大小計算loss。
下面這張圖展示了不同方式的上下文信息獲取,最后一張圖是ASPP的原型:
1.Image Pyramid:將輸入圖片放縮成不同比例,分別應用在 DCNN 上,將預測結果融合得到最終輸出。 2.Encoder-Decoder:利用 Encoder 階段的多尺度特征,運用到 Decoder 階段上恢復空間分辨率,代表工作有 FCN、SegNet、PSPNet 等工。 3.Deeper w. Atrous Convolution:使用空洞卷積。 4.Spatial Pyramid Pooling:空間金字塔池化具有不同采樣率和多種視野的卷積核,能夠以多尺度捕捉對象。
v3
第三版相對于第二版的改動不是很大,主要是借鑒了下面的兩篇論文的思想,然后分別對之前的空洞卷積和ASPP模塊就行了改進,然后整體加入了BN,需要注意的是從本版本開始已經不要CRF進行后處理了:
Understanding Convolution for Semantic Segmentation Pyramid Scene Parsing Network
另外文章指出了,在訓練的時候將GT應該保持不動,將概率圖插值之后再進行計算loss,這樣不會導致金標準在降采樣過程中丟失細節,畢竟8倍的降采樣還是很嚴重的。
v3+
鑒于對最后的概率圖依然使用大倍數的雙線性插值恢復到與原圖一樣的大小還是過于簡單了,因此在這個版本中,增加了一個恢復細節的解碼器部分。A是aspp結構,其中8x的上采樣可以看做是一個解碼器;B是編解碼結構,它集合了高層和底層的特征;C就是本文采取的結構:
下圖展示了具體的網絡表示:
該框架參考了spatial pyramid pooling(SPP) module和encoder-decoder兩種形式的分割框架。前一種就是PSPNet那一款,后一種更像是SegNet的做法。
ASPP方法的優點是該種結構可以提取比較dense的特征,因為參考了不同尺度的feature,并且atrous convolution的使用加強了提取dense特征的能力。但是在該種方法中由于pooling和有stride的conv的存在,使得分割目標的邊界信息丟失嚴重。
Encoder-Decoder方法的decoder中就可以起到修復尖銳物體邊界的作用。
關于Encoder中卷積的改進: DeepLab V3+效仿了Xception中使用的depthwise separable convolution,在DeepLab V3的結構中使用了atrous depthwise separable convolution,降低了計算量的同時保持了相同(或更好)的效果。
Decoder的設計: 2.1. Encoder提取出的特征首先被x4上采樣,稱之為F1; 2.2. Encoder中提取出來的與F1同尺度的特征F2'先進行1x1卷積,降低通道數得到F2,再進行F1和F2的concatenation,得到F3;(為什么要進行通道降維?因為在encoder中這些尺度的特征通常通道數有256或者512個,而encoder最后提取出來的特征通道數沒有這么多,如果不進行降維就進行concate的話,無形之中加大了F2'的權重,加大了網絡的訓練難度) 2.3. 對F3進行常規的3x3convolution微調特征,最后直接x4upsample得到分割結果。
編輯:黃飛
?
評論
查看更多