當前位置:
首頁 > 知識 > 先理解Mask R-CNN的工作原理,然後構建顏色填充器應用

先理解Mask R-CNN的工作原理,然後構建顏色填充器應用

上年 11 月,matterport 開源了 Mask R-CNN 實現,它在 GitHub 已 fork1400 次,被用於很多項目,同時也獲得了完善。作者將在本文中解釋 Mask R-CNN 的工作原理,並介紹了顏色填充器的應用案例和實現過程。

代碼(包括作者構建的數據集和已訓練的模型):https://github.com/matterport/Mask_RCNN/tree/master/samples/balloon

什麼是實例分割?

實例分割是一種在像素層面識別目標輪廓的任務,相比其他相關任務,實例分割是較難解決的計算機視覺任務之一:

分類:這張圖像中有一個氣球。

語義分割:這些全是氣球像素。

目標檢測:這張圖像中的這些位置上有 7 個氣球。

實例分割:這些位置上有 7 個氣球,並且這些像素分別屬於每個氣球。

Mask R-CNN

Mask R-CNN 是一個兩階段的框架,第一個階段掃描圖像並生成提議(proposals,即有可能包含一個目標的區域),第二階段分類提議並生成邊界框和掩碼。Mask R-CNN 擴展自 Faster R-CNN,由同一作者在去年提出。Faster R-CNN 是一個流行的目標檢測框架,Mask R-CNN 將其擴展為實例分割框架。

Mask R-CNN 的主要構建模塊:

1. 主幹架構

主幹網路的簡化圖示

這是一個標準的卷積神經網路(通常來說是 ResNet50 和 ResNet101),作為特徵提取器。底層檢測的是低級特徵(邊緣和角等),較高層檢測的是更高級的特徵(汽車、人、天空等)。

經過主幹網路的前向傳播,圖像從 1024x1024x3(RGB)的張量被轉換成形狀為 32x32x2048 的特徵圖。該特徵圖將作為下一個階段的輸入。

代碼提示:主幹網路在 resnet_graph() 函數中。代碼支持 ResNet50 和 ResNet101。

特徵金字塔網路(FPN)

來源:Feature Pyramid Networks for Object Detection

上述的主幹網路還可以進一步提升。由 Mask R-CNN 的同一作者引入的特徵金字塔網路(FPN)是對該主幹網路的擴展,可以在多個尺度上更好地表徵目標。

FPN 通過添加第二個金字塔提升了標準特徵提取金字塔的性能,第二個金字塔可以從第一個金字塔選擇高級特徵並傳遞到底層上。通過這個過程,它允許每一級的特徵都可以和高級、低級特徵互相結合。

在我們的 Mask R-CNN 實現中使用的是 ResNet101+FPN 主幹網路。

代碼提示:FPN 在 MaskRCNN.build() 中創建,位於構建 ResNet 的部分之後。FPN 引入了額外的複雜度:在 FPN 中第二個金字塔擁有一個包含每一級特徵的特徵圖,而不是標準主幹中的單個主幹特徵圖(即第一個金字塔中的最高層)。選用哪一級的特徵是由目標的尺寸動態地確定的。

2. 區域建議網路(RPN)

展示 49 個 anchor box 的簡化圖示

RPN 是一個輕量的神經網路,它用滑動窗口來掃描圖像,並尋找存在目標的區域。

RPN 掃描的區域被稱為 anchor,這是在圖像區域上分布的矩形,如上圖所示。這只是一個簡化圖。實際上,在不同的尺寸和長寬比下,圖像上會有將近 20 萬個 anchor,並且它們互相重疊以儘可能地覆蓋圖像。

RPN 掃描這些 anchor 的速度有多快呢?非常快。滑動窗口是由 RPN 的卷積過程實現的,可以使用 GPU 並行地掃描所有區域。此外,RPN 並不會直接掃描圖像,而是掃描主幹特徵圖。這使得 RPN 可以有效地復用提取的特徵,並避免重複計算。通過這些優化手段,RPN 可以在 10ms 內完成掃描(根據引入 RPN 的 Faster R-CNN 論文中所述)。在 Mask R-CNN 中,我們通常使用的是更高解析度的圖像以及更多的 anchor,因此掃描過程可能會更久。

代碼提示:RPN 在 rpn_graph() 中創建。anchor 的尺度和長寬比由 config.py 中的 RPN_ANCHOR_SCALES 和 RPN_ANCHOR_RATIOS 控制。

RPN 為每個 anchor 生成兩個輸出:

anchor 類別:前景或背景(FG/BG)。前景類別意味著可能存在一個目標在 anchor box 中。

邊框精調:前景 anchor(或稱正 anchor)可能並沒有完美地位於目標的中心。因此,RPN 評估了 delta 輸出(x、y、寬、高的變化百分數)以精調 anchor box 來更好地擬合目標。

