R-CNN , Fast R-CNN , Faster R-CNN原理及區別
==RCNN==
1、生成候選區域
使用Selective Search(選擇性搜尋)方法對一張影象生成約2000-3000個候選區域,基本思路如下:
(1)使用一種過分割手段,將影象分割成小區域
(2)檢視現有小區域,合併可能性最高的兩個區域,重複直到整張影象合併成一個區域位置。優先合併以下區域:
- 顏色(顏色直方圖)相近的
- 紋理(梯度直方圖)相近的
- 合併後總面積小的
- 合併後,總面積在其BBOX中所佔比例大的
在合併時須保證合併操作的尺度較為均勻,避免一個大區域陸續“吃掉”其它小區域,保證合併後形狀規則。
(3)輸出所有曾經存在過的區域,即所謂候選區域
2、特徵提取
使用深度網路提取特徵之前,首先把候選區域歸一化成同一尺寸227×227。
使用CNN模型進行訓練,例如AlexNet,一般會略作簡化。
3、類別判斷
對每一類目標,使用一個線性SVM二類分類器進行判別。
輸入為深度網路(如上圖的AlexNet)輸出的4096維特徵,輸出是否屬於此類。
4、位置精修
目標檢測的衡量標準是重疊面積:許多看似準確的檢測結果,往往因為候選框不夠準確,
重疊面積很小,故需要一個位置精修步驟,對於每一個類,訓練一個線性迴歸模型去判定這個框是否框得完美。
==Fast R-CNN==
Fast R-CNN主要解決R-CNN的以下問題:
1、訓練、測試時速度慢
R-CNN的一張影象內候選框之間存在大量重疊,提取特徵操作冗餘。
而Fast R-CNN將整張影象歸一化後直接送入深度網路,緊接著送入從這幅影象上提取出的候選區域。
這些候選區域的前幾層特徵不需要再重複計算。
2、訓練所需空間大
R-CNN中獨立的分類器和迴歸器需要大量特徵作為訓練樣本。Fast R-CNN把類別判斷和位置精調統一用深度網路實現,不再需要額外儲存。
下面進行詳細介紹
- 在特徵提取階段,通過CNN(如AlexNet)中的conv、pooling、relu等操作都不需要固定大小尺寸的輸入,
因此,在原始圖片上執行這些操作後,輸入圖片尺寸不同將會導致得到的feature map(特徵圖)尺寸也不同,這樣就不能直接接到一個全連線層進行分類。
在Fast R-CNN中,作者提出了一個叫做ROI Pooling的網路層,這個網路層可以把不同大小的輸入對映到一個固定尺度的特徵向量。
ROI Pooling層將每個候選區域均勻分成M×N塊,對每塊進行max pooling。將特徵圖上大小不一的候選區域轉變為大小統一的資料,送入下一層。
這樣雖然輸入的圖片尺寸不同,得到的feature map(特徵圖)尺寸也不同,
但是可以加入這個神奇的ROI Pooling層,對每個region都提取一個固定維度的特徵表示,就可再通過正常的softmax進行型別識別。 - 在分類迴歸階段,在R-CNN中,先生成候選框,然後再通過CNN提取特徵,之後再用SVM分類,最後再做迴歸得到具體位置(bbox regression)。
而在Fast R-CNN中,作者巧妙的把最後的bbox regression也放進了神經網路內部,與區域分類合併成為了一個multi-task模型
實驗表明,這兩個任務能夠共享卷積特徵,並且相互促進。
Fast R-CNN很重要的一個貢獻是成功地讓人們看到了Region Proposal+CNN(候選區域+卷積神經網路)這一框架實時檢測的希望,原來多類檢測真的可以在保證準確率的同時提升處理速度。
==Faster R-CNN==
在Faster R-CNN中加入一個提取邊緣的神經網路,也就說找候選框的工作也交給神經網路來做了。
這樣,目標檢測的四個基本步驟(候選區域生成,特徵提取,分類,位置精修)終於被統一到一個深度網路框架之內。
Faster R-CNN可以簡單地看成是“區域生成網路+Fast R-CNN”的模型,用區域生成網路(Region Proposal Network,簡稱RPN)來代替Fast R-CNN中的Selective Search(選擇性搜尋)方法。
RPN的工作步驟如下:
- 在feature map(特徵圖)上滑動視窗
- 建一個神經網路用於物體分類+框位置的迴歸
- 滑動視窗的位置提供了物體的大體位置資訊
- 框的迴歸提供了框更精確的位置
==總結==
R-CNN、Fast R-CNN、Faster R-CNN一路走來,基於深度學習目標檢測的流程變得越來越精簡、精度越來越高、速度也越來越快。
基於region proposal(候選區域)的R-CNN系列目標檢測方法是目標檢測技術領域中的最主要分支之一。
print_r('點個贊吧');
var_dump('點個贊吧');
NSLog(@"點個贊吧!")
System.out.println("點個贊吧!");
console.log("點個贊吧!");
print("點個贊吧!");
printf("點個贊吧!\n");
cout << "點個贊吧!" << endl;
Console.WriteLine("點個贊吧!");
fmt.Println("點個贊吧!")
Response.Write("點個贊吧");
alert(’點個贊吧’)