本系列為 斯坦福CS231n 《深度學習與計算機視覺(Deep Learning for Computer Vision)》的全套學習筆記,對應的課程視訊可以在 這裡 檢視。更多資料獲取方式見文末。
ShowMeAI在前面的內容中給大家做了很多影象分類的介紹,主要圍繞折積神經網路(LeNet / AlexNet / NIN / VGG / Google / ResNet / MobileNet / squeezenet)講解,但計算機視覺領域有其他一些更為複雜的任務,例如本篇開始介紹的目標檢測(object detection)問題。
大家知道人工智慧領域的3大熱點方向是計算機視覺(CV,computer vision)、自然語言處理(Natural Language Process, NLP )和語音識別(Speech Recognition) 應用 。而計算機視覺領域又有影象分類、目標檢測、影象分割三大任務,如下圖所示
這3大任務其實對應機器視覺理解影象的3個主要層次:
影象分類任務中,我們要將影象識別判定為某個類別。它是最簡單、最基礎的影象理解任務,也是深度學習模型最先取得突破和實現大規模應用的任務。大家在前面也瞭解到了 ImageNet 這個權威評測集,每年的ILSVRC催生了大量的優秀深度網路結構,為其他任務提供了基礎。
有一些其他的應用,包括臉部辨識、場景識別等都可以化歸為分類任務來解決。
影象分類任務關心整體圖片類別,而目標檢測則關注特定的物體目標,要求在圖片中,同時識別出目標物的類別資訊和位置資訊(是一個classification + localization的問題)。
相比分類,目標檢測任務要求我們需要從背景中分離出感興趣的目標,並確定這一目標的描述(類別和位置),檢測模型的輸出形式通常是一個列表,列表的每一項使用一個陣列給出檢出目標的類別和位置(常用矩形檢測框的座標表示)。
影象分割包括語意分割(semantic segmentation)和範例分割(instance segmentation),前者是對前背景分離的拓展,要求分離開具有不同語意的影象部分(相當於畫素級別的分類),而後者是檢測任務的拓展,要求描述出目標的輪廓(相比檢測框更為精細)。
分割是對影象的畫素級描述,它賦予每個畫素類別意義,適用於理解要求較高的場景,如無人駕駛中對道路和非道路的分割,醫療影像中對於不同區域的劃分。
影象分類對應將影象劃分為單個類別的過程,它通常對應於影象中最突出的物體。實際現實世界的很多影象通常包含多個物體,如果僅僅使用影象分類模型分配單一標籤是非常粗糙的,並不準確。而目標檢測(object detection)模型可以識別一張圖片的多個物體,並可以給出不同物體的具體位置(邊界框)。目標檢測在很多場景有用,如無人駕駛和安防系統。
常見的經典目標檢測演演算法如下圖所示:
目標檢測的基本思路是:解決定位(localization) + 識別(Recognition) 兩個任務。
一個大致的pipeline如下圖所示,我們可以用同樣的特徵抽取過程,藉助兩個不同的分支輸出。
傳統的目標檢測框架,主要包括三個步驟:
現在主流的深度學習目標檢測方法主要分為兩類:兩階段(Two Stages)目標檢測演演算法和一階段(One Stage)目標檢測演演算法。
上述兩類方法,基於候選區域(Region Proposal)的方法(兩階段)在檢測準確率和定位精度上佔優,基於端到端(一階段)的演演算法速度佔優。相對於R-CNN系列的「兩步走」(候選框提取和分類),YOLO等方法只「看一遍」。
我們在本篇中給大家介紹兩階段的目標檢測方法,主要是R-CNN系列目標檢測方法,在下篇內容目標檢測 (SSD,YOLO系列)中給大家介紹一階段的目標檢測方法(YOLO系列,SSD等)。
如何將深度學習分類演演算法應用到目標檢測?
R-CNN核心思想: 對每張圖片選取多個區域,然後每個區域作為一個樣本進入一個折積神經網路來抽取特徵。
R-CNN演演算法是較早提出的兩階段目標檢測演演算法,它先找出 Region Proposal,再進行分類和迴歸。
對於每張輸入的影象,R-CNN目標檢測主要包括下述步驟:
R-CNN 的效果如下圖所示,它有一些不足之處(也是系列演演算法後續改進的點):
優化方式為:
我們通過前面的 CNN 相關知識學習知道,CNN 的折積層不需要固定尺寸的影象,而全連線層是需要固定大小的輸入。所以當全連線層面對各種尺寸的輸入資料時,就需要對輸入資料進行 crop(摳圖)或者 wrap(影象resize)操作。
在 R-CNN中,因為不同的 proposal 大小不同,所以需要先 resize 成相同大小再輸入到 CNN 中。既然折積層是可以接受任何尺寸的,可以在折積層後面加上一部分結構使得後面全連線層的輸入為固定的,這個「化腐朽為神奇」的結構就是 spatial pyramid pooling layer。
下圖是 R-CNN 和 SPP-Net 檢測流程的比較:
SPP-Net 和普通 CNN 的對比結構如下,在網路結構上,直接把 pool5 層替換成 SPP 層:
SPP-Net 的具體細節如下,由 features map 上確定的 region proposal 大小不固定,將提取的 region proposal 分別經過三個折積 \(4 \ast 4\),\(2 \ast 2\),\(1 \ast 1\) ,都將得到一個長度為 21 的向量(21是資料集類別數,可以通過調整折積核大小來調整),因此不需要對 region proposal 進行尺寸調整:
相比R-CNN,SPP-Net有兩大優點。
① 通過「特徵金字塔池化」模組,實現了 CNN 的多尺度輸入,使得網路的輸入影象可以是任意尺寸的,輸出則不變,同樣是一個固定維數的向量。
② R-CNN 要對每個區域計算折積,而 SPPNet 只需要計算一次折積,從而節省了大量的計算時間。
對於 RCNN 速度過慢等問題,提出了基於 RCNN 的改善模型 Fast RCNN。
Fast RCNN 主要改進以下部分:
如下圖所示為Fast R-CNN流程與網路結構
Fast R-CNN具體包括的核心環節如下:
跟RCNN一樣,Fast-RCNN 採用的也是 Selective Search 的方法來產生 Region Proposal,每張圖片生成 2k 張圖片。但是不同的是,之後不會對 2k 個候選區域去原圖擷取,後輸入 CNN,而是直接對原圖進行一次 CNN,在 CNN 後的 feature map,通過 ROI project 在 feature map 上找到 Region Proposal的位置。
就是對原圖輸入到 CNN 中去計算,Fast-RCNN 的工具包提供提供了 3 種 CNN 的結構,預設是使用 VGG-16 作為 CNN 的主幹結構。根據 VGG-16 的結構,Fast-RCNN 只用了 4 個 MaxPooling 層,最後一個換成了 ROI Pooling,因此,只需要對 Region Proposal 的在原圖上的 4 元座標 \((x, y, w, h)\) 除以 \(16\),並找到最近的整數,便是 ROI Project 在 feature map 上對映的座標結果。最終得到 \(2k\) 個 ROI。
對每一個 ROI 在 feature map 上擷取後,進行 ROI Pooling,就是將每個 ROI 擷取出的塊,通過 MaxPooling 池化到相同維度。
ROI Pooling的計算原理是,將每個不同大小的 ROI 平均劃分成 \(7 \times 7\) 的 grid,在每個 grid 中取最大值,最後所有 ROI 都會池化成大小為 \(7 \times 7\) 維度。
將每個 ROI Pooling 後的塊,通過全連線層生成 ROI 特徵向量,最後用一個 Softmax 和一個 bbox regressor 進行分類和迴歸預測,得到每個 ROI 的類別分數和 bbox 座標。全連線層為矩陣相乘運算,執行消耗較多,速度較慢,作者在這裡提出可以使用 SVD 矩陣分解來加快全連線層的計算。
Fast-RCNN 的兩個任務:
Fast R-CNN 效果如上圖所示,相比之 R-CNN 它在訓練和預測速度上都有了很大的提升,但它依舊有不足之處,大家觀察整個流程,會發現在候選區域選擇上,依舊使用的 Selective Search 方法,它是整個流程中的時間消耗瓶頸,無法用 GPU 硬體與網路進行加速。
Faster-RCNN 在 Fast-RCNN 的基礎上做了兩個重大的創新改進:
Faster R-CNN的總體流程結構如下,可分為Backbone、RPN、ROI+分類 / 迴歸 三個部分。
Anchor 是影象檢測領域一個常用的結構,它可以用來表示原圖中物體所在的區域,是一個以feature map 上某個點為中心的矩形框。
Faster-RCNN 的 anchor,在 feature map 上每個點,生成 3 種尺度和 3 種比例共 9 個 anchor。
RPN 是一個全折積的神經網路,它的工作原理可以分成 classification,regression 和 proposal 三個部分
Classification 部分將得到的 feature map 通過一個 \(3 \times 3\) 和 \(1 \times 1\) 的折積後,輸出的維度為 \([1 \times 18 \times 38 \times 50]\),這18個channel可以分解成 \(2\times9\),2代表著是否是感興趣物體備選區域(region proposal)的 0/1 的 score,9 代表著 9 個 anchors。
因此,特徵圖維度 \(38\times50\) 的每一個點都會生成 9 個 anchor,每個 anchor 還會有 0/1 的 score。
Regression 部分原理和 Classification 部分差不多,feature map通過一個 \(3 \times 3\) 和 \(1 \times 1\) 的折積後,輸出的維度為 \([1 \times 36 \times 38 \times 50]\),其中 36 個channel可以分成 \(4 \times 9\),9就是跟 cls 部分一樣的 9 個anchor,4 是網路根據 anchor 生成的 bbox 的 4 元座標 target 的 offset。通過 offset 做 bbox regression,再通過公式計算,算出預測 bbox 的 4 元座標 \((x, y, w, h)\) 來生成 region proposal。
將前兩部分的結果綜合計算,便可以得出 Region Proposals。
一般來說,前景和背景的 anchor 保留的比例為 \(1:3\)
RPN 網路的訓練樣本有如下的策略和方式:
RPN 網路是監督學習訓練,包含分類和迴歸兩個任務,分類分支和迴歸分支的預測值和 label 構建方式如下:
RPN 網路的總體 loss 由 2 部分構成,分別是分類 loss 和迴歸 loss,為其加權求和結構。其中分類 loss 使用常規的交叉熵損失,迴歸損失函數使用的是 Smooth L1 Loss,本質上就是L1 Loss 和 L2 Loss 的結合。
特別說一下回歸部分使用到的 Smooth L1 Loss,對比於 L1 Loss 和 L2 Loss,Smooth L1 Loss 可以從兩方面限制梯度:
結合分類和迴歸結果得出 Region Proposals。若 anchor 的 \(IoU > 0.7\),就認為是前景;若 \(IoU < 0.3\),就認為是背景,其他的anchor全都忽略。一般來說,前景和背景的anchor保留的比例為 \(1:3\) 。
得到 Region Proposal 後,會先篩選除掉長寬小於 16 的預測框,根據預測框分數進行排序,取前N(例如6000)個送去 NMS,經過 NMS 後再取前 \(top_k\)(例如300)個作為 RPN 的輸出結果。
候選框共用特徵圖特徵,並保持輸出大小一致。
候選框分為若干子區域,將每個區域對應到輸入特徵圖上,取每個區域內的最大值作為該區域的輸出。
在 ROI 對映中,涉及到 region proposal 的座標對映變換問題,在這過程中難免會產生小數座標。但是在 feature map 中的點相當於一個個的 pixel,是不存在小數的,因此會將小數座標量化成向下取整,這就會造成一定的誤差。
在 ROI Pooling 中,對每個 ROI 劃分 grid 的時候又會有一次座標量化向下取整。
這樣,整個過程畫素座標會經過兩次量化,導致 ROI 雖然在 feature map 上有不到 1 pixel 的誤差,對映回原圖後的誤差可能會大於 10 pixel,甚至誤差可能會大於整個物體,這對小物體的檢測非常不友好。
Faster R-CNN 中通過 ROI Align 消除 RoI Pooling 中產生的誤差。
ROI Align 的原理是,先將 ROI Project 和 ROI Pooling 時計算出的 ROI 帶小數的座標儲存在記憶體中,不直接量化成畫素座標。
隨後,ROI Align 不取每個 grid 的最大值,而是再將每個 grid 劃分成 \(2\times2\) 的小格,在每個小格中找到中心點,將離中心點最近的四個點的值進行雙線性差值,求得中心點的值,再取每個 \(grid\) 中四個中心點的最大值作為 \(Pooling\) 後的值。
下面是分類與迴歸的 BBox 頭部分,它的處理流程展開後如下圖所示:
而BBox訓練階段的樣本構建方式如下,我們對比RPN階段的樣本構建方式:
BBox頭的分類與迴歸任務的標籤構建方式如下,其中分類分支是典型的分類問題,學習每個預測框的類別;迴歸分支則是學習每個 RoI 到真實框的偏移量。
BBox 頭的總體 loss 由分類 loss 和迴歸 loss 加權組合構成。
Faster R-CNN的效果如下圖所示
可以點選 B站 檢視視訊的【雙語字幕】版本