一文讀懂 RoIPooling、RoIAlign 和 RoIWarp
點(diǎn)擊上方“AI算法與圖像處理”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時間送達(dá)
導(dǎo)讀
本文詳細(xì)講解了 RoIPooling 、RoIAlign 和 RoIWarp ,用非常的圖來幫助理解,相信通過本文閱讀能讓你對這三者有更加深刻的理解
如果對你有所幫助請點(diǎn)個在看、點(diǎn)或分享,鼓勵一下小編
理解Region of Interest — (RoI Pooling)
快速而簡單地解釋什么是RoI Pooling 以及它是如何工作的?為什么我們在Fast R-CNNs中使用它?

Fast R-CNNs 架構(gòu)。來源https://arxiv.org/pdf/1504.08083.pdf
我們將討論在Fast R-CNN文件中描述的原始RoI池化(上圖中的淺藍(lán)色矩形)。這個過程還有第二種和第三種版本分別叫做 RoIAlign 和 RoIWarp 。
什么是RoI?
RoI(Region of Interest) 是從原始圖像中提取的區(qū)域。我們不打算講解如何提取這些區(qū)域,因為有很多方法可以做到。我們現(xiàn)在唯一應(yīng)該知道的是,有多個類似的區(qū)域,最后都應(yīng)該接受測試。
Fast R-CNN 的原理
特征提取
Fast R-CNN 不同于基本的 R-CNN 網(wǎng)絡(luò)。它只有一個卷積特征提取(在我們的示例中,我們將使用VGG16)。

VGG16 特征提取輸出尺寸
我們的模型取一個尺寸為 512x512x3 (寬度x高度x RGB) 的圖像輸入,VGG16將其映射為一個 16x16x512 的feature map。你可以使用不同的輸入大?。ㄍǔ]^小,Keras中VGG16的默認(rèn)輸入大小為224x224)。
如果你看輸出矩陣,你應(yīng)該注意到它的 寬度和高度 正好比輸入圖像小32倍(512/32 = 16)。這很重要,因為所有 RoIs 都要按這個因子減小。
Sample RoIs
這里只畫出了 4 個不同的 RoI 。在實際的Fast R-CNN你可能有成千上萬個,但打印所有使圖像難于觀察。

Regions of Interest, 圖片來源:https://www.flickr.com/photos/bunny/
重要!需要記住的是 RoI 不是一個邊界框。它可能看起來像一個,但它只是一個進(jìn)一步處理的proposal。很多人都這么認(rèn)為,因為大多數(shù)論文和博客文章都是在提出proposals,而不是實際的對象。這樣更方便,上面的圖像上也這樣做了。這里有一個不同的 proposal area ,也將被Fast R-CNN(綠框)選中。

Region of Interest which doesn’t make sense
有一些方法可以限制 RoI 的數(shù)量,也許我將來會寫一些關(guān)于它的東西。
如何從feature map 上獲取 RoI ?
現(xiàn)在,當(dāng)我們知道RoI是什么時,我們必須能夠?qū)⑺鼈冇成涞絍GG16的輸出 feature map上。

將RoI映射到VGG16的輸出
每個RoI都有它的原始坐標(biāo)和大小。從現(xiàn)在開始,我們將只關(guān)注其中之一:

我們的RoI 對象
其原始大小為 145x200 ,左上角設(shè)置為 (192x296) 。正如你可能知道的,我們無法將這些數(shù)字的大部分整除以 32(比例因子)。
- width: 200/32 = 6.25
- height: 145/32 = ~4.53
- x: 296/32 = 9.25
- y: 192/32 = 6
只有最后一個數(shù)字(左上角的Y坐標(biāo))是有意義的。這是因為我們現(xiàn)在使用的是16x16 網(wǎng)格,我們關(guān)心的數(shù)字只有整數(shù)(更精確地說:自然數(shù))。
feature map上坐標(biāo)的量化
量化是將輸入從一大組值(如實數(shù))約束為一組離散的值(如整數(shù))的過程。
如果我們feature map 上原始的 RoI 如下所示:

feature map 上的 原始 RoI
我們不能真正地在它上面應(yīng)用池化層,因為一些“cells”被分割了。量化所做的就是每一個結(jié)果在放到矩陣上之前都進(jìn)行約減。9.25變成9, 4.53變成4,等等。

量化后的RoI
你可以注意到我們剛剛丟失了一堆數(shù)據(jù)(深藍(lán)色)和獲得了新的數(shù)據(jù)(綠色):

