yolo v1原理

本文結構如下: yolo v1基本思路、網絡結構、網絡訓練、網絡預測

一、基本思路

yolo v1 是one stage的目標檢測算法,將一張圖片分爲S×SS×S個網格,每個網格負責預測中心點落在此網格內的目標。每個網格會預測BB個bounding box,CC個類別概率值。

一張圖片的預測結果有(S×S×[(4+1)B+C])(S×S×[(4+1)*B+C])個值。

在PASCAL VOC 數據集上評估模型,S=7,B=2,C=20S=7,B=2,C=20,最終得到7×7×30的tensor。

目標的中心點落在哪個網格,則由該網格負責預測此目標

如下圖所示:狗的中心在紅色網格內,由該網格來負責預測這隻狗。
在這裏插入圖片描述

每個boundingboxbounding box的大小和位置可以通過(x,y,w,h)(x,y,w,h)四個值來表示,其中(x,y)(x,y)的值是相對於每個網格的,(w,h)(w,h)的值是想對於整張圖片的。
在這裏插入圖片描述

confidenceconfidencePr(Object)Pr(Object) 的取值爲0或者1.
若目標的中心在網格內,則 Pr(Object)Pr(Object) 的取值爲1;
若目標的中心不在網格內,則 Pr(Object)Pr(Object) 的取值爲0;
注意: 必須是目標的中心在網格內,若僅僅只是目標的一部分在網格內,Pr(Object)Pr(Object) 的取值仍然爲0。

二、網絡結構

整個網絡先進行特徵提取,再進行分類和迴歸。

yolo網絡由24層卷積+2層全連接層組成。使用1×1卷積可以降維,從而較少網絡的參數和計算量。使用PASCAL VOC 數據集來評估模型,所以網絡的最後輸出爲7×7×30=1470。

最後一層使用線性激活函數,其它層均使用leaky Relu激活函數。

在這裏插入圖片描述

三、網絡訓練

網絡的訓練分爲2部分。
(1)先預訓練一個分類網絡,使用上述網絡的前20個卷積層+average-pool+全連接層在ImageNet進行訓練,網絡輸入爲(224×224×3)。
(2)訓練完成後,再訓練檢測網絡,在預訓練網絡的基礎上+4層卷積層+2層全連接層,將網絡的輸入變爲(448×448×3)。這部分增加4層卷積層是爲了網絡的性能更好
在這裏插入圖片描述

網絡輸出:
在這裏插入圖片描述

bbox->(x,y,w,h)(x,y,\sqrt{w},\sqrt{h})

爲什麼將 (w,h)>(w,h)(w,h) -> (\sqrt{w},\sqrt{h}) ?
實際上較小的邊界框的座標誤差應該要比較大的邊界框要更敏感。爲了保證這一點,將網絡的邊界框的寬與高預測改爲對其平方根的預測
在這裏插入圖片描述

loss函數

一個網格中會預測多個bbox,在訓練時,只選擇IOU最大的那個bbox來負責預測該目標,其他bbox的Pr(Object)Pr(Object)值被設爲0。

在這裏插入圖片描述

1ijobj1_{ij}^{obj}意爲:第(i+1)(i+1)個網格內存在目標,且該目標由此網格內的第(j+1)(j+1)個bbox來負責預測。
不同的部分採取不同的權重,其中,λcord=5\lambda_{cord}=5 ; 因爲大部分網格中沒有目標,所以λnoobj\lambda_{noobj}的值設置的小一些,λnoobj=0.5\lambda_{noobj}=0.5

因大部分網格中沒有目標,所以,上式中1,2,3,5行的結果大部分爲0,4行不爲0。

四、網絡預測

在這裏插入圖片描述

第三步詳細過程如下:

對於98個boxes,首先將小於置信度閾值的值歸0,然後分類別地對類別置信度值採用NMS。
在這裏插入圖片描述

non_max_suppression

一個目標可能有多個預測框,通過NMS可以去除多餘的預測框,確保一個目標只有一個預測框。NMS是通過類別置信度來篩選的。

classclass confidenceconfidence 計算公式如下:
在這裏插入圖片描述
其中,Pr(Object)IOUpresdtruthPr(Object)*IOU_{presd}^{truth} 爲bbox置信度 ;Pr(ClassObject)Pr(Class|Object)爲類別概率。

原理: 首先從所有的預測框中找到置信度最大的那個bbox,然後挨個計算其與剩餘bbox的IOU,如果其值大於一定閾值(重合度過高),那麼就將該剩餘bbox剔除;然後對剩餘的預測框重複上述過程,直到處理完所有的檢測框。

def _non_max_suppression(self, scores, boxes):
        """Non max suppression"""
        # https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/ObjectDetections/yolo/yolo.py	
      
        # scores :[S*S*B, C] ;   boxes:[S*S*B, 4]
        # for each class
        for c in range(self.C):
            sorted_idxs = np.argsort(scores[:, c])
            last = len(sorted_idxs) - 1
            while last > 0:
                # scores[sorted_idxs[last], c]爲一個類中scores最大的值
                if scores[sorted_idxs[last], c] < 1e-6:
                    break
                for i in range(last):
                    if scores[sorted_idxs[i], c] < 1e-6:
                        continue
                    # 將兩個bbox的IOU值 與 iou_threshold 進行比較
                    if self._iou(boxes[sorted_idxs[i]], boxes[sorted_idxs[last]]) > self.iou_threshold:
                        scores[sorted_idxs[i], c] = 0.0
                last -= 1

總結

輸入圖片被劃分爲7x7個網格。網格只是物體中心點位置的劃分之用,並不是對圖片進行切片,不會讓網格脫離整體的關係。

下一篇將通過分析yolo源碼加深對yolo算法的理解。

參考資料:

1、paper
2、論文翻譯
3、yolo詳解
4、ppt

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章