1. 程式人生 > >faster R-CNN 框架總結

faster R-CNN 框架總結

這幾天在學習faster R-CNN,看到一篇文章總結得很棒,特轉來學習。

轉自:https://zhuanlan.zhihu.com/p/32905770

論文:Towards Real-Time Object Detection with Region Proposal Networks

code:matlab ShaoqingRen/faster_rcnn,python AssetionError: training py-faster-rcnn with one class · Issue #34 · rbgirshick/py-faster-rcnn

論文筆記:【目標檢測】Faster RCNN演算法詳解

CNN目標檢測(一):Faster RCNN詳解faster-rcnn原理及相應概念解釋

上圖是論文給出的faster rcnn框架圖,再細緻一點的話,就是:

此圖來自於https://zhuanlan.zhihu.com/p/35922980

VGG網路

faster rcnn中使用的VGG16,沒有全連階層

論文主要內容

一、論文主要解決三個問題

1.設計RPN網路,生成推薦區域;

2.用fast rcnn 檢測推薦區域;

3.使RPN和fast rcnn共享卷積特徵提取網路。

二 、主幹網過程

主幹網可以採用VGG16、resnet101等網路模型,進行特徵提取。採用VGG16的話,對輸入[1, W, H, 3]的圖片(這個batch size我設為1了)。進行多層卷積操作。輸出是一個[1, W/16, H/16, 512]維的特徵形式,即feature map。

假設輸入圖片尺寸是[1, 256, 256, 3],那麼VGG16之後,feature map中,特徵形式為[1, 16, 16, 512],記P=Q=16。

三、獲得標準anchor過程

1.anchors(初始的推薦區域)

在feature Map上,對於每一張影象的每一個位置,生成9個初始的推薦區域(即anchors),這9個推薦區域的大小、尺寸是三種面積*三種比例,即 \left\{ {{128^{2},256^{2},512^{2}}} \right\}\times\left\{ 1:1,1:2;2:1 \right\} 。

在論文公佈的程式碼中,generate_anchor.py執行得到的9個初始化anchor輸出如下:

-83 -39 100 56
-175 -87 192 104
-359 -183 376 200
-55 -55 72 72
-119 -119 136 136
-247 -247 264 264
-35 -79 52 96
-79 -167 96 184
-167 -343 184 360

注意,這裡面對座標進行了取整,因此,在進行驗證的時候可能計算出來的面積與給定的面積有點出入,但是沒有關係。每一行的四個數分別代表{xmin,ymin,xmax,ymax}。這9個初始化anchor的中心點座標都是[7.5,7.5],這個座標是在feature map上面的。 \left\{ 128^{2},256^{2},512^{2} \right\} 三種面積的長寬分別為:

128 128;128/1.414 128*1.414;128*1.414 128/1.414;

256 256;256/1.414 256*1.414;256*1.414 256/1.414;

512 512;512/1.414 512*1.414;512*1.414 512/1.414;

每個點有9個anchor,那麼[1, 16, 16, 512]的特徵向量共有16*16*9個anchor(~2400)。

anchor得到以後都要對映到原影象上面,對於特徵圖大小為[16,16]每個點有9個anchor,原圖為[256,256]。即

[0,1,2,…,15]--->[0,16,32,…,240]

那麼特徵圖上的座標[0 0; 0 1; …;14 15; 15 15]對應到原圖就是[0 0; 0 16; …;224 240;240 240]。

首先計算出所有以特徵圖上的座標為中心的anchor,然後將所有以特徵圖上的座標為中心的anchor全部轉換到以原圖座標為中心的anchor。一般影象上原點是影象左上角,向下為y軸正方向(高),向右為x正方向(寬)。

記原圖上面anchor的中心點為 x_{a},y_{a} 。那麼原圖上面,anchor表示為 [x_{a},y_{a},w_{a},h_{a}] ,表示anchor的中心點座標和寬、高。原圖上面的這個anchor稱為標準的anchor輸出,也可以叫做box。

每個點的anchor

四、RPN過程

RPN,其中的k指的是k個初始的anchors,論文中k=9

該部分的主要內容是通過卷積網路得到每個anchor是否是前景的概率以及每個anchor的座標、尺寸的偏差。

偏差計算公式如下:

偏差計算公式

其中

即公式中的 x_{a},y_{a},w_{a},h_{a} 即上一部分中的標準的anchor的相關資料。

但是 x,y,w,h 是如何獲得的呢?

論文采用一個3*3的滑動視窗對feature map進行卷積操作。feature map大小為[P, Q, 512],得到的輸出大小仍然是[P, Q, 512]。然後再對這個輸出分兩部分進行操作(這一塊要看看程式碼)。

cls layer:一路進行[1, 1, 512, 18]的卷積操作。輸出大小是[P, Q, 9*2]。這裡很好理解,每個點有9個anchor,相當於對每個anchor對應生成一個1*2的向量,用來表示這個anchor是不是目標。我們可以令[1, 0]代表這個anchor是目標,[0,1]表示是框的是背景。當然,因為要歸一化到0,1所以要經過一個簡單的reshape把每個1*2的向量單獨分出來再做一個softmax分類。這樣分類之後再reshape回去就可以了。這一路輸出得到輸出大小是[1, P, Q, 9*2],記為rpn_cls_prob。

