全卷積網絡FCN進行圖像分割

2020-12-12 電子產品世界

CNN能夠對圖片進行分類,可是怎麼樣才能識別圖片中特定部分的物體,在2015年之前還是一個世界難題。神經網絡大神Jonathan Long發表了《Fully ConvoluTIonal Networks for SemanTIc SegmentaTIon》在圖像語義分割挖了一個坑,於是無窮無盡的人往坑裡面跳。

本文引用地址:http://www.eepw.com.cn/article/201710/365497.htm

全卷積網絡 Fully ConvoluTIonal Networks

CNNFCN

通常CNN網絡在卷積層之後會接上若干個全連接層, 將卷積層產生的特徵圖(feature map)映射成一個固定長度的特徵向量。以AlexNet為代表的經典CNN結構適合於圖像級的分類和回歸任務,因為它們最後都期望得到整個輸入圖像的一個數值描述(概率),比如AlexNet的ImageNet模型輸出一個1000維的向量表示輸入圖像屬於每一類的概率(softmax歸一化)。

慄子:下圖中的貓, 輸入AlexNet, 得到一個長為1000的輸出向量, 表示輸入圖像屬於每一類的概率, 其中在「tabby cat」這一類統計概率最高。

FCN對圖像進行像素級的分類,從而解決了語義級別的圖像分割(semantic segmentation)問題。與經典的CNN在卷積層之後使用全連接層得到固定長度的特徵向量進行分類(全聯接層+softmax輸出)不同,FCN可以接受任意尺寸的輸入圖像,採用反卷積層對最後一個卷積層的feature map進行上採樣, 使它恢復到輸入圖像相同的尺寸,從而可以對每個像素都產生了一個預測, 同時保留了原始輸入圖像中的空間信息, 最後在上採樣的特徵圖上進行逐像素分類。

最後逐個像素計算softmax分類的損失, 相當於每一個像素對應一個訓練樣本。下圖是Longjon用於語義分割所採用的全卷積網絡(FCN)的結構示意圖:

簡單的來說,FCN與CNN的區域在把於CNN最後的全連接層換成卷積層,輸出的是一張已經Label好的圖片。

其實,CNN的強大之處在於它的多層結構能自動學習特徵,並且可以學習到多個層次的特徵:較淺的卷積層感知域較小,學習到一些局部區域的特徵;較深的卷積層具有較大的感知域,能夠學習到更加抽象一些的特徵。這些抽象特徵對物體的大小、位置和方向等敏感性更低,從而有助於識別性能的提高。下圖CNN分類網絡的示意圖:

這些抽象的特徵對分類很有幫助,可以很好地判斷出一幅圖像中包含什麼類別的物體,但是因為丟失了一些物體的細節,不能很好地給出物體的具體輪廓、指出每個像素具體屬於哪個物體,因此做到精確的分割就很有難度。

傳統的基於CNN的分割方法:為了對一個像素分類,使用該像素周圍的一個圖像塊作為CNN的輸入用於訓練和預測。這種方法有幾個缺點:一是存儲開銷很大。例如對每個像素使用的圖像塊的大小為15x15,然後不斷滑動窗口,每次滑動的窗口給CNN進行判別分類,因此則所需的存儲空間根據滑動窗口的次數和大小急劇上升。二是計算效率低下。相鄰的像素塊基本上是重複的,針對每個像素塊逐個計算卷積,這種計算也有很大程度上的重複。三是像素塊大小的限制了感知區域的大小。通常像素塊的大小比整幅圖像的大小小很多,只能提取一些局部的特徵,從而導致分類的性能受到限制。

而全卷積網絡(FCN)則是從抽象的特徵中恢復出每個像素所屬的類別。即從圖像級別的分類進一步延伸到像素級別的分類。

全連接層 -> 成卷積層

全連接層和卷積層之間唯一的不同就是卷積層中的神經元只與輸入數據中的一個局部區域連接,並且在卷積列中的神經元共享參數。然而在兩類層中,神經元都是計算點積,所以它們的函數形式是一樣的。因此,將此兩者相互轉化是可能的:

對於任一個卷積層,都存在一個能實現和它一樣的前向傳播函數的全連接層。權重矩陣是一個巨大的矩陣,除了某些特定塊,其餘部分都是零。而在其中大部分塊中,元素都是相等的。

相反,任何全連接層都可以被轉化為卷積層。比如,一個 K=4096 的全連接層,輸入數據體的尺寸是 7?7?512,這個全連接層可以被等效地看做一個 F=7,P=0,S=1,K=4096 的卷積層。換句話說,就是將濾波器的尺寸設置為和輸入數據體的尺寸一致了。因為只有一個單獨的深度列覆蓋並滑過輸入數據體,所以輸出將變成 1?1?4096,這個結果就和使用初始的那個全連接層一樣了。

