图像目标分割_2 FCN(Fully Convolutional Networks for Semantic Segmentation)
6.2.1 FCN 背景介紹
圖像語義分割:給定一張圖片,對圖片上每一個像素點進行分類!但是與圖像分類目的不同,語義分割模型要具有像素級的密集預測能力才可以。
6.2.2 FCN介紹
6.2.2.1 全卷積網絡
全卷積網絡,模型由卷積層、池化層組成(沒有全連接層),可以接受任意大小的輸入,網絡的示意圖如下
過程:輸入一張圖片,網絡由淺到深,隨著卷積層和池化層不斷作用,產生的特征圖分辨率越來越小,但是通道數會越來越多。最后通過逐層上采樣得到一個和輸入形狀一樣的結果。
- 輸入可為任意尺寸圖像彩色圖像;輸出與輸入尺寸相同,深度為:20類目標+背景=21(VOC分類)
1、結構修改,保證任意圖像對應輸入輸出
典型的識別網絡,包括LeNet、AlexNet,表面上采用固定大小的輸入并產生非空間輸出。 這些網全連接的層具有固定的尺寸并丟棄空間坐標。 然而,這些完全連接的層也可以被視為與覆蓋整個輸入區域的內核的卷積。
一般圖像分類CNN網絡在最后一層卷積層后會跟若干個全連接層, 將卷積層產生的特征圖映射成一個固定長度的特征向量。論文中的例子:輸入一張貓的圖片, 經過CNN網絡, 得到一個長為1000的輸出向量, 這個向量經過softmax歸一化,分別對應1000個類別的概率,這樣我們可以得到輸入圖像屬于每一類的概率, 在下例中我們可以看出圖像屬于"tabby cat"這一類可能性最大。
這篇論文里面是將全連接層轉化為卷積層。上圖中我們可以看出FCN將最后3層轉換為卷積層,卷積核的大小(通道數,寬,高)分別為(4096,1,1)、(4096,1,1)、(1000,1,1)。
全連接層怎么轉成卷積層:拿上圖為例,最后一層卷積層的輸出為7 x 7 x 256 。后面再接三個全連接層變為(1,4096),(1,4096),(1,1000)(一維向量)。我們可以把這三個全連接層變為卷積層。
變換方式:
-
針對FC1 ,選卷積核K=7卷積,輸出為1 x 1 x 4096。
-
針對FC2,選卷積核K=1卷積,輸出為1 x 1 x 4096。
-
對最后一個FC3,選卷積核k=1卷積,輸出為1x1x1000。
這樣轉換后的網絡輸出的就是一個熱力圖 ,這個圖明顯二維的。這樣轉換后的網絡輸出的就是一個熱力圖 ,這個圖明顯二維的。
2、上采樣得到預測映射(dense prediction)的策略
我們可以看出
- 1、對原圖像進行卷積conv1, pool1后原圖像縮小為1/2;
- 2、之后對圖像進行第二次conv2,pool2后圖像縮小為1/4;
- 3、對圖像進行第三次卷積操作conv2,pool3縮小為原圖像的1/8, 此時保留pool3的feature map;
- 4、繼續對圖像進行第四次卷積操作conv4,pool4,縮小為原圖像的1/16,保留 pool4的feature map;
- 5、最后對圖像進行第五次卷積操作conv5,pool5,縮小為原圖像的1/32
- 6、然后把原來CNN操作中的全連接變成卷積操作 conv6,圖像的feature map 數量改變但是圖像大小依然為原圖的1/32,此時圖像heatmap(熱力圖)。
最后的輸出是1000張heatmap經過upsampling變為原圖大小的圖片,為了對每個像素進行分類預測label成最后已經進行語義分割的圖像
論文作者研究過3種方案實現dense prediction:反卷積法以及(移針法(shift-and-stitch)、稀疏濾波(filter rarefaction))
(1)反卷積法(deconvolutional)
注:反卷積(Deconvolution),當然關于這個名字不同框架不同,Caffe和Kera里叫Deconvolution,而tensorflow里叫Conv2DTranspose。叫conv_transpose更為合適。
-
反卷積(轉置卷積):反卷積是一種特殊的正向卷積,先按照一定的比例通過補0來擴大輸入圖像的尺寸,接著卷積核卷積,再進行正向卷積。
- 1、先進行上采樣,即擴大像素;再進行卷積
-
卷基的forward、backward操作對調,就是轉置卷積。
-
卷積與轉置卷積的本質就是進行了矩陣運算,從矩陣角度理解
理解:然后把普通卷積的輸出作為轉置卷積的輸入,而轉置卷積的輸出,就是普通卷積的輸入,常用于CNN中對特征圖進行上采樣,比如語義分割和超分辨率任務中。
- 卷積與轉置卷積的可視化計算過程
- 參考:https://github.com/vdumoulin/conv_arithmetic
公式:設反卷積的輸入是n * n,
反卷積的輸出為m*m,?padding=p,stride=spadding=p,stride=s?。
那么此時反卷積的輸出就為:m = s(n-1) + k -2p,反過來就是n = (m+2p -k)/s + 1
例子理解:
下圖中藍色是反卷積層的input,綠色是反卷積層的output,元素內和外圈都補0的轉置卷積。
舉個例子:選擇一個輸入input尺寸為?3 ,卷積核kernel 尺寸?3,步長strides=2,填充padding=1 ,即n=3,k=3,s=2,p=1,則輸出output的尺寸為m=2x(3-1) +3=5 。
問題:怎么使反卷積的output大小和輸入圖片大小一致,從而得到pixel level prediction?
因為FCN里面全部都是卷積層(pooling也看成卷積),卷積層不關心input的大小,inputsize和outputsize之間存在線性關系。
假設圖片輸入為n×n大小,第一個卷積層輸出map就為conv1_out.size=(n-kernelsize)/stride + 1,記做conv1_out.size = f(n), 依次類推,conv5_out.size = f(conv5_in.size) = f(... f(n)), 反卷積是要使n = f‘(conv5_out.size)成立,要確定f’,就需要設置deconvolution層的kernelsize,stride,padding。
TensorFlow 中tf.keras.layers.Conv2DTranspose
tf.keras.layers.Conv2DTranspose(filters, kernel_size, strides=(1, 1), padding='valid', output_padding=None,data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True,kernel_initializer='glorot_uniform', bias_initializer='zeros',kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None,kernel_constraint=None, bias_constraint=None, **kwargs )參數: 1、filters:整數,輸出空間的維數(即卷積中輸出過濾器的數量)。 2、kernel_size:2個整數的整數或元組/列表,指定2D卷積窗口的高度和寬度。可以是單個整數,以為所有空間尺寸指定相同的值。 4、strides:一個整數或2個整數的元組/列表,指定沿高度和寬度的卷積步幅。可以是單個整數,以為所有空間尺寸指定相同的值。指定任何跨步值!= 1與指定任何dilation_rate值!= 1 不兼容。 5、padding:"valid"或之一"same"(不區分大小寫)。 6、output_padding:一個整數或2個整數的元組/列表,指定沿輸出張量的高度和寬度的填充量。可以是單個整數,以為所有空間尺寸指定相同的值。沿給定尺寸的輸出填充量必須小于沿相同尺寸的步幅。如果設置為None(默認),則推斷輸出形狀。 7、data_format:字符串,channels_last(默認)或之一channels_first。輸入中尺寸的順序。 8、channels_last對應于具有形狀的輸入, (batch, height, width, channels)而channels_first 對應于具有形狀的輸入 (batch, channels, height, width)。默認為image_data_format在Keras配置文件中找到的值~/.keras/keras.json。如果您從未設置,那么它將是“ channels_last”。 9、dilation_rate:一個整數或2個整數的元組/列表,指定用于擴張卷積的擴張率。可以是單個整數,以為所有空間尺寸指定相同的值。當前,指定任何dilation_rate值!= 1與指定任何步幅值!= 1不兼容。 10、activation:要使用的激活功能。如果您未指定任何內容,則不會應用任何激活(即“線性”激活:)a(x) = x。 11、use_bias:布爾值,層是否使用偏置向量。 12、kernel_initializer:kernel權重矩陣的初始化程序。 13、bias_initializer:偏置矢量的初始化器。其他方法如下:
(2)移針法(shift-and-stitch)
對于移針法,設原圖與FCN所得輸出圖之間的降采樣因子是f,那么對于原圖的每個f的區域(不重疊),“shift the input x pixels to the right and y pixels down for every (x,y) ,0 < x,y < f." 把這個f區域對應的output作為此時區域中心點像素對應的output,這樣就對每個f的區域得到了f^2個output,也就是每個像素都能對應一個output,所以成為了dense prediction。(3)稀疏濾波
就是放大CNN網絡中的下采樣層的濾波器尺寸,得到新的濾波方法。
其中s是下采樣的滑動步長,這個新濾波器的滑動步長要設為1,這樣的話,下采樣就沒有縮小圖像尺寸,最后可以得到dense prediction。
以上兩種方法作者都沒有采用,主要是因為這兩種方法都是經過折中(trade-off)的。
-
對于移針法, 下采樣的功能被減弱,使得更細節的信息能被filter看到,但是其感受野會相對變小,可能會損失全局信息,且會對卷積層引入更多運算。
-
對于稀疏濾波,雖然receptive fileds沒有變小,但是由于原圖被劃分成f*f的區域輸入網絡,使得filters無法感受更精細的信息。
6.2.2.2 skip layers實現fusion prediction
作者在試驗中發現,得到的分割結果比較粗糙,所以考慮加入更多前層的細節信息,也就是把倒數第幾層的輸出和最后的輸出做一個fusion,實際上也就是加和,過程如下,一共有三種方式:
- 第一種方法對所得特征圖像直接進行32倍的上采樣,被稱為FCN-32s,處理方法簡單迅速,但是其采樣預測結果的邊緣信息比較模糊,無法表現得更具體。
- 第二種方法提出了層跨越(skip layers)的思路,即特征圖像進行2倍的上采樣后,將其結果與第四層池化操作后的結果相迭加,之后再對結果進行16倍上采樣,最終獲得采樣預測,即FCN-16s。
- 其將低層的fine layer與高層的coarse layer進行結合,兼顧了局部信息與全局信息,對像素的空間判別與語義判別進行了很好的折中處理。相較FCN-32s,FCN-16s所獲得的采樣預測不管是從預測結果還是網絡結構來說顯然都更加優秀。
- 第三種方法則是在FCN-16s的基礎上,進行了與第三層池化操作后的結果相迭加,再對結果進行8倍上采樣的FCN-8s。顯然,其生成的語義標簽圖像是三種情況中最好的。?
最終:在逐層fusion的過程中,做到第三層再往下,結果又會變差,所以作者做到這里就停了。
6.2.2.3 patch-wise training in FCN?
1、損失計算
upsample之后,網絡輸出是與origin image大小相同,channel數為C+1的每個pixel的分類預測,其中C表示分類數量(如Pascal voc數據集,則C=20),對空間每個pixel 做softmax分類預測,那么易知損失函數為。
其中x為最后一層的輸出(3-D),記origin image 大小為h x w,那么x大小為(C+1) x h x w。每個pixel都是一個softmax 分類預測。
2、訓練
一般對于語義分割的訓練,學術界有兩種辦法: Patchwise training 和類別損失加權的方法來進行訓練。
- 類別損失加權: 根據類別數量的分布比例對各自的損失函數進行加權,比如有些樣本的數量較少,我就給它的損失函數比重增大一些。
- 分批訓練: 旨在避免完整圖像訓練的冗余。
- 定義:patchwise training是指對每一個感興趣的像素,以它為中心取一個patch,然后輸入網絡,輸出則為該像素的標簽,訓練時就將一個個patch組成一個batch作為網絡輸入。由于patches可能高度重疊,所以需要一些sampling方法對選取一些patches作為訓練集
- 避免完全圖像訓練的冗余,在語義分割中,假設你在對圖像中的每個像素進行分類,通過使用整個圖像,你在輸入中添加了大量的冗余。在訓練分割網絡中避免這種情況的一種標準方法是從訓練集而不是完整的圖像中向網絡提供批量的隨機patches(圍繞感興趣的對象的小圖像區域)。
- 從另一種角度出發,我們也可以使得這些補丁區域盡量減少背景信息,從而緩解類別不均衡問題。
作者根據實驗結果給出結論:補丁式訓練完全沒有必要,訓練 FCN 還是輸入整張圖片比較好。并且解決這種類別不均衡的問題,只需要給損失函數按比例加權重就行。
6.2.2.4 訓練細節
- 第一階段
以經典的分類網絡為初始化。最后兩級是全連接(紅色),參數棄去不用。
- 第二階段
從特征小圖(16x16x4096)預測分割小圖(161621),之后直接升采樣為大圖。 反卷積(橙色)的步長為32,這個網絡稱為FCN-32s。 這一階段作者使用單GPU訓練約需3天。
- 第三階段
上采樣分為兩次完成(橙色×2)。 在第二次上采樣前,把第4個pooling層(綠色)的預測結果(藍色)融合進來。使用跳級結構提升精確性。 第二次反卷積步長為16,這個網絡稱為FCN-16s。 這一階段作者使用單GPU訓練約需1天。
- 第四階段
上采樣分為三次完成(橙色×3)。 進一步融合了第3個pooling層的預測結果。 第三次反卷積步長為8,記為FCN-8s。 這一階段作者使用單GPU訓練約需1天。
- 論文中優化利用momentum訓練了GSD。 對于FCN-AlexNet,FCN-VGG16和FCN-GoogLeNet,使用20個圖像的小批量大小和0.001,0.0001和0.00005的固定學習速率。
通過反向傳播通過整個網絡對所有層進行微調。 考慮到學習基本分類網絡所需的時間,單獨對輸出分類器單獨進行微調只能獲得完整微調性能的70%,因此從頭開始進行訓練是不可行的。 (VGG網絡是分階段訓練的,從完整的16層初始化后進行訓練)。對于的FCN-32s,在單GPU上,微調要花費三天的時間,而且大約每隔一天就要更新到FCN-16s和FCN-8s版本。
圖中對比了patch取樣,全圖有效地訓練每張圖片batches到常規的、大的、重疊的patches網格。采樣在收斂速率上沒有很顯著的效果相對于全圖式訓練,但是由于每個每個批次都需要大量的圖像,很明顯的需要花費更多的時間。
6.2.2.5 評價指標
論文中實驗了四種評價指標:
6.2.3 分割架構效果
最終分割通過在ILSVRC12的AlexNet3體系結構,以及在ILSVRC14中的VGG網絡和GoogLeNet4做的很不錯。
通過丟棄最終的分類器層來斬斷每個網絡的開始,并將所有的全連接層轉換為卷積。下面在PASCAL VOC 2011 數據集中,NVIDIA Tesla K40c上對500×500輸入進行20次試驗的平均值)的比較
- 不同的FCN的skip效果比較
- 其它效果
- FCN-8s is the best in Pascal VOC 2011.
- FCN-16s is the best in NYUDv2.
- FCN-16s is the best in SIFT Flow.
缺點
-
得到的結果還是不夠精細。進行8倍上采樣雖然比32倍的效果好了很多,但是上采樣的結果還是比較模糊和平滑,對圖像中的細節不敏感
-
對各個像素進行分類,沒有充分考慮像素與像素之間的關系。忽略了在通常的基于像素分類的分割方法中使用的空間規整(spatial regularization)步驟,缺乏空間一致性
6.2.4 網絡結構總結
- 全卷積(convolutional):采樣端對端的卷積網絡,將普通分類網絡的全連接層換上對應的卷積層(FCN)
- 上采樣(upsample):即反卷積(deconvolution),恢復圖片的位置信息等,反卷積層可以通過最小化誤差學習得到。
- 跳躍連接(skip layer):通過連接不同卷積層的輸出到反卷積層,來改善上采樣很粗糙的問題。
6.2.5 總結
- FCN的結構組成
- FCN的上采樣方法以及skip layers
- FCN training的訓練過程以及訓練方式
總結
以上是生活随笔為你收集整理的图像目标分割_2 FCN(Fully Convolutional Networks for Semantic Segmentation)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 读取外部配置文件_SpringBoot外
- 下一篇: 数据结构链表之循环链表——4