一文讀懂目標檢測:R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD

v_JULY_v發表於2018-05-02

一文讀懂目標檢測:R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD

 

前言

之前我所在的公司七月線上開設的深度學習等一系列課程經常會講目標檢測,包括R-CNN、Fast R-CNN、Faster R-CNN,但一直沒有比較好的機會深入(但當你對目標檢測有個基本的瞭解之後,再看這些課程你會收益很大)。但目標檢測這個領域實在是太火了,經常會看到一些寫的不錯的通俗易懂的資料,加之之前在京東上掏了一本書看了看,就這樣耳濡目染中,還是開始研究了。

今年五一,從保定回京,怕高速路上堵 沒坐大巴,高鐵又沒搶上,只好選擇哐當哐當好幾年沒坐過的綠皮車,關鍵還不斷晚點。在車站,用手機做個熱點,修改題庫,順便終於搞清R-CNN、fast R-CNN、faster R-CNN的核心區別。有心中熱愛 何懼任何啥。

為紀念這心中熱愛,故成此文。

 

一、目標檢測常見演算法

object detection,就是在給定的圖片中精確找到物體所在位置,並標註出物體的類別。所以,object detection要解決的問題就是物體在哪裡以及是什麼的整個流程問題。


然而,這個問題可不是那麼容易解決的,物體的尺寸變化範圍很大,擺放物體的角度,姿態不定,而且可以出現在圖片的任何地方,更何況物體還可以是多個類別。

目前學術和工業界出現的目標檢測演算法分成3類:
1. 傳統的目標檢測演算法:Cascade + HOG/DPM + Haar/SVM以及上述方法的諸多改進、優化;

2. 候選區域/窗 + 深度學習分類:通過提取候選區域,並對相應區域進行以深度學習方法為主的分類的方案,如:
R-CNN(Selective Search + CNN + SVM)
SPP-net(ROI Pooling)
Fast R-CNN(Selective Search + CNN + ROI)
Faster R-CNN(RPN + CNN + ROI)
R-FCN

 

等系列方法;

3. 基於深度學習的迴歸方法:YOLO/SSD/DenseBox 等方法;以及最近出現的結合RNN演算法的RRC detection;結合DPM的Deformable CNN等

傳統目標檢測流程:
1)區域選擇(窮舉策略:採用滑動視窗,且設定不同的大小,不同的長寬比對影象進行遍歷,時間複雜度高)
2)特徵提取(SIFT、HOG等;形態多樣性、光照變化多樣性、背景多樣性使得特徵魯棒性差)
3)分類器分類(主要有SVM、Adaboost等)

 

 

 

 

二、傳統的目標檢測演算法

2.1 從影象識別的任務說起

這裡有一個影象任務:既要把圖中的物體識別出來,又要用方框框出它的位置。

這個任務本質上就是這兩個問題:一:影象識別,二:定位。

影象識別(classification)
輸入:圖片
輸出:物體的類別
評估方法:準確率


