1. 程式人生 > >語義分割總結(未完待續)

語義分割總結(未完待續)

一、綜述

由於工作中很長一段時間都是在做語義分割系列的工作,所以這篇文章主要對自己用到的一些方法做個簡單的總結,包括其優缺點等,以便日後能夠及時複習檢視。

目前語義分割的方法主要集中在兩個大的結構上:1、encode-decode的結構:影象通過encode階段進行特徵抽取,decode則負責將抽取到的資訊進行對應的分類復位;2、dialted convolutional結構,這種結構拋棄了pool層而採用了空洞卷積(dilated convolutional layers)進行代替,能夠起到增加感受野的作用。

所以本文將會按照時間順序來分別對FCN、SetNet、U-Net、DeepLab V1 (and V2)、RefineNet、PSPNet、DeepLab V3這幾個典型的網路結構作分析。

二、 網路結構

1)FCN

分類網路的分類層通常會在最後連線全連線層,它會將前面層卷積提取到的二維特徵的矩陣壓縮成一維的,從而丟失了空間資訊,最後訓練輸出一個標量,用來分類。而FCN 的核心思想是將一個卷積網路的最後全連線輸出層替換成轉置卷積層來獲取對每個輸入畫素的預測。具體來說,它去掉了過於損失空間資訊的全域性池化層,並將最後的全連線層替換成輸出通道是原全連線層輸出大小的 1×1 卷積層,最後接上轉置卷積層來得到需要形狀的輸出。
在這裡插入圖片描述
在這裡插入圖片描述

如上圖所示,即為FCN的網路結構圖,為了便於理解,我在mxnet的網站找了一張比較形象的圖來解釋一下這個網路結構,如下圖:
在這裡插入圖片描述
FCN的結構就是將VGG16中的fc6和fc7都換成卷積,然後經過conv_transpose進行還原擴大,而FCN-8s和FCN-16s則是結合了前面pooling層的輸出,然後進行element wise(對應值相加),然後輸出。

  1. FCN-32s:直接對pool5 feature進行32倍上取樣獲得32x upsampled feature,再對32x upsampled feature每個點做softmax prediction獲得32x upsampled feature prediction(即分割圖)。
  2. FCN-16s:首先對pool5 feature進行2倍上取樣獲得2x upsampled feature,再把pool4 feature和2x upsampled feature逐點相加,然後對相加的feature進行16倍上取樣,並softmax prediction,獲得16x upsampled feature prediction。
  3. FCN-8s,首先進行pool4+2x upsampled feature逐點相加,然後又進行pool3+2x upsampled逐點相加,即進行更多次特徵融合。具體過程與16s類似.
    根據上面三種不同的connect對比可知:使用多層feature融合有利於提高分割準確性。即:準確率FCN-32s < FCN-16s < FCN-8。
    難點:作者開源了程式碼,但是細細度過後就會發現有幾個比較奇怪的難以理解的點,我寫出來如下:
    1、作者在conv1_1中採用的padding=100,為什麼呢?
    在這裡插入圖片描述
    為什麼需要padding=100呢?
    因為作者為了保證輸出的尺寸不至於太小,所以對第一層進行了padding。當然了還有的做法就是可以減少池化的層,但是這樣做會帶來的問題就是原先的網路結構不可用了,也就沒辦法fine-tune了。當然了還有一種比較好的辦法就是想deeplab那樣,將pooling的stride改為1,padding=1,這樣之後池化並沒有帶來圖片尺寸的減少。

2)SegNet

網路結構如下:
在這裡插入圖片描述
segnet是個典型的encode-decode結構,和FCN的思路很像。segnet採用的是vgg16全連線層前面的網路結構。
這個網路結構比較特殊的地方在於將池化層結果應用到譯碼過程。引入了更多的編碼資訊。使用的是pooling indices而不是直接複製特徵,只是將編碼過程中 pool 的位置記下來,在 uppooling 是使用該資訊進行 pooling 。
Upsamping就是Pooling的逆過程(index在Upsampling過程中發揮作用),Upsamping使得圖片變大2倍。我們清楚的知道Pooling之後,每個filter會丟失了3個權重,這些權重是無法復原的,但是在Upsamping層中可以得到在Pooling中相對Pooling filter的位置。所以Upsampling中先對輸入的特徵圖放大兩倍,然後把輸入特徵圖的資料根據Pooling indices放入,下圖所示,Unpooling對應上述的Upsampling,switch variables對應Pooling indices。
在這裡插入圖片描述
對比FCN可以發現SegNet在Unpooling時用index資訊,直接將資料放回對應位置,後面再接Conv訓練學習。這個上取樣不需要訓練學習(只是佔用了一些儲存空間)。反觀FCN則是用transposed convolution策略,即將feature 反捲積後得到upsampling,這一過程需要學習,同時將encoder階段對應的feature做通道降維,使得通道維度和upsampling相同,這樣就能做畫素相加得到最終的decoder輸出.
在這裡插入圖片描述
對於這個paper中對於類別不平衡的問題也進行了相應的加權,計算方法如下:

f(class) = frequency(class) / (image_count(class) * w * h)
weight(class) = median of f(class)) / f(class)

其中frequency(class)的意思是該類別的training set的總畫素的個數;比如在我的資料集合中training set的數量為500張圖片,房屋畫素的個數總和為30000個畫素;
image_count(class)的意思是在training set中含有該類別的畫素的圖片的數量;比如含有房屋的圖片的個數位467張
,w*h為圖片的尺寸;median of f(class))為計算出的f(class) 的中位數;

附我實現的程式碼如下:https://github.com/gbyy422990/segnet_tf/blob/master/median_frequency_balancing.py

另外一種Bayesian SegNet模型我後面再補充。

3)U-Net

這個網路結構由於比較簡單,在這裡就不再贅述了,結構圖如下:
在這裡插入圖片描述
依然使用Vgg16進行特徵抽取,然後上取樣的時候結合前面的同等大小的取樣過程中的特徵進行channel維度上的拼接。
U-Net採用了與FCN完全不同的特徵融合方式:拼接!即:與FCN的逐點相加不同,Unet採用的是特徵在channel維度上拼接在一起,形成更“厚”的特徵。

DeepLab V1

TODO

DeepLab V2

TODO

RefineNet

TODO

PSPNet

TODO