1. 程式人生 > >Faster-RCNN和Region Proposal Network

Faster-RCNN和Region Proposal Network

論文閱讀

RPN是一種全卷積網路,同時預測目標的邊界和目標在沒個位置的目標可信度得分。解決了region Proposal的計算瓶頸。傳統的SS(selective search)方法比較耗時,佔據了目標檢測的大部分時間。本文使用一個深度網路計算Proposals,得出一個優雅而有效的解決方法,使得Proposals的計算幾乎不佔用目標檢測網路的時間。提出的RPN網路與經典的目標檢測網路共享卷積層。通過在測試時共享卷積層,計算region Proposal的邊際成本變得很小。
我們發現基於region的目標檢測網路的卷積feature map 也可以用到生產region Proposals中。因此在卷積特徵的頂層,我們通過使用額外的兩層卷積層來構建RPNs:其中一個是把卷積特徵平面上的每個位置編碼為一個短的特徵向量(maybe 256);另一個在每一個卷積特徵層的每個位置輸出一個“是目標的得分”,並對k(maybe 9)個region Proposal的邊界和尺度和位置的迴歸。
我麼的RPN網路是一種全卷積網路(FCN,簡單的來說,FCN與CNN的區域在把於CNN最後的全連線層換成卷積層,輸出的是一張已經Label好的圖片。

FCN),可以使用端到端的方式訓練用於產生目標檢測Proposals。為了把我們的RPNs 和FAST Rcnn網路統一到一個框架中,我們提出了一個訓練框架:交替訓練優調region Proposal任務和目標檢測任務。這種方法可以很快收斂並且可以生成一個共享卷積特徵的統一網路框架。
使用該框架的網路檢測精度浩宇fast rcnn,而且用於計算啊region Proposal的時間只有10ms。使用VGG,可以達到5fps。

RPN

RPN輸入一個任意大小的影象,輸出一組矩形目標候選區,每個候選區有一個是目標或者背景的分數(“Objectness” measures membership to a set of object classes vs. background)。我們吧這個過程使用FCN(fully convolution network)建模。因為我們的最終目標是與Fast rcnn目標檢測網共用部分計算,我們設定這兩個net共享部分卷積層。我們使用了ZFnet,共享5層卷積層,VGG共享13層卷積層。
為了生產region Proposals,我們在最後一層共享的卷積層輸出的feature map 上滑動一個小得網路
,這個小的網路把輸入的feature map全連線到一個nXn的空間視窗。每個小的滑動視窗對映到一個低維的向量上(256dfor ZF,512 for VGG)。這個向量輸入到兩個(並列)兄弟全連線網路層:一個框迴歸層(reg)和一個框分類層(cls)。本文中我們設定n=3,注意到輸入影象上的有效對映場較大。這個小網路如下圖所示:
RPN


因為這個小網路是滑動視窗風格,全連線層在整個空間上是共享的。這種架構自然地使用一個nXn的卷積層跟著兩個1X1的卷積層(cls,reg)。Relu在nXn卷積層之後。

轉換不變anchors

在每個滑動視窗位置,我們同時預測k個候選區域,我們的reg層需要4k個輸出以編碼k個框的座標。我們的cls層需要輸出2k個引數來估計每個Proposal的是目標/不是目標的概率。k個Proposals通過k個參考框(稱之為Anchor)設定。每個anchor在所討論的滑動視窗中心,並通過尺度和縱橫比想關聯。我們使用三種尺度和3中縱橫比,即9個anchors 在每個滑動視窗。因此對於一個W*H的特徵圖,共有W*H*K個anchors。我們的方法的一個特點是在anchors和與anchors相關的計算中都保持轉換不變性。不變性與MultiBox方法相比減少了引數的數量,減小了過擬合的風險。

學習RP的損失函式(loss func)

