YOLOv3中的新玩意兒

2019-08-08     AI公園
作者:Ayoosh Kathuria
編譯:ronghuaiyang

導讀

有小夥伴提到想要了解YOLOv3,其實網上有很多講解這個算法的內容,很多都非常的好,這篇我也非常的喜歡,圖文並茂,非常的詳細,非常的通俗易懂,分享給大家。

YOLO是一種快速的目標檢測算法。雖然它不是最精確的目標檢測算法,但在需要實時檢測時,它是一個非常好的選擇,不會損失太多的準確性。

YOLO的第三個版本發布了,本文主要解釋一下YOLOv3中引入的變化。這篇文章不會從頭開始解釋YOLO是什麼。我假設你知道YOLOv2是如何工作的。如果不是這樣的話,我建議你看看之前的論文,了解一下YOLO是如何工作的。

YOLOv3: Better, not Faster, Stronger

YOLOv2論文的官方標題: 「YOLO9000: Better, Faster, Stronger」,看起來就像是一款兒童牛奶健康飲料,而不是一種目標檢測算法。

在當時,YOLO 9000是最快的算法,也是最精確的算法之一。然而,幾年過去了,它的準確率不如RetinaNet了,SSD在準確性上也超過了它。然而,它仍然是最快的。

但是在YOLOv3中,這種速度已經被用來提高準確性。早期的版本在Titan X上的運行速度為45FPS,而當前版本的速度約為30FPS。這與底層架構Darknet複雜性的增加有關。

Darknet-53

YOLOv2使用了定製的darknet-19,這是一個19層網絡,添加了11個層用於對象檢測。對於一個30層的架構,YOLOv2經常在小物體檢測方面遇到困難。這是由於隨著層的下採樣,細粒度特徵的丟失造成的。為了解決這個問題,YOLOv2使用了一個恆等映射,將來自前一層的特徵映射和當前層特徵連接起來,以捕獲低層特徵。

然而,YOLOv2的架構仍然缺少一些最重要的元素,而這些元素現在是大多數最先進算法的核心,沒有殘差塊,沒有跳躍連接,沒有上採樣,而YOLOv3包含了所有這些。

首先,YOLOv3使用了Darknet的一個變體,該變體最初在Imagenet上訓練了53層網絡。在檢測任務上,它又增加了53層,變成了106層的全卷積的底層架構。這就是YOLOv3相對於YOLOv2慢的原因。現在YOLO的結構變成這樣了。

在3個尺度上做檢測

新的結構擁有殘差,跳躍連接和上採樣。v3最顯著的特徵是它在三個不同的尺度上進行檢測。YOLO是一個全卷積網絡,它的最終輸出是通過在feature map上使用一個1×1的卷積核生成的。在YOLOv3中,檢測是通過在網絡中三個不同位置的三個不同大小的feature map上應用1×1卷積核來完成的。

卷積核的形狀為1×1 x (B x (5 + C))。這裡B是feature map上一個單元格可以預測的包圍框的數量,「5」是4個包圍框的屬性和一個對象的置信度,C是類的數量。在YOLOv3對COCO的訓練中,B = 3, C = 80,所以卷積核的大小是1 x 1 x 255。該卷積核生成的feature map具有與前一個feature map相同的高度和寬度,並且具有上面說過的檢測屬性。

在我們繼續之前,我想指出網絡的步長,或者一個層對輸入進行下採樣的比例。在下面的例子中,假設我們有一個大小為416 x 416的輸入圖像。

YOLOv3在三個尺度下進行準確的預測,分別將輸入圖像的維數降採樣32、16、8。

第一個檢測是由第82層進行的。對於前81層,網絡對圖像進行下採樣,使得第81層的步長為32。如果我們有一張416 x 416的圖像,那麼得到的feature map的大小就是13 x 13。這裡使用1×1卷積核進行了一次檢測,得到了一個13×13×255的檢測特徵圖。

然後,對第79層的feature map進行幾層卷積,然後用上採樣2倍到26x26。然後,這個feature map與第61層的feature map拼接起來。然後,再對組合之後的feature maps進行幾個1x1卷積層的處理,以融合來自前一層(61)的特徵。然後,第94層進行第二次檢測,得到26×26×255的檢測特徵圖。

同樣的過程也會被重複,在第91層的feature map與第36層的feature map進行深度連接之前,只對少數卷積層進行處理。像以前一樣,後面的幾個1×1卷積層融合來自前一層(36)的信息。我們在第106層對第3個檢測進行最後處理,生成大小為52 x 52 x 255的feature map。

更好的檢測小物體

不同層的檢測有助於解決檢測小物體的問題,這是YOLOv2經常遇到的問題。上採樣層與前一層連接在一起,有助於保留對檢測小物體有幫助的細粒度特徵。

13 x 13層負責檢測大的物體,52 x 52層檢測小的物體,26 x 26層檢測中等物體。下面是不同層在選擇不同物體的比較分析。

anchor boxes的選擇

YOLO v3,共使用9個anchor boxes。每個尺度三個。如果你正在自己的數據集上訓練YOLO,那麼應該使用K-Means聚類來生成9個anchor boxes。

然後,將按維度降序排列。為第一個尺度分配三個最大的anchor boxes,為第二個尺度分配下三個anchor boxes,為第三個尺度分配最後三個anchor boxes。

每張圖像更多的邊界框

