如何在物體檢測代碼中使用ROI Pool和ROI Align(PyTorch 1.0)

2019-10-19     AI公園
作者:Andrew Jong
編譯:ronghuaiyang

導讀

如果你想做一個與計算機視覺或圖像處理相關的深度學習項目,你可能會用到ROI Pool和ROI Align層。雖然最初是為目標檢測而構建的,但是ROI Pool的變體對於從圖像的局部區域提取信息也很有用。

如果你想做一個與計算機視覺或圖像處理相關的深度學習項目,你可能會用到ROI Pool和ROI Align層。雖然最初是為目標檢測而構建的,但是ROI Poll的變體對於從圖像的局部區域提取信息也很有用。例如,你可能想從一個人身上提取特定的身體部位:

在此圖中,ROI Pool用來從圖像中的六個任意大小的區域提取紋理信息。ROI Pooling將矩形轉換成一個漂亮的方形的張量。

我發現了許多有用的文章,解釋了ROI Pool和ROI Align在概念上是如何工作的,然而,我沒有找到任何關於如何將ROI Pooling/Aglign層在我的神經網絡中編寫代碼的清晰教程。

不幸的是,PyTorch沒有內置ROI Pool(及其變體)。當然,你可以自己實現這些層。但是要實現一個實際的與gpu兼容的實現,你必須花時間在CUDA中編寫代碼。更實際的選擇是使用第三方庫。然而,這些庫大多數都沒有文檔。

因此,這篇文章總結了我從幾周的探索、實驗和與無文檔庫的鬥爭中學到的東西。我將解釋如何安裝和編譯第三方實現以供你的項目使用,以及如何使用所提供的ROI層的API。希望有了這個指南,我可以節省別人很多時間!

安裝

我使用了來自https://github.com/jwyang/faster-rcnn.pytorch的ROI層實現。這是GitHub上最流行的fast-rcnn PyTorch庫,因此提供了一個可靠的選擇。另外,我認為這裡的一些ROI層代碼受Facebook的maskrcnn-benchmark庫的影響很大。(Maskrcnn介紹了改進的變體,ROI Align!)

注意:我使用的是Python 3.7,但是這應該適用於任何Python版本(2.7或以上)。我還使用了PyTorch 1.0,但是PyTorch 0.4的用戶應該能夠進行一些小的調整。

首先,克隆jwyang的fast -rcnn.pytorch庫。然後確保check out出pytorch-1.0分支。這是很重要的!編譯步驟在master分支(對於PyTorch 0.4)和PyTorch -1.0分支之間有所不同。

git clone https://github.com/jwyang/faster-rcnn.pytorch.git
cd faster-rcnn.pytorch
git checkout pytorch-1.0

複製自述文件中的說明,使用pip安裝requirements ,然後使用Python安裝使用setup tools安裝和編譯:

jwyang/fast -rcnn截圖。pytorch-1.0分支上的自述,顯示編譯指令。

pip install -r requirements.txt
cd lib
python setup.py build develop

要點:要能夠使用ROI-Pool和ROI-Align層,必須在Python環境中安裝 requirements.txt。否則會遇到segfault錯誤。如果使用conda,請確保激活的環境與用於編譯庫的環境相同。

要確保安裝成功,打開Python提示符並鍵入:

>>> import sys
>>> sys.path.append(「/[location_to]/faster-rcnn.pytorch/lib」)
>>> from model.roi_layers import ROIPool # PyTorch 1.0 specific!
>>> roi_pool = ROIPool((2,2), 1)

[location_to]是fast -rcnn所在的位置。sys.path語句將編譯後的庫附加到Python的路徑中,這樣我們就可以導入「ROIPool」。

如果一切順利,應該不會出現導入錯誤。如果導入失敗,則說明編譯出錯或路徑不正確。

注意:import語句是特定於PyTorch 1.0的。如果你使用PyTorch 0.4,正確的導入語句是:> from model.roipooling.modules import roipool # PyTorch 0.4

基本用法

好!既然我們已經編譯了這個庫並驗證了它是可以工作的,那麼我們如何使用在實際項目中使用ROI Pool和ROI Align呢?