為了訓練RPNs,我們對每個anchor設定了一個二分類的標籤(是/不是目標)。我們設定兩種anchors為正樣本:(i) the anchor/anchors with the highest Intersectionover-Union (IoU) overlap with a ground-truth box,與Groud-truth-box 有最大的IOU;(ii) an anchor that has an IoU overlap higher
than 0.7 with any ground-truth box,IOU大於0.7的Anchor。因此一個Ground-truth box可能對應多個正樣本Anchors。如果一個Anchor的對於任何ground-truth box的IOU都小於0.3,設定為負樣本。其他樣本不在訓練中使用。
根據以上定義,我們的最小化目標函式按照Fast RCNN中的多工損失函式:
loss function
i代表anchor的索引,pi為Anchor i是目標的概率,anchor是目標則pi*為1,否則為0;ti是表示預測邊界框的4個引數化座標的向量,ti*是與正樣本Anchor相關聯的Ground-truth框座標向量;分類損失函式Lcls is log loss over two classes (object vs. not object)(???);迴歸損失函式為R(ti-ti*),其中R是具有魯棒性的損失函式(maybe smooth L1)(???);pi*Lreg項表示只有當為正anchor該項被啟用。網路的輸出包含pi和ti,這兩項通過Ncls和Nerg歸一化,通過lamda超參平衡。對於迴歸,我們採用4座標的引數化方法:
引數模型
xywh分別代表中心座標和寬高;x,xa,x*分別代表預測的box,Anchor box和Ground-truthbox。這可以當做是從Anchor box到最近的GT box迴歸。
我們的bounding-box迴歸不同於之前的基於feature map的方法。原來的方法對來自任意大小區域的特徵進行邊界迴歸,並且所有區域大小共享迴歸權重。在我們的公式中,用於迴歸的特徵在特徵圖上具有相同的空間大小(n×n)。為了解決不同大小的問題,我們學習了k組邊界迴歸值。每個迴歸負責一個比例和一個縱橫比,k個迴歸不共享權重。因此,即使特徵具有固定的尺寸/尺度,仍然可以預測各種尺寸的boxes.

優化

RPN是FCN的自然應用,可以使用端到端的訓練方法,使用後向傳播和隨機梯度下降法訓練。我們使用以影象為中心的樣本策略訓練網路。每個mini-batch都是由一個單一的影象產生的,它包含許多正負的anchors。可以對所有anchor的損失函式進行優化,但是它們將偏向負向樣本,因為負樣本佔大多數。相反,我們在影象中隨機抽取256個錨點來計算小批量的損失函式,其中取樣的正和負錨點的比率為1:1。如果影象中少於128個正樣本,則使用負樣本填充小批量。我們通過從具有標準偏差0.01的零均值高斯分佈繪製權重來隨機初始化所有新層(RPN)。所有其他層(共享轉換層)通過預先訓練ImageNet分類的模型來初始化。我們tune ZF網路的所有層,VGG網路優調conv3 1及以上層,以節省記憶體。在PASCAL資料集上,對於60k小批量,我們使用0.001的學習率,接下來的20k小批量的學習率為0.0001。我們也使用0.9的動量,重量衰減為0.0005

RPN和目標檢測共享卷積特徵

目標檢測使用Fast-rcnn,RPN和Fast RCNN獨立訓練,使用不同的方式修改卷積層。因此,我們需要開發一種允許在兩個網路之間共享conv層的技術,而不是學習兩個單獨的網路。原因是快速R-CNN訓練取決於固定object Proposal,並且不太明確,學習快速R-CNN同時改變Proposal機制是否會收斂。這種聯合優化是未來工作的一個有趣的問題,我們開發了一種務實的4步訓練演算法,通過交替優化來學習共享特徵。
第一步:訓練上述的RPN,該網路使用ImageNet預先訓練的模型進行初始化,並針對RP任務進行端到端的微調;
第二步:我們使用第一步RPN生成的提案,通過Fast R-CNN訓練單獨的檢測網路;
第三步:我們使用檢測器網路來初始化RPN訓練,但是我們固定共享cov層,並且僅微調RPN的層;
第四步:最後,保持共享的cov層固定,我們微調fast R-CNN的fc層。 因此,兩個網路共享相同的cov層並形成統一的網路。

應用細節

使用相同大小的圖片訓練和測試RPN和目標檢測而網路。
針對Anchors,三種尺度:128,256,512,三種縱橫比:1:1,;1:2,2:1;我們注意到,我們的演算法允許在預測大的RP時使用比底層接受域大的anchor框。這樣的預測並不是不可能的 - 如果只有物件的中間是可見的,那麼還可以粗略地推斷物件的範圍。我們的解決方案不需要多尺度功能或多尺度滑動視窗來預測大型區域,從而節省大量的執行時間。跨影象邊界的anchor box需要小心處理。在訓練過程中,我們忽視所有的跨境Anchors,以免造成損失。然而,在測試期間,我們仍然將全卷積RPN應用於整個影象。 這可能會產生跨邊界rp框,我們將剪輯到影象邊界(???)。
一些RPN Proposal相互重疊,為了減少冗餘,我們根據其cls分數對提案區域採用非最大抑制(NMS)。我們固定IoU為0.7作為NMS的閾值,這使得我們每個影象大約有2k個提RPs。正如我們將展示的,NMS不會損害最終的檢測精度,而是大大減少了RP數量。在NMS之後,我們使用排名前N位的RPs區進行檢測。 以下,我們使用2k RPNRP訓練Fast R-CNN,但在測試時評估不同數量的Proposal。