對於相同大小的輸入圖像,YOLOv3比YOLOv2預測更多的邊界框。例如,在416 x 416的解析度下,YOLOv2預測了13 x 13 x 5 = 845個盒子。在每個網格單元中,使用5個anchor boxes檢測到5個邊界框。

另一方面,YOLOv3在3種不同的尺度上預測邊界框。對於416 x 416的相同圖像,預測框的數量為10,647。這意味著YOLOv3預測的邊界框數量是YOLOv2的10倍。你可以很容易地想像為什麼它比YOLOv2慢。在每個尺度上,每個網格可以使用3個anchor boxes預測3個邊界框。由於有3個尺度,所以每個尺度使用的anchor boxes總數為9,每個尺度3個。

損失函數的變化

之前,YOLOv2的損失函數是這樣的。

我知道這有點嚇人,但請注意最後三項。其中,第一項,懲罰的是負責預測物體的邊界框中是否有物體的得分的預測(理想情況下是1)。第二項,對於邊界框中沒有物體時(理想情況下,得分應該是零)。最後一項,懲罰了對檢測框中預測物體的類別的預測。

YOLOv2中的最後三項是平方誤差,而YOLOv3中的,它們被交叉熵誤差所取代。換句話說,YOLOv3中的物體的置信度和類預測現在通過邏輯回歸進行預測。

在訓練檢測器時,我們為每個ground truth框指定一個邊界框,其錨點與ground truth框重疊最大。

別再softmax分類了

YOLOv3現在對圖像中檢測到的物體進行多標籤分類。

在YOLO的早期,作者習慣於對類別得分進行softmax分類,並將得分最高的類作為包圍框中包含的物體的類。這已經在YOLO v3中進行了修改。

Softmaxing是基於這樣的假設的:類是互斥的,或者簡單地說,如果一個對象屬於一個類,那麼它就不能屬於另一個類。這在COCO數據集中工作得很好。

然而,當我們在數據集中有像PersonWomen這樣的類時,上述假設就失敗了。這就是為什麼YOLO的作者沒有softmax的原因。相反,使用邏輯回歸預測每個類的得分,並使用閾值預測對象的多個標籤。得分高於此閾值的類被分配到該框中。

Benchmarking

YOLOv3在COCO mAP 50基準測試中的表現與RetinaNet等其他先進的檢測器相當,但速度要快得多。它也比SSD和它的變體更好。這是這篇論文的性能比較。

但是,但是,但是,YOLO在COCO的基準測試中輸掉了,因為COCO基準測試中拒絕一個檢測的IoU的值更高。我不打算解釋COCO基準測試是如何工作的,因為它超出了我們今天的範圍,但是COCO 50基準測試中的50是對預測的邊界框與物體的ground truth框對齊程度的度量。這裡的50對應於0 .5的IoU。如果預測與ground truth框之間的IoU小於0.5,則該預測將被歸類為錯誤定位並標記為假陽性。

在基準測試中,如果這個數字更高(比如COCO 75),則需要更完美地對齊這些框,以避免被評估指標拒絕。這裡是YOLO被RetinaNet超越的地方,因為它的邊框沒有像RetinaNet那樣對齊。下面是針對各種基準測試的詳細表。

做幾個實驗玩玩

您可以使用本Github repo (https://github.com/ayooshkathuria/pytorch-yolo-v3)提供的代碼在圖像或視頻上運行檢測器。該代碼需要PyTorch 0.3+、OpenCV 3和Python 3.5。設置repo,你可以在其上運行各種實驗。

不同的尺度

下面我們來看看不同的檢測層會檢測到什麼。

python detect.py --scales 1 --images imgs/img3.jpg

在尺度1的檢測中,我們看到一些較大的物體被選中,但是有幾輛車沒有檢測到。

python detect.py --scales 2 --images imgs/img3.jpg

尺度2上什麼也沒有檢測到。

python detect.py --scales 3 --images imgs/img3.jpg

在最大尺度(3)下進行檢測。看到只有小的物體被檢測到了,而這些在尺度1下沒有檢測到。

不同的輸入解析度

python detect.py --reso 320 --images imgs/imgs4.jpg


圖像輸入解析度: 320 x 320

python detect.py --reso 416 --images imgs/imgs4.jpg

圖像輸入解析度: 416 x 416

python detect.py --reso 608 --images imgs/imgs4.jpg

現在,我們比之前少檢測出一張椅子。

python detect.py --reso 960 --images imgs/imgs4.jpg

現在,出現了誤檢,右邊的「Person」。

在我們的例子中,較大的輸入解析度幫助不大,但它們可能有助於檢測帶有小物體的圖像。另一方面,較大的輸入解析度會增加推理時間。這是一個需要根據應用程式進行調優的超參數。

你可以通過repo試驗其他指標,如批大小、物體可信度和NMS閾值。ReadMe文件中已經提到了所有內容。

從頭實現YOLOv3

如果您想在PyTorch中自己實現YOLOv3檢測器,這裡有一系列教程,我在Paperspace上也編寫了這些教程。現在,如果你想學習本教程,我希望你對PyTorch有基本的了解。如果你正在從一個初級PyTorch用戶過渡到中級PyTorch用戶,那麼本教程非常適合你。

英文原文:https://towardsdatascience.com/yolo-v3-object-detection-53fb7d3bfe6b

更多文章,請關注微信公眾號:AI公園

文章來源: https://twgreatdaily.com/zh-hk/416sj2wBvvf6VcSZ0ADR.html