CNN--卷積神經網路從R-CNN到Faster R-CNN的理解(CIFAR10分類程式碼)
1. 什麼是CNN
卷積神經網路(Convolutional Neural Networks, CNN)是一類包含卷積計算且具有深度結構的前饋神經網路(Feedforward Neural Networks),是深度學習(deep learning)的代表演算法之一。
我們先來看卷積神經網路各個層級結構圖:
上圖中CNN要做的事情是:給定一張圖片,是車還是馬未知,是什麼車也未知,現在需要模型判斷這張圖片裡具體是一個什麼東西,總之輸出一個結果:如果是車 那是什麼車。
- 最左邊是資料輸入層(input layer),對資料做一些處理,比如去均值(把輸入資料各個維度都中心化為0,避免資料過多偏差,影響訓練效果)、歸一化(把所有的資料都歸一到同樣的範圍)、PCA/白化等等。CNN只對訓練集做“去均值”這一步。
- CONV:卷積計算層(conv layer),線性乘積求和。
- RELU:激勵層(activation layer),下文有提到:ReLU是啟用函式的一種。
- POOL:池化層(pooling layer),簡言之,即取區域平均或最大。
- FC:全連線層(FC layer)。
這幾個部分中,卷積計算層是CNN的核心。
1.1 輸入層
在做輸入的時候,需要把圖片處理成同樣大小的圖片才能夠進行處理。
常見的處理資料的方式有:
去均值(常用)
- AlexNet:訓練集中100萬張圖片,對每個畫素點求均值,得到均值影象,當訓練時用原圖減去均值影象。
- VGG:對所有輸入在三個顏色通道R/G/B上取均值,只會得到3個值,當訓練時減去對應的顏色通道均值。(此種方法效率高)
TIPS:在訓練集和測試集上減去訓練集的均值。
歸一化
幅度歸一化到同樣的範圍。
PCA/白化(很少用)
- 用PCA降維
- 白化是對資料每個特徵軸上的幅度歸一化。
1.2 卷積計算層(conv)
對影象(不同的資料視窗資料)和濾波矩陣(一組固定的權重:因為每個神經元的多個權重固定,所以又可以看做一個恆定的濾波器filter)做內積(逐個元素相乘再求和)的操作就是所謂的『卷積』操作,也是卷積神經網路的名字來源。
濾波器filter是什麼呢!請看下圖。圖中左邊部分是原始輸入資料,圖中中間部分是濾波器filter,圖中右邊是輸出的新的二維資料。
不同的濾波器filter會得到不同的輸出資料,比如顏色深淺、輪廓。相當於提取影象的不同特徵,模型就能夠學習到多種特徵。用不同的濾波器filter,提取想要的關於影象的特定資訊:顏色深淺或輪廓。如下圖所示。
在CNN中,濾波器filter(帶著一組固定權重的神經元)對區域性輸入資料進行卷積計算。每計算完一個數據視窗內的區域性資料後,資料視窗不斷平移滑動,直到計算完所有資料。這個過程中,有這麼幾個引數:
- 深度depth:神經元個數,決定輸出的depth厚度。同時代表濾波器個數。
- 步長stride:決定滑動多少步可以到邊緣。
- 填充值zero-padding:在外圍邊緣補充若干圈0,方便從初始位置以步長為單位可以剛好滑倒末尾位置,通俗地講就是為了總長能被步長整除。
引數共享機制
假設每個神經元連線資料窗的權重是固定對的。固定每個神經元連線權重,可以看做模板,每個神經元只關注一個特性(模板),這使得需要估算的權重個數減少:一層中從1億到3.5萬。
一組固定的權重和不同視窗內資料做內積:卷積
作用在於捕捉某一種模式,具體表現為很大的值。
卷積操作的本質特性包括稀疏互動和引數共享。
1.3 激勵層
把卷積層輸出結果做非線性對映。
啟用函式有:
- sigmoid:在兩端斜率接近於0,梯度消失。
- ReLu:修正線性單元,有可能出現斜率為0,但概率很小,因為mini-batch是一批樣本損失求導之和。
TIPS:
- CNN慎用sigmoid!慎用sigmoid!慎用sigmoid!
- 首先試RELU,因為快,但要小心點。
- 如果RELU失效,請用 Leaky ReLU或者Maxout。
- 某些情況下tanh倒是有不錯的結果,但是很少。
1.4 池化層
也叫下采樣層,就算通過了卷積層,緯度還是很高 ,需要進行池化層操作。
- 夾在連續的卷積層中間。
- 壓縮資料和引數的量,降低維度。
- 減小過擬合。
- 具有特徵不變性。
方式有:Max pooling、average pooling
Max pooling
取出每個部分的最大值作為輸出,例如上圖左上角的4個黃色方塊取最大值為3作為輸出,以此類推。
average pooling
每個部分進行計算得到平均值作為輸出,例如上圖左上角的4個黃色方塊取得平均值2作為輸出,以此類推。
1.5 全連線層
全連線層的每一個結點都與上一層的所有結點相連,用來把前邊提取到的特徵綜合起來。由於其全連線的特性,一般全連線層的引數也是最多的。
- 兩層之間所有神經元都有權重連線
- 通常全連線層在卷積神經網路尾部
1.6 層次結構小結
CNN層次結構 | 作用 |
---|---|
輸入層 | 卷積網路的原始輸入,可以是原始或預處理後的畫素矩陣 |
卷積層 | 引數共享、區域性連線,利用平移不變性從全域性特徵圖提取區域性特徵 |
啟用層 | 將卷積層的輸出結果進行非線性對映 |
池化層 | 進一步篩選特徵,可以有效減少後續網路層次所需的引數量 |
全連線層 | 用於把該層之前提取到的特徵綜合起來。 |
1.7 CNN優缺點
優點:
- 共享卷積核,優化計算量。
- 無需手動選取特徵,訓練好權重,即得特徵。
- 深層次的網路抽取影象資訊豐富,表達效果好。
- 保持了層級網路結構。
- 不同層次有不同形式與功能。
缺點:
- 需要調參,需要大樣本量,GPU等硬體依賴。
- 物理含義不明確。
與NLP/Speech共性:
都存在區域性與整體的關係,由低層次的特徵經過組合,組成高層次的特徵,並且得到不同特徵之間的空間相關性。
2. 典型CNN發展歷程
- LeNet,這是最早用於數字識別的CNN
- AlexNet, 2012 ILSVRC比賽遠超第2名的CNN,比LeNet更深,用多層小卷積層疊加替換單大卷積層。
- ZF Net, 2013 ILSVRC比賽冠軍
- GoogLeNet, 2014 ILSVRC比賽冠軍
- VGGNet, 2014 ILSVRC比賽中的模型,影象識別略差於GoogLeNet,但是在很多影象轉化學習問題(比如objectdetection)上效果很好
- ResNet(深度殘差網路(Deep Residual Network,ResNet)), 2015ILSVRC比賽冠軍,結構修正(殘差學習)以適應深層次CNN訓練。
- DenseNet, CVPR2017 best paper,把ResNet的add變成concat
3. 影象相關任務
3.1 影象識別與定位
classification:C個類別識別
- input:Image
- Output:類別標籤
- Evaluation metric:準確率
Localization定位)
Input:Image
Output:物體邊界框(x,y,w,h)
Evaluation metric:交併準則(IOU) > 0.5 圖中陰影部分所佔面積
3.1.1 思路1:識別+定位過程
識別可以看作多分類問題(用softmax),用別人訓練好的CNN模型做fine-tune
定位的目標是(x,y,w,h)是連續值,當迴歸問題解決(mse)
在1的CNN尾部展開(例如把最後一層拿開),接上一個(x,y,w,h)的神經網路,成為classification+regression的模型。
更細緻的識別可以提前規定好有k個組成部分,做成k個部分的迴歸,
例如:框出兩隻眼睛和兩條腿,4元祖*4=16(個連續值)
Regression部分用歐氏距離損失,使用SGD訓練。
3.1.2 思路2:圖窗+識別
- 類似剛才的classification+regression思路
- 咱們取不同大小的“框”
- 讓框出現在不同的位置
- 判定得分
- 按照得分的高低對“結果框”做抽樣和合並
3.2 物體檢測(object detection)
3.2.1 過程
當影象有很多物體怎麼辦的?難度可是一下暴增啊。
那任務就變成了:多物體識別+定位多個物體,那把這個任務看做分類問題?
看成分類問題有何不妥?
- 你需要找很多位置, 給很多個不同大小的框
- 你還需要對框內的影象分類
- 當然, 如果你的GPU很強大, 恩, 那加油做吧…
邊緣策略:想辦法先找到可能包含內容的圖框(候選框),然後進行分類問題的識別。
方法:根據RGB值做區域融合。fast-CNN,共享圖窗,從而加速候選框的形成。
R-CNN => fast-CNN => faster-RCNN 速度對比
3.2.2 R-CNN
R-CNN的簡要步驟如下:
- 輸入測試影象。
- 利用選擇性搜尋Selective Search演算法在影象中從下到上提取2000個左右的可能包含物體的候選區域Region Proposal。
- 因為取出的區域大小各自不同,所以需要將每個Region Proposal縮放(warp)成統一的227x227的大小並輸入到CNN,將CNN的fc7層的輸出作為特徵。
- 將每個Region Proposal提取到的CNN特徵輸入到SVM進行分類。
3.2.3 SPP-Net
SPP:Spatial Pyramid Pooling(空間金字塔池化),SPP-Net是出自2015年發表在IEEE上的論文。
眾所周知,CNN一般都含有卷積部分和全連線部分,其中,卷積層不需要固定尺寸的影象,而全連線層是需要固定大小的輸入。所以當全連線層面對各種尺寸的輸入資料時,就需要對輸入資料進行crop(crop就是從一個大圖扣出網路輸入大小的patch,比如227×227),或warp(把一個邊界框bounding box(紅框)的內容resize成227×227)等一系列操作以統一圖片的尺寸大小,比如224224(ImageNet)、3232(LenNet)、96*96等。
所以才如你在上文中看到的,在R-CNN中,“因為取出的區域大小各自不同,所以需要將每個Region Proposal縮放(warp)成統一的227x227的大小並輸入到CNN”。
但warp/crop這種預處理,導致的問題要麼被拉伸變形、要麼物體不全,限制了識別精確度。沒太明白?說句人話就是,一張16:9比例的圖片你硬是要Resize成1:1的圖片,你說圖片失真不?
SPP Net的作者Kaiming He等人逆向思考,既然由於全連線FC層的存在,普通的CNN需要通過固定輸入圖片的大小來使得全連線層的輸入固定。那借鑑卷積層可以適應任何尺寸,為何不能在卷積層的最後加入某種結構,使得後面全連線層得到的輸入變成固定的呢?
這個“化腐朽為神奇”的結構就是spatial pyramid pooling layer。
它的特點有兩個:
結合空間金字塔方法實現CNNs的多尺度輸入。
SPP Net的第一個貢獻就是在最後一個卷積層後,接入了金字塔池化層,保證傳到下一層全連線層的輸入固定。
換句話說,在普通的CNN機構中,輸入影象的尺寸往往是固定的(比如224*224畫素),輸出則是一個固定維數的向量。SPP Net在普通的CNN結構中加入了ROI池化層(ROI Pooling),使得網路的輸入影象可以是任意尺寸的,輸出則不變,同樣是一個固定維數的向量。
簡言之,CNN原本只能固定輸入、固定輸出,CNN加上SSP之後,便能任意輸入、固定輸出。神奇吧?
只對原圖提取一次卷積特徵
在R-CNN中,每個候選框先resize到統一大小,然後分別作為CNN的輸入,這樣是很低效的。
而SPP Net根據這個缺點做了優化:只對原圖進行一次卷積計算,便得到整張圖的卷積特徵feature map,然後找到每個候選框在feature map上的對映patch,將此patch作為每個候選框的卷積特徵輸入到SPP layer和之後的層,完成特徵提取工作。
如此這般,R-CNN要對每個區域計算卷積,而SPPNet只需要計算一次卷積,從而節省了大量的計算時間,比R-CNN有一百倍左右的提速。
3.2.4 Fast R-CNN
SPP Net真是個好方法,R-CNN的進階版Fast R-CNN就是在R-CNN的基礎上採納了SPP Net方法,對R-CNN作了改進,使得效能進一步提高。
R-CNN有一些相當大的缺點(把這些缺點都改掉了,就成了Fast R-CNN)。
大缺點:由於每一個候選框都要獨自經過CNN,這使得花費的時間非常多。
解決:共享卷積層,現在不是每一個候選框都當做輸入進入CNN了,而是輸入一張完整的圖片,在第五個卷積層再得到每個候選框的特徵。
原來的方法:許多候選框(比如兩千個)-->CNN-->得到每個候選框的特徵-->分類+迴歸
現在的方法:一張完整圖片-->CNN-->得到每張候選框的特徵-->分類+迴歸
所以容易看見,Fast R-CNN相對於R-CNN的提速原因就在於:不過不像R-CNN把每個候選區域給深度網路提特徵,而是整張圖提一次特徵,再把候選框對映到conv5上,而SPP只需要計算一次特徵,剩下的只需要在conv5層上操作就可以了。
演算法步驟:
- 在影象中確定約1000-2000個候選框 (使用選擇性搜尋)。
- 對整張圖片輸進CNN,得到feature map。
- 找到每個候選框在feature map上的對映patch,將此patch作為每個候選框的卷積特徵輸入到SPP layer和之後的層。
- 對候選框中提取出的特徵,使用分類器判別是否屬於一個特定類。
- 對於屬於某一類別的候選框,用迴歸器進一步調整其位置。
3.2.5 Faster R-CNN
Fast R-CNN存在的問題:存在瓶頸:選擇性搜尋,找出所有的候選框,這個也非常耗時。那我們能不能找出一個更加高效的方法來求出這些候選框呢?
解決:加入一個提取邊緣的神經網路,也就說找到候選框的工作也交給神經網路來做了。
所以,rgbd在Fast R-CNN中引入Region Proposal Network(RPN)替代Selective Search,同時引入anchor box應對目標形狀的變化問題(anchor就是位置和大小固定的box,可以理解成事先設定好的固定的proposal)。這就是Faster R-CNN。
演算法步驟:
- 對整張圖片輸進CNN,得到feature map。
- 卷積特徵輸入到RPN,得到候選框的特徵資訊。
- 對候選框中提取出的特徵,使用分類器判別是否屬於一個特定類。
- 對於屬於某一類別的候選框,用迴歸器進一步調整其位置。
3.2.6 YOLO
Faster R-CNN的方法目前是主流的目標檢測方法,但是速度上並不能滿足實時的要求。YOLO一類的方法慢慢顯現出其重要性,這類方法使用了迴歸的思想,利用整張圖作為網路的輸入,直接在影象的多個位置上回歸出這個位置的目標邊框,以及目標所屬的類別。
我們直接看上面YOLO的目標檢測的流程圖:
- 給個一個輸入影象,首先將影象劃分成7*7的網格。
- 對於每個網格,我們都預測2個邊框(包括每個邊框是目標的置信度以及每個邊框區域在多個類別上的概率)。
- 根據上一步可以預測出772個目標視窗,然後根據閾值去除可能性比較低的目標視窗,最後NMS去除冗餘視窗即可。
小結:YOLO將目標檢測任務轉換成一個迴歸問題,大大加快了檢測的速度,使得YOLO可以每秒處理45張影象。而且由於每個網路預測目標視窗時使用的是全圖資訊,使得false positive比例大幅降低(充分的上下文資訊)。
但是YOLO也存在問題:沒有了Region Proposal機制,只使用7*7的網格迴歸會使得目標不能非常精準的定位,這也導致了YOLO的檢測精度並不是很高。
3.2.7 SSD
SSD: Single Shot MultiBox Detector。上面分析了YOLO存在的問題,使用整圖特徵在7*7的粗糙網格內迴歸對目標的定位並不是很精準。那是不是可以結合region proposal的思想實現精準一些的定位?SSD結合YOLO的迴歸思想以及Faster R-CNN的anchor機制做到了這點。
上圖是SSD的一個框架圖,首先SSD獲取目標位置和類別的方法跟YOLO一樣,都是使用迴歸,但是YOLO預測某個位置使用的是全圖的特徵,SSD預測某個位置使用的是這個位置周圍的特徵(感覺更合理一些)。
那麼如何建立某個位置和其特徵的對應關係呢?可能你已經想到了,使用Faster R-CNN的anchor機制。如SSD的框架圖所示,假如某一層特徵圖(圖b)大小是8*8,那麼就使用3*3的滑窗提取每個位置的特徵,然後這個特徵迴歸得到目標的座標資訊和類別資訊(圖c)。
不同於Faster R-CNN,這個anchor是在多個feature map上,這樣可以利用多層的特徵並且自然的達到多尺度(不同層的feature map 3*3滑窗感受野不同)。
小結:SSD結合了YOLO中的迴歸思想和Faster R-CNN中的anchor機制,使用全圖各個位置的多尺度區域特徵進行迴歸,既保持了YOLO速度快的特性,也保證了視窗預測的跟Faster R-CNN一樣比較精準。SSD在VOC2007上mAP可以達到72.1%,速度在GPU上達到58幀每秒。
3.3 語義(影象)分割
識別圖上pixel的類別,用全卷積網路。
4. 程式碼實現CNN
cifar10資料集分類--CNN
【機器學習通俗易懂系列文章】
5. 參考文獻
- 基於深度學習的目標檢測技術演進:R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD
- 通俗理解卷積神經網路
作者:@mantchs
GitHub:https://github.com/NLP-LOVE/ML-NLP
歡迎大家加入討論!共同完善此專案!群號:【541954936】