做者:chen_h
微信號 & QQ:862251340
微信公衆號:coderpai
個人博客:請點擊這裏git
自從 Alex Krizhevsky, Geoff Hinton, and Ilya Sutskever 成爲了 ImageNet 2012 冠軍以後,CNN 已經變成了圖像分割的標配。實際上,從那時起,CNN 已經在 ImageNet 挑戰上面打敗了人類。github
雖然這些分類結果使人印象深入,可是比真實的人類視覺理解仍是要簡單不少。算法
在分類中,一般咱們會把圖像中一個單一對象做爲分類焦點,也就是說主要去識別焦點的物體(好比上面的狗狗)。可是,當咱們環顧咱們周圍世界的時候,咱們面對的是一個更加複雜的問題。spring
咱們看到場景是一個很是複雜的場景,並且是多個目標進行重疊的背景,咱們不只須要分類這些不一樣的對象,並且須要識別他們的邊界和彼此的關聯。windows
CNN 能夠幫助咱們實現這樣複雜的任務嗎?也就是說,咱們給出更復雜的圖像,能夠利用 CNN 來識別圖像中的不一樣物體之間的邊界嗎?這個問題,在過去幾年裏,已經由 Ross Girshick 和他的同事向咱們證實了,答案是確定的。微信
經過這篇文章,咱們將介紹一些用於對象檢測和分割的主要技術手段,而且瞭解他們是如何從上一個模型演變到下一個模型的。具體來講,咱們將介紹 R-CNN(Regional CNN),一個最先利用CNN解決這個問題的模型,以及其後期的 Fast R-CNN 模型和 Faster R-CNN 模型。最後,咱們將介紹 Mask R-CNN 模型,這個模型是由 Facebook Research 最近發佈的一篇文章,這篇文章提供了像素級別的分割。如下是各個模型的文章:網絡
R-CNN: arxiv.org/abs/1311.25…架構
Fast R-CNN: arxiv.org/abs/1504.08…app
Faster R-CNN: arxiv.org/abs/1506.01…框架
Mask R-CNN: arxiv.org/abs/1703.06…
.](upload-images.jianshu.io/upload_imag…
受 Hinton 實驗室的啓發,UCB 的 Jitendra Malik 的團隊問了這樣一個問題:
對象檢測到底能如何泛化?
對象檢測是找到圖像中的不一樣對象而且進行分類的任務(如上圖所示)。由 Ross Girshick,Jeff Donahue 和 Trevor Darrel 組成的團隊發現這個問題能夠用 Krizhevsky 的方法在 PASCAL VOC Challenge 上面進行實現,他們寫道:
本文首先顯示,與基於 HOG 類特徵的簡單系統相比,CNN 能夠顯著提升 PASCAL VOC 上的對象檢測性能。
如今讓咱們來了解一下 R-CNN 的架構,以及它是如何工做的。
R-CNN 模型的目標是根據拍攝的圖像,正確識別圖像中主要對象(經過邊框)的位置。
輸入:image
輸出:物體邊框 + 每一個對象的標籤
可是咱們如何找出這些邊框的位置呢?R-CNN 的作法就是按照人類的直觀理解來作的 —— 咱們先從圖像裏把一些物體給框出來,而後來肯定這個物體是什麼對象。
R-CNN 使用一種稱爲選擇性搜索的技術來建立這些邊界框,更多的細節你能夠閱讀這篇文章。更高層次來講,選擇性搜索(如上圖所示)是經過不一樣大小的窗口來查看圖像,而且對於每一個大小不一樣的窗口,嘗試經過文理,顏色或強度將相鄰像素分組在一塊兒以識別對象。
一旦這些邊框肯定以後,R-CNN 就會將該區域轉變到一個標準的平方尺寸,並將其傳送到 AlexNet 的一個變體中,如上圖所示。
在 CNN 的最後一層,R-CNN 添加了一個支持向量機(SVM),它簡單的分類這是不是一個對象,也就是圖中的第四步。
如今,咱們已經得到了物體的大體邊框,那麼咱們能夠將這個邊框縮小以適應物體自己真實的尺寸嗎?答案是能夠的,這是 R-CNN的最後一步。R-CNN 對區域進行一個簡單的線性迴歸,以生成更緊密的邊界框座標以得到結果。如下是迴歸模型的輸入和輸出:
輸入:與物體對應圖像的子區域。
輸出:子區域中對象的新邊界框座標。
最後,總結一下 R-CNN 的幾個步驟:
給圖像生成一組邊界框。
經過預先訓練的 AlexNet 運行邊框中的圖像,最後經過 SVM 來進行分類。
一旦對象被分類,邊界框經過運行線性迴歸模型輸出更加緊密的邊框座標。
R-CNN 能夠很好的工做,可是基於如下幾個理由,它很是慢:
‘
’它須要 CNN(AlexNet)針對每一個圖像區域進行運行分類(每一個圖像大約 2000 次前向傳遞)。
它須要分別訓練三種不一樣的模型 —— CNN生成圖像特徵,SVM來預測分類,最後經過線性迴歸來收緊邊界框。這樣設計使得數據管道很是難設計。
2015年,R-CNN 的第一做者 Ross Girshick 解決了這兩個問題,也就誕生了第二個算法 —— Fast R-CNN。如今,讓咱們來看看它的主要思路:
對於 CNN 的前向傳播,Girshick 意識到,對於每一個圖像,圖像的許多分割區域都是重疊的,這就使得咱們一次又一次地運行相同的 CNN 計算(大約 2000 次)。他的想法很簡單,就是讓CNN運行一次圖像,而後找到一種共享計算的方法,來區分這 2000 個區域。
這正是 Fast R-CNN 被稱之爲 PolPool(Region of Interest Pooling)的核心技術,該技術能分享 CNN 在其次區域的前向傳遞。在上圖中,請注意每一個 CNN 特徵圖是從一個原來的大特徵圖中進行選取的。而後,區域中的特徵都被進行合併(通常是採用最大池)。因此須要咱們計算的是一個原始圖片,而不是那個 2000 次區域。
Fast R-CNN 的第二個改進是在單一模型中同時訓練了 CNN,分類器和邊界迴歸。早期的模型咱們使用 CNN 來進行圖像特徵提取,SVM 來進行分類,最後用線性迴歸來進行邊框收緊。Fast R-CNN 使用一個模型來同時達到這三個模型的效果。
上圖展現的就是這個聯合模型。Fast R-CNN 用 CNN 頂部的 softmax 層來替代 SVM 分類器的輸出分類。它還添加了與 softmax 層平行的線性迴歸層用來輸出邊界框座標。這樣,全部咱們須要模型的輸出都是來自於單一的網絡。整個網絡模型的輸入和輸出以下:
輸入:帶有區域目的的圖像。
輸出:每一個區域的對象分類以及更緊密的邊界框。
即便取得了這些進步,Fast R-CNN 仍然存在一個瓶頸 —— 區域檢測。正如咱們所看到的,檢測對象位置的第一步是產生一對潛在的邊界框和區域進行測試。在 Fast R-CNN 中,這些邊界框是採用選擇性搜索建立的,這是一個至關緩慢的過程,被認爲是整個流程額瓶頸。
在2015年中期,一個微軟研究員的團隊 Shaoqing Ren,Kaiming He,Ross Girshick 和 Jian Sun,找到了一個方法來解決這個瓶頸問題,他們將這個方法命名爲 Faster R-CNN。
Faster R-CNN 的一個重大改進是,在 CNN 第一步分類的時候,後續步驟重用那些相同的 CNN 結構,而不是單獨運行選擇性搜索算法。
的確,這正是 Faster R-CNN 團隊所取得的成就。在上圖中,你能夠看到如何使用單個 CNN 來對區域進行處理和分類。這樣,咱們只須要一個 CNN 進行訓練,而其餘的區域均可以從這個 CNN 網絡中獲取,做者這樣寫道:
咱們的觀測結果是,用於區域檢查(如 Fast R-CNN)的卷積特徵圖也能夠用於區域生成,從而實現幾乎無成本的區域生成。
一下是其模型的輸入和輸出:
輸入:圖像(注意不須要區域提案)。
輸出:圖像中對象的分類和邊界框座標。
接下來,讓咱們來看看 Faster R-CNN 是如何從 CNN 特徵圖中來生成區域。Faster R-CNN 在網絡上添加了一個徹底卷積網絡,建立了一個所謂的區域生成網絡。
區域生成網絡經過在 CNN 特徵圖上面的滑動窗口,並在每一個窗口中輸出 k 個潛在的邊界框和分數,以便預測哪些框是最好的。那麼,k 個框是表明什麼呢?
直觀地,咱們知道圖像中的對象應該符合某些常見的比例和大小。例如,咱們知道咱們想要的一些相似於人類形狀的邊框比例和大小。一樣,咱們知道咱們看到的不少的盒子厚度都不會很薄。以這種方式,咱們能夠建立 k 個這樣的盒子,咱們稱之爲錨盒(anchor boxes)。對於每一個這樣的錨盒,咱們在圖像中輸出一個邊界框和每一個位置的得分。
考慮到這些錨盒,咱們來看看這個區域生成網絡的輸入和輸出:
輸入:CNN 特徵圖。
輸出:每一個錨盒對應的邊界框和該邊界框中圖像會是某個對象的可能性分數。
而後,咱們將每一個這樣的可能對象邊界框傳遞到 Fast R-CNN 中,以生成分類結果和收緊邊界框。
到目前爲止,咱們已經看到咱們如何使用 CNN 特徵圖去有效地定位圖像中不一樣對象的邊界框。
咱們能夠將這些技術進一步擴展,並定位每一個對象的精確像素,而不是僅限於邊框。這個像素級別的圖像分割問題被 Kaiming He 等科學家解決,這個框架被稱爲 Mask R-CNN。
Fast R-CNN 和 Faster R-CNN 都能很好的工做,那麼咱們能不能將模型進行擴展,使得他們在像素級別進行分割?
Mask R-CNN 經過向 Faster R-CNN 添加一個分支來輸出一個二進制掩碼,說明給定像素是不是對象的一部分。如上所述,分支(在上圖中的白色部分)僅僅是基於 CNN 特徵圖的徹底卷積網絡,一下是它的輸入和輸出:
輸入:CNN特徵圖
輸出:在像素屬於對象的全部位置上標記爲 1,其餘地方標記爲 0(這個稱爲二進制掩碼)。
可是 Mask R-CNN 的做者不得不對模型進行一個小的調整,使這個管道能夠按預期工做。
咱們須要對原始的 Faster R-CNN 架構進行修改,Mask R-CNN 的做者發現 RoIPool 選擇的特徵圖的區域與原始圖形的區域略有一點不對氣。因爲圖像分割須要作到像素級,這與邊框分割不一樣,因此必然致使不許確。
做者能夠經過巧妙的調整 RoIPool 網絡來解決這個問題,調整好的模型被稱爲 RoIAlign。
想象一下,咱們有一個大小爲 128
咱們知道原始圖像中的每一個像素對應於特徵圖中大約 25/128 像素。要從原始圖像中選擇 15 像素,因此咱們只是選擇了 15*25/128 ~= 2.93 像素。
在 RoIPool 中,咱們會將小數點捨去,從而選擇 2 個像素,這樣就會致使輕微的錯位。然而,在 RoIAlign 中,咱們避免了這種四捨五入。相反的,咱們使用雙線性差值來精確地瞭解像素 2.93 中的全部內容。這在很大程度上讓咱們避免 RoIPool 所形成的錯位。
一旦這些掩碼生成,Mask R-CNN 將它們與來自 Faster R-CNN 的分類和邊界框組合起來,以產生如此奇妙的精確分割:
若是你有興趣本身嘗試這些算法,這裏有一些相關的庫:
Caffe: github.com/rbgirshick/…
PyTorch: github.com/longcw/fast…
MatLab: github.com/ShaoqingRen…
PyTorch: github.com/felixgwu/ma…
TensorFlow: github.com/CharlesShan…
CoderPai 是一個專一於算法實戰的平臺,從基礎的算法到人工智能算法都有設計。若是你對算法實戰感興趣,請快快關注咱們吧。加入AI實戰微信羣,AI實戰QQ羣,ACM算法微信羣,ACM算法QQ羣。詳情請關注 「CoderPai」 微信號(coderpai)。