目标检测 /yolo算法原理的详解
前言
談到計算機視覺時,我們都會聯想到圖像分類,圖像分類是計算機視覺最基本的任務之一,在圖像分類的基礎上,我們還有更復雜的任務,比如目標檢測,物體定位,圖像分割等,本文主要講目標檢測,目標檢測是分類與定位的結合,在給定一張圖片,目標檢測的任務是要識別出圖片的目標以及它的位置,由于圖片中的目標個數不確定,且要精確定位目標,目標檢測比分類任務更復雜。? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 目標檢測?
目標檢測目前有兩類流行算法:一類是基于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算法的原理。
一. yolo v1算法原理
從整體上看,yolo是通過一個cnn網絡模型來實現end-to-end的目標檢測,整個流程如下圖所示:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? YOLO的檢測過程
該過程整體上首先是將輸入的圖像resize成448*448的大小,然后送入cnn中,運行該cnn網絡,接著采用非極大值抑制的方法進行篩選,最后處理網絡預測結果得到檢測的目標。
接下來詳細的分析整個過程,首先對輸入的圖像resize成448*448的大小送入到cnn模型中,yolo中的cnn模型是將輸入的圖像分割成S*S大小的網格,然后對每一個單元格都會預測B個邊界框(bounding boxes),每個邊界框都包含5個預測值:x,y,w,h 和confidence(置信度),其中x,y就是預測邊界框的中心坐標,中心坐標(x,y)的預測值?是相對于該單元格左上角坐標點的偏移值,并且單位是相對于單元格大小的,與單元格對齊(即相對于當前grid cell的偏移值),使得范圍變成0到1,單元格的坐標定義如圖1所示;而邊界框的w和h的預測值是相對于整個圖片的寬和高的比例(即w和h進行歸一化,分別除以圖像的w和h,這樣最后的w和h就在0到1范圍了)。另外每一個單元格(grid cell)都有C個類別的概率預測值,其表示的是由該單元格負責預測的邊界框,在包含目標條件下屬于各個類別的概率。但是這些概率值其實是在各個邊界框置信度下的條件概率,即p(classi? | object).
? ? ? ? ? ? ? ? ? ? ? ? 圖1
所謂置信度其實就是這個邊界框含有目標的可能性大小與這個邊界框的準確度的乘積。前者記為Pr(object),當邊界框的為背景時(沒有目標),Pr(object)=0,當邊界框包含目標時,Pr(object)=1,
后者記為邊界框的準確度可以用預測框與實際框(ground truth)的IOU(intersection over union,交并比)來表示,記為?,因此置信度為
前面已經有每一個單元格(grid cell)的C個類別的概率預測值Pr(class i? | object),我們可以計算每個邊界框的類別置信度:
邊界框類別置信度反映的是該邊界框中目標屬于各個類別的可能性大小以及邊界框匹配目標的好壞??
每個邊界框的類別置信度的過程圖如下:這里把圖片分割成了7*7的網格,每個單元格有2個預測邊框,一共有20個類別,則整張圖片共有7*7*2個邊框,每個邊框的類別置信度為20*1
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖2
即得到每個邊界框屬于20類的confidence score。也就是說最后會得到20*(7*7*2)=20*98的置信度矩陣。
?
?
二.網絡模型
網絡上采用的是GoogLeNet,24個卷積層+2個全連接層,卷積層主要用來提取特征,全連接層主要用來預測類別概率和坐標。輸入的是448*448,最后的輸出是7*7*30,這個30是20+2*5,20代表類別數量,2代表每一個單元格有2個邊界框,5代表(x,y,w,h,c),具體含義前面講過,7*7是單元格的數量。模型如下圖3
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖3
PS:這里有三點需要注意
①原文YOLO模型未使用inception module,而是使用1x1卷積層(此處1x1卷積層的存在是為了跨通道信息整合)+3x3卷積層簡單替代
②原文YOLO作者先在ImageNet數據集上預訓練網絡,而且網絡只采用fig3的前面20個卷積層,輸入是224*224大小的圖像。然后在檢測的時候再加上隨機初始化的4個卷積層和2個全連接層,同時輸入改為更高分辨率的448*448。
③Relu層改為pRelu,即當x<0時,激活值是0.1*x,而不是傳統的0。
?
三.損失函數
YOLO算法是將目標檢測看出一個回歸問題,所以將均方差作為損失函數,損失函數分為定位誤差部分和分類誤差部分,對于不同部分他們的比重值λ;對于定位誤差,即邊界框中心坐標誤差以及邊界框的寬高誤差,均采用的比重是λcoord?=5,而對于不含目標的邊界框的置信度誤差所采用的比重是λnoobj?=0.5,含有目標的邊框的置信度誤差的比重λ=1,每個單元格的分類誤差的比重λ=1,所以采用均方誤差
對于相等的誤差值,大物體誤差對檢測的影響應小于小物體誤差對檢測的影響。這是因為,相等的位置偏差占大物體的比例遠小于同等偏差占小物體的比例,比如原來大物體w=10,h=20,預測出來w=8,h=22,跟原來小物體w=3,h=5,預測出來w1,h=7相比,經過計算兩個物體損失影響是一樣的,實際上大物體的誤差對檢測的影響要比小物體小,所以YOLO將物體大小的信息項(w和h)進行求平方根來改進這個問題,即預測值變為了(x,y,w,h)
另外由于每一個單元格有多個邊界框,但是每一個單元格其對應類別只有一個,如果在訓練時,多個邊界框存在目標,那就只選擇與真實邊框(ground truth)的IOU最大的那個邊界框來負責預測該目標,而其它邊界框認為不存在目標。這樣設置的結果使每一個單元格只對應一個邊框,一個類別。大家可能會想如果一個單元格內存在多個目標怎么辦,其實這時候Yolo算法就只能選擇其中一個來訓練,這也是Yolo算法的缺點之一。要注意的一點時,對于不存在對應目標的邊界框,其誤差項就是只有置信度,坐標項誤差是沒法計算的。而只有當一個單元格內確實存在目標時,才計算分類誤差項,否則該項也是無法計算的。
綜上所述,損失函數如下:
第一行的式子表示邊界框中心坐標的誤差,第二行式子表示邊界框的寬高誤差,第三行式子表示含有目標的邊界框的置信度誤差,第四項式子表示不含有目標的邊界框的置信度誤差,第五行式子表示含有目標的單元格的類別誤差;這里注意置信度Ci的值,如果不存在目標,則Pr(object)=0,那么置信度Ci=0,如果存在目標,則Pr(object)=1,需要確定值,才能得到置信度Ci的值;為了方便計算,你可以將Ci置為1;
四.網絡訓練
前面已經講過YOLO的cnn模型(GoogleNet),在訓練之前,先在ImageNet上進行了預訓練,其預訓練的分類模型采用之前圖中前20個卷積層,然后添加一個average-pool層和全連接層。預訓練之后,在預訓練得到的20層卷積層之上加上隨機初始化的4個卷積層和2個全連接層。由于檢測任務一般需要更高清的圖片,所以將網絡的輸入從224x224增加到了448x448。整個網絡的流程如下圖所示:
一張圖片經過該模型的處理后得到一個7*7*30的張量,剛好是我們需要的所有數據信息,這個30是20+2*5,20代表類別數量,2代表每一個單元格有2個邊界框,5代表(x,y,w,h,c),具體含義前面講過,7*7是單元格的數量。我們可以將其劃分為三個部分:①類別概率部分,[7,7,20],②邊界框置信度部分,[7,7,2],③邊界框部分,[7,7,2,4],類別概率部分*邊界框置信度部分=邊界框類別置信度(矩陣[7,7,2]乘以[7,7,20],為了方便計算,我們可以先將它們各補一個維度來完成[7,7,2,1]×[7,7,1,20]),兩者相乘可以得到邊界框類別置信度[7,7,2,20],這里總共有7*7*2=98個邊界框,如前面的圖二所示,所有的數據信息已經得到,接下來有兩種策略得到邊界框的類別結果和置信度
第一種策略:對于每個預測框選擇類別置信度最大的類別作為該預測框的類別標簽,然后通過上一步得到了每個預測框的類別標簽以及該類別的置信度,然后設置置信度閾值,將小于該置信度閾值的邊框過濾掉,經過這樣處理后,剩下的就是置信度比較高的邊框,然后對這些預測框進行NMS算法處理,最后留下來的檢測結果。
這里提一下非極大值抑制算法(NMS),NMS算法主要解決一個目標被多次檢測到的問題,比如人臉識別,如果人臉被多個邊界框檢測到,這時我們通過nms算法得到的是一個效果最好的檢測框;NMS算法原理是首先從所有預測邊界框中選擇類別置信度最大的邊界框,然后計算該邊界框與剩余其他邊界框進行IOU(交并比),如果其IOU值大于一定閾值(重復度過高),則將該邊界框過濾掉,接下來對剩余的邊界框重復上述過程,直至處理完所有的邊界框。
第二種策略:是原YOLO論文中使用的策略,首先對每個類別使用NMS,然后再確定各個邊界框的類別,其過程如下圖4所示,其過程是對于7*7*2=98個邊界框,首先設置一定閾值,然后對每一個邊界框的類別置信度與閾值作比較,如果小于該閾值,則將該類別置信度設置為0,接著對所有邊界框的置信度從高到低做排序,然后對所有邊界框分類別的(矩陣的每一行)進行NMS,得到一個最佳邊界框獲得該類別以及其置信度(該過程NMS:針對某一類別,選擇類別置信度最大的bounding box,然后計算它和其它bounding box的IOU值,如果IOU大于閾值0.5,說明重復率較大,該置信度設為0,如果IOU不大于閾值0.5,則不改,再選擇該行剩下的置信度里面最大的那個bounding box,然后計算該bounding box和其它bounding box的IOU,重復比較閾值過程,直到這一行所有的邊界框結束為止;然后進行下一個類別,每一類別重復以上過程直到最后),這里不是剔除其他邊界框,最后從每一個邊界框中選擇最大的類別置信度作為該邊界框的類別標簽以及置信度,最后篩選出置信度大于0的邊界框作為檢測的最后結果,如果小于0,說明這個邊界框里面沒有物體,跳過即可。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖4
五.YOLO v1的代碼實現
源碼:https://e.coding.net/xucancan1/yolov1/YOLOv1.git
效果:
六.YOLO的優缺點
優點:
第一點Yolo采用一個CNN網絡來實現檢測,是單管道策略,其訓練與預測都是end-to-end,所以Yolo算法比較簡潔且速度快。
第二點由于Yolo是對整張圖片做卷積,所以其在檢測目標有更大的視野,它不容易對背景誤判。
缺點:
第一點Yolo各個單元格僅僅預測兩個邊界框,而且屬于一個類別,如果一個單元格有兩個以上的目標,就只能預測一個,對于小目標物體以及物體比較密集的也檢測不好,比如一群小鳥
第二點定位不準確,Yolo對于在物體的寬高比方面泛化率低,就是無法定位不尋常比例的物體。
參考:
https://blog.csdn.net/u014380165/article/details/72616238
https://zhuanlan.zhihu.com/p/32525231
?
?
總結
以上是生活随笔為你收集整理的目标检测 /yolo算法原理的详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tf.reduce_max()函数的用法
- 下一篇: input.get_shape()的用法