引言
在 object detection 領(lǐng)域,近 5 年的突破性進(jìn)展似乎都與一個名字有關(guān)系:Ross Girshick。梳理從 R-CNN,F(xiàn)ast R-CNN, Faster R-CNN 到 Mask R-CNN 等各種經(jīng)典模型,Ross Girshick 都是作者之一,甚至連 YOLO 的作者中也出現(xiàn)了 Ross Girshick 的名字。
這位大神簡歷如下:
2012.04: 芝加哥大學(xué)博士,師從 Pedro Felzenszwalb,就是提出 Felzenszwalb and Huttenlocher 圖像分割算法的那位 Felzenszwalb。
2012.09 - 2014.08: 加州大學(xué)伯克利分校博士后。2014 CVPR 會議上作為第一作者提出 R-CNN。另外,他還是深度學(xué)習(xí)框架 Caffe 的主要貢獻(xiàn)者之一。
2014.09 - 2015 Fall: 微軟雷德蒙德研究院(Microsoft Research Redmond)研究員,期間提出 Fast R-CNN,唯一作者!另外,他還是 Microsoft COCO (Common Objects in COntext) 數(shù)據(jù)集 的作者之一。
2015 Fall 至今: Facebook 人工智能研究院 (FAIR)研究科學(xué)家。 Faster R-CNN 作者之一,文中指出大部分工作是在 Microsoft 時完成的。2016年YOLO 算法作者之一。2018年 Mask R-CNN 作者之一。
從算法到實現(xiàn)框架再到數(shù)據(jù)集,這位大神實現(xiàn)了一條龍的突破~
本文的目的是整理總結(jié) R-CNN 系列算法的發(fā)展歷程和模型本身的核心思想,不涉及太多技術(shù)細(xì)節(jié)(例如訓(xùn)練數(shù)據(jù)預(yù)處理,超參數(shù)設(shè)置等)。
參考文獻(xiàn)主要是上述各算法的原文以及下列資源:
- 很經(jīng)典的斯坦福大學(xué)計算機(jī)視覺課程:http://cs231n.stanford.edu/index.html
- 計算機(jī)視覺開源工具集 LUMINOTH 的技術(shù)博客:https://tryolabs.com/blog/2018/01/18/faster-r-cnn-down-the-rabbit-hole-of-modern-object-detection/
- medium.com 上若干優(yōu)秀博客文章,在下邊正文中有具體引用。
R-CNN
R-CNN,一般認(rèn)為全稱是 Region-based CNN 或者作者原文中提到的 Regions with CNN features。
概括地說,R-CNN 的步驟如下圖所示:
- 輸入待檢測圖片
- 從圖片中提取若干子區(qū)域 (region proposal)
- 對每個 region 扭曲變形 (warp),得到 CNN 希望的輸入圖片大小,通過 CNN 進(jìn)行特征提取,得到該 region 的 feature vector
- 將 region feature vector 送入 SVM 進(jìn)行 image classification (或者稱為 recognition),同時通過線性回歸預(yù)測 bounding box 的位置調(diào)整。
下面詳細(xì)介紹 R-CNN 中的關(guān)鍵環(huán)節(jié)。
region proposal
對于輸入的圖片,首先利用 selective search 算法生成約 2000 個 region。關(guān)于 selective search 算法可以參考原文,也可以參考我們之前的博客文章。原文中提到 R-CNN 對各種 region proposal 算法沒有偏好,之所以選擇 selective search 算法僅僅是為了方便與前人工作做對比。
region feature vector 提取
這一部分的目的是對于每一個 region,通過 CNN (原文選用 AlexNet) 進(jìn)行特征提取,得到統(tǒng)一長度的 feature vector,以便后續(xù)的分類。
由于每個 region 的大小差別比較大,而 AlexNet 默認(rèn)接收 227×227 pixel 的圖片,這里就需要對 region 做一些預(yù)處理,主要是 region 大小的轉(zhuǎn)化。
要把一個任意大小的圖片轉(zhuǎn)化成 227×227 像素的圖片方法有很多,原文中介紹了 4 種方式:
分別是:
- 保持原 region 比例,填充周邊像素點(diǎn),再縮放成 227×227,對應(yīng)上圖中(B)列
- 保持原 region 比例,不填充周邊像素,縮放成 227×227,對應(yīng)上圖中(C)列
- 直接將原 region 扭曲(warp)縮放成 227 × 227,對應(yīng)上圖中(D)列
- 與 3 相同,但是在周邊額外添加了一些像素點(diǎn)(即 padding),使得生成的 227×227 圖像中上下左右包含了 16 pixel 的填充,對應(yīng)上圖中第 2 行和第 4 行。
最終作者選擇了 warp + padding 的方式,一方面 warp 相對來說是最簡單的,直接把任意大小的圖片縮放成 227×227 即可,另外 padding 是在原 region 周圍稍微添加了一些像素點(diǎn),從實際效果看提高了檢測正確率。
將統(tǒng)一大小的 region 送入 CNN 中,進(jìn)行特征提取。如何得到這個 CNN 也是一個問題。
針對目標(biāo)檢測的數(shù)據(jù)集 ILSVRC detection dataset 包含了 200 類物體,PASCAL VOC (Visual Object Classes) 包含了 20 類物體。相對來說帶有標(biāo)簽的訓(xùn)練數(shù)據(jù)比較少,不足以訓(xùn)練一個大型的 CNN,因此采用了 transfer learning 的技術(shù)。原文中并沒有提到 transfer learning 這個名詞,只是說 fine-tuning。
首先借用在 ImageNet 上已經(jīng)訓(xùn)練好的 CNN 模型(最初的文章中用了 AlexNet,后來 arXiv 上新版文章中用了 VGG,效果提升很明顯),然后在 PASCAL 數(shù)據(jù)集上進(jìn)行 fine-tuning。這里對 AlexNet 網(wǎng)絡(luò)結(jié)構(gòu)的改變只是將原本對應(yīng) ImageNet 1000 類輸出的 classification layer 替換成了對應(yīng) N+1 類輸出的 classification layer,該層權(quán)重隨機(jī)初始化。對于 PASCAL 數(shù)據(jù)集 N=20,ILSVRC 數(shù)據(jù)集 N=200,另外 +1 對應(yīng) background 類型。
經(jīng)過 fine-tuning 之后,CNN softmax layer 之前的 4096 維向量即為該 region 的 feature vector.
classification by SVM
得到 region 的 feature vector 之后,送入 SVM 進(jìn)行最后的分類。
這里 SVM 的訓(xùn)練是針對不同類型的物體分開進(jìn)行的,每一類訓(xùn)練一個 SVM,它只給出針對這一類物體的分類結(jié)果。之所以最后用 SVM 分類,而不是直接用 CNN 的 softmax 進(jìn)行分類,原文作者的解釋是嘗試過 softmax 之后發(fā)現(xiàn)效果比 SVM 差一些,但是同時指出如果調(diào)整一些訓(xùn)練策略,softmax 和 SVM 之間的差距有可能縮小。這也為后來基于 R-CNN 的改進(jìn)埋下了伏筆。
得到所有 region 對應(yīng)的檢測結(jié)果(即包含某種類型物體的概率 score)之后,還有一步操作:Non-Maximum Suppression (NMS)。如果兩個 region 檢測到同一類物體,比如都檢測到了行人,一個 region score 較高,而另一個 score 較低,當(dāng)這兩個 region 的 IoU (intersection-over-union) 超過某個閾值時,即它們重合較多時,只保留那個 score 較高的 region.
對 bounding box 的調(diào)整
object detection 的任務(wù)除了檢測圖中的物體,還要給出定位,即用 bounding box 盡量準(zhǔn)確的圈出該物體。前邊基于 region 的分類過程可能能夠正確辨識出 region 中的物體,但是初始的 region 并不一定是一個合適的 bbox。在 R-CNN 最后又添加了一個線性回歸模型,基于 feature vector 來預(yù)測正確的 bbox 相對于 region 的位置變換,即預(yù)測 bbox 應(yīng)該如何調(diào)整。這個訓(xùn)練過程也是 class-specific 的。
在最終使用時,R-CNN 輸出包含兩部分:
- 對每個 region 進(jìn)行分類
- 預(yù)測 bbox 位置的調(diào)整
理論上來說,更新 bbox 的位置之后,應(yīng)該在新的 bbox 中重新進(jìn)行分類,這樣準(zhǔn)確度可能更高一些,但是原文作者發(fā)現(xiàn)實際上并沒有明顯改進(jìn)。因此,實際使用中并沒有對新的 bbox 重新分類。
Fast R-CNN
總的來說,上述 R-CNN 的訓(xùn)練是分多步走的:先是 fine-tuning 一個 CNN 得到 feature vector,然后訓(xùn)練 SVM 進(jìn)行分類,最后還要再訓(xùn)練一個線性回歸環(huán)節(jié)預(yù)測 bounding box 的調(diào)整。
Fast R-CNN 的改進(jìn)是不再使用獨(dú)立的 SVM 和線性回歸,而是統(tǒng)一用 CNN 將這三個環(huán)節(jié)整合起來。Fast R-CNN 在訓(xùn)練時間和檢測時間方面比當(dāng)時已有的其他算法快若干數(shù)量級。
Fast R-CNN 整體框架如下:
基本步驟:
- 輸入為一整幅圖片,以及 Regions of Interest (RoI)。RoI 在之前的 R-CNN 中稱為 region proposals,即通過 selective search 算法得到的原圖上的若干 regions;
- 圖片經(jīng)過若干卷積層和 max pooling 層處理之后得到 feature map;
- 對于每一個 RoI 通過 RoI project 找到 feature map 上對應(yīng)的區(qū)域,經(jīng)過 RoI pooling layer 轉(zhuǎn)化為統(tǒng)一大小的 sub feature map,進(jìn)而得到統(tǒng)一大小的 feature vector;
- 對于每個 RoI 的 feature vector 有兩個輸出:用于分類的 softmax layer 和用于預(yù)測 bounding box 的 regressor.
在上述各環(huán)節(jié)中,我認(rèn)為比較關(guān)鍵的有兩個:一是 RoI projection,即將 image 上的 RoI 映射到 feature map 上的 RoI。二是通過 RoI pooling layer 將 feature map 上不同大小的 RoI 轉(zhuǎn)化成統(tǒng)一大小的 sub feature map。而這兩個環(huán)節(jié)都借鑒了 SPPnets,其中 RoI pooling layer 是 SPPnets 中 Spatial Pyramid Pooling layer 的特例。
RoI projection
原本 R-CNN 是在原圖上選取若干RoI,然后經(jīng)過 CNN 處理,最后提取出 feature vector。對于每個圖片上不同的 RoI 來說,從輸入到輸出沒有任何共享的東西。
RoI projection 的作用是將 R-CNN 中對 image RoI 的處理推遲到了 feature map 上,這樣可以讓一個 image 的所有 RoI 共享從 image 到 feature map 的卷積處理過程。這很顯然會加速訓(xùn)練和測試過程。至于如何將 image RoI 映射到 feature map RoI,已經(jīng)有了非常細(xì)致的討論,這里不再贅述。
RoI pooling layer
如何將 feature map 上不同大小的 RoI 轉(zhuǎn)化成統(tǒng)一大小的 sub feature map? 這里有非常直觀的動畫演示。
概括如下:
假設(shè)我們已經(jīng)得到下面的 feature map (只考慮 2D)
其中 RoI 為黑框部分,大小為 。
我們希望將 RoI 轉(zhuǎn)化成 2×2 大小,可以選擇一個 2×2 的窗口如下
對每一個格子進(jìn)行 max pooling 操作,得到如下的 2×2 的 feature map
總的來說,如果 RoI 大小為 ,希望得到的 feature map 大小為
,則窗口中格子數(shù)目為
。可以根據(jù)具體情況向上或向下取整。
結(jié)合實際應(yīng)用,如果 CNN 網(wǎng)絡(luò)選用 VGG16,結(jié)構(gòu)如下:
將最后一個 max pooling layer 替換為 RoI pooling layer。前部的卷積層對輸入圖片的大小沒有嚴(yán)格限制,這一限制主要是在 fully connected layer,所以為了配合 VGG16 網(wǎng)絡(luò)結(jié)構(gòu),要確保每個 RoI 輸出的 feature map 依然為 。
對于 VGG16 網(wǎng)絡(luò)結(jié)構(gòu)的修改還包括:
- 去掉最后的 FC layer 和 softmax layer (原為 ImageNet 對應(yīng)的 1000 類輸出)
- 添加隨機(jī)參數(shù)的 FC layer 和 K+1 輸出的 softmax layer,其中 K 為物體種類,+1 對應(yīng) background
- 添加隨機(jī)參數(shù)的 FC layer 和 K 個輸出,每個輸出對應(yīng)一類物體,輸出內(nèi)容為 bbox 的調(diào)整函數(shù),這里與 R-CNN 相同。
Faster R-CNN
在 Fast R-CNN 中,region proposal 是由 CNN 網(wǎng)絡(luò)之外的算法提供的,例如 selective search。相對于后續(xù)的 region recognition 過程,region proposal 這一步實際上是整個算法的速度瓶頸。
Faster R-CNN 之所以 "Faster",就是因為提出了 Region Proposal Network (RPN) ,加速了 region proposal 過程。Faster R-CNN 本質(zhì)上就是 RPN + Fast R-CNN.
整個 Faster R-CNN 結(jié)構(gòu)如下:
或者更加詳細(xì)的結(jié)構(gòu)如下:
RPN 和 Fast R-CNN 共享從 image 到最后一層 CNN 輸出的 feature map 這一段網(wǎng)絡(luò)結(jié)構(gòu)。有些文章也將 Faster R-CNN 看做三個模塊:用于生成 feature map 的 Feature network,用于生成 region proposal 的 RPN,以及用于最終的 object detection 的 Detection network。我們這里還是采用 RPN + Fast R-CNN 的形式。
Region Proposal Network
RPN 的輸入是原始 image,輸出是 region proposals。在具體實現(xiàn)中,RPN 是 fully convolutional network (FCN),只包含 convolutional layer,原本在分類/回歸中常用的全連通層也由卷積操作替代。
- 原始 image 經(jīng)過卷積層操作得到 feature map。
- 對 feature map 中每一個 "pixel",找到其在原圖中的 receptive field,以此為中心選取不同大小和高寬比的
個 anchors,原文中選擇了 3 個 size:
,
,
pixels,3 個 ratio:
,
,
,不同組合共
個 anchors。之所以稱為 anchor (錨),是因為 RPN 輸出的 region 是以這些 anchor 為參考/基準(zhǔn)進(jìn)行調(diào)整的。如果 feature map 的 size 為
,相應(yīng)的 anchors 數(shù)目為
。
Anchors.png
-
RPN 通過一個
(默認(rèn) 3×3) 的滑動窗口依次掃過 feature map,每個窗口通過 512 個 3×3 filter (對應(yīng) pre-trained CNN 為 VGG16)進(jìn)行卷積操作得到 1×1×512 feature map (實際上也是 feature vector)。
注意 step 2 和 step 3 是兩個層面上的操作:step 3 中是在 feature map 中對每個 3×3 滑動窗口進(jìn)一步特征提取和降維,step 2 中是在原始圖片中與滑動窗口中心 "pixel" 對應(yīng)的位置選取 9 個不同大小和高寬比的 anchors。這些 anchors 顯然不太可能都包含物體,到底那些 anchors 可以作為最后的 region,需要根據(jù) feature map 上滑動窗口中的數(shù)據(jù)來預(yù)測。
以 1×1×512 feature map 作為輸入, 一方面用
個 1×1 的 filter 做卷積得到
個輸出,預(yù)測這
個 anchor 中每個 anchor 包含物體和不包含物體的概率,很顯然兩個概率的和為1;另一方面用
個 1×1 的 filter 做卷積得到
個輸出,預(yù)測每個 anchor 位置和大小的調(diào)整。
有了 region proposals,后邊的操作與 Fast R-CNN 是相同的。
Faster R-CNN 訓(xùn)練
原文中采用 alternating training 的方式:
- 先基于 VGG16 fine tuning RPN
- 然后將 RPN 輸出的 region proposal 加上原始 image 一起訓(xùn)練 Fast R-CNN,在此過程中 RPN 和 Fast R-CNN 中前部生成 feature map 的 CNN 是獨(dú)立的,也就說 RPN 和 Fast R-CNN 現(xiàn)在還沒有共享的網(wǎng)絡(luò)結(jié)構(gòu),兩者都是基于 pre-trained VGG-16 fine tuning 的
- 將 Fast R-CNN 訓(xùn)練好的前部 CNN 網(wǎng)絡(luò)共享給 RPN 并固定,只 fine tuning RPN 后部特有的網(wǎng)絡(luò)部分
- 固定 RPN 和 Fast R-CNN 共享的前部 CNN 不變,只 fine tuning Fast R-CNN 后部特有的部分