使用 RPN 的預測,我們可以選出最好地包含了目標的 anchor,並對其位置和尺寸進行精調。如果有多個 anchor 互相重疊,我們將保留擁有最高前景分數的 anchor,並捨棄餘下的(非極大值抑制)。然後我們就得到了最終的區域建議,並將其傳遞到下一個階段。

代碼提示:ProposalLayer 是一個自定義的 Keras 層,可以讀取 RPN 的輸出,選取最好的 anchor,並應用邊框精調。

3. ROI 分類器和邊界框回歸器

這個階段是在由 RPN 提出的 ROI 上運行的。正如 RPN 一樣,它為每個 ROI 生成了兩個輸出:

階段 2 的圖示。來源:Fast R-CNN

類別:ROI 中的目標的類別。和 RPN 不同(兩個類別,前景或背景),這個網路更深並且可以將區域分類為具體的類別(人、車、椅子等)。它還可以生成一個背景類別,然後就可以棄用 ROI 了。

邊框精調:和 RPN 的原理類似,它的目標是進一步精調邊框的位置和尺寸以將目標封裝。

代碼提示:分類器和邊框回歸器已在 fpn_classifier_graph() 中創建。

ROI 池化

在我們繼續之前,需要先解決一些問題。分類器並不能很好地處理多種輸入尺寸。它們通常只能處理固定的輸入尺寸。但是,由於 RPN 中的邊框精調步驟,ROI 框可以有不同的尺寸。因此,我們需要用 ROI 池化來解決這個問題。

圖中展示的特徵圖來自較底層。

ROI 池化是指裁剪出特徵圖的一部分,然後將其重新調整為固定的尺寸。這個過程實際上和裁剪圖片並將其縮放是相似的(在實現細節上有所不同)。

Mask R-CNN 的作者提出了一種方法 ROIAlign,在特徵圖的不同點採樣,並應用雙線性插值。在我們的實現中,為簡單起見,我們使用 TensorFlow 的 crop_and_resize 函數來實現這個過程。

代碼提示:ROI 池化在類 PyramidROIAlign 中實現。

4. 分割掩碼

到第 3 節為止,我們得到的正是一個用於目標檢測的 Faster R-CNN。而分割掩碼網路正是 Mask R-CNN 的論文引入的附加網路。

掩碼分支是一個卷積網路,取 ROI 分類器選擇的正區域為輸入,並生成它們的掩碼。其生成的掩碼是低解析度的:28x28 像素。但它們是由浮點數表示的軟掩碼,相對於二進位掩碼有更多的細節。掩碼的小尺寸屬性有助於保持掩碼分支網路的輕量性。在訓練過程中,我們將真實的掩碼縮小為 28x28 來計算損失函數,在推斷過程中,我們將預測的掩碼放大為 ROI 邊框的尺寸以給出最終的掩碼結果,每個目標有一個掩碼。

代碼提示:掩碼分支網路在 build_fpn_mask_graph() 中。

建立一個顏色填充過濾器

和大多數圖像編輯 app 中包含的過濾器不同,我們的過濾器更加智能一些:它能自動找到目標。當你希望把它應用到視頻上而不是圖像上時,這種技術更加有用。

訓練數據集

通常我會從尋找包含所需目標的公開數據集開始。但在這個案例中,我想向你展示這個項目的構建循環過程,因此我將介紹如何從零開始構建一個數據集。

我在 flickr 上搜索氣球圖片,並選取了 75 張圖片,將它們分成了訓練集和驗證集。找到圖片很容易,但標註階段才是困難的部分。

等等,我們不是需要數百萬張圖片來訓練深度學習模型嗎?實際上,有時候需要,有時候則不需要。我是考慮到以下兩點而顯著地減小了訓練集的規模:

首先,遷移學習。簡單來說,與其從零開始訓練一個新模型,我從已在 COCO 數據集(在 repo 中已提供下載)上訓練好的權重文件開始。雖然 COCO 數劇集不包含氣球類別,但它包含了大量其它圖像(約 12 萬張),因此訓練好的圖像已經包含了自然圖像中的大量常見特徵,這些特徵很有用。其次,由於這裡展示的應用案例很簡單,我並不需要令這個模型達到很高的準確率,很小的數據集就已足夠。

有很多工具可以用來標註圖像。由於其簡單性,我最終使用了 VIA(VGG 圖像標註器)。這是一個 HTML 文件,你可以下載並在瀏覽器中打開。標註最初幾張圖像時比較慢,不過一旦熟悉了用戶界面,就能達到一分鐘一個目標的速度。

VGG 圖像標註器工具的用戶界面

如果你不喜歡 VIA 工具,可以試試下列工具,我都測試過了:

LabelMe:最著名的標註工具之一,雖然其用戶界面有點慢,特別是縮放高清圖像時。

RectLabel:簡單易用,只在 Mac 可用。

LabelBox:對於大型標記項目很合適,提供不同類型標記任務的選項。

COCO UI:用於標註 COCO 數據集的工具。

載入數據集

分割掩碼的保存格式並沒有統一的標準。有些數據集中以 PNG 圖像保存,其它以多邊形點保存等。為了處理這些案例,在我們的實現中提供了一個 Dataset 類,你可以通過重寫幾個函數來讀取任意格式的圖像。

VIA 工具將標註保存為 JSON 文件,每個掩碼都是一系列多邊形點。

代碼提示:通過複製 coco.py 並按你的需要修改是應用新數據集的簡單方法,我將新的文件保存為 ballons.py。

我的 BalloonDataset 類是這樣定義的:

load_balloons 讀取 JSON 文件,提取標註,然後迭代地調用內部的 add_class 和 add_image 函數來構建數據集。

load_mask 通過畫出多邊形為圖像中的每個目標生成點陣圖掩碼。

image_reference 返回鑒別圖像的字元串結果,以進行調試。這裡返回的是圖像文件的路徑。

你可能已經注意到我的類不包含載入圖像或返回邊框的函數。基礎的 Dataset 類中默認的 load_image 函數可以用於載入圖像,邊框是通過掩碼動態地生成的。

驗證該數據集

為了驗證我的新代碼可以正確地實現,我添加了這個 Jupyter notebook:inspect_balloon_data.ipynb。它載入了數據集,並可視化了掩碼、邊框,還可視化了 anchor 來驗證 anchor 的大小是否擬合了目標大小。以下是一個 good example。

來自 inspect_balloon_data notebook 的樣本

代碼提示:為了創建這個 notebook 我複製了 inspect_data.ipynb(這是為 COCO 數據集寫的),然後修改了代碼的初始部分來載入 Balloons 數據集。

配置

這個項目的配置和訓練 COCO 數據集的基礎配置很相似,因此我只需要修改 3 個值。正如我對 Dataset 類所設置的,我複製了基礎的 Config 類,然後添加了我的覆寫:

基礎的配置使用的是 1024x1024 px 的輸入圖像尺寸以獲得最高的準確率。我保持了相同的配置,雖然圖像相對較小,但模型可以自動地將它們重新縮放。

代碼提示:基礎的 Config 類在 config.py 中,BalloonConfig 在 balloons.py 中。

訓練

Mask R-CNN 是一個規模很大的模型。尤其是在我們的實現中使用了 ResNet101 和 FPN,因此你需要一個 12GB 顯存的 GPU 才能訓練這個模型。我使用的是 Amazon P2 實例來訓練這個模型,在小規模的數據集上,訓練時間不到 1 個小時。

用以下命令開始訓練,以從 balloon 的目錄開始運行。這裡,我們需要指出訓練過程應該從預訓練的 COCO 權重開始。代碼將從我們的 repo 中自動下載權重。

如果訓練停止了,用以下命令讓訓練繼續:

代碼提示:除了 balloon.py 以外,該 repo 還有兩個例子:train_shapes.ipynb,它訓練了一個小規模模型來檢測幾何形狀;coco.py,它是在 COCO 數據集上訓練的。

檢查結果

inspect_balloon_model notebook 展示了由訓練好的模型生成的結果。查看該 notebook 可以獲得更多的可視化選項,並一步一步檢查檢測流程。

代碼提示:這個 notebook 是 inspect_model.ipynb 的簡化版本,包含可視化選項和對 COCO 數據集代碼的調試。

顏色填充

現在我們已經得到了目標掩碼,讓我們將它們應用於顏色填充效果。方法很簡單:創建一個圖像的灰度版本,然後在目標掩碼區域,將原始圖像的顏色像素複製上去。以下是一個 good example:

代碼提示:應用填充效果的代碼在 color_splash() 函數中。detect_and_color_splash() 可以實現載入圖像、運行實例分割和應用顏色填充過濾器的完整流程。

FAQ 環節

Q:我希望了解更多該實現的細節,有什麼可讀的?

A:按這個順序閱讀論文:RCNN、Fast RCNN、Faster RCNN、FPN、Mask RCNN。

Q:我能在哪裡提更多的問題?

A:我們的 repo 的 Issue 頁面:https://github.com/matterport/Mask_RCNN/issues

原文鏈接:https://engineering.matterport.com/splash-of-color-instance-segmentation-with-mask-r-cnn-and-tensorflow-7c761e238b46


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器之心 的精彩文章:

美國東北大學提出MoNet,使用緊密池化緩解特徵高維問題
李飛飛、李佳宣布發布Cloud AutoML:AI技術:飛入尋常百姓家

TAG:機器之心 |