Part 1:YOLO是如何工作的

翻譯原文:https://blog.paperspace.com/how-to-implement-a-yolo-object-detector-in-pytorch/

本篇文章是《如何使用PyTorch從零開始實現YOLO(v3)目標檢測算法》的第一部分。這系列論文一共有五篇文章,五篇文章的主要內容在下文中有涉及。如果有問題歡迎和我交流~


目錄

如何使用PyTorch從零開始實現YOLO(v3)目標檢測算法?

前沿知識:

1 什麼是YOLO

2 全卷積神經網絡

3 輸入層說明

4 錨框

5 做出預測

5.1 中心點座標

5.2 邊界框的尺寸

5.3 目標物體的得分

5.4 種類的置信度

6  跨尺度預測

 7 處理輸出

7.1 給目標物體的置信度設置一個閾值

7.2 非極大值抑制

8 總結


如何使用PyTorch從零開始實現YOLO(v3)目標檢測算法?

從零開始創建YOLO v3檢測器的教程詳細介紹了如何從配置文件中創建網絡架構加載權重設計輸入輸出傳輸途徑

目標檢測這個領域,從最近深度學習的發展中受益良多。最近幾年,已經有人研究出了關於目標檢測的諸多算法,包括YOLO, SSD,Mask RCNN以及RetinaNet。

在過去的幾個月中,我在實驗室一直在研究提高目標檢測的性能。從實驗中得到的最重要的收穫就是意識到了學習目標檢測最好的方法就是你自己從零開始實現這個算法。這的確就這個教程中要涉及的事情。我們將會使用PyTorch來實現基於YOLO v3的目標檢測算法,這個算法是目標檢測中最快的算法之一。

這個教程分爲五個部分:

  1. 第一部分:理解YOLO是如何工作的
  2. 第二部分:創建網絡架構的層
  3. 第三部分:實現神經網絡的前向傳播
  4. 第四部分:目標得分閾值化和非極大值抑制迴歸
  5. 第五部分:設計輸入輸出的傳輸途徑

前沿知識

  • 瞭解卷積神經網絡是如何工作的。這應該包括殘差網絡、跳躍連接和上採樣
  • 瞭解什麼是目標檢測。邊界框迴歸,IoU和非極大值迴歸
  • 瞭解PyTorch的基本使用。你應該能夠很容易創建簡單的神經網

1 什麼是YOLO

      YOLO 表示You Only Look Once。它是一個目標檢測器,它使用深度卷積神經網絡學習到的特徵去預測一個物體。在我們動手寫代碼之前,我們必須要理解YOLO是如何工作的。

2 全卷積神經網絡

YOLO算法只使用卷積層,它確確實實是一個全卷積神經網絡(FCN)它有75個卷積層,跳躍連接和上採樣層。沒有使用任何形式的池化層,步長爲2的卷積層用來對特徵映射圖進行下采樣這有助於減少經常由於池化所導致的低維度特徵的損失

作爲一個全卷積層,YOLO輸入圖片的尺寸是固定的。但是,在實際應用過程中,各種各樣的問題只有在應用這個算法的時候纔會暴露出來,因此我們需要一個恆定的輸入圖片的尺寸。一個最大的問題就是,如果我們想要以批量的形式處理我們的圖片的話(GPU可以以並行的形式處理批量的圖片,會加快處理速度),我們需要所有的圖片都有固定的寬和高。這需要把多個圖片匯聚成一個大的批量(匯聚多個PyTorch張量變爲一個張量)。

這個網絡通過網絡步長對圖片進行下采樣。舉個例子,如果網絡的步長是32,當輸入圖片的尺寸是416*416的時候,它的輸出的特徵圖就是13*13了。一般來說,網絡中一個層的步長等於這個層的輸出較之輸入縮小的比例(stride = input_size / output_size)。

3 輸入層說明

一般來說,對於所有的目標檢測器來說,卷積層學習到的特徵會傳遞給分類器/迴歸器,然後它們能夠做出預測(邊界框的座標值,類別標籤等等)。在YOLO中,使用一個含有1*1卷積核的卷積層來進行預測(它將代替全連接層進行預測)。現在,第一個我們需要注意的事情就是,它的輸出是一個特徵圖。既然我們使用了1*1的卷積核,預測之前和之後的特徵圖大小就會完全一致。在YOLO v3中,每一個柵格(grid)都會預測一個固定數量的邊界框(每個柵格會預測三個邊界框),特徵映射圖中每個柵格都有B*(5+C)參數,B代表的是每個單元可以預測幾個邊界框。根據論文所述,B個邊界框中的每一個邊界框都會專門檢測一個確定的類別。每一個邊界框都有(5+C)個屬性,5是指用來描述邊界框的中心點座標(tx, ty),尺寸(tw, th),置信度得分(to)這五個參數,C是指每個邊界框對於C個類別對象的的置信度。YOLO v3的單元預測3個邊界框。(補充一句,因爲有3個尺度的輸出,每個尺度輸出分配3類邊界框,因此就會有3*3 = 9個類別的邊界框)。我們希望特徵映射圖的每個單元使用一個邊界框去預測一個目標物體,如果該目標物體的中心點落在這個單元的感受野中,我們就讓這個單元去預測這個目標物體