全連接層轉化為卷積層:在兩種變換中,將全連接層轉化為卷積層在實際運用中更加有用。假設一個卷積神經網絡的輸入是 224x224x3 的圖像,一系列的卷積層和下採樣層將圖像數據變為尺寸為 7x7x512 的激活數據體。AlexNet使用了兩個尺寸為4096的全連接層,最後一個有1000個神經元的全連接層用於計算分類評分。我們可以將這3個全連接層中的任意一個轉化為卷積層:

針對第一個連接區域是[7x7x512]的全連接層,令其濾波器尺寸為F=7,這樣輸出數據體就為[1x1x4096]了。

針對第二個全連接層,令其濾波器尺寸為F=1,這樣輸出數據體為[1x1x4096]。

對最後一個全連接層也做類似的,令其F=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塊進行多次評價,其效果和使用把全連接層變換為卷積層後的卷積神經網絡進行一次前向傳播是一樣的。
Evaluating the original ConvNet (with FC layers) independently across 224x224 crops of the 384x384 image in strides of 32 pixels gives an identical result to forwarding the converted ConvNet one time.

如下圖所示,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(勘誤:其實真正代碼當中第一層是1/2,以此類推)。

經過多次卷積和pooling以後,得到的圖像越來越小,解析度越來越低。其中圖像到 H/32?W/32 的時候圖片是最小的一層時,所產生圖叫做heatmap熱圖,熱圖就是我們最重要的高維特徵圖,得到高維特徵的heatmap之後就是最重要的一步也是最後的一步對原圖像進行upsampling,把圖像進行放大、放大、放大,到原圖像的大小。

最後的輸出是1000張heatmap經過upsampling變為原圖大小的圖片,為了對每個像素進行分類預測label成最後已經進行語義分割的圖像,這裡有一個小trick,就是最後通過逐個像素地求其在1000張圖像該像素位置的最大數值描述(概率)作為該像素的分類。因此產生了一張已經分類好的圖片,如下圖右側有狗狗和貓貓的圖。

upsampling

相較於使用被轉化前的原始卷積神經網絡對所有36個位置進行迭代計算,使用轉化後的卷積神經網絡進行一次前向傳播計算要高效得多,因為36次計算都在共享計算資源。這一技巧在實踐中經常使用,一次來獲得更好的結果。比如,通常將一張圖像尺寸變得更大,然後使用變換後的卷積神經網絡來對空間上很多不同位置進行評價得到分類評分,然後在求這些分值的平均值。

最後,如果我們想用步長小於32的浮窗怎麼辦?用多次的向前傳播就可以解決。比如我們想用步長為16的浮窗。那麼先使用原圖在轉化後的卷積網絡執行向前傳播,然後分別沿寬度,沿高度,最後同時沿寬度和高度,把原始圖片分別平移16個像素,然後把這些平移之後的圖分別帶入卷積網絡。

如下圖所示,當圖片在網絡中經過處理後變成越小的圖片,其特徵也越明顯,就像圖像中顏色所示,當然啦,最後一層的圖片不再是一個1個像素的圖片,而是原圖像 H/32xW/32 大小的圖,這裡為了簡化而畫成一個像素而已。

如下圖所示,對原圖像進行卷積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的缺點:
1、是得到的結果還是不夠精細。進行8倍上採樣雖然比32倍的效果好了很多,但是上採樣的結果還是比較模糊和平滑,對圖像中的細節不敏感。

2、是對各個像素進行分類,沒有充分考慮像素與像素之間的關係。忽略了在通常的基於像素分類的分割方法中使用的空間規整(spatial regularization)步驟,缺乏空間一致性。

實踐

輸入的圖片是:

現在可以直接來點代碼嗎?
# import package
import numpy as np
from PIL import Image
import caffe

# 初始化地址
caffe_root = fcn.berkeleyvision.org-master/voc-fcn8s/
model_def = caffe_root + deploy.prototxt # 模型文件
model_weights = caffe_root + fcn8s-heavy-pascal.caffemodel #模型權重值
test_image = images/2007_000129.jpg #測試圖片

# load image, switch to BGR, subtract mean, and make dims C x H x W for Caffe
im = Image.open(test_image)
in_ = np.array(im, dtype=np.float32)
in_ = in_[:,:,::-1] # change RGB image to BGR image
in_ -= np.array((104.00698793,116.66876762,122.67891434))
in_ = in_.transpose((2,0,1)) # Reshape the image from (500, 334, 3) to (3, 500, 334)