用法如下:

如果你已經對如何加載ROI文件以及spatial_scale和sampling_ratio的含義很有信心,那麼你就可以往下走了!只是需要注意一下sampling_ratio的值意味著ROI Align將會對每個bin採樣sampling_ratio²個點,例如sampling_ratio=2將通過雙線性插值對每個bin採樣4個點,然後對這些點進行平均。

如果你不知道這些詞的意思,那就繼續讀下去!

細節

首先,如果你還不知道ROI Pool的概念,請閱讀教程:(https://deepsense.ai/region-of-interest-pooling-explained/)。

ROI Pool 需要 1)圖像,2)感興趣區域(ROI)進行提取。這個圖像很簡單—就是標準的張量。你的DataLoader的輸出生成一個(batch×channel×height×width)形狀的張量。但是我們如何來用ROI呢?ROIs長什麼樣呢?

ROI Data長什麼樣子?

按照實際標準,ROIs是用第一列中的image-ID進行格式化的。其餘四列包含邊框左上角和右下角的坐標。

在上面的示例中,對於image-ID 0有兩個roi,對於image-ID為1有兩個roi。

通常,所有roi都存儲在一個csv文件中。我們可以使用pandas將它加載到一個numpy數組中,然後將該數組轉換為一個PyTorch張量。最後,創建一個自定義數據集和DataLoader將圖像+ roi輸入到你的神經網絡。

當我們向ROI層提供數據時,輸入維度必須如下所示:

ROI維度和圖像id的問題

但是,你可能會注意到,dataloader總是為批大小添加額外的維度。例如,如果你的minibatch處理大小為4,那麼DataLoader將生成一個 (4×n×5)的ROI張量。但是roipool和roialign 只適用於(n×5)張量。我們該怎麼辦?

解決方法是用PyTorch的view()函數重新構造ROI張量:

# turn our (batch_size×n×5) ROI into just (n×5)
rois = rois.view(-1, 5)

另一個問題是圖像id將不會與批處理索引對齊。這是因為數據集中的每個圖像id都是惟一的,但是批處理索引是0~batch_size。因此,我們必須手動「重置」圖像id:

# reset ROI image-ID to align with the 0-indexed minibatch
rois[:, 0] = rois[:, 0] - rois[0, 0]

ROI層初始化參數

我們構建如下所示的ROI層,但是這些參數都是什麼意思呢?

# init the layers
roi_pool = ROIPool((width, height), spatial_scale)
roi_align = ROIAlign((width, height), spatial_scale, sampling_ratio)

讓我們從一個典型的CNN開始。下面是VGG16的示意圖:

CNN在網絡中的傳播中可以有效的對圖像進行下採樣。這個比例因子是空間縮放比例。例如,第4層(28×28)相對於輸入(224×224)的空間尺度為28/224=0.125。如果我們要在第4層進行ROI池,我們將向spatial_scale參數傳遞0.125。

在ROI align中sampling_ratio是什麼?為了理解這一點,我們需要了解一下ROI是如何對齊的。(http://check%20out%20page%203%20from%20this%20excellent%20writeup/)的第3頁提供了一個很好的解釋。

每個「bin」在ROI Align 層輸出大小中的值由雙線性插值樣本的平均確定。在左邊的圖像中,每個bin有4個樣本(藍色的點)。

參數sampling_ratio決定採樣的「寬度」。例如,如果sampling_ratio=2,採樣將有2×2=4個點。(如果你想自己驗證這一點,請查看實現的底層C原始碼。)

總結

希望現在你已經了解了如何在PyTorch中為你自己的神經網絡添加ROI層。我們介紹了如何從jwyang的庫中安裝ROI實現,如何在代碼中使用層和ROI,並解釋了初始化參數。如果你有任何問題,請在評論中告訴我。編程快樂!

英文原文:https://medium.com/@andrewjong87/how-to-use-roi-pool-and-roi-align-in-your-neural-networks-pytorch-1-0-b43e3d22d073

請長按或掃描二維碼關注本公眾號

文章來源: https://twgreatdaily.com/zh/l78b520BMH2_cNUg3Ery.html