Reference
- yolo實踐參考資料
yolo(darknet)官網:https://pjreddie.com/darknet/yolo/
github 源碼:https://github.com/pjreddie/darknet
YOLO源碼解析(tensorflow):https://zhuanlan.zhihu.com/p/250533
- yolo理論參考資料
YOLO 原文鏈接:https://arxiv.org/pdf/1506.02640.pdf
基於深度學習的目標檢測(附有參考文獻):https://www.cnblogs.com/gujianhan/p/6035514.html
YOLO - 實時快速目標檢測:https://zhuanlan.zhihu.com/p/25045711?refer=shanren7、https://blog.csdn.net/surgewong/article/details/51864859
- darknet 源碼解析:
github 地址:https://github.com/hgpvision/darknet
github 地址(推薦):https://github.com/AlexeyAB/darknet
- keras 版本的yolo-v2
GitHub 地址:https://github.com/allanzelener/YAD2K
主要從三個方面來說明,網絡的輸入、結構、輸出。
1. 網絡輸入
原論文中提到的輸入大小320*320,416*416,608*608。這個大小必須是32的整數倍數,yolo_v3有5次下采樣,每次采樣步長為2,所以網絡的最大步幅(步幅指層的輸入大小除以輸出)為2^5=32。
2. 網絡結構
作者首先訓練了一個darknet-53,訓練這個主要是為了主要有兩個目的:
a.這個網路結構能在ImageNet有好的分類結果,從而說明這個網路能學習到好的特征(設計新的網絡結構,這個相當於調參,具體參數怎么調,就是煉丹了),
b.為后續檢測模型做初始化。
作者在ImageNet上實驗發現這個darknet-53,的確很強,相對於ResNet-152和ResNet-101,darknet-53不僅在分類精度上差不多,計算速度還比ResNet-152和ResNet-101強多了,網絡層數也比他們少。
圖一 darknet-53網絡結構
圖二 darknet-53的性能測試
Darknet-53采用了ResNet這種跳層連接方式,性能完全比ResNet-152和ResNet-101這兩種深層網絡好,這里作者並沒有給出原因,可能的原因:
a. 網絡的基本單元的差異;
b. 網絡層數越少,參數少。需要的計算量少;
圖三 兩種結構基本單元比較
Yolo_v3網路就是使用了darknet-53的前面的52層(沒有全連接層),直接拿過來,yolo_v3這個網絡是一個全卷積網絡,大量使用殘差的跳層連接。之前的工作中,采樣一般都是使用size為2*2,步長(stride)為2的max-pooling或者average-pooling進行降采樣。但在這個網絡結構中,使用的是步長為2的卷積來進行降采樣。同時,網絡中使用了上采樣、route操作,還在一個網絡結構中進行3次檢測(有點盜用SSD的思想)
使用殘差的結構的好處:
(1)深度模型一個關鍵的點就是能否正常收斂,殘差這種結構能保證網絡結構在很深的情況下,仍能收斂,模型能訓練下去。
(2)網絡越深,表達的特征越好,分類+檢測的效果都會提升。
(3)殘差中的1*1卷積,使用network in network的想法,大量的減少了每次卷積的channel,一方面減少了參數量(參數量越大,保存的模型越大),另一方面在一定程度上減少了計算量
網路中作者進行了三次檢測,分別是在32倍降采樣,16倍降采樣,8倍降采樣時進行檢測,這樣在多尺度的feature map上檢測跟SSD有點像。在網絡中使用up-sample(上采樣)的原因:網絡越深的特征表達效果越好,比如在進行16倍降采樣檢測,如果直接使用第四次下采樣的特征來檢測,這樣就使用了淺層特征,這樣效果一般並不好。如果想使用32倍降采樣后的特征,但深層特征的大小太小,因此yolo_v3使用了步長為2的up-sample(上采樣),把32倍降采樣得到的feature map的大小提升一倍,也就成了16倍降采樣。同理8倍采樣也是對16倍降采樣的特征進行步長為2的上采樣,這樣就可以使用深層特征進行detection。
Yolo_v3通過上采樣的方式很好的使16倍降采樣和8倍降采樣使用深層特征,但進行4次下采樣和3次下采樣得到的淺層feature map大小是一樣的。Yolo_v3想把這些淺層特征也利用起來,就有了route層。把16倍降采樣得到的feature map和四次下采樣得到的層拼接在一起,在channel那個維度進行拼接。這樣拼接的好處:讓網絡同時學習深層和淺層特征,表達效果更好。8倍降采樣同樣也是這樣的操作,把三次下采樣的feature map拼接在一起。
res 殘差層
route 路由層——多個層拼接才一起
upsample 上采樣
(箭頭沒畫好,箭頭從up-sample指向detection,代表把feature map的大小上升一倍)
3. 網絡輸出
a. 首先先確定網絡輸出特征層的大小。
比如輸入為320*320時,則輸出為320/32=10,因此輸出為10*10大小的特征層(feature map),此時有10*10=100個cell;同理當輸入為416*416時輸出的特征層為13*13大小的特征層,13*13=169個cell;輸入為608*608時,輸出的feature map大小為19*19,cell有19*19=361個。進行每進行一次up-sample時,輸出特征層擴大一倍。
b. Anchor box的確定。
這個先驗框不同於之前Faster-Rcnn和SSD那樣人工設定,在yolo_v2和yolo_v3中,都采用了對圖像中的object采用k-means聚類。在yolo_v3中作者是這樣描述的:We still use k-means clustering to determine our bounding box priors. We just sort of chose 9 clusters and 3 scales arbitrarily and then divide up the clusters evenly across scales. On the COCO dataset the 9 clusters were:(10,13); (16,30); (33,23); (30,61); (62,45); (59,119); (116 ,90); (156 ,198); (373 ,326). 這個地方,作者有一個地方沒有說清楚,這個框的大小是在什么輸入大小的圖像下確定的,比如你在608*608作為輸入圖像中object的大小和在320*320大小圖像中的object大小肯定不同,對這兩種輸入聚類的結果肯定不同。但查看作者提供的yolo_v3網絡配置文件,這個聚類結果應該是在416*416大小的圖像下聚類得到的結果。
圖四 Yolo_v3部分網絡配置文件
c. feature map中的每一個cell都會預測3個邊界框(bounding box) ,每個bounding box都會預測三個東西:
(1)每個框的位置(4個值,中心坐標tx和ty,,框的高度bh和寬度bw);
(2)一個objectness prediction;
(3)N個類別,coco數據集80類,voc20類。因此對於coco數據集,在網絡輸入為416*416時,網絡的輸出大小為13*13(3*(4+1+80))=43095
對於上圖的幾點說明:
中心坐標(tx和ty)
Yolo_v3使用 sigmoid 函數進行中心坐標預測。這使得輸出值在 0 和 1 之間。正常情況下,YOLO 不會預測邊界框中心的確切坐標。
它預測的是:與預測目標的網格單元左上角相關的偏移;並且使用feature map中的cell大小進行歸一化。
當輸入圖像為416*416,如果中心的預測是 (0.4, 0.7),則第二個cell在 13 x 13 特征圖上的相對坐標是 (1.4, 1.7),具體的位置x坐標還需要1.4乘以cell的寬,y坐標為1.7乘以cell的高。
Bounding box的寬度bw和高度bh
Yolo_v3得出的預測 bw 和bh 使用圖像的高和寬進行歸一化,框的預測 bx 和 by 是 (0.3, 0.8),那么 13 x 13 特征圖的實際寬和高是 (13 x 0.3, 13 x 0.8)。
d. 三次檢測,每次對應的感受野不同
32倍降采樣的感受野最大,適合檢測大的目標,所以在輸入為416*416時,每個cell的三個anchor box為(116 ,90); (156 ,198); (373 ,326)。
16倍適合一般大小的物體,anchor box為(30,61); (62,45); (59,119)。
8倍的感受野最小,適合檢測小目標,因此anchor box為(10,13); (16,30); (33,23)。
所以當輸入為416*416時,實際總共有(52*52+26*26+13*13)*3=10647個proposal box。
圖六 打印出10647個proposal box