定位(localization)
輸入:圖片
輸出:方框在圖片中的位置(x,y,w,h)
評估方法:檢測評價函式 intersection-over-union(關於什麼是IOU,請參看七月線上APP題庫大題檢視深度學習分類下第55題:https://www.julyedu.com/question/big/kp_id/26/ques_id/2138) 


卷積神經網路CNN已經幫我們完成了影象識別(判定是貓還是狗)的任務了,我們只需要新增一些額外的功能來完成定位任務即可。

定位的問題的解決思路有哪些?
思路一:看做迴歸問題
看做迴歸問題,我們需要預測出(x,y,w,h)四個引數的值,從而得出方框的位置。


步驟1:
  • 先解決簡單問題, 搭一個識別影象的神經網路
  • 在AlexNet VGG GoogleLenet上fine-tuning一下(關於什麼是微調fine-tuning,請參看:https://www.julyedu.com/question/big/kp_id/26/ques_id/2137)


 
步驟2:
  • 在上述神經網路的尾部展開(也就說CNN前面保持不變,我們對CNN的結尾處作出改進:加了兩個頭:“分類頭”和“迴歸頭”)
  • 成為classification + regression模式


步驟3:
  • Regression那個部分用歐氏距離損失
  • 使用SGD訓練

步驟4:
  • 預測階段把2個頭部拼上
  • 完成不同的功能

這裡需要進行兩次fine-tuning
第一次在ALexNet上做,第二次將頭部改成regression head,前面不變,做一次fine-tuning

Regression的部分加在哪?
有兩種處理方法:
  • 加在最後一個卷積層後面(如VGG)
  • 加在最後一個全連線層後面(如R-CNN)

regression太難做了,應想方設法轉換為classification問題。
regression的訓練引數收斂的時間要長得多,所以上面的網路採取了用classification的網路來計算出網路共同部分的連線權值。

思路二:取影象視窗
  • 還是剛才的classification + regression思路
  • 我們們取不同的大小的“框”
  • 讓框出現在不同的位置,得出這個框的判定得分
  • 取得分最高的那個框

左上角的黑框:得分0.5


右上角的黑框:得分0.75


左下角的黑框:得分0.6


右下角的黑框:得分0.8


根據得分的高低,我們選擇了右下角的黑框作為目標位置的預測。
注:有的時候也會選擇得分最高的兩個框,然後取兩框的交集作為最終的位置預測。

疑惑:框要取多大?
取不同的框,依次從左上角掃到右下角。非常粗暴啊。

總結一下思路:
對一張圖片,用各種大小的框(遍歷整張圖片)將圖片擷取出來,輸入到CNN,然後CNN會輸出這個框的得分(classification)以及這個框圖片對應的x,y,h,w(regression)。


這方法實在太耗時間了,做個優化。
原來網路是這樣的:


優化成這樣:把全連線層改為卷積層,這樣可以提提速。

 

2.2 物體檢測(Object Detection)

當影象有很多物體怎麼辦的?難度可是一下暴增啊。

那任務就變成了:多物體識別+定位多個物體
那把這個任務看做分類問題?


看成分類問題有何不妥?
  • 你需要找很多位置, 給很多個不同大小的框
  • 你還需要對框內的影象分類
  • 當然, 如果你的GPU很強大, 恩, 那加油做吧…

所以,傳統目標檢測的主要問題是:
1)基於滑動視窗的區域選擇策略沒有針對性,時間複雜度高,視窗冗餘
2)手工設計的特徵對於多樣性的變化沒有很好的魯棒性

看做classification, 有沒有辦法優化下?我可不想試那麼多框那麼多位置啊!

 

三、候選區域/窗 + 深度學習分類

3.1 R-CNN橫空出世

有人想到一個好方法:預先找出圖中目標可能出現的位置,即候選區域(Region Proposal)。利用影象中的紋理、邊緣、顏色等資訊,可以保證在選取較少視窗(幾千甚至幾百)的情況下保持較高的召回率(Recall)。

所以,問題就轉變成找出可能含有物體的區域/框(也就是候選區域/框,比如選2000個候選框),這些框之間是可以互相重疊互相包含的,這樣我們就可以避免暴力列舉的所有框了。


大牛們發明好多選定候選框Region Proposal的方法,比如Selective Search和EdgeBoxes。那提取候選框用到的演算法“選擇性搜尋”到底怎麼選出這些候選框的呢?具體可以看一下PAMI2015的“What makes for effective detection proposals?”

以下是各種選定候選框的方法的效能對比。


有了候選區域,剩下的工作實際就是對候選區域進行影象分類的工作(特徵提取+分類)。對於影象分類,不得不提的是2012年ImageNet大規模視覺識別挑戰賽(ILSVRC)上,機器學習泰斗Geoffrey Hinton教授帶領學生Krizhevsky使用卷積神經網路將ILSVRC分類任務的Top-5 error降低到了15.3%,而使用傳統方法的第二名top-5 error高達 26.2%。此後,卷積神經網路CNN佔據了影象分類任務的絕對統治地位。

2014年,RBG(Ross B. Girshick)使用Region Proposal + CNN代替傳統目標檢測使用的滑動視窗+手工設計特徵,設計了R-CNN框架,使得目標檢測取得巨大突破,並開啟了基於深度學習目標檢測的熱潮。

R-CNN的簡要步驟如下
(1) 輸入測試影象
(2) 利用選擇性搜尋Selective Search演算法在影象中從下到上提取2000個左右的可能包含物體的候選區域Region Proposal
(3) 因為取出的區域大小各自不同,所以需要將每個Region Proposal縮放(warp)成統一的227x227的大小並輸入到CNN,將CNN的fc7層的輸出作為特徵
(4) 將每個Region Proposal提取到的CNN特徵輸入到SVM進行分類

具體步驟則如下
步驟一:訓練(或者下載)一個分類模型(比如AlexNet)


步驟二:對該模型做fine-tuning
  • 將分類數從1000改為20,比如20個物體類別 + 1個背景
  • 去掉最後一個全連線層


