簡單過一下語義分割的主流框架——FCN、UNet、SegNet、PSPNet、DeepLab
全卷積網絡FCN
論文:《Fully Convolutional Networks for Semantic Segmentation(CVPR2015)》
參考:《FCN的學習及理解 | CSDN, moonuke》
主要貢獻:
- 在分類網絡的基礎上,取消要求固定輸入長度的全連接FC,使網絡能接受任意尺寸的輸入
- 在網絡深層部分使用反卷積層上采樣,恢復深層特征的空間尺度
- 淺層特征注重細致的局部、位置信息,深層特征注重抽象的全局、分類信息。通過跨層連接,融合淺層(上采樣前)和深層(上采樣后)特征以提高網絡的表現
為了跟圖示統一,后續將以AlexNet為backbone進行討論。
從CNN到FCN
就像《卷積神經網絡CNN - 全連接層 | Hey~YaHei!》所提到的,卷積神經網絡CNN因為全連接層的限制,要求網絡輸入具有固定的尺寸大小。FCN作者將最后的三個全連接層換成1x1卷積,如果輸入特征圖恰好是1x1,那明顯是等價的;如果不是1x1,那網絡也不至于出錯,但輸出大小也會由輸入大小決定。
反卷積上采樣
FCN用反卷積(deconvolution)在網絡深層做上采樣操作,以恢復出輸入圖片同等尺寸的分割結果,也就是每個像素點的類別。
反卷積其實相當于零填充上采樣+卷積,與padding不同的是,它填充在輸入特征圖的像素點之間。
3x3標準卷積 | 3x3反卷積 | 3x3空洞卷積 |
---|---|---|
(以上三圖,藍色方塊為輸入特征圖的像素點,綠色方塊為輸出特征圖像素點,空白部分填零) |
關于反卷積的詳細過程此處不再贅述,感興趣可以參考《怎樣通俗易懂地解釋反卷積? | 知乎, 孫小也》
值得一提的是,通常部署的時候不喜歡用反卷積,因為推理引擎往往沒有針對反卷積做充分的優化。大多都直接用雙線性插值/三線性插值做上采樣(簡化操作順便提高推理速度),頂多再疊一層普通卷積來進一步提取特征。
跨層融合
眾所周知,淺層特征注重細致的局部、位置信息,深層特征注重抽象的全局、分類信息。分類任務里不關注位置信息,所以隨著網絡前傳,即使特征圖分辨率越來越小,信息越來越抽象,位置信息逐步丟失,也無傷大雅。但檢測任務和分割任務不同,除了需要給出對象的分類之外,還得給出位置信息——因此淺層特征的位置得想辦法把它保留下來,比較直觀的想法就是跨層把淺層和深層信息融合起來。
融合的方式有很多,最簡單的如逐元素相加/相乘,或者連接特征(一般是從通道維度上做拼接)后做進一步的特征提取。FCN采用的即是簡單的逐元素相加的形式,以500x500x3的輸入圖片為例(虛線以上就一個普通的全卷積網絡,虛線以下是跨層融合相關的層)——
- 首先,由于不做分類任務,作為“分類器”的最后一層全連接()可以直接丟棄,保留前端的特征提取部分;
- 分別將若干淺層特征圖和最后的特征圖抽離出來,經過卷積層特征映射到21通道的特征空間上(這里以VOC數據集為例,20正樣本+1負樣本(背景)=21分類),然后反卷積進行上采樣(如圖虛線以下的藍色方塊,有必要的話還得裁剪,通常是中央裁剪,到統一的尺寸),再對應逐元素相加(如圖黃色方塊)達到特征融合的目的;
- 最后再一個反卷積上采樣(配合裁剪)到原始尺寸,通道方向即相當于分類任務里的輸出特征向量,決定著每個像素點所屬的分類
訓練細節
FCN采用普通的softmax交叉熵作為損失函數,既然通道方向決定了每個像素點的類別,那就對每個像素點計算softmax交叉熵,最后加和起來作為最終的損失進行訓練。
原文倒是講究,采用分階段訓練的方式,用與訓練好的分類網絡作為backbone,丟棄最后一層全連接,其他全連接替換成卷積并重新初始化權重(丟棄原有的全連接權重),再逐一融合中間層特征進行多階段訓練。
階段 | 訓練部分 |
---|---|
#1 | |
#2 | |
#3 | |
#4 |
UNet
論文:《U-Net: Convolutional Networks for Biomedical Image Segmentation(MICCAI2015)》
主要貢獻:
- 以拼接+進一步提取特征的形式融合淺層(上采樣前)與深層(上采樣后)特征
- 用重疊切片的平鋪策略對大尺度圖像進行分割
- 采用加權的損失函數,加大邊緣部分像素的權重,鼓勵網絡區分邊界,有助于實例分割
拼接實現的跨層融合
網絡整體結構呈現U型的對稱結構,故稱為UNet,左半部分為卷積組成的下采樣路徑,右半部分為反卷積和卷積組成的上采樣路徑。下采樣路徑每個階段包含兩_次_卷積和一次池化(卷積通道擴增+卷積等通道特征提取+池化下采樣),上采樣路徑每個階段包含一次反卷積和兩次卷積(反卷積上采樣并收縮通道+卷積通道收縮+卷積等通道特征提取)。
與FCN不同的是,UNet采取的是拼接(Concat)+進一步提取特征的特征融合方式,如上圖上采樣路徑最左側的藍色外框空白填充的方塊。相比粗暴的逐點相加,拼接更好的保留淺層的特征信息,但相對地也會增加計算的開銷。
為了保證拼接的正確性,淺層特征圖需要裁剪到目標尺寸,如上圖下采樣路徑最右側藍色方塊的虛線部分,這里通常采用的是中央裁剪。拼接后由于通道倍增,按照“特征圖尺寸倍增,通道減半;尺寸減半,通道倍增”的慣例,需要先用卷積把通道數收縮到原來的一半。
重疊切片的平鋪策略
UNet對大尺寸圖像分割任務采用了重疊切片的平鋪策略。
首先要注意到UNet與常規的網絡不同,所有的卷積和池化都不加以padding(為了2x2池化下采樣不加padding由不丟失信息,需要保證每次池化輸入的尺寸為2的倍數),于是每做一次卷積,特征圖都會稍微收縮一點點,這就導致了UNet的輸出尺寸小于輸入尺寸(如上圖,572x572的輸入最后出來只有392x392的掩膜)。
不padding意味著不引入無效信息,直觀上是有好處的;另外這相當于用一張更大的圖像來預測中央小區域的分割結果,相當于在分割的時候輸入了目標區域以外的外圍信息(如上圖,藍色框表示輸入UNet的圖像,最終只能產生黃色框部分的分割結果,實際在推理黃色框分割結果的時候也引用了黃色框以外藍色框以內的外圍信息的),這有助于提高模型的表現。
此外,UNet每步迭代采用單張圖片輸入,通過最大化輸入圖片尺寸來充分利用顯存,同時對優化器采取一個較大的動量(如0.99)使之前的迭代結果能對本次迭代產生較大的影響,以此穩定訓練過程。
加權損失懲罰邊緣像素
首先看一下softmax交叉熵:
為了著重某些特殊的像素點,可以賦予一個權重,此時損失函數改造為
而
其中,
是權衡分類為每個分類所設置的一個損失權重;
和也是人為設置的權重,如論文中推薦的
和分別代表當前像素點到最近和次近的細胞的歐式距離
將計算出來的可視化后可以得到上圖中的(d)
由于損失中對邊緣位置的像素作出的較重的懲罰,最終將鼓勵網絡在實例邊界做出較好的區分。
原文中還提到了對卷積參數采用標準差為的高斯分布初始化方式(如3x3卷積,輸入通道數為64,有),這種方式其實跟He Initialization也差不多。事實上自從BN層的出現之后,深度學習網絡對參數初始化也不再那么敏感。
變種和改進
UNet變種:《圖像分割的U-Net系列方法 | 知乎, taigw 》
UNet++:《研習U-Net | 知乎, 周縱葦 》
SegNet
論文:《SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation(TPAMI2016)》
參考:《SegNet圖像分割網絡直觀詳解 | 知乎, 郭冠華》
主要貢獻:用反池化替代反卷積進行上采樣,簡化上采樣過程,降低計算開銷
整體結構跟FCN和UNet其實差不多,主要差別在于上采樣的手段變成了反池化。
反池化上采樣
假設下采樣路徑采用的是最大池化,2x2池化操作如下圖所示:
每個滑窗只會采樣最大值作為輸出,反池化上采樣則是反過來,把一個像素值填到一個2x2的輸出框內,為了跟下采樣對應,需要在做最大值池化的時候記錄采樣點的索引(如總體框架圖上的Pooling Indices信息),反池化的時候則填到對應位置上的。其余三個像素點則直接填零,由后續的卷積層完成特征圖的平滑處理。
反池化有三個優點:
- 改善了邊緣輪廓的處理
- 減少參數數量和計算量
- 容易實現,可以很方便地應用到其他框架中
PSPNet
論文:《Pyramid Scene Parsing Network (CVPR2017)》
參考:《論文筆記:Pyramid Scene Parsing Network | 簡書, Efackw13》
《【圖像分割模型】多感受野的金字塔結構—PSPNet | 知乎, 言有三》
主要貢獻:
- 從場景解析實際任務中發現了關系失配、相似分類混淆、不顯眼物體難識別三個問題
- 在最后得到分割結果前,用混合尺度的池化獲取不同感知區域的局部信息,加強網絡對場景的感知
三個問題
作者在場景解析的實際任務當中發現FCN存在以下問題:
- 關系失配:比如在水面上識別出了汽車(如下圖第一行所示)
- 相似分類混淆:比如把摩天大樓內部的一部分像素識別成普通建筑(如下圖第二行所示)
- 不顯眼物體難識別:比如在床被上識別不出相似花紋的枕頭(如下圖第三行所示)
金字塔池化模塊(Pyramid Pooling Module)
為了解決上述三個問題,PSPNet提出了金字塔池化模塊,該模塊插入在輸出分割結果前的最后一個特征圖后邊。
首先由CNN提取出特征圖(PSPNet沒像FCN, UNet, SegNet一樣建立淺層到深層之間的跨層連接),然后經過不同的池化層下采樣出不同尺寸的特征圖(原文下采樣為1x1, 2x2, 3x3, 6x6四種特征圖),接著分別由卷積層將通道收縮為原來的1/N(原文中N=4)以保證拼接之后通道數與原來相同,由此得到不同尺寸的感知區域的局部信息。再將不同尺寸的局部信息上采樣為原來特征圖的尺寸但不改變通道數量(原文用雙線性插值來上采樣),與原始特征圖拼接起來,最后經過卷積層映射到目標空間得到分割結果。
以hszhao/PSPNet | github為例,用netron可視化后可以看到詳細的金字塔池化模塊及后續處理的結構:
輔助損失
除了最終的分割分類損失之外,PSPNet還在中間位置加入了輔助損失,如下圖所示,對ResNet第四階段的輸出特征圖提前取出并且上采樣到輸入圖片的尺寸,然后計算輔助損失loss2,并與主損失loss1加權求和后反傳。
如yassouali/pytorch_segmentation/trainer.py#L61 | github設置了權重為0.4;
用于計算loss2的特征圖的產生,具體也可以參見 yassouali/pytorch_segmentation/models/pspnet.py 的L65-L71和L90-L94
DeepLab
參考:《【語義分割系列:一】DeepLab v1 / v2 論文閱讀翻譯筆記 | CSDN, 鹿鹿最可愛》
《【語義分割系列:五】DeepLab v3 / v3+ 論文閱讀翻譯筆記 | CSDN, 鹿鹿最可愛》
《deeplab系列總結(deeplab v1& v2 & v3 & v3+) | CSDN, Dlyldxwl》
v1
論文:《Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFs (ICLR2015)》
主要貢獻:
- 結合CNN和PGM(概率圖模型)
- 使用空洞卷積替代標準卷積,在保持計算量的同時增大感受野
(為了與原文對應,以下討論均以VGG16為backbone)
_
兩個問題
- 典型的CNN隨著模型的深入需要逐漸下采樣,這就導致信號(特征圖)的分辨率逐漸減小;盡管可以通過減少下采樣實現,但卻帶來另一個問題,即感受野偏小;
- 分類任務要求空間不變性,即圖像經過空間變換(如旋轉、平移)后識別的類別不發生改變;而分割任務不同,像素的定位信息也至關重要,如果圖像經過空間變換,那么要求模型預測結果也要隨之改變
減少下采樣和使用空洞卷積
(緩解第一個問題)
按照常規利用分類網絡做backbone的方式,作者剝離掉VGG16最后的三層全連接,此時最后一層卷積層的輸出特征圖分辨率為7x7,與輸入的原始圖像分辨率224x224相比,已經下采樣了32倍,丟失了非常多的細節信息(原文中稱之為很sparse、不dense)。
為了保留更多的信息,作者將最后兩層池化的步長修改為1,也即取消了這兩個池化的下采樣功能,此時相當于只下采樣了8倍。但如上一小節所說,這樣就帶來新的感受野偏小的問題。
DeepLab使用空洞卷積(dilated convolution)來解決這個問題,同時節約了不少的計算量。關于空洞卷積的圖示和幾種卷積的比較可以參考 FCN的反卷積上采樣一節。
(“下采樣-標準卷積-上采樣”和“空洞卷積”的效果比較,圖源自v2)
(“標準卷積-下采樣”和“空洞卷積”特征圖尺寸變化示意,圖源自以ResNet為backbone的v3)
簡單來說,空洞卷積通過跳躍性地采樣,能以3x3的卷積核得到5x5、7x7等更大的等效感受野。
前述兩個取消下采樣功能的池化層之后的卷積層就換成了成空洞卷積。
緩解了第一個問題后,論文同時指出隨后的上采樣不再需要反卷積來恢復分辨率,直接雙線性插值就可以得到可觀的結果。訓練時直接對ground truth下采樣8倍,然后與改造后的VGG16輸出求交叉熵作為損失函數;預測時則直接雙線性插值得到分割的結果。
全連接條件隨機場后處理
(緩解第二個問題)
全連接條件隨機場(Fully Connected Conditional Random Field, Fully Connected CRF)
(上下兩行分別是softmax的輸入和輸出)
如上圖的 DCNN output 一列所示,經過層層的下采樣和上采樣,特征圖逐漸丟失部分信息,導致最終輸出的圖像顯得比較平滑。而分割任務希望分割的結果邊緣輪廓能夠比較清楚犀利,于是作者引入了全連接CRF對CNN的輸出結果進行后處理。
在傳統的圖像處理中,CRF通常用相鄰像素來設計能量函數,從而消除一些噪音,達到平滑處理的目的。然而在分割中,我們的目標是恢復局部信息而非進一步平滑處理。
因此作者借鑒了《Efficient Inference in Fully Connected CRFs with Gaussian Edge Potentials (NIPS2011)》全連接條件隨機場來實現分割結果的銳化處理。其能量函數為
其中
對于一元項來說,是CNN產生的像素點的概率分布;
對于二元項來說,
,這意味著每個像素點都會和全圖像的所有像素點建立聯系,也即“全連接”;
求和項里是加權的應用在像素特征上的高斯核函數,原文采用像素點值和位置構造核函數
這里包含兩項,第一項包含位置信息和值信息,后一項值考慮位置信息,兩者通過和加權;
而也是人工設置的超參數
融合多尺度信息進行預測
和FCN、UNet一樣,作者也嘗試從淺層抽取特征與深層融合完成最后的分割預測。
具體來說,在輸入圖片和中間池化結果(前四個池化層的輸出)上分別加兩層卷積(3x3+1x1)做特征提取和通道縮放映射,使得分割效果得到少量的提升,但這個提升明顯不如全連接CRF(兩者可以兼容使用)。
v2
論文:《DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs (CVPR2016)》
主要貢獻:對同一張特征圖使用不同dilation的空洞卷積,并用多孔空間金字塔池化下采樣到同一尺寸,以此融合多種感受野的特征信息。
多孔空間金字塔池化(Atrous Spatial Pyramid Pooling, ASPP)
思路很簡單,其實是何愷明的空間金字塔池化的一個演化。關于空間金字塔池化(SPP)的內容可以回顧《漫談池化層 - 空間金字塔池化 | Hey~YaHei!》,此處不再贅述。
(圖中rate指的就是我們常說的dilation,也即對輸入特征圖兩個采樣點的間隔,如標準卷積dilation=1)
v3
論文:《Rethinking Atrous Convolution for Semantic Image Segmentation (CVPR2017)》
主要貢獻:
- 歸納了四種常見的語義分割框架
- 改進了v2提出的ASSP
(原文以ResNet為backbone)
常見語義分割框架的比較
-
圖像金字塔
多尺度輸入,小尺度輸入響應語義,大尺度輸入響應細節,最后融合多個結果,多個模型之間可以共享部分底層特征;顯著缺點是模型冗余而龐大,推理慢開銷大,訓練麻煩 -
編碼器-解碼器
深層捕獲更加抽象的分類信息,輔之融合淺層特征恢復目標的細節尤其是空間信息 -
級聯空洞卷積
減少將采樣保持特征圖上的細節尤其是空間信息,利用空洞卷積擴大感受野 -
空間金字塔池化
用不同dilation的并行空洞卷積提取不同感受野下的特征,最后用ASSP下采樣到統一尺度進行特征融合
改進ASSP
- 去掉一個“dilation=24的3x3卷積”分支
- 增加一個“1x1的標準卷積”分支
- 增加一個“全局平均池化 + 1x1標準卷積 + 雙線性插值上采樣”分支
v3+
論文:《Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation (ECCV2018)》
主要貢獻:
- 借鑒編碼器-解碼器架構,額外融合中間特征提高最終的分割能力
- 引入深度可分離卷積
(原文以使用了深度可分離卷積的Xception為backbone)
額外融合中間特征
如圖,作者發現經過空間金字塔池化之后直接做一次八倍上采樣過于粗暴,于是借鑒了編碼器-解碼器架構的思路,在空間金字塔池化后的特征圖上采樣四倍之后,與從中間層抽離出特征相融合,再做一次四倍上采樣(注意編碼器部分比原始模型要多一層,所以與原輸入相比編碼器的輸出實際上下采樣了十六倍而非八倍,換句話v3+加深了網絡)
深度可分離卷積
可參考《漫談卷積層 - 高效卷積 | Hey~YaHei!》,此處不再贅述。
損失函數
參考:《圖像分割領域常見的loss fuction有哪一些? | 知乎, 小鋒子Shawn》
圖像增廣
工具:mdbloice/Augmentor支持在變換原圖的時候同步操作ground truth,很方便
審核編輯:符乾江
-
人工智能
+關注
關注
1791文章
46859瀏覽量
237576 -
深度學習
+關注
關注
73文章
5492瀏覽量
120977
發布評論請先 登錄
相關推薦
評論