FCN学习:Semantic Segmentation
Fully Convolutional Networks for Semantic Segmentation
全卷積網絡首現于這篇文章。這篇文章是將CNN結構應用到圖像語義分割領域并取得突出結果的開山之作,因而拿到了CVPR 2015年的best paper.
圖像語義分割,簡而言之就是對一張圖片上的所有像素點進行分類
如上圖就是一個語義分割的例子,不同的顏色代表不同的類別
下面簡單介紹一下論文,重點介紹文中的那幾個結構:
一.論文解讀
1.Introduction
CNN這幾年一直在驅動著圖像識別領域的進步。無論是整張圖片的分類(ILSVRC),還是物體檢測,關鍵點檢測都在CNN的幫助下得到了非常大的發展。但是圖像語義分割不同于以上任務,這是個空間密集型的預測任務,換言之,他需要預測一幅圖像中所有像素點的類別。
以往的用于語義分割的CNN,每個像素點用包圍其的對象或區域類別進行標注,但是這種方法不管是在速度上還是精度上都有很大的缺陷。
本文提出了全卷積網絡(FCN)的概念,針對語義分割訓練一個端到端,點對點的網絡,達到了state-of-the-art。這是第一次訓練端到端的FCN,用于像素級的預測;也是第一次用監督預訓練的方法訓練FCN。
2.Fully Convolutional networks & Architecture
下面我們重點看一下FCN所用到的三種技術:
1.卷積化(convolutionalization)
分類所使用的網絡通常會在最后連接全連接層,它會將原來二維的矩陣(圖片)壓縮成一維的,從而丟失了空間信息,最后訓練輸出一個標量,這就是我們的分類標簽。
而圖像語義分割的輸出需要是個分割圖,且不論尺寸大小,但是至少是二維的。所以,我們丟棄全連接層,換上卷積層,而這就是卷積化了。
這幅圖顯示了卷積化的過程,圖中顯示的是AlexNet的結構,簡單來說卷積化就是將其最后三層全連接層全部替換成卷積層
2.上采樣(Upsampling)
上采樣也就是對應于上圖中最后生成heatmap的過程。
在一般的CNN結構中,如AlexNet,VGGNet均是使用池化層來縮小輸出圖片的size,例如VGG16,五次池化后圖片被縮小了32倍;而在ResNet中,某些卷積層也參與到縮小圖片size的過程。我們需要得到的是一個與原圖像size相同的分割圖,因此我們需要對最后一層進行上采樣,在caffe中也被稱為反卷積(Deconvolution),可能叫做轉置卷積(conv_transpose)更為恰當一點。
為理解轉置卷積,我們先來看一下Caffe中的卷積操作是怎么進行的
在caffe中計算卷積分為兩個步驟:
1)使用im2col操作將圖片轉換為矩陣
2)調用GEMM計算實際的結果
這里舉個簡單的例子: ?4x4的輸入,卷積Kernel為3x3, 沒有Padding / Stride, 則輸出為2x2
輸入矩陣可展開為16維向量,記作x
輸出矩陣可展開為4維向量,記作y
卷積運算可表示為y=Cx
不難想象C
其實就是如下的稀疏陣:
平時神經網絡中的正向傳播就是轉換成了如上矩陣運算。
那么當反向傳播時又會如何呢?首先我們已經有從更深層的網絡中得到的.?
根據矩陣微分公式,可推得
Caffe中的卷積操作簡單來說就是這樣,那轉置卷積呢?
其實轉置卷積相對于卷積在神經網絡結構的正向和反向傳播中做相反的運算。
所以所謂的轉置卷積其實就是正向時左乘C^T,而反向時左乘(C^T)^T
,即C
的運算。
注:以上示例來自這個回答:如何理解深度學習中的deconvolution networks?
雖然轉置卷積層和卷積層一樣,也是可以train參數的,但是實際實驗過程中,作者發現,讓轉置卷積層可學習,并沒有帶來performance的提升,所以實驗中的轉置卷積層的lr全部被置零了
注意:在代碼中可以看出,為了得到和原圖像size一模一樣的分割圖,FCN中還使用了crop_layer來配合deconvolution層
3.跳躍結構(Skip Architecture)
其實直接使用前兩種結構就已經可以得到結果了,但是直接將全卷積后的結果上采樣后得到的結果通常是很粗糙的。所以這一結構主要是用來優化最終結果的,思路就是將不同池化層的結果進行上采樣,然后結合這些結果來優化輸出,具體結構如下:
而不同的結構產生的結果對比如下:
二.實踐
作者在github上開源了代碼:Fully Convolutional Networks
git clone https://github.com/shelhamer/fcn.berkeleyvision.org.git我們首先將項目克隆到本地
項目文件結構很清晰,如果想train自己的model,只需要修改一些文件路徑設置即可,這里我們應用已經train好的model來測試一下自己的圖片:
我們下載voc-fcn32s,voc-fcn16s以及voc-fcn8s的caffemodel(根據提供好的caffemodel-url),fcn-16s和fcn32s都是缺少deploy.prototxt的,我們根據train.prototxt稍加修改即可
略微修改infer.py,就可以測試我們自己的圖片了
import numpy as np from PIL import Image import matplotlib.pyplot as plt import caffe# load image, switch to BGR, subtract mean, and make dims C x H x W for Caffe im = Image.open('data/pascal/VOCdevkit/VOC2012/JPEGImages/2007_000129.jpg') in_ = np.array(im, dtype=np.float32) in_ = in_[:,:,::-1] in_ -= np.array((104.00698793,116.66876762,122.67891434)) in_ = in_.transpose((2,0,1))# load net net = caffe.Net('voc-fcn8s/deploy.prototxt', 'voc-fcn8s/fcn8s-heavy-pascal.caffemodel', caffe.TEST) # shape for input (data blob is N x C x H x W), set data net.blobs['data'].reshape(1, *in_.shape) net.blobs['data'].data[...] = in_ # run net and take argmax for prediction net.forward() out = net.blobs['score'].data[0].argmax(axis=0)plt.imshow(out,cmap='gray');plt.axis('off') plt.savefig('test.png') plt.show()接下來,只需要修改script中的圖片路徑和model的路徑,就可以測試自己的圖片了:
這是我跑出來的最終結果,可以看出skip architecture對最終的結果卻是有優化作用。
這里沒有對最終結果上色,按照VOC的顏色設置之后,就可以得到和論文中一模一樣的結果了
下面是我測試自己圖片的結果:
?三.總結
圖像語義分割可能是自動駕駛技術下一步發展的一個重要突破點,而且本身也特別有意思!借此機會也學習了一下Caffe計算卷積和轉置卷積的過程,對語義分割也有了一個初步的了解,收獲頗豐!
總結
以上是生活随笔為你收集整理的FCN学习:Semantic Segmentation的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于深度学习的图像语义分割技术概述之背景
- 下一篇: python基础系列教程——python