步驟三:特徵提取
  • 提取影象的所有候選框(選擇性搜尋Selective Search)
  • 對於每一個區域:修正區域大小以適合CNN的輸入,做一次前向運算,將第五個池化層的輸出(就是對候選框提取到的特徵)存到硬碟



步驟四:訓練一個SVM分類器(二分類)來判斷這個候選框裡物體的類別
每個類別對應一個SVM,判斷是不是屬於這個類別,是就是positive,反之nagative。

比如下圖,就是狗分類的SVM


步驟五:使用迴歸器精細修正候選框位置:對於每一個類,訓練一個線性迴歸模型去判定這個框是否框得完美。


細心的同學可能看出來了問題,R-CNN雖然不再像傳統方法那樣窮舉,但R-CNN流程的第一步中對原始圖片通過Selective Search提取的候選框region proposal多達2000個左右,而這2000個候選框每個框都需要進行CNN提特徵+SVM分類,計算量很大,導致R-CNN檢測速度很慢,一張圖都需要47s。



有沒有方法提速呢?答案是有的,這2000個region proposal不都是影象的一部分嗎,那麼我們完全可以對影象提一次卷積層特徵,然後只需要將region proposal在原圖的位置對映到卷積層特徵圖上,這樣對於一張影象我們只需要提一次卷積層特徵,然後將每個region proposal的卷積層特徵輸入到全連線層做後續操作。

但現在的問題是每個region proposal的尺度不一樣,而全連線層輸入必須是固定的長度,所以直接這樣輸入全連線層肯定是不行的。SPP Net恰好可以解決這個問題。
 

3.2 SPP Net

SPP:Spatial Pyramid Pooling(空間金字塔池化)

SPP-Net是出自2015年發表在IEEE上的論文-《Spatial Pyramid Pooling in Deep ConvolutionalNetworks for Visual Recognition》。

眾所周知,CNN一般都含有卷積部分和全連線部分,其中,卷積層不需要固定尺寸的影象,而全連線層是需要固定大小的輸入。


