一文詳解圖像分割基本方法(收藏版)
來源:投稿 作者:卷舒
編輯:學姐
上回我們了解了圖像分割的基本概念,今天就來學習一下圖像分割的基本方法。
輸入輸出
下面講解一下模型的輸入與輸出的形式。尤其是輸出。
輸入 (Input):RGB圖像 (height, width, 3) 或者灰度圖 (height, width, 1) 。第三個維度是通道數(shù),RGB圖像有三個通道,而灰度圖只有一個通道。在第一維再加一個batch size 就是 RGB 圖像 (batch_size, height, width, 3) / 灰度圖 (batch_size, height, width, 1)
輸出 (Output) :和我們處理分類任務的時候類似,我們通過為每個可能的類別創(chuàng)建一個輸出通道,并one-hot來編碼類別標簽,來表示target。如下圖所示。

通過采用每個深度方向像素向量的argmaxargmax,可以將預測折疊到一張分割圖中(如下圖所示)
注意:對于視覺清晰度,我標記了一個低分辨率預測圖。實際上,分段標簽分辨率應匹配原始輸入的分辨率。

我們可以很容易地檢查一個目標,把它覆蓋到觀察。

當我們覆蓋我們的target(或預測)的單個頻道時,我們將此稱為 mask,該 mask 照亮存在特定類的圖像的區(qū)域。
當我們不做argmaxargmax直接輸出target的時候,輸出的形狀應該是 (batch_size, num_class, height, width),每張圖片的每個通道的里是非0即1的one-hot向量 。
而當我們對target進行argmaxargmax后,輸出的形狀應該是跟輸入同一形狀 (batch_size, height, width)。
模型結構
這一節(jié)我們來簡要地了解一下用于圖像分割的最經(jīng)典的深度學習模型結構:編碼器/解碼器結構 (Encoder/Decoder structure)
全連接到1×1卷積
回想一下在分類任務當中的CNN網(wǎng)絡都是幾個卷積層和池化層組成,最后是幾個全連接層。然而一張圖片經(jīng)全連接層之后的輸出是個一維的向量。這對分類任務中,我們只需要知道圖片的內(nèi)容,而不關心其位置十分適用。如果想得到上面我我們想要的二維的輸出,那么我們就不能采用全連接層。在2014年發(fā)表的 Fully Convolutional Network 的論文認為,最終的全連接層可以被認為是做一個覆蓋整個區(qū)域的1x1卷積。即如下圖所示。

這里使用1×1的卷積替代全連接層還有一個好處:那就是輸入的圖片形狀不在固定了。由于全連接層的輸入必須固定形狀的,所以輸入模型的圖片一般都要先resize到固定的shape,而使用1×1卷積代替全連接層之后變不在存在這一問題。在推理的時候,不需要再對圖片進行resize,從而最好可能會導致輸出的圖片的失真。
這么一個不斷加深網(wǎng)絡并不斷增加通道數(shù)來提取淺層信息和深層特征的過程就是**編碼器 (Encoder)**。
上采樣
很明顯上方編碼器的輸出與我們想要的輸出還是存在一定的差距。我們想要的一個與原輸入同尺寸的輸出。如果我們直接用雙線性插值來進行上采樣,講encoder的輸出直接resize到原圖的大小,這可能會有一定的效果,但一定不是最理想的。
那么還有一張方法,每層我們設置一定數(shù)量的padding,只是用卷積層,取消所有池化層。這樣堆疊多個卷積層最后得到的輸出變能夠跟原圖保持同尺寸,輸出對應像素點的類別了。就如下圖所示一樣。

然而,我們知道,要想抽取出深層的特征,那么這個網(wǎng)絡就需要足夠的深,通道數(shù)足夠多。而由于所有的層都保留了原尺寸,所以他的計算量是極其巨大的。所以這種方法也沒有被廣泛使用。
最終我們還是采用了先通過編碼器將圖像的特征映射到高維空間,這之后再通過解碼器上采樣,將特征恢復到圖片的原尺寸。我們將上采樣的這一部分網(wǎng)絡叫做解碼器(Decoder)。
而上采樣主要采用的是一種可以學習參數(shù)的轉(zhuǎn)置卷積 (Transposed Convolution) /反卷積 (Deconvolution) 的非線性上采樣。
所以整個模型結構可以理解為是一個先下采樣再上采樣的過程,如下圖所示。