net = caffe.Net(model_def, model_weights, caffe.TEST) #導入模型
net.blobs[data].reshape(1, *in_.shape)
net.blobs[data].data[...] = in_ #讀入圖像
net.forward() #圖片進入前饋卷積神經網絡
out = net.blobs[score].data[0].argmax(axis=0) #最後得到的圖片

print net.blobs[score].data[0].shape #(21, 500, 334)
print net.blobs[score].data[0].argmax(axis=0)

好了,已經用fcn模型訓練網一張圖片了,接著就是要看看圖片到底是怎麼樣的楽
import matplotlib.pyplot as plt
# display plots in this notebook
%matplotlib inline

# set display defaults

print out.shape
plt.imshow(out)

輸出是:

現在做圖片分割的都是基於FCN的升級版、FCN超級升級版,FCN改版、FCN超級改版。。。個人覺得最難的、也是個人正在學習的是從如何研究自己的樣本,什麼樣的樣本集才能提高最後結果的精度和召回率;有了樣本然後怎麼給CNN訓練,訓練後如何把CNN->FCN,然後到FCN能夠對新的數據進行分割。整套流程能夠自動化下來就更加perfect了。

相關焦點

  • 圖像語義分割入門:FCN/U-Net網絡解析
    語義分割即是對圖像中每一個像素點進行分類,確定每個點的類別(如屬於背景、人或車等),從而進行區域劃分。目前,語義分割已經被廣泛應用於自動駕駛、無人機落點判定等場景中。與分類不同的是,語義分割需要判斷圖像每個像素點的類別,進行精確分割。圖像語義分割是像素級別的!
  • 10分鐘看懂全卷積神經網絡( FCN ):語義分割深度模型先驅
    語義分割簡單地說,分割就是摳圖。語義分割,就是按圖像中物體表達的含義進行摳圖。現在ps已經集成很多自動分割的功能,相比舊版本軟體,新軟體提高了美工人員的摳圖和美圖的效率。如果我們能在更複雜的環境下,完成自動分割圖像進行分析,這將降低多少人工?這類場景我們很熟悉,比如現在快速發展的自動駕駛。
  • FCN、Unet、Unet++:醫學圖像分割網絡一覽
    Unet在醫學圖像上的適用與CNN分割算法的簡要總結一、相關知識點解釋語義分割(Semantic Segmentation):就是對一張圖像上的所有像素點進行分類。(eg: FCN/Unet/Unet++/...)
  • 重新發現語義分割,一文簡述全卷積網絡
    全卷積網絡自 2012 年出現以來,在圖像分類和圖像檢測領域取得了巨大成功。本文利用筆記本電腦構建了一個小型全卷積網絡,詳細介紹了全卷積網絡的思路、過程等等,值得一看語義分割是一種學習如何識別圖像中對象範圍的機器學習技術。語義分割賦予機器學習系統與人類相似的理解圖像內容的能力。
  • 從全卷積網絡到大型卷積核:深度學習的語義分割全指南
    使用圖像塊分類的主要原因是分類網絡通常是全連接層(fullconnectedlayer),且要求固定尺寸的圖像。  2014年,加州大學伯克利分校的Long等人提出全卷積網絡(FCN),這使得卷積神經網絡無需全連接層即可進行密集的像素預測,CNN從而得到普及。使用這種方法可生成任意大小的圖像分割圖,且該方法比圖像塊分類法要快上許多。之後,語義分割領域幾乎所有先進方法都採用了該模型。
  • FCN、Unet、Unet++等:圖像分割那些事兒
    先上目錄:相關知識點解釋FCN 網絡算法的理解Unet 網絡算法的理解Unet++ 網絡算法的理解Unet+++ 網絡算法的理解DeepLab v3+ 算法簡閱Unet在醫學圖像上的適用與CNN分割算法的簡要總結一、相關知識點解釋1、圖像分割中幾種定義的區別語義分割(Semantic Segmentation):就是對一張圖像上的所有像素點進行分類
  • 【軟體下載】基於深度學習全卷積網絡(FCN)的視覺影像語義分割軟體
    該網絡為中國地質大學(武漢)信息工程學院高性能計算智能實驗室(HPSCIL@CUG)基於ADE_20K數據集訓練的深度學習FCN網絡。
  • 語義分割網絡經典:FCN與SegNet
    作者:石文華          編輯:田  旭           語義分割網絡經典
  • 一文概覽主要語義分割網絡:FCN,SegNet,U-Net...
    雖然自 2007 年以來,語義分割/場景解析一直是計算機視覺社區的一部分,但與計算機視覺中的其他領域很相似,自 2014 年 Long 等人首次使用全卷積神經網絡對自然圖像進行端到端分割,語義分割才有了重大突破。
  • 資源 | 從全連接層到大型卷積核:深度學習語義分割全指南
    在深度學習應用到計算機視覺領域之前,人們使用 TextonForest 和 隨機森林分類器進行語義分割。卷積神經網絡(CNN)不僅對圖像識別有所幫助,也對語義分割領域的發展起到巨大的促進作用。語義分割任務最初流行的深度學習方法是圖像塊分類(patch classification),即利用像素周圍的圖像塊對每一個像素進行獨立的分類。
  • 圖像語義分割
    圖像語義分割是圖像處理和計算機視覺技術中關於圖像理解的重要的一環。語義分割對圖像中的每一個像素點進行分類,確定每個點的類別(如屬於背景、邊緣或身體等)需要和實例分割區分開來。語義分割沒有分離同一類的實例;它關心的只是每個像素的類別,如果輸入對象中有兩個相同類別的對象,則分割本身不會將它們區分為單獨的對象。
  • 圖像分割二十年,Mask R-CNN 影響力僅排第十?
    發布信息:2015,IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE論文:https://arxiv.org/pdf/1511.00561.pdf代碼:https://github.com/aizawan/segnetSegNet是用於進行像素級別圖像分割的全卷積網絡
  • 圖像分類-卷積網絡閱讀筆記(一)AlexNet
    這個網絡由5個卷積層、3個池化層和3個全連接層組成,共包含6000萬多個參數。為了降低全連接層過擬合的風險,我們使用最近開發的正則化方法-Dropout。在ILSVRC-2012年的圖像分類競賽中,我們訓練的網絡在測試集上的top-5誤差為15.3%,大幅度領先第二名的26.2%的成績。1. Introduction(簡介)
  • 基於深度學習方法的圖像分割
    Image Segmentation(圖像分割)網絡結構比較FCNImage Segmentation(圖像分割)族譜按分割目的劃分普通分割將不同分屬不同物體的像素區域分開。 如前景與後景分割開,狗的區域與貓的區域與背景分割開。
  • 語義分割中的深度學習方法全解:從FCN、SegNet到各版本DeepLab
    其中,使用圖像塊的主要原因是分類網絡通常具有全連接層,其輸入需為固定大小的圖像塊。2014年,加州大學伯克利分校的Long等人提出的完全卷積網絡(Fully Convolutional Networks),推廣了原有的CNN結構,在不帶有全連接層的情況下能進行密集預測。
  • 2019 語義分割指南
    用於語義分割的全卷積網絡(PAMI,2016)用於語義分割的全卷積網絡(https://arxiv.org/abs/1605.06211)這篇文章提出的模型在PASCAL VOC 2012上取得了67.2%的平均IU。全連接網絡輸入任意大小的圖像,生成一個對應空間維度的輸出。
  • 100個深度圖像分割算法,紐約大學UCLA等最新綜述論文
    值得一提的是,有一些部件在這些工作中是很常見的,比如有編碼器和解碼器部分,跳連接,多尺度分析,以及最近使用的膨脹卷積。因此,很難提及每個工作的獨特貢獻,但是根據它們對先前工作的基礎架構貢獻將它們分組比較容易。Long等人利用全卷積網絡(FCN)提出了最早的語義圖像分割深度學習算法之一。FCN(圖7)只包含卷積層,這使得它可以獲取任意大小的圖像並生成相同大小的分割圖。
  • 人工智慧・圖像分割(2)
    全卷積神經網絡的英語名字是Fully Convolutional Networks,簡稱FCN。不過,本黃鴨強烈建議寶寶們不要使用這個簡稱,因為它很可能會被誤解成Fully Connected Networks,也就是全連接神經網絡。在《人工智慧・循環神經網絡》一文中,本黃鴨曾經說過,之所以全連接神經網絡不適合處理一維、二維連續數據,是因為它沒辦法提取到足夠的、與順序相關的特徵。
  • 人工智慧・圖像分割(5)
    上回我們說到了建立全卷積神經網絡的方法,還閱讀了論文中的一些重點段落。在這篇文章中,本黃鴨將繼續為大家介紹U-Net。Last but not least,U-Net的輸出層與全卷積神經網絡完全相同。先是1* 1卷積,再是softmax激活函數,最後是argmax輸出分類結果。其中,1* 1卷積層的、kernel的個數要設置為<輸入圖像中物體類別的個數 + 1>,「+1」是輸入圖像的背景。
  • 從0到1必看 | 基於深度學習方法的圖像分割
    這篇論文是第一篇成功使用深度學習做圖像語義分割的論文。論文的主要貢獻有兩點:提出了全卷積網絡。將全連接網絡替換成了卷積網絡,使得網絡可以接受任意大小的圖片,並輸出和原圖一樣大小的分割圖。只有這樣,才能為每個像素做分類。使用了反卷積層(Deconvolution)。分類神經網絡的特徵圖一般只有原圖的幾分之一大小。