所以當全連線層面對各種尺寸的輸入資料時,就需要對輸入資料進行crop(crop就是從一個大圖扣出網路輸入大小的patch,比如227×227),或warp(把一個邊界框bounding box的內容resize成227×227)等一系列操作以統一圖片的尺寸大小,比如224*224(ImageNet)、32*32(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。下圖便是R-CNN和SPP Net檢測流程的比較:



它的特點有兩個:
1.結合空間金字塔方法實現CNNs的多尺度輸入。
SPP Net的第一個貢獻就是在最後一個卷積層後,接入了金字塔池化層,保證傳到下一層全連線層的輸入固定。
換句話說,在普通的CNN機構中,輸入影象的尺寸往往是固定的(比如224*224畫素),輸出則是一個固定維數的向量。SPP Net在普通的CNN結構中加入了ROI池化層(ROI Pooling),使得網路的輸入影象可以是任意尺寸的,輸出則不變,同樣是一個固定維數的向量。

簡言之,CNN原本只能固定輸入、固定輸出,CNN加上SSP之後,便能任意輸入、固定輸出。神奇吧?

ROI池化層一般跟在卷積層後面,此時網路的輸入可以是任意尺度的,在SPP layer中每一個pooling的filter會根據輸入調整大小,而SPP的輸出則是固定維數的向量,然後給到全連線FC層。

2.只對原圖提取一次卷積特徵
在R-CNN中,每個候選框先resize到統一大小,然後分別作為CNN的輸入,這樣是很低效的。
而SPP Net根據這個缺點做了優化:只對原圖進行一次卷積計算,便得到整張圖的卷積特徵feature map,然後找到每個候選框在feature map上的對映patch,將此patch作為每個候選框的卷積特徵輸入到SPP layer和之後的層,完成特徵提取工作。

如此這般,R-CNN要對每個區域計算卷積,而SPPNet只需要計算一次卷積,從而節省了大量的計算時間,比R-CNN有一百倍左右的提速。

 

3.3 Fast R-CNN

SPP Net真是個好方法,R-CNN的進階版Fast R-CNN就是在R-CNN的基礎上採納了SPP Net方法,對R-CNN作了改進,使得效能進一步提高。

R-CNN與Fast R-CNN的區別有哪些呢?
先說R-CNN的缺點:即使使用了Selective Search等預處理步驟來提取潛在的bounding box作為輸入,但是R-CNN仍會有嚴重的速度瓶頸,原因也很明顯,就是計算機對所有region進行特徵提取時會有重複計算,Fast-RCNN正是為了解決這個問題誕生的。

 

與R-CNN框架圖對比,可以發現主要有兩處不同:一是最後一個卷積層後加了一個ROI pooling layer,二是損失函式使用了多工損失函式(multi-task loss),將邊框迴歸Bounding Box Regression直接加入到CNN網路中訓練(關於什麼是邊框迴歸,請參看七月線上APP題庫大題檢視深度學習分類下第56題:https://www.julyedu.com/question/big/kp_id/26/ques_id/2139)。

(1) ROI pooling layer實際上是SPP-NET的一個精簡版,SPP-NET對每個proposal使用了不同大小的金字塔對映,而ROI pooling layer只需要下采樣到一個7x7的特徵圖。對於VGG16網路conv5_3有512個特徵圖,這樣所有region proposal對應了一個7*7*512維度的特徵向量作為全連線層的輸入。

換言之,這個網路層可以把不同大小的輸入對映到一個固定尺度的特徵向量,而我們知道,conv、pooling、relu等操作都不需要固定size的輸入,因此,在原始圖片上執行這些操作後,雖然輸入圖片size不同導致得到的feature map尺寸也不同,不能直接接到一個全連線層進行分類,但是可以加入這個神奇的ROI Pooling層,對每個region都提取一個固定維度的特徵表示,再通過正常的softmax進行型別識別。

(2) R-CNN訓練過程分為了三個階段,而Fast R-CNN直接使用softmax替代SVM分類,同時利用多工損失函式邊框迴歸也加入到了網路中,這樣整個的訓練過程是端到端的(除去Region Proposal提取階段)。

也就是說,之前R-CNN的處理流程是先提proposal,然後CNN提取特徵,之後用SVM分類器,最後再做bbox regression,而在Fast R-CNN中,作者巧妙的把bbox regression放進了神經網路內部,與region分類和併成為了一個multi-task模型,實際實驗也證明,這兩個任務能夠共享卷積特徵,並相互促進。

所以,Fast-RCNN很重要的一個貢獻是成功的讓人們看到了Region Proposal + CNN這一框架實時檢測的希望,原來多類檢測真的可以在保證準確率的同時提升處理速度,也為後來的Faster R-CNN做下了鋪墊。

畫一畫重點:
R-CNN有一些相當大的缺點(把這些缺點都改掉了,就成了Fast R-CNN)。
大缺點:由於每一個候選框都要獨自經過CNN,這使得花費的時間非常多。
解決:共享卷積層,現在不是每一個候選框都當做輸入進入CNN了,而是輸入一張完整的圖片,在第五個卷積層再得到每個候選框的特徵

原來的方法:許多候選框(比如兩千個)-->CNN-->得到每個候選框的特徵-->分類+迴歸
現在的方法:一張完整圖片-->CNN-->得到每張候選框的特徵-->分類+迴歸

所以容易看見,Fast R-CNN相對於R-CNN的提速原因就在於:不過不像R-CNN把每個候選區域給深度網路提特徵,而是整張圖提一次特徵,再把候選框對映到conv5上,而SPP只需要計算一次特徵,剩下的只需要在conv5層上操作就可以了。

在效能上提升也是相當明顯的:

 

3.4 Faster R-CNN

Fast R-CNN存在的問題:存在瓶頸:選擇性搜尋,找出所有的候選框,這個也非常耗時。那我們能不能找出一個更加高效的方法來求出這些候選框呢?

解決:加入一個提取邊緣的神經網路,也就說找到候選框的工作也交給神經網路來做了。

所以,rgbd在Fast R-CNN中引入Region Proposal Network(RPN)替代Selective Search,同時引入anchor box應對目標形狀的變化問題(anchor就是位置和大小固定的box,可以理解成事先設定好的固定的proposal)。

具體做法:
  • 將RPN放在最後一個卷積層的後面
  • RPN直接訓練得到候選區域


RPN簡介:
  • 在feature map上滑動視窗
  • 建一個神經網路用於物體分類+框位置的迴歸
  • 滑動視窗的位置提供了物體的大體位置資訊
  • 框的迴歸提供了框更精確的位置


一種網路,四個損失函式;
  • RPN calssification(anchor good.bad)
  • RPN regression(anchor->propoasal)
  • Fast R-CNN classification(over classes)
  • Fast R-CNN regression(proposal ->box)

速度對比

Faster R-CNN的主要貢獻就是設計了提取候選區域的網路RPN,代替了費時的選擇性搜尋selective search,使得檢測速度大幅提高。

最後總結一下各大演算法的步驟:
RCNN
1.在影象中確定約1000-2000個候選框 (使用選擇性搜尋Selective Search)
2.每個候選框內影象塊縮放至相同大小,並輸入到CNN內進行特徵提取 
3.對候選框中提取出的特徵,使用分類器判別是否屬於一個特定類 
4.對於屬於某一類別的候選框,用迴歸器進一步調整其位置

Fast R-CNN
1.在影象中確定約1000-2000個候選框 (使用選擇性搜尋Selective Search)
2.對整張圖片輸進CNN,得到feature map
3.找到每個候選框在feature map上的對映patch,將此patch作為每個候選框的卷積特徵輸入到SPP layer和之後的層
4.對候選框中提取出的特徵,使用分類器判別是否屬於一個特定類 
5.對於屬於某一類別的候選框,用迴歸器進一步調整其位置

Faster R-CNN
1.對整張圖片輸進CNN,得到feature map
2.卷積特徵輸入到RPN,得到候選框的特徵資訊
3.對候選框中提取出的特徵,使用分類器判別是否屬於一個特定類 
4.對於屬於某一類別的候選框,用迴歸器進一步調整其位置

簡言之,即如本文開頭所列
R-CNN(Selective Search + CNN + SVM)
SPP-net(ROI Pooling)
Fast R-CNN(Selective Search + CNN + ROI)
Faster R-CNN(RPN + CNN + ROI)

總的來說,從R-CNN, SPP-NET, Fast R-CNN, Faster R-CNN一路走來,基於深度學習目標檢測的流程變得越來越精簡,精度越來越高,速度也越來越快。可以說基於Region Proposal的R-CNN系列目標檢測方法是當前目標檢測技術領域最主要的一個分支。

 

四、基於深度學習的迴歸方法

4.1 YOLO (CVPR2016, oral)

(You Only Look Once: Unified, Real-Time Object Detection)

Faster R-CNN的方法目前是主流的目標檢測方法,但是速度上並不能滿足實時的要求。YOLO一類的方法慢慢顯現出其重要性,這類方法使用了迴歸的思想,利用整張圖作為網路的輸入,直接在影象的多個位置上回歸出這個位置的目標邊框,以及目標所屬的類別。
 

我們直接看上面YOLO的目標檢測的流程圖:

(1) 給個一個輸入影象,首先將影象劃分成7*7的網格
(2) 對於每個網格,我們都預測2個邊框(包括每個邊框是目標的置信度以及每個邊框區域在多個類別上的概率)
(3) 根據上一步可以預測出7*7*2個目標視窗,然後根據閾值去除可能性比較低的目標視窗,最後NMS去除冗餘視窗即可(關於什麼是非極大值抑制NMS,請參看七月線上APP題庫大題檢視深度學習分類下第58題:https://www.julyedu.com/question/big/kp_id/26/ques_id/2141)。

可以看到整個過程非常簡單,不再需要中間的Region Proposal找目標,直接回歸便完成了位置和類別的判定。


小結:YOLO將目標檢測任務轉換成一個迴歸問題,大大加快了檢測的速度,使得YOLO可以每秒處理45張影象。而且由於每個網路預測目標視窗時使用的是全圖資訊,使得false positive比例大幅降低(充分的上下文資訊)。

但是YOLO也存在問題:沒有了Region Proposal機制,只使用7*7的網格迴歸會使得目標不能非常精準的定位,這也導致了YOLO的檢測精度並不是很高。
 

4.2 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幀每秒。

 

主要參考及擴充套件閱讀

1 https://www.cnblogs.com/skyfsm/p/6806246.html,by @Madcola
2 https://mp.weixin.qq.com/s?__biz=MzI1NTE4NTUwOQ==&mid=502841131&idx=1&sn=bb3e8e6aeee2ee1f4d3f22459062b814#rd
3 https://zhuanlan.zhihu.com/p/27546796
4 https://blog.csdn.net/v1_vivian/article/details/73275259
5 https://blog.csdn.net/tinyzhao/article/details/53717136
6 Spatial Pyramid Pooling in Deep Convolutional
Networks for Visual Recognition,by Kaiming He等人
7 https://zhuanlan.zhihu.com/p/24774302
8 知乎專欄作者何之源新書《21個專案玩轉深度學習——基於TensorFlow的實踐詳解》
9 YOLO:https://blog.csdn.net/tangwei2014/article/details/50915317,https://zhuanlan.zhihu.com/p/24916786

相關文章