幾種上采樣 (upsample)方法
上采樣的幾種方法的名字很容易混淆,下面讓我們來一一濾清。
上采樣 (upsample) 主要有三種方法:轉(zhuǎn)置卷積 (Transpose Convolution)、上采樣 (unsampling)和反池化 (unpooling)。講到這里有兩個地方需要提前解釋清楚。
上采樣 (upsample) 是這些方法的總稱,而上采樣 (unsampling) 是一種具體的方法。主要一個是 ”up”,一個是 ”un”,所以這樣要將英文給寫出來。
這里的的轉(zhuǎn)置卷積 (Transpose Convolution) 還有很多名稱:反卷積 (Deconvolution)、逆卷積 (Inverse Convolution)、Upconvolution、Fractionally strided convolution、Backward strided convolution。最常用的是轉(zhuǎn)置卷積和反卷積這兩個名稱。這里我們主要使用轉(zhuǎn)置卷積這個名稱。
這一節(jié)將簡單介紹三種方法的區(qū)別,然后主要講解轉(zhuǎn)置卷積的原理,和輸出形狀的計算公式。
三種方法對比


圖(a)是反池化。在MaxPooling的時候會保留Pooling使用的最大值的索引,然后UnPooling的時候使用索引將輸入映射到feature map中,而其他位置全填0。
再對比圖(b),反池化和上采樣很明顯的差別就是沒有Pooling Indices這個輸入,而是直接將輸入特征擴充到feature map中
圖(c)是轉(zhuǎn)置卷積,通過有參數(shù)的卷積核將輸入特征映射到feature上,重復的地方會進行疊加。
轉(zhuǎn)置卷積原理
在這之前我們要先引入卷積矩陣 (Convolution Matrix) 這一概念。
卷積矩陣
首先讓我們來回顧一下卷積的操作過程。
給定輸入,卷積核
。大家可以計算一下卷積操作之后的輸出是什么。

大致是按下圖方式進行計算。

下圖是一個動畫演示,3×3的卷積核在4×4的藍色輸入上進行沒有padding 和單位stride的卷積操作,得到2×2的灰色輸出

最后的卷積計算結果應該是

那么卷積矩陣是什么呢?我們用另一種方式來表示卷積操作:
我們將3×3的卷積核的卷積運算表示成一個4×16的矩陣,如下圖所示。

每一行表示一次卷積操作。比如第一行:

就是由第一次卷積操作時卷積核在輸入中的映射拉直而來的。可以看到,沒有進行卷積計算的位置被補了零。
而后我們再將輸入拉直成一個列向量,如下圖所示,這樣通過卷積矩陣C與輸入向量I進行矩陣乘法,就能得到最后的輸出O了。即O=CI


卷積操作是將卷積矩陣與拉直的輸入進行矩陣乘法,即O=CI,那么反卷積不就是卷積的反向操作,希望對卷積操作的輸出進行反卷積操作,從而得到卷積操作的輸入嘛。
那么我們可以有如下公式推導:
所以我們只需要將卷積矩陣轉(zhuǎn)置一下就可以得到轉(zhuǎn)置卷積矩陣。
轉(zhuǎn)置卷積矩陣
即如下圖所示,轉(zhuǎn)置卷積操作即可從轉(zhuǎn)置卷積矩陣與拉直的輸入進行舉證乘法得到輸出。

注意:轉(zhuǎn)置卷積矩陣中的權值不必要來自于原始的卷積矩陣,重要的是這些權值的布局時從卷積矩陣中來的。同時,轉(zhuǎn)置卷積不保證恢復輸入卷積操作的輸入本身,而只是返回具有相同形狀的特征圖。
可以將卷積操作和轉(zhuǎn)置卷積操作理解成一個卷積核使用卷積矩陣進行正向操作或使用轉(zhuǎn)置卷積矩陣進行反向操作。
轉(zhuǎn)置卷積的輸出形狀計算
我們可以通過卷積來模擬轉(zhuǎn)置卷積。
如下左圖,3×3的卷積核在4×4的藍色輸入上進行沒有padding和單位stride的卷積操作,得到2×2的灰色輸出。
當反過來進行轉(zhuǎn)置卷積操作的時候,想由2×2的藍色輸入,通過3×3的卷積核轉(zhuǎn)置卷積得到4×4的輸出,那么就要對原輸入產(chǎn)生2×2的padding。這里的卷積核大小和stride都是保持不變的。如下右圖所示。


