天天看點

使用深度學習做語義分割:簡介和代碼

本文為 AI 研習社編譯的技術部落格,原标題 :

Semantic Segmentation with Deep Learning: A guide and code

翻譯 | 小豬咪 校對 | Lamaric 整理 | 孔令雙

原文連結:

https://towardsdatascience.com/semantic-segmentation-with-deep-learning-a-guide-and-code-e52fc8958823

什麼是語義分割?

大多數深度學習和計算機視覺大家庭中的人都知道什麼是圖像分類:我們想讓我們的模型告訴我們,圖檔中存在的單個物體或場景是什麼。分類是一種非常模糊和高層次的任務。

很多人同樣對目标檢測很熟悉:我們嘗試定位和分類圖像中的多個物體,手段就是在它們周圍畫出範圍框,并對框内的東西進行分類。檢測是一種中層次的任務,我們可以得到一些很有用的細節資訊,但由于我們隻是畫出檢測框而沒有得到物體的準确形狀,是以還是略顯粗糙。

語義分割是這三者中資訊量最大的,我們對圖檔中的每一個像素都進行分類,就像你在上方的動态圖中看到的那樣!最近幾年,這些完全是基于深度學習完成的。

在這篇簡介中,你将會學到語義分割模型的基本結構和功能,以及最新最棒的高水準成果。

如果你想要自己試一試這些模型,你可以登陸我的語義分割程式組,對于很多這篇指南中出現的模型,那裡有我用 TensorFlow 實作的訓練和測試!

GeorgeSeif/Semantic-Segmentation-Suite

Semantic Segmentation Suite in TensorFlow. Implement, train, and test new Semantic Segmentation models easily! …github.com

基本結構

我将要向你展示的語義分割模型的基本結構在所有的頂尖工作中都存在。這使得實作不同的模型變得異常簡單,因為他們幾乎全部都有着相同的骨架、構造方法和構造流程。

U-Net 模型可以對這個結構給出很好的闡釋。模型左側表示了任何訓練出來可為圖檔分類任務提取特征的網絡。包括了VGGNet, ResNets, DenseNets, MobileNets,和 NASNets!這裡你幾乎可以用任何你想用的結構。在選擇你的用以特征提取的分類網絡時,你心中的主要參考名額是網絡的均衡。使用一個很深的 ResNet152 可以為你提供很高的準确度,速度卻不及 MobileNet。這些在圖像分類任務中出現的折衷因素在語義分割中同樣存在。你需要記住一個重要的事實:這些骨架将是你設計/選擇你的語義分割網絡時的主要驅動力,我再強調也不為過。

使用深度學習做語義分割:簡介和代碼

用于語義分割的 U-Net

特征被提取出來後将在不同的大小被處理,原因有二。首先,你的模型很可能遇到很多不同大小的物體;在不同的尺寸中處理特征圖将賦予網絡處理不同大小物體的能力。

第二點,當進行語義分割時有一點需要權衡折衷之處。如果你想得到好的分類準确度,你必須處理深層網絡中那些高層級的特征資訊,因為它們更有辨識度并包含更多對語義分割有用的資訊。但另一方面,如果你隻采用深層特征,你的定位将會變得很糟,因為此時的分辨率太低了!

最近的高水準工作都利用了上述特征提取結構并和多尺度處理技術,是以很多都很容易實作以及端到端地訓練。你的選擇将基于你對準确度和速度/記憶體的需求,其實這些工作也全部都在尋找新的方法,希望在保留效率的基礎上改善這種折衷。

接下來在對前沿工作的介紹中,我将主要關注最新的方法,因為在了解了上述基本結構後,這些方法可能對于大多數讀者來說是最有幫助的。我們将會大緻以時間順序闡述,這也大緻反映了前沿工作這些年來逐漸發展改進的情況。

前沿概覽

全分辨率殘差網絡(FRRN)

FRRN 模型是多尺度處理技術中一個很典型的案例。它借助兩條分立的流來完成:殘差流和池化流。

我們希望在處理語義特征時獲得更高的分類準确度,是以 FRRN 在池化流中對特征圖進行處理和下采樣。同時,在殘差流中以全分辨率處理特征圖。是以池化流負責處理高層的語義資訊(為了更高的分類準确度),殘差流處理低層像素資訊(為了更高的定位準确度)!

既然我們希望端到端地訓練網絡,我們就不希望兩條流間完全沒有聯系。是以在每次最大池化後,FRRN 會對來自雙流的特征圖進行一些融合操作來結合他們的資訊。

使用深度學習做語義分割:簡介和代碼

