當前位置:
首頁 > 知識 > 目標檢測演算法之YOLOv2損失函數詳解

目標檢測演算法之YOLOv2損失函數詳解

本文來自@BBuf的社區專欄GianPandaCV,文末掃碼即可訂閱專欄。

前言

前面的YOLOv2推文詳細講解了YOLOv2的演算法原理,但官方論文沒有像YOLOv1那樣提供YOLOv2的損失函數,難怪Ng說YOLO是目標檢測中最難懂的演算法。今天我們嘗試結合DarkNet的源碼來分析YOLOv2的損失函數。

關鍵點回顧

直接位置預測

YOLOv2借鑒RPN網路使用Anchor boxes來預測邊界框相對於先驗框的offsets。邊界框的實際中心位置

需要利用預測的坐標偏移值

,先驗框的尺度

以及中心坐標

來計算,這裡的

也即是特徵圖每個位置的中心點:

上面的公式也是Faster-RCNN中預測邊界框的方式。但上面的預測方式是沒有約束的,預測的邊界框容易向任何方向偏移,例如當

時邊界框將向右偏移Anchor的一個寬度大小,導致每個位置預測的邊界框可以落在圖片的任意位置,這就導致模型訓練的不穩定性,在訓練的時候要花很長時間才可以得到正確的offsets。以,YOLOv2棄用了這種預測方式,而是沿用YOLOv1的方法,就是預測邊界框中心點相對於對應cell左上角位置的相對偏移值,為了將邊界框中心點約束在當前cell中,使用sigmoid函數處理偏移值,這樣預測的偏移值在(0,1)範圍內(每個cell的尺度看做1)。

綜上,根據邊界框預測的4個偏移值

,可以使用如下公式來計算邊界框實際中心位置和長寬,公式在圖中:

其中,

為cell的左上角坐標。在Fig3中,當前的cell的左上角坐標為

。由於

函數的處理,邊界框的中心位置會被約束在當前cell的內部,防止偏移過多,然後

是先驗框的寬度與高度,它們的值也是相對於特徵圖(這裡是13*13,我們把特徵圖的長寬記作H,W)大小的,在特徵圖中的cell長寬均為1。這樣我們就可以算出邊界框相對於整個特徵圖的位置和大小了,公式如下:

我們如果將上面邊界框的4個值乘以輸入圖像長寬,就可以得到邊界框在原圖中的位置和大小了。

細粒度特徵

YOLOv2提取Darknet-19最後一個max pool層的輸入,得到26x26x512的特徵圖。經過1x1x64的卷積以降低特徵圖的維度,得到26x26x64的特徵圖,然後經過pass through層的處理變成13x13x256的特徵圖(抽取原特徵圖每個2x2的局部區域組成新的channel,即原特徵圖大小降低4倍,channel增加4倍),再與13x13x1024大小的特徵圖連接,變成13x13x1280的特徵圖,最後在這些特徵圖上做預測。使用Fine-Grained Features,YOLOv2的性能提升了1%。這個過程可以在下面的YOLOv2的結構圖中看得很清楚:

這個地方今天還要補充一點,那就是passthrough層到底是怎麼操作的,在DarkNet中passthough層叫作reorg_layer,可以用下圖來表示這個操作:

訓練

上篇推文講了YOLOv2的訓練分為三個階段,具體就不再贅述了。這裡主要重新關注一下訓練後的維度變化,我們從上一小節可以看到最後YOLOv2的輸出維度是

。這個125使用下面的公式來計算的:

和訓練採用的數據集有關係。由於anchors數為5,對於VOC數據集輸出的channels數就是125,而對於COCO數據集則為425。這裡以VOC數據集為例,最終的預測矩陣為

,shape為

,可以將其reshape成

,這樣

是邊界框的位置和大小

表示邊界框的置信度

,而

表示類別預測值。

YOLOv2的模型結構

損失函數

接下來就說一說今天的主題,損失函數。損失函數我看網上的眾多講解,發現有兩種解釋。

解釋1

YOLOv2的損失函數和YOLOv1一樣,對於訓練集中的ground truth,中心落在哪個cell,那麼該cell的5個Anchor box對應的邊界框就負責預測它,具體由哪一個預測同樣也是根據IOU計算後卡閾值來確定的,最後選IOU值最大的那個。這也是建立在每個Cell至多含有一個目標的情下,實際上也基本不會出現多餘1個的情況。和ground truth匹配上的先驗框負責計算坐標誤差,置信度誤差以及分類誤差,而其它4個邊界框只計算置信度誤差。這個解釋參考的YOLOv2實現是darkflow.源碼地址為:https://github.com/thtrieu/darkflow

解釋2

在官方提供的Darknet中,YOLOv2的損失函數可以不是和YOLOv1一樣的,損失函數可以用下圖來進行表示:

可以看到這個損失函數是相當複雜的,損失函數的定義在Darknet/src/region_layer.c中。對於上面這一堆公式,我們先簡單看一下,然後我們在源碼中去找到對應部分。這裡的

代表的是特徵圖的高寬,都為

,而A指的是Anchor個數,YOLOv2中是5,各個

值是各個loss部分的權重係數。我們將損失函數分成3大部分來解釋:

第一部分:

第一項需要好好解釋一下,這個loss是計算background的置信度誤差,這也是YOLO系列演算法的特色,但是用哪些預測框來預測背景呢?這裡需要計算各個預測框和所有的ground truth之間的IOU值,並且取最大值記作MaxIOU,如果該值小於一定的閾值,YOLOv2論文取了0.6,那麼這個預測框就標記為background,需要計算

這麼多倍的損失函數。為什麼這個公式可以這樣表達呢?因為我們有物體的話,那麼

,如果沒有物體

,我們把這個值帶入到下面的公式就可以推出第一項啦!

第二部分:

這一部分是計算Anchor boxes和預測框的坐標誤差,但是只在前12800個iter計算,這一項應該是促進網路學習到Anchor的形狀。

第三部分:

這一部分計算的是和ground truth匹配的預測框各部分的損失總和,包括坐標損失,置信度損失以及分類損失。3.1 坐標損失這裡的匹配原則是指對於某個特定的ground truth,首先要計算其中心點落在哪個cell上,然後計算這個cell的5個先驗框和grond truth的IOU值,計算IOU值的時候不考慮坐標只考慮形狀,所以先將Anchor boxes和ground truth的中心都偏移到同一位置,然後計算出對應的IOU值,IOU值最大的先驗框和ground truth匹配,對應的預測框用來預測這個ground truth。3.2 置信度損失在計算obj置信度時, 增加了一項

權重係數,也被稱為rescore參數,當其為1時,損失是預測框和ground truth的真實IOU值(darknet中採用了這種實現方式)。而對於沒有和ground truth匹配的先驗框,除去那些Max_IOU低於閾值的,其它就全部忽略。YOLOv2和SSD與RPN網路的處理方式有很大不同,因為它們可以將一個ground truth分配給多個先驗框。3.3 分類損失這個和YOLOv1一致,沒什麼好說的了。

我看了一篇講解YOLOv2損失函數非常好的文章:https://www.cnblogs.com/YiXiaoZhou/p/7429481.html 。裡面還有一個關鍵點:

在計算boxes的

誤差時,YOLOv1中採用的是平方根以降低boxes的大小對誤差的影響,而YOLOv2是直接計算,但是根據ground truth的大小對權重係數進行修正:l.coord_scale * (2 - truth.w*truth.h)(這裡

都歸一化到(0,1)),這樣對於尺度較小的

其權重係數會更大一些,可以放大誤差,起到和YOLOv1計算平方根相似的效果。

代碼實現

貼一下YOLOv2在Keras上的復現代碼,地址為:https://github.com/yhcc/yolo2 。網路結構如下,可以結合上面可視化圖來看:

然後,網路經過我們介紹的損失函數優化訓練以後,對網路輸出結果進行解碼得到最終的檢測結果,這部分代碼如下:

補充

這個損失函數最難的地方應該是YOLOv2利用sigmoid函數計算默認框坐標之後怎麼梯度回傳,這部分可以看下面的代碼(來自Darknet源碼):

結合一下我們前面介紹的公式,這就是一個逆過程,現在是不是清晰一些了?有任何問題歡迎在留言區和我討論哦。

後記

今天就介紹到這裡了,YOLOv2的損失函數實現都在region_layer.c裡面了,同時推薦一下我的一個Darknet源碼解析項目,我會在裡面努力解析YOLO目標檢測演算法的細節,地址為:https://github.com/BBuf/Darknet 。明天開始講解YOLOv3,後面安排一下YOLOv3的實戰,就用NCNN和YOLOv3為例子吧。

參考

https://zhuanlan.zhihu.com/p/35325884https://www.cnblogs.com/YiXiaoZhou/p/7429481.htmlhttps://github.com/yhcc/yolo2

掃碼訂閱專欄

關於專欄

AI 研習社專欄旨在滿足有持續創作能力的的知名學者、技術專家、優秀博主、講師和人工智慧人才文字創作和打造專屬個人IP的需求。AI 研習社希望能夠幫助大咖見證求知,分享洞見~

歡迎大家來AI研習社訂閱/開通專欄:https://www.yanxishe.com/column

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


請您繼續閱讀更多來自 AI研習社 的精彩文章:

圖嵌入方法介紹
人工智慧及其演算法&雲原生技術的前世今生