那么到底該如何控制轉(zhuǎn)置卷積輸出的形狀呢?下面會通過幾個栗子,來粗略推導一下轉(zhuǎn)置卷積輸出形狀的計算。
首先,分別表示卷積操作的輸入形狀、卷積核大小、stride(步長)大小、padding (填充)大小、輸出形狀。
分表表示轉(zhuǎn)置卷積操作的輸入形狀、卷積核大小、stride(步長)大小、padding(填充)大小、輸出形狀。
這里假設高寬的填充是相等的,不考慮不對稱填充情況。
No zero padding, unit strides, transposed?
這里的no zero padding指的是卷積操作的時候沒有填充的。示意動畫在上面給出。
這里,而
這里的都是固定的。為了能使轉(zhuǎn)置卷積的輸出與原卷積操作的輸入保持一致,就需要做
的填充。
則,當卷積操作是No zero padding, unit strides時,其對應的轉(zhuǎn)置卷積有如下公式:

Zero padding, unit strides, transposed?
前面是最簡單的卷積操作沒有填充的。那么我們卷積操作再加上padding會是什么樣呢?

這里可以看到,為了讓轉(zhuǎn)置卷積的輸出與卷積操作的輸入形狀相同,所以這里我們轉(zhuǎn)置卷積時的padding 減小了。


則,有如下公式:

No zero padding, non-unit strides,transposed
前面的考慮了卷積操作時采用了padding。那么卷積操作沒有padding,但不采用單位長度的stride又該怎么計算呢?




Zero padding, non-unit strides, transposed?
最后我們來考慮最復雜的情況:卷積輸入即使用了 padding,stride 也不是單位步長。
這樣我們就能過得到一個對各種情況較為普適的公式。



結合前面的兩種情況的公式,假設輸入i滿足i+2p-k是s的倍數(shù),則有以下公式:

有以上公式,基本可以應付轉(zhuǎn)置卷積的大部分的計算。如有任何疑問,歡迎討論,同時建議參考Dumoulin, Vincent, and Francesco Visin. "A guide to convolution arithmetic for deep learning." arXiv preprint arXiv:1603.07285 (2016).
此外,轉(zhuǎn)置卷積也有它的弊端:會產(chǎn)生棋盤效應。具體更詳細的解釋請參考:Odena, et al., "Deconvolution and Checkerboard Artifacts", Distill, 2016. http://doi.org/10.23915/distill.00003
Reference
Jeremy Jordan. “An overview of semantic image segmentation.” https://www.jeremyjordan.me/semantic-segmentation/
Fei-Fei Li & Justin Johnson & Serena Yeung. “CS231n: Deep Learning for Computer Vision.” (2017). Lecture11. http://cs231n.stanford.edu/slides/2017/cs231n_2017_lecture11.pdf
Sultana, Farhana, Abu Sufian, and Paramartha Dutta. "Evolution of image segmentation using deep convolutional neural network: a survey." Knowledge-Based Systems 201 (2020): 106062.
Kirillov, Alexander, et al. "Panoptic segmentation." Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2019.
Long, Jonathan, Evan Shelhamer, and Trevor Darrell. "Fully convolutional networks for semantic segmentation." Proceedings of the IEEE conference on computer vision and pattern recognition. ?2015.
Naoki, “Up-sampling with Transposed Convolution” https://naokishibuya.medium.com/up-sampling-with-transposed-convolution-9ae4f2df52d0
Dumoulin, Vincent, and Francesco Visin. "A guide to convolution arithmetic for deep learning." arXiv preprint arXiv:1603.07285 (2016).
vdumoulin, fvisin. “Convolution arithmetic” https://github.com/vdumoulin/conv_arithmetic
Odena, et al., "Deconvolution and Checkerboard Artifacts", Distill, 2016. http://doi.org/10.23915/distill.00003
關注【學姐帶你玩AI】公眾號
回復“500”獲取圖像分割論文資源
CVPR圖像分割方向論文回復“CVPR”獲取