FRRN 的模型結構

金字塔場景解析網絡(PSPNet)

FRRN 在直接施加多尺度處理方面做出了很好的工作。但是在每一種尺寸上做複雜處理的計算複雜度很高。以及 FRRN 的一些過程是在全像素下施加的,本身就是一種很慢的工作。

PSPNet 提出了一種巧妙的辦法來規避這個問題,就是利用多尺度池化。它會從一個标準的特征提取網絡(如 ResNet,DenseNet 等)開始,從第三個下采樣後提取出特征進行進一步計算。

為了得到多尺度資訊,PSPNet 應用了四種不同的最大池化操作,通過四種不同的視窗和步長尺寸。這高效地從四種不同的尺度中獲得了特征資訊而無需為它們每個都進行單獨運算。我們隻需要在每個後面做一次輕量級的卷積,上采樣,這樣每個特征圖都有同樣的分辨率了,之後将它們拼合起來就可以了。

瞧!我們沒有做任何卷積就把多尺度的特征圖結合起來了。

所有這些都是在低像素的特征圖上提高速度的手段。最後,我們利用雙線性內插補點法把輸出的語義分割圖放大到想要的大小。這種在所有的步驟之後施加的放大手法存在于很多先進工作中。

使用深度學習做語義分割:簡介和代碼

PSPNet 的模型結構

一百層的提拉米蘇(FCDenseNet)

如果有一種深度學習帶來的極好的趨勢,那就是優秀的論文名字一百層提拉米蘇 FCDenseNet (聽起來就很美味)使用了一張和我們之前看到的 U-Net 相似的結構。它主要的貢獻是對密集連接配接的巧妙運用,和 DenseNet 分類模型有異曲同工之妙。

這真是強調了計算機視覺領域越來越強的導向:前端的特征提取是任何其他任務想要效果好的核心骨架。是以,如果想要提高準确率,首先要考慮的就是前端的特征提取。

使用深度學習做語義分割:簡介和代碼

FCDenseNet 模型結構

帶孔卷積核的再思考(DeepLabV3)

DeepLabV3 是另一種無需加設系數的多尺度處理方法。

這個模型十分輕量級。我們再次從一個特征提取前端開始,從第四次下采樣後的特征入手處理。現在的分辨率已經很低(比輸入圖檔小了16倍)是以我們就從這裡入手就很好!不太好的一點是,在這樣一種低分辨率的情況下,由于像素的低準确度,很難得到很好的定位。

這就是展現 DeepLabV3 的突出貢獻之處了,對多孔卷積的巧妙運用。普通的卷積隻能處理局部資訊,因為權值總是一個挨着一個。例如,在一個标準的3*3卷積中,兩個權重值之間的距離隻有一個步長/像素。

有了多孔卷積,我們可以直接增加卷積權重值之間的空間,而實際上在操作中不增權重重值的總數。是以我們仍然隻有3*3也就是9個為參數總量,我們隻是把它們分布得更開了。我們把每個權重值間的距離稱作擴張率。下面的模型圖解很好的闡釋了這個思想。

當我們使用一種低擴張率時,我們會得到非常局部/低尺度的資訊。當我們采用高擴張率時,我們會處理到更多全局/高尺度的資訊。是以 DeepLabV3 模型融合了不同擴張率的多孔卷積來擷取多尺度資訊。

和 PSPNet 中解釋過的解釋過的處理手法類似,在最後也會有一步尺度提升的過程。

使用深度學習做語義分割:簡介和代碼

DeepLabV3 模型結構

多路徑細化網絡(RefineNet)

之前我們看到了 FRRN 結構是如何在結合多尺度分辨率資訊時發揮巨大作用的。它的缺點是在處理高分辨率時計算量巨大,我們還需要把那些特征和低分辨率的特征結合!

是以 RefineNet 模型提出我們不需要這樣做。當我們把圖檔送入特征提取網絡後,在每一次下采樣後我們自然而然地會得到多尺度的特征圖。

細化網絡之後采用自底而上的方式對這些多分辨率特征圖進行處理以結合多尺度資訊。首先,每張特征圖會被獨立處理。然後當我們升尺度的時候我們會把高/低分辨率的結合起來,對它們同時進行一些處理。是以,我們的多尺度特征圖既是獨立也是共同處理的。整個流程從左至右呈現在下面的圖解中。

和 PSPNet 中解釋過的解釋過的處理手法類似,在最後也會有一步尺度提升的過程。

使用深度學習做語義分割:簡介和代碼

RefineNet 模型的結構

大卷積核的情況(GCN)