這和YOLO如何訓練有關,我們需要一個邊界框去負責檢測任何給定的目標物體。首先,我們必須要確保這個邊界框屬於哪一個單元(這個目標物體的中心座標落在了哪個柵格,這個柵格就負責預測這個目標物體的位置)。爲了實現這個目標,我們將輸入圖片劃分爲和最終特徵映射圖相同尺寸的網格。我們來思考一下下面的例子,輸入的圖片尺寸是416*416,網絡的步長是32,正如前面所指出,特徵映射圖的尺寸將會是13*13,然後我們將輸入圖片劃分成13*13個單元

然後,包含物體的真實邊界框的中心點的單元(在輸入圖像中)就被選爲去負責預測這個目標物體。在圖像中,就是那個被標記爲紅色的單元包含了真實邊界框(標記爲黃色)的中心點。現在,這個紅色的單元就在輸入網格中第七行。現在,我們就讓特徵映射圖(和特徵映射圖的單元相一致)中第七列的第七個單元去負責檢測這隻小狗。現在,這個單元就可以去預測三個邊界框。但是,哪一個邊界框去負責預測這隻小狗的真實標籤值呢?爲了搞清楚這個,我們必須要學習一下錨框的概念。注意我們現在在討論的單元是指預測特徵映射圖的單元。我們將輸入圖片劃分成一個柵格,就是爲了決定讓預測特徵映射圖上的哪個柵格負責預測目標物體。

4 錨框

直接預測邊界框的寬和高是有可行的,但是在實際過程中,在訓練過程中這樣做會導致不穩定的梯度(YOLOv1就是輸入一張圖片,然後直接輸出目標物體的中心座標以及寬高,但是效果不好,纔有了v2的改進)。相反,在大多數的模型目標物體檢測器都是預測對數變換,或者使用簡單的偏移量來根據默認的邊界框進行學習,這稱之爲錨框(anchor box)