Quantization losses
我們不需要處理它因為它仍然可以工作但是這個過程有一個不同的版本叫做RoIAlign它可以修復(fù)這個問題
RoI Pooling
現(xiàn)在,當(dāng)我們把RoI映射到feature map上時,我們可以在上面應(yīng)用pooling。為了方便起見,我們將再次選擇 RoI池化層 的大小,但請記住,大小可能是不同的。你可能會問:“我們?yōu)槭裁匆獞?yīng)用RoI Pooling呢?”這是個好問題。如果你看原始設(shè)計的Fast R-CNN:

原始的 Fast R-CNN 架構(gòu) ,來源:(https://arxiv.org/pdf/1504.08083.pdf)
在 RoI池化層 之后是一個固定大小的 全連接層。因為RoIs的大小不同,所以我們必須將它們池化為相同的大小(在我們的示例中為 3x3x512)。此時我們映射的RoI大小為 4x6x512,你可以想象我們 不能將4除以3:(這就是量化再次使用的地方。)

映射后的 RoI 和 池化層
這次我們不需要處理坐標(biāo),只需要處理大小。我們很幸運(yùn)(或者只是適用于池化層的大小) 6 可以整除以 3 得到2,但當(dāng)你用 4 除以 3 時,剩下1.33。在應(yīng)用相同的方法(約簡 round down )后,我們有一個 1x2的向量。我們的映射是這樣的:

數(shù)據(jù)池化映射
由于量化,我們又一次失去了最底下的那行
數(shù)據(jù)的池化映射
現(xiàn)在我們能將數(shù)據(jù)池化成 3x3x512 的矩陣

數(shù)據(jù)池化處理過程
在本例中,我們應(yīng)用了 最大池化,但在你的模型中可能會有所不同。當(dāng)然,這個過程是在整個RoI矩陣上完成的,而不僅僅是在最頂層。所以最終的結(jié)果是這樣的:

同樣的過程應(yīng)用到原始圖像的每一個RoI上,因此最終,我們可能會得到數(shù)百甚至數(shù)千個3x3x512矩陣。每一個矩陣都必須通過網(wǎng)絡(luò)的其余部分(從FC層開始)發(fā)送。對于它們,模型分別生成bbox和類。
接下來呢?
在池化完成之后,我們確定輸入的大小為**3x3x512**,這樣我們就可以將其輸入到FC層進(jìn)行進(jìn)一步處理。還有一件事要討論。由于量化過程,我們丟失了很多數(shù)據(jù)。確切地說,就是:

量化數(shù)據(jù)丟失(深藍(lán)色和淺藍(lán)色),數(shù)據(jù)獲得(綠色)
這可能是一個問題,因為每個“單元格”都包含大量數(shù)據(jù)(feature map上的1x1x512,在原始圖像上大致相當(dāng)于32x32x3,但請不要使用這個引用,因為卷積層不是這樣工作的)。有一種方法可以解決這個問題(RoIAlign)
Understanding Region of Interest — (RoI Align and RoI Warp)
為什么我們想去修改 RoI 池化
正如我們上面所說的,RoI 池化 有一個主要的問題。它在處理過程中丟失了大量的數(shù)據(jù)。

量化數(shù)據(jù)丟失(深藍(lán)色和淺藍(lán)色),數(shù)據(jù)獲得(綠色)
每次進(jìn)行 RoI 池化操作的時候,就會丟失關(guān)于該對象的部分信息。這降低了整個模型的精確度,很多真正聰明的人都考慮過這個問題。
設(shè)置
在我們開始之前,我需要快速解釋一下我們的模型。

原始的 Mask R-CNN 架構(gòu)。來源:(https://arxiv.org/pdf/1703.06870.pdf)

Mask R-CNN 的輸出
我們將使用 Mask R-CNN 網(wǎng)絡(luò)進(jìn)行測試。我們使用它的唯一原因是,這種網(wǎng)絡(luò)從一個精確的池化層中獲益更多,因此更容易顯示 RoI Align和RoI池化之間的差異。我們使用哪個網(wǎng)絡(luò)并不重要,重要的是它實現(xiàn)了RoI 池化。因此我們的設(shè)置不變,看起來是這樣的:

模型特征映射過程。圖片來源:https://www.flickr.com/photos/bunny/
我們的模型取一個大小為 512x512x3 (寬度x高度x RGB)的圖像輸入,VGG16將其映射為一個 16x16x512 的feature map。比例因子是 32 。
接下來,我們將使用其中一個proposed RoIs (145x200 box),并嘗試將其映射到feature map上。因為不是所有的對象維度都可以整除以32,所以我們沒有將RoI與網(wǎng)格對齊。

RoI 位置
- (9.25,6) — top left corner
- 6.25 — width
- 4.53 — height
再一次,我們選擇池化層的大小為3x3,所以最終的形狀是3x3x512(這只是一個任意的例子,以便更容易在圖像上顯示。你的池化層可能有不同的大小)。

池化層
在這里,所有看上去和 RoI 池化一樣
引入RoI Align
RoI池化和RoI Align之間的主要區(qū)別是量化。**RoI Align沒有將量化**用于數(shù)據(jù)池化。你知道Fast R-CNN應(yīng)用了兩次量化。第一次在映射過程中,第二次在池化過程中。

我們可以跳過這些操作,將原始RoI分成9個等大小的小格子,并在每個盒子內(nèi)應(yīng)用雙線性插值。讓我們定義框:

每個框的大小由映射的RoI的大小和池化層的大小決定。我們使用了一個 3x3 的池化層,所以我們必須將映射的RoI (6.25x4.53)除以3。這樣我們就得到了一個高為 1.51 ,寬為 2.08 的方框(我在這里約簡以使它更容易)?,F(xiàn)在我們可以把我們的方框放入映射的RoI中:

RoI分割成多個框
如果查看第一個框(左上角),可以注意到它覆蓋了6個不同的網(wǎng)格單元格。為了提取池化層的值,我們必須從池化層中采樣一些數(shù)據(jù)。為了對數(shù)據(jù)進(jìn)行采樣,我們必須在盒子里創(chuàng)建 四個采樣點(diǎn)。

采樣點(diǎn)分布
你可以 通過方框的高度和寬度除以3 來計算每個點(diǎn)的位置。
在我們的例子中,我們計算第一個點(diǎn)(左上角)的坐標(biāo)如下:
- X = X_box + (width/3) * 1 = 9.94
- Y = Y_box + (height/3) * 1 = 6.50
為了計算第二點(diǎn)(左下角),我們只需要改變Y:
- X = X_box + (width/3) * 1 = 9.94
- Y = Y_box + (height/3) * 2 = 7.01
現(xiàn)在,當(dāng)我們有了所有的點(diǎn)我們可以應(yīng)用雙線性插值對這個方框進(jìn)行數(shù)據(jù)采樣。圖像處理中常用雙線性插值對顏色進(jìn)行采樣,其方程如下:

雙線性差值方程
不要試圖理解這個方程,請看看它是如何工作的圖形解釋:

雙線性插值第一個點(diǎn)
當(dāng)您從我們的方框中取出第一個點(diǎn)時,除非它已經(jīng)被取走了,您將它與最鄰近的單元格連接(正好在中間)。在本例中,我們的點(diǎn)的坐標(biāo)是**(9.44,6.50)**。單元格左上角最接近的中間位置是**(9.50,6.50)**(如果我們的點(diǎn)只比網(wǎng)格高0.01,那么它應(yīng)該是(9.50,5.50))。然后我們必須選擇一個左下角的點(diǎn),最近的是**(9.50,7.50)**遵循同樣的規(guī)則,我們選擇**(10.50,6.50)**和**(10.50,7.50)**作為右上角和右下角的點(diǎn)。在RoI上面,您可以看到整個計算過程,從而得到第一個點(diǎn)(0.14)的值。

雙線性插值的第二個點(diǎn)
這一次我們從:
- top-left: (10.50, 6.50)
- bottom-left: (10.50, 7.50)
- top-right: (11.50, 6.50)
- bottom-right: (11.50, 7.50)
你應(yīng)該開始在這里看到一個模式:)。以下是其他要點(diǎn):

雙線性插值的第三個點(diǎn)
- top-left: (9.50, 6.50)
- bottom-left: (9.50, 7.50)
- top-right: (10.50, 6.50)
- bottom-right: (10.50, 7.50)

雙線性插值的第四個點(diǎn)
- top-left: (10.50, 6.50)
- bottom-left: (10.50, 7.50)
- top-right: (11.50, 6.50)
- bottom-right: (11.50, 7.50)
現(xiàn)在我們已經(jīng)計算了所有的點(diǎn),并可以應(yīng)用**Max Pooling**對他們(它可以是Avg池,如果你想):

第一個 Box Pooling
我不會給你們講所有的插值,因為這會花很長時間而且你們可能已經(jīng)知道怎么做了。我將向你們展示整個過程是如何使用RoIAlign,對RoI進(jìn)行池化的:

當(dāng)然,這一過程適用于每一層,因此最終結(jié)果包含512個層(與feature map輸入相同)

請注意,即使我們沒有把采樣點(diǎn)放在feature map的所有單元格中,我們也通過雙線性插值從它們中提取數(shù)據(jù)。
在這種情況下,單元11x6, 11x7, 11x8, 11x9, 11x10, 13x6, 13x7, 13x8, 13x9, 13x10, 15x6, 15x7, 15x8, 15x9, 15x10將不會有任何點(diǎn)。如果你觀察第二個點(diǎn)的計算(第一個框),它仍然使用單元格11x6和11x7來進(jìn)行雙線性插值,即使點(diǎn)在單元格10x6中。
如果您比較從RoIAlign和RoIPooling的數(shù)據(jù)丟失/數(shù)據(jù)獲取,您應(yīng)該看到RoIAlign使用來自整個區(qū)域來池化數(shù)據(jù):

比較RoIAlign(左)和RoIPooling(右)數(shù)據(jù)源。
- 綠色意味著用于池化的額外數(shù)據(jù)。
- 藍(lán)色(兩種陰影)表示池化是丟失數(shù)據(jù)。
RoIWarp — meet me in the middle
第三種池化數(shù)據(jù)的方法是通過 [*Instance-aware semantic segmentation via multi-task network cascades*](https://arxiv.org/pdf/1512.04412.pdf) 中引入的,它被稱為RoIWarp。RoIWarp的想法和RoIAlign差不多,唯一的區(qū)別是RoIWarp是將RoI量化到feature map上。
https://arxiv.org/pdf/1512.04412.pdf

RoI Warp
如果你看數(shù)據(jù)丟失/額外數(shù)據(jù):

RoI Warp data lost/data gain
由于雙線性插值,我們只損失了一小部分。
RoIAlign 和 RoIWarp 是如何影響準(zhǔn)確率的
如果我們看一下Mask R-CNN的文件,有一些重要的數(shù)字需要討論。第一個是使用stride 16在ResNet-50-C4上應(yīng)用不同RoI層時的 平均精度 變化:

當(dāng)使用RoIWarp的時候只有一個小的提升,但是使用RoIAlign在精度上給了我們一個顯著的提高。這種提升隨著步長(stride)的增加而增加:

其中 APbb 是檢測邊界看的平均精度。該測試是在ResNet-50-C5上使用stride 32完成的。
總結(jié)
當(dāng)我們想要提高類似 R-CNN 的模型的準(zhǔn)確性時,理解RoI池化是很重要的。2014年論文中提出的Fast R-CNN的標(biāo)準(zhǔn)方法和2018年論文中提出的Mask R-CNN的新方法有很大區(qū)別。這并不意味著這些方法只適用于特定的網(wǎng)絡(luò),我們可以很容易地使用RoIAlign在Fast R-CNN和RoIPooling在Mask R-CNN,但你必須記住,RoIAlign給我們更好的平均精度。
我真的希望我的解釋能容易理解,因為我看過很多關(guān)于RoI 池化而不涉及計算的文章。在我看來,更直觀的方法總是更好的,特別是如果你不想花一整天的時間閱讀原始的論文來最終理解它的作用。
參考
- Fast R-CNN [*https://arxiv.org/pdf/1504.08083.pdf*](https://arxiv.org/pdf/1504.08083.pdf)
- R. Girshick. Fast R-CNN. In ICCV, 2014 https://arxiv.org/pdf/1504.08083.pdf
- J. Dai, K. He, and J. Sun. Instance-aware semantic segmentation via multi-task network cascades. In CVPR, 2016 https://arxiv.org/pdf/1512.04412.pdf
- K. He, G. Gkioxari, P. Dollar and R. Girshick. Mask R-CNN In ICCV, 2018 https://arxiv.org/pdf/1703.06870.pdf
https://towardsdatascience.com/understanding-region-of-interest-part-1-roi-pooling-e4f5dd65bb44
個人微信(如果沒有備注不拉群!) 請注明:地區(qū)+學(xué)校/企業(yè)+研究方向+昵稱