reg layer:另一路同樣經過[1, 1, 512, 9*4]的卷積操作得到[P, Q, 9*4]的輸出,對應的是每個點的每個anchor的四個偏移量 。為什麼要四個偏移量呢,因為我們前面的anchor就是一個定值,而實際的物體box和前面的anchor肯定有偏差。所以我們再用四個偏差來進行一次box的修正(偏差計算公式),獲得 x,y,w,h ,這些值都是原圖上的。該部分的輸出是[1, P, Q, 4*9],記為rpn_reg。

如下圖所示,圖片中所示的feature map 深度是256,我在前面計算的feature map是512的深度(VGG16網路)。以256深度為例子,介紹cls layer和reg layer。

由於anchor是對於每張圖的每個位置,都有9個初始的anchors,那麼首先只看一個位置的:

那麼對於整個feature map,則是:

修正後的box,我們稱為第一次修正後的box。該box是對標準輸出的anchor做平移和尺寸縮放。如下圖所示,黑色的box是標準anchor,紅色的box是第一次修正後的box,綠色的box是真實的box(ground truth)。

五、proposal過程

RPN過程獲得了第一次修正後的所有box以及每個box所對應的概率。proposal過程是根據每個第一次修正後的box的值,選取出合適的部分box,再反向投影到前面得到的[1, P, Q, 512]的feature map上。

首先,對第一次修正後的box進行判斷,如果box的大小超出了邊界,那麼就將這一邊改成邊界值,我們令這個修正後的輸出是proposal_clip_box,其輸入是rpn_reg獲得的第一次修正後的圖。

其次,對所有輸出的proposal_clip_box和真實的ground truth box求重合度IoU,進行篩選。

那麼IoU是什麼?假設proposal_clip_box的面積為SA,真實box面積為SB,兩者的重疊面積為 SA and SB。那麼IOU:

IoU=\frac{SA\cap SB}{SA \cup SB}

篩選規則如下:

  • 與GT相比,擁有最高的IOU的anchor為前景(可以低於0.7)
  • 與任意GT相比,IOU>0.7為前景
  • 與任意GT相比,IOU<0.3為背景
  • 其餘的非負非正,則沒有用

那麼對於proposal_clip_box,怎麼比較其IoU呢?

step 1,用scores表示rpn_cls_prob([1, P, Q, 2*9]),取第四維度的後九位數,這九位數表示真實物體的概率。見下圖

將其reshape成向量,使scores=[1, P*Q*9]。我們再按大小排序後取出對應的索引值。取scores比較大的前topN個(12000),進行NMS(非極大值抑制)。

step 2,NMS(非極大值抑制)。什麼是NMS?

所謂非極大值抑制:先假設有6個輸出的矩形框(即proposal_clip_box),根據分類器類別分類概率做排序,從小到大分別屬於車輛的概率(scores)分別為A、B、C、D、E、F。
(1)從最大概率矩形框F開始,分別判斷A~E與F的重疊度IOU是否大於某個設定的閾值;
(2)假設B、D與F的重疊度超過閾值,那麼就扔掉B、D;並標記第一個矩形框F,是我們保留下來的。
(3)從剩下的矩形框A、C、E中,選擇概率最大的E,然後判斷E與A、C的重疊度,重疊度大於一定的閾值,那麼就扔掉;並標記E是我們保留下來的第二個矩形框。
就這樣一直重複,找到所有被保留下來的矩形框。

如上圖F與BD重合度較大,可以去除BD。AE重合度較大,我們刪除A,保留scores較大的E。C和其他重疊都小保留C。最終留下了C、E、F三個。

比較IoU並進行篩選的整體過程

該過程後,得到大約2000個box(稱為blob)。

真正的proposal過程:將這些blob反向投影到前面的feature map上得到對應的2000個rois。Blob表示的是原圖上的box大小,rois表示的是投影到[1, P, Q, 512]的feature map上時對應的box大小。經過這個反向投影就得到了2000個roils了(圖裡維度是[2000,5]而不是[2000,4]是因為加了一維全0的項用於表示一個圖片,要是多張圖片就要改了)。

六、predict

前面得到了所有的rois後就可以進行最後的預測模型了。假設我們的一個rois取出來大小是[10, 10, 512]即從原影象投影到feature map上大小變成[10, 10]。我們後面分類的時候要複用同一個卷積網路,所以對不同大小的rois要池化成同一個大小的輸入:這裡統一池化成[7, 7, 512]。

Rois pooling過程:將輸入特徵先進行 的均勻劃分,然後對分的每一塊進行max pooling即可。 太大,我們以 輸出為例子:

max pooling