之後,這些變換都被用在錨框中去進行預測YOLO v3有三個錨框,這是因爲每個單元中有三個錨框去進行預測。回到我們剛纔的問題,負責檢測這隻狗的邊界框,它的錨框和標籤邊界框一定有着最高的IoU。(錨框的具體知識還請看這裏

5 做出預測

下面的公式描述了網絡的輸出時如何轉變成預測邊界框的。

\small b_{x}, b_{y}, b_{w}, b_{h}我們預測的邊界框的中心座標和寬高。\small t_{x}, t_{y}, t_{w}, t_{h}是網絡的輸出。\small c_{x}, c_{y}是左上角柵格的座標,\small p_{w},p_{h}是錨框的寬和高。具體詳情看這篇博客

5.1 中心點座標

注意的是,我們將我們的中心點座標的預測輸入到sigmoid函數中,這是爲了強制讓網絡的輸出值在0和1的範圍之間,這樣是爲了讓預測邊界框的中心點一直落在需要作出預測的柵格中。通常來說,YOLO並沒有直接預測邊界框的中心點,它預測的是下面的偏差:

  • 預測左上角用來預測目標物體的柵格的偏移量(上面兩個公式)
  • 在特徵圖中,使用單元的尺寸(寬和高)來進行歸一化(下面兩個公式)

舉個例子,使用我們上面包含小狗的圖片。如果預測的中心點座標是(0.4,07),這就意味着在13*13的特徵映射圖中,它的中心位置是(7.4, 7.7)。如果預測的結果是(1.2, 0.7),這就一位置目標物體的座標是 (7.2, 6.7)。這和YOLO的理論背道而馳,因爲我們假設這個紅色的邊界框負責預測這隻狗,這隻狗的中心座標應該落在紅色的單元中,而不是落在其他單元中。因此,爲了修正這個問題,網絡的輸出要經過sigmoid函數,它能夠將輸出擠壓在0和1之間,有效的讓目標物體的中心在保持在要預測的單元中。

5.2 邊界框的尺寸

      邊界框的尺寸由輸出的對數變化,然後乘以錨框的尺寸來預測:

結果的預測值\small b_{w}, b_{h}是經過圖片的寬和高歸一化而來的,如果包含狗的邊界框的寬和高的預測值是(0.3, 0.8),在13*13的特徵映射圖中,而目標物體實際中的寬和高就是(stride*0.3, stride*0.8),要乘以步長,這是因爲特徵圖相比於真實圖片縮小了stride倍,因此特徵圖中的物體比實際物體縮小了stride倍。

5.3 目標物體的得分

目標物體的得分表示的是邊界框中包含目標物體的可能性。在紅色單元中,它的值也應該是接近1的,而且在它相鄰的單元中,幾乎是0的。目標物體的得分也應該經過一個sigmoid函數,它表示的是一種可能性(我們希望越是能夠包含物體的probability就越接近1,但是實際上並不是這樣,因此focal loss對其進行了優化)。

5.4 種類的置信度

種類的置信度表示的是檢測到的目標物體屬於一個特定種類的可能性。在v3之前,YOLO使用的都是softmax函數來表示這種種類的置信度。但是,在v3中,這種使用softmax函數的方法已經被捨棄了,而且作者已經採用sigmoid函數來代替它。這是因爲softmax種類的置信度假定類與類之間時相互排斥的。簡單來說,如果一個目標物體屬於一個類別,那麼他就不能屬於其他類別了。在coco數據集中,使用softmax函數是沒有問題的。但是,當我們同時含有“人”和“女人”兩種類型的時候,這種假設就站不住腳了。這也是作者已經避開使用softmax函數的原因。

6  跨尺度預測

YOLO v3跨越了三個尺度進行預測。檢測層在三個不同尺寸的特徵映射圖上進行目標檢測,這些尺寸的步長分別是32,16,8。這意味着,當輸入的圖片是416*416的時候,我們可以在13*13,26*26,52*52三個尺度上的特徵映射圖進行目標檢測。這個網絡對輸入圖片進行上採樣,直到遇到第一個檢測層,其中對步長爲32的層的特徵特徵映射圖進行檢測。然後,對層向上採樣2倍,並且將其和之前層擁有相同特徵映射圖的尺寸的特徵映射層進行連接。另外一個目標檢測在步長爲16的網絡層,執行相同的上採樣步驟。最後一個目標檢測發生在步長爲8的層。對於每一個尺度的目標檢測,每一個單元使用三個錨框預測三個邊界框,總共有9個錨框。

作者認爲這些幫助YOLO v3更好的檢測小物體,這比YOLO之前的版本複雜的多了。上採樣使得網絡能夠學習到更加顆粒的特徵,這有助於檢測到小的目標物體(經過了兩次上採用,52*52的輸出能夠包含更多的細節信息,這對檢測小物體更優幫助),這個多尺度預測是參考FPN網絡,13*13的輸出層用來預測較大的物體,26*26的輸出層用來預測中等物體,52*52的輸出層用來預測小物體。

 7 處理輸出

對於一幅尺寸爲416*416的圖片來說,YOLO算法預測了(52*52+26*26+13*13)*3 = 10647個邊界框。但是在本案例中只有一個目標物體:小狗。我們如何把檢測到的邊界框的數量從10647減少到1呢?

7.1 給目標物體的置信度設置一個閾值

首先,我們基於他們的目標物體置信度進行過濾邊界框。通常來說,置信度低於一定閾值的邊界框將會被忽略。

7.2 非極大值抑制

非極大值抑制旨在解決同一張圖片一個目標物體出現多個檢測結果的問題。舉例來說,紅色單元的三個邊界框可能會檢測一個目標物體,或者相鄰的單元可能會檢測同一個物體,這就需要用到非極大值抑制了。

8 總結

YOLO算法只能夠檢測到已經在神經網絡中訓練過的、屬於數據集中所提供的類別。我們會爲檢測器使用官方提供的權重參數文件。

1 從整體的網絡架構上。YOLO v3變成了全卷積網絡(FCN),只有卷積層、殘差層和上採樣層,沒有池化層(保留更多低維度信息),沒有全連接層,取而代之使用1*1的卷積層代替進行檢測和分類。當使用批量方式對圖片進行處理的時候,需要限制所有的輸入圖片都要有相同的尺寸。

2)目標物體的框定。使用相對座標的形式對目標物體進行框定,使用9個不同的anchor boxes作爲參考,配合\small t_{x}, t_{y}, t_{w}, t_{h}間接表示預測邊界框的位置,這樣就能夠保證我們可以更加準確的表示目標物體的位置。

3)對小物體的識別上。爲了能夠更好的識別小物體,作者使用了多尺度預測,每個尺度下的特徵映射圖包含不同的圖片特徵,而且每個尺度使用3種不同的anchor boxes進行預測。

4)邊界框的處理上。生成的衆多邊界框,我們需要兩步處理:設置置信度閾值非極大值抑制

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