paper實驗結果(移步論文)

mAP:目標檢測中衡量識別精度的指標是mAP(mean average precision)。多個類別物體檢測中,每一個類別都可以根據recall和precision繪製一條曲線,AP就是該曲線下的面積,mAP是多個類別AP的平均值。目標檢測評價指標解釋

程式碼閱讀

實驗測試

按照github裡的說明一步一步執行。

  1. 問題1:

AttributeError: ‘dict’ object has no attribute ‘iteritems
錯誤1
Python3.5中:iteritems變為items
把setup.py line 53 修改一下即可。

  1. 問題2:

cudnn.hpp:108:70: error: too few arguments to function ‘cudnnStatus_t cudnnSetConvolution2dDescriptor(cudnnConvolutionDescriptor_t, int, int, int, int, int, int, cudnnConvolutionMode_t, cudnnDataType_t)’
用新版的caffe替換檔案。
1.cp caffe裡的cudnn.hpp ./include/caffe/util/cudnn.hpp
2.將./src/caffe/layer裡所有以cudnn開頭的檔案,如cudnn_xxx_layer.cu,cudnn_xxx_layer.cpp
都替換成最新版的caffe裡的相應的同名檔案。

  1. 問題3:

error: ‘activ_desc_’ was not declared in this scope
cudnn::createActivationDescriptor(&activ_desc_, CUDNN_ACTIVATION_RELU);
解決方法:將./include/caffe/layers的,所有以cudnn開頭的檔案,例如cudnn_conv_layer.hpp,cudnn_lcn_laye.hpp

都替換成最新版的caffe裡的相應的同名檔案 。
執行./tools/demo.py 提示:No module named ‘easydict’
解決方法:
為了確保正確install ,我把python2,python3,和anconda3 的python全部安裝一次,暴力。
這個東西已使我瘋狂,凌晨兩點半

libopencv_imgcodecs.so:對‘[email protected]_0’未定義的引用
解決:cd /usr/lib/x86_64-linux-gnu
sudo ln -s ~/anaconda/lib/libpng16.so.16 libpng16.so.16
sudo ldconfig
問題4:src/caffe/test/test_smooth_L1_loss_layer.cpp:11:35: fatal error: caffe/vision_layers.hpp: No such file or directory
then simply removed src/caffe/test/test_smooth_L1_loss_layer.cpp file from running by renaming it to test_smooth_L1_loss_layer.cpp.orig.
This issue should be the only problem in make testand in make runtest. If both pass, you can expect the demo to run smoothly on your GPU.
問題5:這個問題困擾兩天,極度崩潰。
ImportError: /home/zero/Documents/caffe-master/python/caffe/_caffe.so:undefined symbol:
_ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE
解決方法:http://blog.csdn.net/donatellobzero/article/details/51304162
這個錯誤的意思是,boost版本不匹配。
boost.python是啥東西呢?我理解的是boost.python是一個類似翻譯器的東西,所以如果你是python3的程式,卻用了python2的翻譯器,那語法、定義等等各方面必然會有衝突。我記得在某篇帖子中看到過,str、int等等的定義,在兩者中是不同的,所以有時會有報錯資訊說找不到str啦int啦之類。當時沒有把沒一個錯誤都記下來。
然後,如果我們去makefile中查詢這個變數PYTHON_LIBRARIES,會發現有這麼一句:

PYTHON_LIBRARIES := boost_python-py35 python3.5m

問題6:ModuleNotFoundError: No module named ‘google’
解決:conda install protobuf
問題7:ModuleNotFoundError: No module named ‘cPickle’
解決:python2有cPickle,但是在python3下,是沒有cPickle的;
解決辦法:將cPickle改為pickle即可
其他是python2,python3的版本問題。
問題8:Demo for data/demo/000456.jpg
F1010 01:35:33.146603 9647 syncedmem.cpp:56] Check failed: error == cudaSuccess (2 vs. 0) out of memory
* Check failure stack trace: *
小本的視訊記憶體不足。。。
修改demo.py,執行ZF 模型。
執行測試

終於成功了,這麼小的事情,過程卻如此艱辛,差距啊。