之前我們看到了 DeepLabV3 模型是如何運用不同步長的多孔卷積來捕捉多尺度資訊的。但問題是我們一次隻能處理一個尺寸,之後還要把它們結合起來。比如說一個擴張率為16的多孔卷積與更小的擴張率相比,在語義分割時就不能很好地處理局部資訊。

是以在之前的方法中,實際上多尺度的處理是先獨立、後整合的。如果我們同時關注多尺度的資訊,将會更有意義。

為了完成這個想法, Global Convolutional Network (GCN) 機智地提出采用大型一維卷積核而不是方形的。如果用如3*3,7*7的卷積核,我們不能把它們做得太大,否則就需要很大的計算速度和記憶體的小号。一維卷積核就很高效了,我們可以做得很大而不拖慢網絡太多。這篇文章甚至做到了15的大小。

一件重要的事情是你一定要做的,就是橫縱卷積的平衡。此外,這篇文章還是用了小型的3*3卷積核作為優化,以防一維卷積會遺漏什麼資訊。

GCN 和前面的工作一樣,從前端特征提取網絡中處理不同尺度的資訊。由于一維卷積的高效率, GCN 連全像素的層數都處理到了,而不是停留在低像素的層上最後再升尺度。這對于提升尺度後的語義分割的結果提供了很好的細化,而避免了由于停留在低分辨率而可能導緻的瓶頸問題。

使用深度學習做語義分割:簡介和代碼

GCN 模型的結構。

DeepLabV3+

DeepLabV3+ 模型就像它名字所說的那樣,是 DeepLabV3 的一個快速延伸,借用了它之前工作的一些優勢。如我們之前看到的那樣,如果我們僅僅在最後利用雙線性內插補點升尺度的話就會遇到潛在的瓶頸。事實上,原來的 DeepLabV3 在最後把尺度放大了16倍!

為了處理這件事, DeepLabV3+ 在 DeepLabV3 上加入了中間的解碼子產品,通過 DeepLabV3 處理後,首先特征圖會被放大4倍。之後它們會和前端特征提取的原特征圖一起處理,之後再放大4倍。這減輕了後端網絡的負擔,并提供了一條從前端特征提取到網絡後面部分的捷徑。

使用深度學習做語義分割:簡介和代碼

DeepLabV3+ 模型結構

CVPR 和 ECCV 2018

我們在以上部分說的網絡結構代表了你在語義分割領域需要知道的大部分技巧!今年在計算機會議裡發表的工作隻有些微新意和準确度上很小的提升,并沒有特别關鍵而值得說明的地方。為了叙述的完整和徹底性,我把他們的工作在這裡為可能有興趣的讀者整理出了一個快速的回顧清單。

Image Cascade Network (ICNet) —使用了深度監督,并在不同尺度上處理輸入圖檔,每一個尺度都有自己的子網絡,最後逐漸合并結果。 

Discriminative Feature Network (DFN) — 使用了深度監督,并嘗試着把分割區域的邊緣和内部區域分開處理。

DenseASPP — 結合了多孔卷積的密集連接配接。

Context Encoding —利用全局環境增加準确度 ,通過加入了一個通道注意力子產品,并基于一個新設計的損失函數把觸發注意力放在特定的特征圖上。損失函數是基于網絡中判斷哪個類别存在的這一部分分支設計的(比如高層級的全局内容)。

Dense Decoder Shortcut Connections — 在解碼階段使用了密集連接配接以達到更高的準确度(之前僅在特征提取/編碼階段使用)。

Bilateral Segmentation Network (BiSeNet) — 有兩個分支:一個為了得到語義資訊而很深,一個為了儲存低層級的像素資訊而僅對輸入進行了很少的操作。

ExFuse — 使用了深度監督,特别是把從前端特征提取中得到的多尺度特征結合起來之後進行處理,這是為了保證多尺度資訊可以在同等程度上一起處理。

使用深度學習做語義分割:簡介和代碼

ICNet 模型結構

長話短說:如何做語義分割

  • 要明白分類網絡的折衷效果。你的分類網絡是你特征提取的主要驅動,而最終效果中大多數的得失源自于此。
  • 分尺度處理并把資訊融合。
  • 多尺度池化、多孔卷積和大型一維卷積都對語義分割有益。
  • 你無需在高分辨率上做很多的處理步驟,為了速度起見把大多數步驟放在低分辨率上吧,之後再提升尺度,如果有必要的話在最後再進行一些輕量級的處理。
  • 深度監督可以提升一點準确率(雖然建立起訓練變得更加棘手了)