[物件偵測] S2: Fast R-CNN 簡介

Ivan
7 min readAug 30, 2019

--

本文同步發表於我的 GitHub page

前言:

回顧一下R-CNN的問題點:

  1. 訓練分太多階段
  2. 訓練消耗太多硬體資源和時間。因為每次要取BBox的feature vector,都需要將每一張影像的region proposals的執行一次CNN,並且將vector存到硬碟上。
  3. 對一張影像進行detection需要47秒的時間(on GPU)

所以,繼R-CNN之後,為了讓速度、精度表現更加出色,所以作者很快的就修改了運算上的順序、結構性的問題、簡化model的設計來提昇運算速度,上detection的表現上升到了2s/image。

論文:
Fast R-CNN

演算法結構:

Fast R-CNN的架構如下圖所示:

https://jhui.github.io/2017/03/15/Fast-R-CNN-and-Faster-R-CNN/

基本上,重要的改變有:

  1. 拿掉SVM結構,改以softmax作為Classification的NN
  2. 一樣是用selective search提出Region Proposals,或叫做ROI (Region of Interest),但是改為先將整張影像通過conv.得到feature map後,將ROI映射在map上來取真正要用的ROI,因此一張影像只須過一次Convolution,也就節省掉很多的計算和硬體資源。
  3. 利用ROI pooling layer來統一ROI送進Fully-connected layer (FC)層前的維度。

以下就自架構圖的下到上說明各部件的的細節。

> Region Proposals:

這裡一樣是使用selective search的方式提出2000個region。不過,並不是將原始影像依據region來切割後送入backbone network中的。而是將region映射到CNN最後的feature map上才切出我們真正要拿來使用的ROI。

> Backbone Network - VGG16:

這次到了Fast R-CNN,backbone的部份換成了VGG16。而在最後一層convolution block的最後一個conv.所得到的feature map (shape=14*14*512),就是剛剛ROI要映射到的目標層,所以這裡的ROI才是我們真正要使用的。
但是,ROI的長寬不一樣要怎麼辦呢?所以作者將原本接的最後一個pooling layer取代掉,換成可以將size固定的ROI Pooling layer。

VGG16 Network Structure

> ROI Pooling Layer

ROI可能是很多不同的長寬構成的框框,而VGGnet的FC層要以7x7的feature map為輸入,所以在ROI pooling layer中,我們要做的事就是「在14x14的feature map上,切出ROI後,以pooling手法將ROI輸出成7x7」。

這個層的機制,我就用下圖來舉個例子直覺說明。假定今天要在一個8x8的map上做ROI pooling,如下圖。

若今天Region proposal映射到這個map上的尺寸是7x5(如下圖紅框),且我們要將ROI輸出成2x2的大小,就會將下圖的紅框分割成2x2(如下圖虛線,因為長寬7,5無法被2整除)。接著就可以透過max-pooling來取值。

> Detector:

在後面的分類器,從FC層後分成兩支進行,第一支是分類器,由原本的SVM改成了FC層的softmax。特別注意到的是,分類的類別數量因為要讓背景獨立成一個類別,所以是K+1個。而第二支就是bbox regressor,則是沒什麼變化。

> Loss:

因為分類器都變成了整個網路中的一部分,所以作者就設計了一套整合所有目標的loss function:

其中,
p:K+1個類別的分類機率
u:目標類別
tu:則是如同R-CNN中所述的預測的bbox和groud-truth之間的offsets
v:ground-truth box

所以,Lcls就是分類部份的loss,是對與真實目標的誤差取-log。而[u>=1]標誌的意思是,若u>=1則為1,反之則為0。也就是說如果一個ROI落在背景的區域而沒有物體,則值等於0,也就不用考慮到bbox的誤差Lloc

而Lloc的式子如下:

他是採用smooth L1的損失函數設計,為的是讓函數對離群值得反應不要那敏感。

簡單用下面這張圖來看,因為一般採用L2的損失函數,會因為平方的關係而使得誤差反應被離群值主導。採用Smooth L1,除了在0值附近以0.5的倍數降低反應以外,在大於1以外的離群值部份,就採用線性的方式表示,來將誤差的呈現趨於平緩。因此雖然L2的函數通常收斂較快,但也同時需要一個較好的起始點,才能避免函數無法收斂。然而Smooth L1就是讓它順順的收斂,比較不容易讓誤差爆炸。

總結

到這邊,算是講完Fast R-CNN的架構思路。也因為這些調整,讓Fast R-CNN的速度比R-CNN的速度快上25倍之多。最後我們再總結一下Fast R-CNN的重點:

  1. 改變ROI sampling的邏輯,讓原本要重複運作2000次的特徵提取,變成只對原始影像做一次特徵提取,而讓原圖上的region proposals映射到feature maps上做sampling。
  2. ROI pooling層統一ROI送進FC層的維度。
  3. 使用多目標的loss function,使得原本R-CNN的多層訓練變成簡單的back-propagation。

這些進步,讓Fast R-CNN的mAP也比R-CNN略高一點,但速度加快很多(2s/image)。而且訓練的速度也增加了將近9倍的時間(9.5hr)。

當然它還是有缺陷的。

其實測試的時間並沒有含括提出proposals的時間,所以納入了selective search在提出proposals的過程,其實表現還遠遠不足以應用。因此,後人提出了將region proposals的部份,也用NN一併解決,整合進網路中,也就誕生了Faster R-CNN。

以上是我個人對這篇論文的消化,如果有錯誤之處,請各位朋友指教或幫我指出,謝謝!

--

--

Ivan

Coding | Machine Learning | 攝影 | 旅遊 工作現在是個製程仔,以後會是甚麼我還不知道,所以邊書寫文章、邊思索生涯、邊閱覽生活。https://yuweichiu.github.io/