經過前面rois pooling後我們對每個roils得到了固定尺寸的特徵矩陣。然後可以進行分類卷積操作。分類時一樣進行兩路。兩路輸入都是[256, 7, 7, 512],256代表有多少個roils。將這個值進行兩次全連線輸出[256, 4096]。然後再分開兩個全連線,一個輸出大小[256, classes numbers], classes numbers是我們的目標物體分類數,假設是10分類的任務,那麼就是10。輸出經過softmax後是One hot形式。另一路輸出[256, classes numbers*4],表示對256個box的第二次修正偏差值 。因為上面雖然修正一次了但是可能還不太正確,這裡再修正一次。修正方法和上面一樣。修正後就可以得到我們最後真正的輸出了。同樣還可以得到每個box的分類概率。通過分類概率大小我們設定一個閾值,當分類概率達到一定閾值之後才輸出。這樣就可以將所有可能的目標的box和分類類別畫出來了。

七、損失函式

採用分類損失+迴歸損失兩種相結合的方式。

其中, i 是mini-batch中的anchor的索引, p_i 表示anchor i是前景的預測概率, p_{i}^{*} 表示anchor i是真實類別的概率:如果anchor i是前景,則p_{i}^{*}為1,否則為0。 t_i 是網路輸出的四個引數組成的向量,t_{i}^{*}代表一個是前景的anchor變為GT的四個引數組成的向量,可以看到 L_{reg} 前乘以了 p^*_i ,說明只有當這個某個anchor的確是前景時才有迴歸損失。另外,N_{cls}是mini-batch的大小(256),N_{reg}是anchor位置的數量(~2000),\lambda 為10,意思是兩種損失基本上同樣重要。

注意:由於在RPN階段有一個分類和迴歸,最後的預測階段也有一個預測和迴歸,因此損失的計算是這兩部分的之和。

八、訓練

RPN的訓練方法:

(1)採用反向傳播和SGD(stochastic gradient descent)進行end to end的訓練;

(2)訓練初始化的時候,其新層的權重服從標準偏差為0.01、均值為0的高斯分佈,其他層的權重通過使用ImageNet分類預訓練的模型獲得。

九、共享卷積特徵提取網路

如何共享,本文提供了三種方法

(1)輪流訓練:

記W0為使用ImageNet的分類庫得到初始引數,那麼

a. 從W0開始,訓練RPN。用RPN提取訓練集上的候選區域,並對區域推薦任務進行end to end的微調。

b. 從W0開始,使用a步驟中RPN生成的區域推薦,fast rcnn訓練檢測網路,獲得W1。

c.從W1開始,訓練訓練RPN。

d.保持共享網路的引數值,對屬於fast rcnn獨有的層進行微調。

這也是本文中採取的方式。

(2)近似聯合訓練

(3)聯合訓練

 

----------------------------------------------------------------------

下面內容來自於Faster R-CNN學習總結,這裡貼出來,自己學習。

怎麼從同一個256維的向量中區分出9個框並挨個評分呢?論文中寫道:並沒有顯式地提取任何候選視窗,完全使用網路自身完成判斷和修正。結合損失函式是不是能看出來什麼。

對於一個網路,我們已經提供了所有的資訊(感受野包含了9個anchor boxes),我們想朝著什麼方向來訓練(這裡就是為9個anchor boxes打分和迴歸)則由損失函式來決定,即損失函式決定了網路擁有什麼樣的能力:我們想網路能識別手寫數字,就讓網路輸出與對應的手寫數字資訊相差最小;我們想讓網路識別人臉,就讓網路輸出與對應的人臉資訊相差最小。ok,這裡我們想讓網路能夠為9個anchors打分並回歸,那麼我們就讓網路的輸出與anchor boxes真實的情況(是否為前景以及與GT的位置偏差)相差最小。而損失函式中 p_i^* 以及 t_i^* 不就是不同anchor boxes的真實情況嗎。所以我們給網路提供了完整的資訊,確定了它的訓練目的,那麼它最終就能做到想要的任務(這裡說的有點絕對,只是為了方便理解)

再結合之前說的"最後那18個卷積核和36個卷積核都有自己的任務:針對同一位置不同Anchor或者同一Anchor的不同的指標(是否是前景,以及迴歸意見等)",可以把網路看成學習了9個前景/背景打分器,9個線性迴歸器。每個打分器對一個點的某種anchor判斷是前景還是背景,每個線性迴歸器對一個點的某種anchor進行位置修正。

說了這麼多隻是希望大家能理解為什麼從同一個256維的向量中能學到這麼多東西(這裡確實很難理解,可能我也理解的有誤,但是這是目前我唯一能想到的,並說服自己的一個想法了。如果不對,希望大佬們能指一條明路)

有了打好分的anchor boxes以及初步修正意見,再結合原圖的一些資訊就能經由圖2中的Proposal層來得到輸入影象的Region Proposals(這裡面又涉及到NMS,以及剔除超出影象邊界的ROI,細節感興趣的可以自行了解,因為對全文的理解不會有太大影響,我也沒有深入了,主要是時間不夠,後面可能會再來更新這一部分)。這樣RPN就代替SS演算法產生了輸入影象的Region Proposals(也就是ROI),剩下的事情例如在feature map中找到Region Proposals對應的部分等就和Fast R-CNN一模一樣了。