㈠ 目標檢測-YOLOv3
傳統的目標檢測演算法適用的場景有限,而且維護成本很大。深度學習方法應用於目標檢測,不僅演算法適應性好,還可以進行遷移學習,降低成本。
深度學習目標檢測演算法中,基於錨框(Anchor)的方法主要分為 一階段 方法和 兩階段 方法。
兩階段 方法先對感興趣的區域進行選擇,然後進一步對候選框內做分類和回歸,最終輸出選擇的框以及對應的分類。兩階段的模型有R-CNN系列,比如 R-CNN,Fast-RCNN,Faster-RCNN 等。兩階段模型的優點是精度高,但是速度及較慢。
一階段 方法直接對anchor進行回歸和分類,得到最終目標框和類別,演算法有 YOLOv2,v3,SSD,RetinaNet 等。一階段模型的推理速度較快,但是相對的精度會下降一些。
此外還有一些 anchor-free 的方法,包括基於關鍵點的檢測演算法以及基於中心檢測演算法等。
下面是一些基礎概念和縮寫:
BBox :Bounding Box 邊界框
Anchor :錨框
RoI : Region of Interest 特定的感興趣區域
Region Proposal : 候選區域
RPN : Region proposal network 提取候選區域的網路
IoU : Intersaction over Union (Area of Overlap/ Area of Union) 交並比,預測框的質量
mAP :mean average precision
NMS :non-maximum suppression 非極大值抑制
YOLO系列的模型在保有一定精度的基礎上擁有很快的推理速度,在下面圖中YOLOv3的推理速度遠超其他模型,因此在實時監測領域中有很好的應用。
YOLO的名字來源於you only look once,從名字上就道出了YOLO的精髓。
YOLOv1將圖像劃分為S*S個網路,物體真實框的中心落在哪個網格上,哪個網格對應的錨框就負責檢測物體。
每個網格會預測一個邊界框以及對應的置信度,這里的置信度反映的是模型認為這個框里包含著物體的把握以及它預測到這個物體的精確程度。所以置信度就等於 。如果物體不存在,那麼置信度應該等於零。
每個邊界框會預測5個值 。(x,y)坐標表示框相對於網格單元邊界的中心。 w,y是相對於整個圖像預測寬度和高度。 最後,置信度預測表示預測框與任何真實框之間的IOU。
YOLOv2在v1的基礎上進行了優化,骨幹網路使用了DarkNet19,並且將輸入圖片給尺寸從224增大到448,並且將網路結構設為全卷積網路結構加上Batch Norm,使用了Kmeans聚類方法來計算anchor,引入了多尺度訓練,使網路在訓練過程中學習不同尺度的圖像。不過待改進的地方有在小目標上召回率不高,靠近的群體目標檢測效果不好,檢測精度還有優化空間。
YOLOv3使用了更加深的骨幹網路DarkNet53,同時加入了多尺度預測,在COCO數據集上聚類; 9中不同尺度的anchor,在分類上使用sigmoid激活函數,支持了目標的多分類。YOLOv3的優點是推理速度快,性價比高,通用性強;缺點是召回率較低,定位精度較差,對於靠近或者遮擋的群體、小物體的檢測能力相對較弱。
YOLOv3在v1的基礎上做了很多改動。
邊界框預測
YOLOv3使用聚類預測到的邊界框作為錨框。網路為邊界框預測4個坐標值 ,如果單元格從圖像的左上角偏移了 ,並且先驗邊界框的寬度和高度為 ,則預測如下圖:
YOLOv3給每個邊界框用邏輯回歸預測一個objectness score,如果某個邊界框和真實框重合度比其他都高,那麼它的objectness score應該是1。而其他框雖然也與真實框有重疊,會被忽略掉。
類別預測
使用的是sigmoid函數,沒有用softmax因為沒必要。
不同尺度的預測
YOLOv3使用k-means聚類來確定bounding box priors,選擇了9個clusters和3個scales,然後在整個scales上均勻分割clusters。在COCO數據集上,9個cluster分別為(10×13),(16×30),(33×23),(30×61),(62×45),(59×119),(116×90) ,(156×198),(373×326)。
特徵提取
YOLOv3使用了Darknet-53,特點是加入了殘差,比之前的網路更深了(有53層卷積層所以叫Darknet-53)。
借一張圖看一下YOLOv3的整個流程:
每個輸出分支上對應著三個尺寸的先驗框(總共3 3=9種尺度)。經過32倍下采樣的網格,每一個網格對應著輸入圖像上32 32的區域,適合檢測尺寸較大的目標,而8倍下采樣的網格適合檢測尺寸小的目標。
輸出特徵的高度H和寬度W,相當於將圖像劃分為H*W個網格,而不是直接在圖像上畫網格。也就是說32倍下采樣之後得到的 ,相當於在輸入圖像上劃一個 的網格,每一個網格對應著輸出特徵圖上的一個點。
特徵圖的C通道上表示預測框的信息,包括坐標信息 ,目標置信度,分類。
C=B*(1+4+class_num),B為特徵圖上分配的錨框個數。
損失函數有三個,分類損失,定位損失和objectness損失。分類使用sigmoid激活函數,loss是sigmoid cross entropy。定位損失在x,y上使用sigmoid函數和sigmoid cross entropy損失,在w,h上使用L1損失。objectness損失用的是sigmoid激活函數和sigmoid cross entropy損失。
對於與真實框重疊的框,三種損失都要計算
對於沒有真實框重疊的框,只計算objectness(0);對於與真實框重疊但不是最匹配的框,忽略它們。
㈡ 目標檢測 YOLO系列——YOLO v1
YOLO v1:You Only Look Once: Unified, Real-Time Object Detection
YOLO v2:YOLO9000:Better,Faster,Stronger
YOLO v3:YOLOv3: An Incremental Improvement
近幾年來,目標檢測演算法取得了很大的突破。比較流行的演算法可以分為兩類,一類是基於Region Proposal的R-CNN系演算法(R-CNN,Fast R-CNN, Faster R-CNN),它們是two-stage的,需要先使用啟發式方法(selective search)或者CNN網路(RPN)產生Region Proposal,然後再在Region Proposal上做分類與回歸。而另一類是Yolo,SSD這類one-stage演算法,其僅僅使用一個CNN網路直接預測不同目標的類別與位置。第一類方法是准確度高一些,但是速度慢,但是第二類演算法是速度快,但是准確性要低一些。這里我們談的是Yolo-v1版本演算法,其性能是差於後來的SSD演算法的,但是Yolo後來也繼續進行改進,產生了Yolo9000、YOLO v3演算法。
傳統方法常採用滑動窗口法,滑動窗口的目標檢測演算法思路非常簡單,它將檢測問題轉化為了圖像分類問題。其基本原理就是採用不同大小和比例(寬高比)的窗口在整張圖片上以一定的步長進行滑動,然後對這些窗口對應的區域做圖像分類,這樣就可以實現對整張圖片的檢測了,如 DPM 就是採用這種思路。但是這個方法有致命的缺點,就是你並不知道要檢測的目標大小是什麼規模,所以你要設置不同大小和比例的窗口去滑動,而且還要選取合適的步長。但是這樣會產生很多的子區域,並且都要經過分類器去做預測,這需要很大的計算量,所以你的分類器不能太復雜,因為要保證速度。解決思路之一就是減少要分類的子區域,這就是R-CNN的一個改進策略,其採用了 selective search 方法來找到最有可能包含目標的子區域(Region Proposal),其實可以看成採用啟發式方法過濾掉很多子區域,這會提升效率。
如果你使用的是CNN分類器,那麼滑動窗口是非常耗時的。但是結合卷積運算的特點,我們可以使用CNN實現更高效的滑動窗口方法。這里要介紹的是一種全卷積的方法,簡單來說就是網路中用卷積層代替了全連接層,如圖所示。輸入圖片大小是16x16,經過一系列卷積操作,提取了2x2的特徵圖,但是這個2x2的圖上每個元素都是和原圖是一一對應的,如圖上藍色的格子對應藍色的區域,這不就是相當於在原圖上做大小為14x14的窗口滑動,且步長為2,共產生4個字區域。最終輸出的通道數為4,可以看成4個類別的預測概率值,這樣一次CNN計算就可以實現窗口滑動的所有子區域的分類預測。這其實是overfeat演算法的思路。之所可以CNN可以實現這樣的效果是因為卷積操作的特性,就是圖片的空間位置信息的不變性,盡管卷積過程中圖片大小減少,但是位置對應關系還是保存的。這個思路也被R-CNN借鑒,從而誕生了Fast R-cNN演算法。
上面盡管可以減少滑動窗口的計算量,但是只是針對一個固定大小與步長的窗口,這是遠遠不夠的。Yolo演算法很好的解決了這個問題,它不再是窗口滑動了,而是直接將原始圖片分割成互不重合的小方塊,然後通過卷積最後生產這樣大小的特徵圖,基於上面的分析,可以認為特徵圖的每個元素也是對應原始圖片的一個小方塊,然後用每個元素來可以預測那些中心點在該小方格內的目標,這就是Yolo演算法的樸素思想。
整體來看,Yolo演算法採用一個單獨的CNN模型實現end-to-end的目標檢測,整個系統如圖所示:首先將輸入圖片resize到448x448,然後送入CNN網路,最後處理網路預測結果得到檢測的目標。相比R-CNN演算法,其是一個統一的框架,其速度更快,而且Yolo的訓練過程也是end-to-end的。
具體來說,Yolo的CNN網路將輸入的圖片分割成 網格,然後每個單元格負責去檢測那些中心點落在該格子內的目標,如圖所示,可以看到狗這個目標的中心落在左下角一個單元格內,那麼該單元格負責預測這個狗。每個單元格會預測B個邊界框(bounding box)以及邊界框的 置信度 (confidence score)。所謂置信度其實包含兩個方面,一是這個邊界框含有目標的可能性大小,二是這個邊界框的准確度。前者記為 ,當該邊界框是背景時(即不包含目標),此時 。而當該邊界框包含目標時, 。邊界框的准確度可以用預測框與實際框(ground truth)的 IOU (intersection over union,交並比)來表徵,記為 IOU 。因此置信度可以定義為 。
很多人可能將Yolo的置信度看成邊界框是否含有目標的概率,但是其實它是兩個因子的乘積,預測框的准確度也反映在裡面。邊界框的大小與位置可以用4個值來表徵:(x,y,h,w),其中(x,y)是邊界框的中心坐標,而w和h是邊界框的寬與高。還有一點要注意,中心坐標的預測值(x,y)是相對於每個單元格左上角坐標點的偏移值,並且單位是相對於單元格大小的,單元格的坐標定義如圖所示。而邊界框的w和h預測值是相對於整個圖片的寬與高的比例,這樣理論上4個元素的大小應該在[0,1]范圍。這樣,每個邊界框的預測值實際上包含5個元素:(x,y,w,h,c),其中前4個表徵邊界框的大小與位置,而最後一個值是置信度。
值得注意的是,不管一個單元格預測多少個邊界框,其只預測一組類別概率值,這是Yolo演算法的一個缺點,在後來的改進版本中,Yolo9000是把類別概率預測值與邊界框是綁定在一起的。同時,我們可以計算出各個邊界框類別置信度(class-specificconfidence scores):
邊界框類別置信度表徵的是該邊界框中目標屬於各個類別的可能性大小以及邊界框匹配目標的好壞。後面會說,一般會根據類別置信度來過濾網路的預測框。
總結一下,每個單元格需要預測 個值。如果將輸入圖片劃分為 網格,那麼最終預測值為 大小的張量。整個模型的預測值結構如下圖所示。對於PASCALVOC數據,其共有20個類別,如果使用S=7,B=2,那麼最終的預測結果就是 大小的張量。在下面的網路結構中我們會詳細講述每個單元格的預測值的分布位置。
Yolo採用卷積網路來提取特徵,然後使用全連接層來得到預測值。網路結構參考GooLeNet模型,包含24個卷積層和2個全連接層,如圖所示。對於卷積層,主要使用1x1卷積來做channle rection,然後緊跟3x3卷積。對於卷積層和全連接層,採用Leaky ReLU激活函數:max(x,0)。但是最後一層卻採用線性激活函數。除了上面這個結構,文章還提出了一個輕量級版本Fast Yolo,其僅使用9個卷積層,並且卷積層中使用更少的卷積核。
可以看到網路的最後輸出為 大小的張量。這和前面的討論是一致的。這個張量所代表的具體含義如圖所示。對於每一個單元格,前20個元素是類別概率值,然後2個元素是邊界框置信度,兩者相乘可以得到類別置信度,最後8個元素是邊界框的(x,y,w,h)。大家可能會感到奇怪,對於邊界框為什麼把置信度c和(x,y,w,h)都分開排列,而不是按照(x,y,w,h,c)這樣排列,其實純粹是為了計算方便,因為實際上這30個元素都是對應一個單元格,其排列是可以任意的。但是分離排布,可以方便地提取每一個部分。這里來解釋一下,首先網路的預測值是一個二維張量P,其shape為 。
採用切片,那麼 就是類別概率部分; 是置信度部分; 是邊界框的預測結果。這樣,提取每個部分是非常方便的,這會方面後面的訓練及預測時的計算。
在訓練之前,先在ImageNet上進行了預訓練,其預訓練的分類模型採用圖中前20個卷積層,然後添加一個average-pool層和全連接層。預訓練之後,在預訓練得到的20層卷積層之上加上隨機初始化的4個卷積層和2個全連接層。由於檢測任務一般需要更高清的圖片,所以將網路的輸入從224x224增加到了448x448。整個網路的流程如下圖所示:
損失函數計算如下:
其中第一項是邊界框中心坐標的誤差項, 指的是第i個單元格存在目標,且該單元格中的第j個邊界框負責預測該目標。第二項是邊界框的高與寬的誤差項。第三項是包含目標的邊界框的置信度誤差項。第四項是不包含目標的邊界框的置信度誤差項。而最後一項是包含目標的單元格的分類誤差項, 指的是第i個單元格存在目標。
在說明Yolo演算法的預測過程之前,這里先介紹一下非極大值抑制演算法(non maximum suppression, NMS),這個演算法不單單是針對Yolo演算法的,而是所有的檢測演算法中都會用到。NMS演算法主要解決的是一個目標被多次檢測的問題,如圖中人臉檢測,可以看到人臉被多次檢測,但是其實我們希望最後僅僅輸出其中一個最好的預測框,比如對於美女,只想要紅色那個檢測結果。那麼可以採用NMS演算法來實現這樣的效果:首先從所有的檢測框中找到置信度最大的那個框,然後挨個計算其與剩餘框的IOU,如果其值大於一定閾值(重合度過高),那麼就將該框剔除;然後對剩餘的檢測框重復上述過程,直到處理完所有的檢測框。
下面就來分析Yolo的預測過程,這里我們不考慮batch,認為只是預測一張輸入圖片。根據前面的分析,最終的網路輸出是 ,但是我們可以將其分割成三個部分:類別概率部分為 ,置信度部分為 ,而邊界框部分為 (對於這部分不要忘記根據原始圖片計算出其真實值)。然後將前兩項相乘可以得到 類別置信度值為 ,這里總共預測了 邊界框。
所有的准備數據已經得到了,那麼先說第一種策略來得到檢測框的結果。首先,對於每個預測框根據類別置信度選取置信度最大的那個類別作為其預測標簽,經過這層處理我們得到各個預測框的預測類別及對應的置信度值,其大小都是[7,7,2]。一般情況下,會設置置信度閾值,就是將置信度小於該閾值的box過濾掉,所以經過這層處理,剩餘的是置信度比較高的預測框。最後再對這些預測框使用NMS演算法,最後留下來的就是檢測結果。一個值得注意的點是NMS是對所有預測框一視同仁,還是區分每個類別,分別使用NMS。Ng在deeplearning.ai中講應該區分每個類別分別使用NMS,但是看了很多實現,其實還是同等對待所有的框,可能是不同類別的目標出現在相同位置這種概率很低吧。
上面的預測方法應該非常簡單明了,但是對於Yolo演算法,其卻採用了另外一個不同的處理思路(至少從C源碼看是這樣的),其區別就是先使用NMS,然後再確定各個box的類別。其基本過程如圖所示。對於98個boxes,首先將小於置信度閾值的值歸0,然後分類別地對置信度值採用NMS,這里NMS處理結果不是剔除,而是將其置信度值歸為0。最後才是確定各個box的類別,當其置信度值不為0時才做出檢測結果輸出。這個策略不是很直接,但是貌似Yolo源碼就是這樣做的。Yolo論文裡面說NMS演算法對Yolo的性能是影響很大的,所以可能這種策略對Yolo更好。
總結一下Yolo的優缺點。首先是優點,Yolo採用一個CNN網路來實現檢測,是單管道策略,其訓練與預測都是end-to-end,所以Yolo演算法比較簡潔且速度快。第二點由於Yolo是對整張圖片做卷積,所以其在檢測目標有更大的視野,它不容易對背景誤判。另外,Yolo的泛化能力強,在做遷移時,模型魯棒性高。
Yolo的缺點,首先Yolo各個單元格僅僅預測兩個邊界框,而且屬於一個類別。對於小物體,Yolo的表現會不如人意。這方面的改進可以看SSD,其採用多尺度單元格。也可以看Faster R-CNN,其採用了anchor boxes。Yolo對於在物體的寬高比方面泛化率低,就是無法定位不尋常比例的物體。當然Yolo的定位不準確也是很大的問題。
參考鏈接
YOLO演算法的原理與實現
https://cloud.tencent.com/developer/article/1058057
㈢ 目標檢測演算法之SSD
目標檢測演算法分為one-stage和two-stage兩類,其中two-stage演算法以R-CNN族為代表,准確度高但速度較慢。one-stage演算法包括YOLO、SSD、CornerNet等,以速度快著稱,但准確度不如two-stage演算法。按是否使用anchor,可分為anchor-based、anchor-free、兩者融合類。anchor-based類演算法代表是fasterRCNN、SSD、YoloV2/V3等,anchor-free類演算法代表是CornerNet、ExtremeNet、CenterNet、FCOS等,融合anchor-based和anchor-free分支的方法有FSAF、SFace、GA-RPN等。
SSD網路由VGG Backbone、Extra Layers、Multi-box Layers三大部分組成。Backbone網路可以使用VGG、ResNet50、mobilenet等。SSD的核心思想是使用多個特徵圖進行目標位置的回歸和類別的分類。Extra layer負責提取6個尺寸和深度的特徵圖,大小分別為 (38,38),(19,19),(10,10),(5,5),(3,3),(1,1),每個特徵圖上設置的先驗框數量不同,prior_box_num = [4,6,6,6,4,4],共8732個anchor。
先驗框的設置包括尺度(大小)和長寬比兩個方面。尺度遵守線性遞增規則:隨著特徵圖大小降低,先驗框尺度線性增加。編碼過程使用gt_box和bounding_box的歸一化後的中心點表示的offset作為基準,與模型的輸出做loss。解碼過程:模型的輸出為bounding_box與真實值的offset。推理階段,用offset與bounding_box,即可得到最終目標框。
綠框為真實框:gt_box;藍框為與gt_box匹配的先驗框prior_box,稱為bounding_box,它是整個回歸過程的核心;紅框為預測框,pred_box。在訓練過程中,首先需要確定訓練圖片中的 gt_box與哪一個prior_box來進行匹配,匹配原則:1、對於圖片中的每個gt_box,找到與其IOU最大的prior_box,該先驗框與其匹配,這樣可以保證每個gt_box一定與某個prior_box匹配。2、對於剩餘未匹配的prior_box,若與某個gt_box的IOU大於某個閾值(一般0.5),那麼該prior_box與這個gt_box匹配。3、難例挖掘(Hard negative mining,選取負樣本):選取完正樣本後,實際上剩下來的都是負樣本,但由於負樣本數目過多,因此需要挑選出Confidence_Loss排在前面的一批負樣本,以保證負/正樣本數為3:1。
SSD的損失函數包括位置損失函數和置信度損失函數,整個損失函數為:N 是先驗框的正樣本數量;c 為類別置信度預測值;l 為先驗框的所對應bounding box的位置預測值;g 為ground truth的位置參數。位置損失函數如下:置信度損失函數如下:訓練階段,測試階段,NMS應該在解碼之後。
模型特點:SSD提取了不同尺度的特徵圖來做檢測,大尺度特徵圖可以用來檢測小物體,而小特徵圖用來檢測大物體;SSD採用了不同尺度和長寬比的先驗框。SSD每一張訓練圖片由如下方法隨機產生:原圖片;截取一部分圖片,保證截取框與物體框的最小IoU是0.1,03,0.5,0.7,或者0.9;隨機截取一部分圖片;隨機截取圖片的大小是[0.1,1]原圖片大小,aspect ratio是0.5~2。
優點:運行速度可以和YOLO媲美,檢測精度可以和Faster RCNN媲美。
缺點:需要人工設置prior box的min_size,max_size和aspect_ratio值。網路中prior box的基礎大小和形狀不能直接通過學習獲得,而是需要手工設置。而網路中每一層feature使用的prior box大小和形狀恰好都不一樣,導致調試過程非常依賴經驗;雖然採用了pyramdial feature hierarchy的思路,但是對小目標的recall依然一般,並沒有達到碾壓Faster RCNN的級別。