FCN简单梳理
全卷積網絡(Fully Convolutional Network)將CNN應用到了圖像語義分割領域。圖像語義分割,就是對一張圖片上的所有像素點進行分類。
以往的CNN都是對整張圖片進行分類,不能識別圖片中特定部分的物體,而全卷積網絡是對一張圖片中的每個像素進行分類,以此達到對圖片特定部分進行分類的效果。
1 卷積化(convolutionalization)
卷積化
以往分類的網絡通常會在最后使用全連接層,將原來二維特征圖轉換成一維的固定長度的特征向量,這就丟失了空間信息,最后輸出一個特定長度的向量,表示輸入圖像屬于每一類的概率,以此作為分類的標簽。
比如將下圖輸入AlexNet,得到一個長度為1000的輸出向量,表示輸入圖像屬于每一類的概率, 其中在“tabby cat”這一類統計概率最高,所以分類標簽為“tabby cat”。
與傳統CNN在卷積層之后使用全連接層得到固定長度的特征向量進行分類(全連接層+softmax)不同,FCN可以接受任意尺寸的輸入圖像,然后通過反卷積層對最后一個卷積層的feature map進行上采樣, 使它恢復到輸入圖像相同的尺寸,從而可以對每個像素都產生了一個預測, 同時保留了原始輸入圖像中的空間信息, 最后在與輸入圖等大小的特征圖上對每個像素進行分類,逐像素地用softmax分類計算損失,相當于每個像素對應一個訓練樣本。
因為語義分割需要輸出整張圖片的分割圖,所以要求網絡中的特征圖至少是二維的,這樣才能通過上采樣還原到輸入圖片的同等大小。
這就需要替換掉全連接層,改換為卷積層,而這就是卷積化。
上面這幅圖展示了卷積化,具體來說,就是將最后仨全連接層替換為卷積層。
全連接層和卷積層的轉化
全連接層和卷積層唯一的不同就是卷積層中的神經元只與輸入數據中的一個局部區域連接,并且在卷積列中的神經元共享參數。
但是這兩類層的神經元都是計算點積,它們的函數形式是一樣的。因此,將此兩者相互轉化是可能的。
對于任意一個卷積層,都存在一個能實現和它一樣的前向傳播函數的全連接層。權重矩陣是一個巨大的矩陣,除了某些特定塊,其余部分都是零。而在其中大部分塊中,元素都是相等的。
任何全連接層都可以被轉化為卷積層。
假設一個 numout=4096 的全連接層,輸入數據體的尺寸是 7?7?512,這個全連接層可以被等效地看做一個 Kernel=7,P=0,S=1,numout=4096 的卷積層。
也就是將濾波器的尺寸設置為和輸入數據體的尺寸一致了,這個結果就和使用初始的那個全連接層一樣了。
全連接層轉化為卷積層:在兩種變換中,將全連接層轉化為卷積層在實際運用中更加有用。
假設卷積神經網絡的輸入是224x224x3的圖像,一系列的卷積層和下采樣層將圖像數據變為尺寸為 7x7x512 的數據體。AlexNet使用了兩個尺寸為4096的全連接層,最后一個有1000個神經元的全連接層用于計算分類評分。
我們可以將這3個全連接層中的任意一個轉化為卷積層:
第一個連接區域是[7x7x512]的全連接層,令其濾波器尺寸為Kernel=7,這樣輸出數據體就為[1x1x4096]了;
第二個全連接層,令其濾波器尺寸為Kernel=1,這樣輸出數據體為[1x1x4096];
最后一個全連接層也做類似的,令其Kernel=1,最終輸出為[1x1x1000]。
轉化的意義
這樣的變換每次都需要把全連接層的權重W重塑成卷積層的濾波器。
如果想讓卷積網絡在一張更大的輸入圖片上滑動,得到多個輸出,那么卷積層可以在單次前向傳播中完成全連接層幾次才能完成的操作。
假設想讓224×224的滑窗,以32的步長在384×384的圖片上滑動,將每個位置的特征都提取到網絡中,最后得到6×6個位置的類別得分。
如果224×224的輸入圖片經過卷積層和下采樣層之后得到了[7x7x512]的特征圖,那么,384×384的大圖片直接經過同樣的卷積層和下采樣層之后會得到[12x12x512]的特征。然后再經過上面由3個全連接層轉化得到的3個卷積層,最終得到[6x6x1000]的輸出((12 – 7)/1 + 1 = 6)。這個結果正是滑窗在原圖中6×6個位置的得分。
對于384×384的圖像,讓(含全連接層)的初始卷積神經網絡以32像素的步長獨立對圖像中的224×224塊進行多次評價,其效果和使用把全連接層變換為卷積層后的卷積神經網絡進行一次前向傳播是一樣的。
所以將全連接層轉換成卷積層會更簡便。
全卷積網絡稱謂的由來
FCN將傳統CNN中的全連接層轉化成卷積層,對應CNN網絡FCN把最后三層全連接層轉換成為三層卷積層。
在傳統的CNN結構中,前5層是卷積層,第6層和第7層分別是一個長度為4096的一維向量,第8層是長度為1000的一維向量,分別對應1000個不同類別的概率。
FCN將這3層轉換為卷積層,卷積核的大小 (通道數,寬,高) 分別為 (4096,1,1)、(4096,1,1)、(1000,1,1)。看上去數字上并沒有什么差別,但是卷積跟全連接是不一樣的概念和計算過程,使用的是之前CNN已經訓練好的權值和偏置,但是不一樣的在于權值和偏置是有自己的范圍,屬于自己的一個卷積核。因此FCN網絡中所有的層都是卷積層,故稱為全卷積網絡。
下圖是一個全卷積層,與上圖不一樣的是圖像對應的大小下標,CNN中輸入的圖像大小是同意固定resize成 227x227 大小的圖像,第一層pooling后為55x55,第二層pooling后圖像大小為27x27,第五層pooling后的圖像大小為13*13。
而FCN輸入的圖像是H*W大小,第一層pooling后變為原圖大小的1/4,第二層變為原圖大小的1/8,第五層變為原圖大小的1/16,第八層變為原圖大小的1/32。
經過多次卷積和pooling以后,得到的圖像越來越小,分辨率越來越低。其中圖像到 H/32?W/32 的時候圖片是最小的一層時,所產生圖叫做heatmap熱圖,熱圖就是我們最重要的高維特征圖,得到高維特征的heatmap之后就是最重要的一步也是最后的一步對原圖像進行upsampling,把圖像進行放大、放大、放大到原圖像的大小。
最后的輸出是1000張(因為有1000類)heatmap經過上采樣得來的圖片。
接著就是對每個像素進行分類預測:逐像素地求其在1000張圖像該像素位置的最大數值描述(概率),并將其作為該像素的分類。
這樣就產生了一張已經分類好的圖片,如下圖。
2 反卷積(Deconvolution)
可能叫做轉置卷積(Transposed Convolution)更為合適。
反卷積過程可以理解為上采樣過程(Upsampling)。
以往的CNN結構,如AlexNet,VGGNet,池化層縮小了特征圖的尺寸。
在語義分割中,我們需要輸出和輸入圖像尺寸相同的分割圖片,因此需要對特征圖進行上采樣。
反卷積是卷積的逆過程,先看一下Caffe中的卷積操作,分為兩個步驟:
使用im2col操作將圖片轉換為矩陣
調用GEMM計算實際的結果
舉例說明:
4x4的輸入,卷積Kernel為3x3, Padding為0,Stride為1, 輸出為2x2。
輸入矩陣可展開為16維向量,記作x;
輸出矩陣可展開為4維向量,記作y;
卷積運算可表示為y=Cx;
其中,C就是如下的稀疏矩陣:
神經網絡的正向傳播就是轉換成了如上矩陣進行運算。
接著是反向傳播。
首先有了從更深層的網絡中得到的?Loss?y
根據矩陣微分公式
?Ax+b?x=AT
可推得?Loss?x=?Loss?y??y?x=CT?Loss?y
?
這就是反向傳播時的矩陣運算。
而反卷積運算和卷積運算在神經網絡的正向和反向傳播剛好相反。
所以反卷積其實就是正向時左乘CT,而反向時左乘(CT)T,即C的運算。
注意:
為了得到和輸入圖像尺寸完全相同的特征圖,FCN中還使用了crop操作來輔助反卷積操作,因為反卷積操作并不是將特征圖恰好放大整數倍。
3 跳躍結構(Skip Architecture)
經過前兩步操作,基本就能實現語義分割了,但是直接將全卷積后的結果進行反卷積,得到的結果往往比較粗糙。
如上圖所示,對原圖像進行卷積conv1、pool1后原圖像縮小為1/2;之后對圖像進行第二次conv2、pool2后圖像縮小為1/4;接著繼續對圖像進行第三次卷積操作conv3、pool3縮小為原圖像的1/8,此時保留pool3的featureMap;接著繼續對圖像進行第四次卷積操作conv4、pool4,縮小為原圖像的1/16,保留pool4的featureMap;最后對圖像進行第五次卷積操作conv5、pool5,縮小為原圖像的1/32,然后把原來CNN操作中的全連接變成卷積操作conv6、conv7,圖像的featureMap數量改變但是圖像大小依然為原圖的1/32,此時圖像不再叫featureMap而是叫heatMap。
現在我們有1/32尺寸的heatMap,1/16尺寸的featureMap和1/8尺寸的featureMap,1/32尺寸的heatMap進行upsampling操作之后,因為這樣的操作還原的圖片僅僅是conv5中的卷積核中的特征,限于精度問題不能夠很好地還原圖像當中的特征,因此在這里向前迭代。把conv4中的卷積核對上一次upsampling之后的圖進行反卷積補充細節(相當于一個插值過程),最后把conv3中的卷積核對剛才upsampling之后的圖像進行再次反卷積補充細節,最后就完成了整個圖像的還原。
具體來說,就是將不同池化層的結果進行上采樣,然后結合這些結果來優化輸出,具體結構如下:
而不同的結構產生的結果對比如下:
總結
- 上一篇: FCN 学习: Semantic Seg
- 下一篇: 从特斯拉到计算机视觉之「图像语义分割」