目標檢測——從RCNN到Faster RCNN 串燒
本人小碩一枚,方向是深度學習的目標檢測,故想把從RCNN到Faster RCNN整個線串一下,理清裡面的整個設計流程和創新思路,也算是對大神的創新思維進行學習。我會不定期改善部落格裡面可能存在的小錯誤,希望大家多多諒解支援啦。另外,在論文中已經講到的點,如果不是特別重要的話,我不會再複述的啦,所以說各位看官先研讀研讀論文先,然後再看看我對這些論文的理解。對了,涉及到哪層是幾乘幾以及那層到底是多少這種細節,在這裡不做太多討論,除非涉及到核心思想,更多的細節將在我之後的部落格——對Faster RCNN原始碼的解讀中進行。
什麼是object detection
object detection我的理解,就是在給定的圖片中精確找到物體所在位置,並標註出物體的類別。object detection要解決的問題就是在哪裡,是什麼,具體在哪裡這整個流程的問題。然而,這個問題可不是那麼容易解決的,物體的尺寸變化範圍很大,擺放物體的角度,姿態不定,而且可以出現在圖片的任何地方,更何況物體還可以是多個類別。故用一般的方法是比較難處理的,這也是為什麼在深度學習興起之前,ILSVRC檢測比賽檢測那麼沉寂的原因,大家都做的太差了嘛~~不過隨著Hinton在2012年的比賽用CNN虐殺其他團隊之後,深度學習以及深度卷積網路再一次進入人們視線,這種比較困難的問題也漸漸有思路了。在開始接觸物體檢測和深度學習時,我想憑藉深度學習強大的擬合能力,給它啥它都能學,最開始的想法是,先訓練出一個網路能分出是否是物體,即先不管是什麼物體,只要bounding box 與ground truth 的IOU大於某個閾值,就認為是正樣本,小於某個閾值為負樣本,然後直接訓練,然後直接給它ground truth,然後用當前框位置與ground truth的歐式距離作為loss,讓它自己去學習什麼是object以及object在哪裡呢,也就是說把這個任務當成分類問題+迴歸問題來做??通過這個網路在一張大圖sliding windows,就能確定存在物體的區域,再根據迴歸,來使得bounding box框得更準。不過實際上,想想就能知道,這種方法是開始沒有任何限制地去學習,這樣會導致任務複雜度非常高,網路會不收斂,而且在測試的時候會非常慢,因為不知道在哪裡有什麼東西,需要sliding windows並且需要不同尺度的縮放,另外並且在RCNN的論文中提到了不加限制直接當迴歸來做實際效果並不是特別好。我覺得不好的原因可能是學習的複雜度太高,這相當於在一開始就沒有給任何限制,讓網路自己去根據自己預測的和真實的框的距離差去學習,這樣子的話,同一種物品在不同位置以不同的大小都可以認為是全新的一個訓練樣本,完全去擬合這樣的任務顯然是不太可能的。所以說,這種問題一定要先降低任務複雜度,然後再去學習降低複雜度的等價任務。當然這是我看了這麼多優秀論文得出的馬後炮式的結論,不過這也恰好說明了Ross Girshick大神科研出RCNN這種跨時代的東東時,思路到底有多麼地超前。他為了降低檢測任務的複雜度,把檢測任務最直觀的在哪裡(迴歸問題),轉化成先用傳統方法先定候選框(通過邊緣特徵啊,輪廓特徵啊什麼的使得整個問題的複雜度降低,我不是全圖搜尋object,而是隻在符合proposals演算法的區域來搜尋),然後在確定是什麼(是背景還是是某種物體),然後根據這些已經判斷是物體的區域(object score分數高於閾值)來進行迴歸(精確位置所在)。通過我以上的分析,我覺得檢測最難做的是網路判斷物體大致在哪裡這個過程,而具體是什麼,精確位置,當知道大致的位置後也就變得異常簡單了。這個思路下來,也就是RCNN,Fast RCNN,Faster RCNN這一條線了。
RCNN 詳解
說了這麼多有關object detection的個人見解,我還是說說這個跨時代的RCNN吧,如果我寫的不夠詳細的話,我相信大家在別的部落格上也能看到RCNN的介紹。流程圖大家應該都比較熟悉了,
RCNN全程就是Regions with CNN features,從名字也可以看出,RCNN的檢測演算法是基於傳統方法來找出一些可能是物體的區域,再把該區域的尺寸歸一化成卷積網路輸入的尺寸,最後判斷該區域到底是不是物體,是哪個物體,以及對是物體的區域進行進一步迴歸的微微調整(與深度學習裡的finetune去分開,我想表達的就只是對框的位置進行微微調整)學習,使得框的更加準確。這就是主要的思路,我去,直接說完了??還是再說一下具體細節吧,這樣也好為下一章過渡一下,哈哈。
正如上面所說的,RCNN的核心思想就是把圖片區域內容送給深度網路,然後提取出深度網路某層的特徵,並用這個特徵來判斷是什麼物體(文章把背景也當成一種類別,故如果是判斷是不是20個物體時,實際上在實現是判斷21個類。),最後再對是物體的區域進行微微調整。實際上文章內容也說過用我之前所說的方法(先學習分類器,然後sliding windows),不過論文用了更直觀的方式來說明這樣的消耗非常大。它說一個深度網路(alexNet)在conv5上的感受野是195×195,按照我的理解,就是195×195的區域經過五層卷積後,才變成一個點,所以想在conv5上有一個區域性的大小(7×7)則需要原圖為227×227,這樣的滑窗每次都要對這麼大尺度的內容進行計算,消耗可想而知,故論文得下結論,不能用sliding windows的方式去做檢測(消耗一次用的不恰當,望各位看官能說個更加準確的詞)。不過論文也沒有提為什麼作者會使用先找可能區域,再進行判斷這種方式,只是說他們根據09年的另一篇論文[1],而做的。這也算是大神們與常人不同的積累量吧。中間的深度網路通過ILSVRC分類問題來進行訓練,即利用訓練圖片和訓練的分類監督訊號,來學習出這個網路,再根據這個網路提取的特徵,來訓練21個分類器和其相應的迴歸器,不過分類器和迴歸器可以放在網路中學習,這也是下面要講的Fast RCNN的內容。
最後補充一下大牛們的針對rcnn的創新思路吧,從上面圖片我們可以把RCNN看成四個部分,ss提proposals,深度網路提特徵,訓練分類器,訓練對應迴歸器,這四個是相對獨立的,每種演算法都有它的缺陷,那麼我們如何對它進行改進呢?如果讓你現在對這個演算法進行改進,該怎麼改進呢??首先肯定能想到的是,如何讓深度網路更好的訓練,之前訓練只用了分類資訊,如果先利用ground truth資訊把圖片與object 無關的內容先cut掉,然後再把cut後的圖片用於深度網路的訓練,這樣訓練肯定會更好。這是第一種思路,另外如果把最後兩個放在一起訓練,並放入深度網路中,這就是joint learning,也就是Fast RCNN的內容,如果把ss也放入深度網路中,成為一個大的網路,則是Faster RCNN的內容。這也就是後面一系列論文的思路了。(這個如何創新的思維是從某某公司的深度學習講座聽到的,我只是深刻學習後地一名合格的搬運工,哈哈。)
SPP詳解
SPP網路,我不得不要先說,這個方法的思想在Fast RCNN, Faster RCNN上都起了舉足輕重的作用。SPP網路主要是解決深度網路固定輸入層尺寸的這個限制,也從各個方面說明了不限制輸入尺寸帶來的好處。文章在一開始的時候就說明了目前深度網路存在的弊端:如果固定網路輸入的話,要麼選擇crop策略,要麼選擇warp策略,crop就是從一個大圖扣出網路輸入大小的patch(比如227×227),而warp則是把一個bounding box的內容resize成227×227 。無論是那種策略,都能很明顯看出有影響網路訓練的不利因素,比如crop就有可能crop出object的一個部分,而無法準確訓練出類別,而warp則會改變object的正常寬高比,使得訓練效果變差。接著,分析了出深度網路需要固定輸入尺寸的原因是因為有全連結層,不過在那個時候,還沒有FCN的思想,那如何去做才能使得網路不受輸入尺寸的限制呢?Kaiming He 大神就想出,用不同尺度的pooling 來pooling出固定尺度大小的feature map,這樣就可以不受全連結層約束任意更改輸入尺度了。下圖就是SPP網路的核心思想:
通過對feature map進行相應尺度的pooling,使得能pooling出4×4, 2×2, 1×1的feature map,再將這些feature map concat成列向量與下一層全連結層相連。這樣就消除了輸入尺度不一致的影響。訓練的時候就用常規方法訓練,不過由於不受尺度的影響,可以進行多尺度訓練,即先resize成幾個固定的尺度,然後用SPP網路進行訓練,學習。這裡講了這麼多,實際上我想講的是下面的 東西, SPP如何用在檢測上面。論文中實際上我覺得最關鍵的地方是提出了一個如何將原圖的某個region對映到conv5的一種機制,雖然,我並不是太認可這種對映機制,等下我也會說出我認為合理的對映方法。論文中是如何對映的,實際上我也是花了好久才明白。
首先,我想先說明函式這個東東,當然我不是通過嚴謹的定義來說明。什麼是y=f(x),我認為只要輸入x,有一組固定的操作f,然後產生一個對應的y,這樣子就算是函式。根據輸入有一個一一對應的輸出,這就是函式。這樣理解的話,卷積也是函式,pooling也是函式。當然我並不想說明函式是什麼,什麼是函式,實際上我想強調的是一一對應這樣的關係。大家都知道,現在默許的無論是卷積還是pooling(無stride),都會加相應的pad,來使得卷積後的尺寸與卷積前相同,當然這種做法還個好處就是使得邊緣不會只被卷積一次就消失了~這樣子的話,實際上原圖與卷積後的圖就是一一對應的關係。原圖的每一個點(包括邊緣)都可以卷積得到一個新的點,這就是一一對應了。如下圖所示(自己畫得太醜):
綠色部分是圖片,紫色部分是卷積核。
如上圖可以看出,藍色的區域是原圖區域,而紅色的區域是padding區域,紫色的是卷積核。卷積後得到的區域與原區域是一一對應的。而卷積或pooling增加stride的話就相當與原圖先進行卷積或池化,再進行sampling,這還是能一一對應的,就這樣原圖的某個區域就可以通過除以網路的所有stride來對映到conv5後去區域。終於把這裡講出來了,大家如果直接按照函式的一一對應關係去理解,很容易理解為什麼原圖的區域除以所有的stride就是對映到conv5的區域。這樣子就可以在原圖上的一些操作放在conv5上進行,這樣可以減小任務複雜度。不過,我並不是太認可這種對映機制,這種對映只能是點到點的關係,不過我覺得從原圖的某個區域R對映到conv5的區域r,應該r對R敏感,換句話說,應該r感受野應該與R有交集。這樣子的話,示意圖如下:
其中藍色的為conv的神經元感受野,紅色的是原圖的某個感興趣區域,而黑色框我才認為是要對映到conv5的區域。
使用SPP進行檢測,先用提候選proposals方法(selective search)選出候選框,不過不像RCNN把每個候選區域給深度網路提特徵,而是整張圖提一次特徵,再把候選框對映到conv5上,因為候選框的大小尺度不同,對映到conv5後仍不同,所以需要再通過SPP層提取到相同維度的特徵,再進行分類和迴歸,後面的思路和方法與RCNN一致。實際上這樣子做的話就比原先的快很多了,因為之前RCNN也提出了這個原因就是深度網路所需要的感受野是非常大的,這樣子的話需要每次將感興趣區域放大到網路的尺度才能卷積到conv5層。這樣計算量就會很大,而SPP只需要計算一次特徵,剩下的只需要在conv5層上操作就可以了。當然即使是這麼完美的演算法,也是有它的瑕疵的,可能Kaiming He大神太投入 SPP的功效了,使得整個流程框架並沒有變得更加完美。首先在訓練方面,SPP沒有發揮出它的優勢,依舊用了傳統的訓練方法,這使得計算量依舊很大,而且分類和bounding box的迴歸問題也可以聯合學習,使得整體框架更加完美。這些Kaiming He都給忽略了,這樣也就有了第二篇神作 Fast RCNN。
Fast RCNN
在我上帝視角(看完整個線)看來,Fast RCNN提出新的東西並不是太多,往往都是別人忽略的東西,實際上也算是對SPP上的撿漏。當然大神能夠找到漏可以撿,所以說這並不是貶義,只是我感覺對這篇論文客觀的評價。首先fast rcnn說無論是訓練還是測試都比RCNN 和SPP快很多倍。其次,自己提出了一個特殊的層RoI,這個實際上是SPP的變種,SPP是pooling成多個固定尺度,而RoI只pooling到一個固定的尺度(6×6)。網路結構與之前的深度分類網路(alex)結構類似,不過把pooling5層換成了RoI層,並把最後一層的Softmax換成兩個,一個是對區域的分類Softmax(包括背景),另一個是對bounding box的微調。這個網路有兩個輸入,一個是整張圖片,另一個是候選proposals演算法產生的可能proposals的座標。訓練的時候,它指出了SPP訓練的不足之處,並提出新的訓練方式,就是把同張圖片的prososals作為一批進行學習,而proposals的座標直接對映到conv5層上,這樣相當於一個batch一張圖片的所以訓練樣本只卷積了一次。文章提出他們通過這樣的訓練方式或許存在不收斂的情況,不過實驗發現,這種情況並沒有發生。這樣加快了訓練速度。另外,它同時利用了分類的監督資訊和迴歸的監督資訊,使得網路訓練的更加魯棒,而且效果更好。值得注意的是,他在迴歸問題上並沒有用很常見的2範數作為迴歸,而是使用所謂的魯棒L1範數作為損失函式(可能在其他地方很常見,不過我是第一次見)。實際訓練時,一個batch訓練兩張圖片,每張圖片訓練64個RoIs(Region of Interest),前向反向計算就不說了,如果把pooling的反向計算理解了,這個roi應該不會太難。這篇論文提到了一個讓人引發遐想的地方就是它將比較大的全連結層用SVD分解了一下使得檢測的時候更加迅速。雖然是別人的工作,但是引過來恰到好處。最後作者寫了個類似討論的板塊,並從實驗角度說明了多工對訓練是否有幫助?尺度不變性如何實現?是單尺度學習還是多尺度學習?(注意,這裡的尺度是對整張圖片的resize尺度)得到的結論是多尺度學習能提高一點點map,不過計算量成倍的增加了,故單尺度訓練的效果更好。最後在SVM和Softmax的對比實驗中說明,SVM的優勢並不明顯,故直接用Softmax將整個網路整合訓練更好。
Faster RCNN詳解
就像之前在RCNN章節提到的創新思路所說,Faster RCNN 將selective search這樣的演算法整合到深度網路中,這樣不光解決了selective search這樣的演算法是cpu實現,速度慢的問題,而且與深度網路相結合,共享前面的卷積計算,這樣做計算效率更高。而其他部分則與Fast RCNN差異不大。故這裡主要講些Region Proposal Networks的設計和訓練思路。
上圖是RPN的網路流程圖,即也是利用了SPP的對映機制,從conv5上進行滑窗來替代從原圖滑窗。不過,要如何訓練出一個網路來替代selective search相類似的功能呢??實際上思路很簡單,就是先通過SPP根據一一對應的點從conv5映射回原圖,根據設計不同的固定初始尺度訓練一個網路,就是給它大小不同(但設計固定)的region圖,然後根據與ground truth的覆蓋率給它正負標籤,讓它學習裡面是否有object即可。這就又變成我介紹RCNN之前提出的方法,訓練出一個能檢測物體的網路,然後對整張圖片進行滑窗判斷,不過這樣子的話由於無法判斷region的尺度和scale ratio,故需要多次放縮,這樣子測試,估計判斷一張圖片是否有物體就需要n久。如何降低這一部分的複雜度??要知道我們只需要找出大致的地方,無論是精確定位位置還是尺寸,後面的工作都可以完成,這樣子的話,與其說用小網路,簡單的學習(這樣子估計和蒙差不多了,反正有無物體也就50%的概率),還不如用深的網路,固定尺度變化,固定scale ratio變化,固定取樣方式(反正後面的工作能進行調整,更何況它本身就可以對box的位置進行調整)這樣子來降低任務複雜度呢。這裡有個很不錯的地方就是在前面可以共享卷積計算結果,這也算是用深度網路的另一個原因吧。而這三個固定,我估計也就是為什麼文章叫這些proposal為anchor的原因了。這個網路的結果就是卷積層的每個點都有有關於k個achor boxes的輸出,包括是不是物體,調整box相應的位置。這相當於給了比較死的初始位置(三個固定),然後來大致判斷是否是物體以及所對應的位置,這樣子的話RPN所要做的也就完成了,這個網路也就完成了它應該完成的使命,剩下的交給其他部分完成就好了。
以上就是我對object detection的RCNN,Fast RCNN, Faster RCNN的整個理解,寫的比較倉促,而且是讀完整條線的論文才決定寫這篇部落格的,故有很多是回憶的,卻又懶得再向文章確認,不過之後的部落格會邊讀邊寫。
我這也是第一次寫部落格,如果有理解不對的地方或者邏輯上有不對的地方,請大家指出來,糾正我的錯誤。