1. 程式人生 > >yolo原理學習

yolo原理學習

學習 只需要 方法 劃分 exclusive 不可 得到 使用 scale

1、【yolov1】
第一步:將圖像劃分為S*S的柵格(grid cell),這裏分成了7*7的grid cell。柵格的任務是:檢測中心落在該柵格中的物體(註意,柵格中心未必與物體的中心重合,這個一定要明確,對後面的理解才不會產生影響)。
第二步:一個grid cell 可以預測B個bounding boxes(包圍盒,以下簡稱bbox),包括預測bbox的confidence scores。bbox有五個預測值,分別是x,y(代表預測的bbox的中心與grid cell 邊界的邊界的相對值),w,h(代表預測的bbox的width/height相對於整個圖像width,height的比例),confidence(代表預測的bbox和ground truth box的IOU值)。confidence = Pr(object) * IOU 一個bbox對應一個confidence score,如果grid cell裏面沒有object,confidence就是0,如果有,則confidence score等於預測的box和ground truth的IOU值,見上面公式。在此解釋一下IOU的意思,ground truth box是物體實際的位置,而IOU=bbox與ground truth box的交集/二者的並集,即交並比(重疊度)。
第三步:每個grid cell 還要預測C個conditional class probability (條件類別概率),即Pr (Class|Object)。即預測出,在grid cell包含object的條件下,該object屬於某個類的概率。註意,一個grid cell只需要預測一組(C個)類的概率,而不需要考慮bbox的數量。因為一個grid cell預測的B個bbox框住的都是同一個物體。也就是說,類別概率是針對grid cell的。在本文中取S=7,B=2,C=20(因為PASCAL 數據集有20個類別),所以最後有7*7*30(30=B*5+C,每個bbox有5個預測值)個tensor。
測試階段:將每個grid cell的conditional class probability與每個bbox的confidence相乘:

Pr(Class | Object) * Pr(Object) * IOU = Pr(Class) * IOU
每個bbox的confidence和每個類別的score相乘,得到每個bbox屬於哪一類的confidence score。也就是說最後會得到20*(7*7*2)=20*98的score矩陣,括號裏面是bbox的數量,20代表類別。接下來的操作都是20個類別輪流進行:在某個類別中(即矩陣的某一行),將得分少於閾值(0.2)的設置為0,然後再按得分從高到低排序。最後再用NMS算法去掉重復率較大的bbox(NMS:針對某一類別,選擇得分最大的bbox,然後計算它和其它bbox的IOU值,如果IOU大於0.5,說明重復率較大,該得分設為0,如果不大於0.5,則不改;這樣一輪後,在選擇剩下的score裏面最大的那個bbox,然後計算該bbox和其它bbox的IOU,重復以上過程直到最後)。最後每個bbox的20個score取最大的score,如果這個score大於0,那麽這個bbox就是這個socre對應的類別(矩陣的行),如果小於0,說明這個bbox裏面沒有物體,跳過即可。

2、【yolov2 (https://blog.csdn.net/u014696921/article/details/65626751 參考) 使用的一些技巧:】
(1)Better
batch Normalization:在卷基層後面增加了batch Normalization,去掉了dropout層,mAP提升2%。
High ResolutionClassifier:x訓練網絡的時候將網絡從224*224變為448*448,當然後續為了保證特征圖中只有奇數個定位位置,從而保證只有一個中心細胞,網絡最終設置為416*416。最終實現了4%的mAP提升。
Convoutional with AnchorBoxes:作者吸收了faster RCNN中RPN的思想,去掉了yolov1中的全連接層,加入了anchor boxes,這樣做的目的就是得到更高的召回率,當然召回率高了,mAP就會相應的下降,這也是人之常情。最終,yolov1只有98個邊界框,yolov2達到了1000多個。mAP由69.5下降到69.2,下降了0.3,召回率由81%提升到88%,提升7%。
Dimension Clusters(維度聚類):這裏作者提出了kmeans聚類,這裏的K作者取值為5,這樣會在模型復雜度和召回率之間達到一個好的折中。並且使用聚類的中心代替Anchor,最後使用歐式距離進行邊界框優先權的衡量,歐式距離公式如下所示,距離越小說明優先權越高。在k為5 的條件下,Avg IOU從60.9提升到了61.0。在k為9的的條件下Avg IOU提升為67.2
Direction locationprediction:引入了anchor boxes就會產生模型不穩定的問題,該問題產生於邊界框位置的預測。簡單的解釋,如果訓練的圖片中的物體一張是在左面,下一張又在右面,就會產生這樣的波動,顯然的這個過程是不受控制的,畢竟圖片中的物體位置他在哪裏就在哪裏。這裏作者,變換了個思路,把最終預測的相對於anchor的邊界框的相關系數變為預測相對於grid cell(yolo v1的機制)的相關系數,使得輸出的系數在0-1直接波動,如此就解決了波動的問題。最終,使用維度聚類和直接預測邊界框中心比使用anchor boxes提升了5%的mAP。
Multi-Scale Training:這裏作者提出的訓練方法也很獨特,在訓練過程中就每隔10batches,隨機的選擇另外一種尺度進行訓練,這裏,作者給出的訓練尺度為{320,352,……,608},這個訓練的方法,使得最終得到的模型可以對不同分辨率的圖像都能達到好的檢測效果。(多尺度訓練對顯卡的內存有要求,由參數random控制, 目前訓練都是關閉這個選項不能會報 cuda out of memory)
Fine-Grained Features(細粒度特征)
上述網絡上的修改使YOLO最終在13 * 13的特征圖上進行預測,雖然這足以勝任大尺度物體的檢測,但是用上細粒度特征的話,這可能對小尺度的物體檢測有幫助。Faser R-CNN和SSD都在不同層次的特征圖上產生區域建議(SSD直接就可看得出來這一點),獲得了多尺度的適應性。這裏使用了一種不同的方法,簡單添加了一個轉移層( passthrough layer),這一層要把淺層特征圖(分辨率為26 * 26,是底層分辨率4倍)連接到深層特征圖。這個轉移層也就是把高低兩種分辨率的特征圖做了一次連結,連接方式是疊加特征到不同的通道而不是空間位置,類似於Resnet中的identity mappings。這個方法把26 * 26 * 512的特征圖連接到了13 * 13 * 2048的特征圖,這個特征圖與原來的特征相連接。YOLO的檢測器使用的就是經過擴張的特征圖,它可以擁有更好的細粒度特征,使得模型的性能獲得了1%的提升。(這段理解的也不是很好,要看到網絡結構圖才能清楚)
(2)Faster
這裏,vgg16雖然精度足夠好,但是模型比較大,網絡傳輸起來比較費時間,因此,作者提出了一個自己的模型,Darknet-19。而darknetv2也正式已Darknet-19作為pretrained model訓練起來的。
(3)Stronger
這裏作者的想法也很新穎,解決了2個不同數據集相互排斥(mutualy exclusive)的問題。作者提出了WordTree,使用該樹形結構成功的解決了不同數據集中的排斥問題。使用該樹形結構進行分層的預測分類,在某個閾值處結束或者最終達到葉子節點處結束。下面這副圖將有助於WordTree這個概念的理解。

3、【yolov3使用的一些技巧:】
(1)Darknet-53
(2)YOLOv3不使用Softmax對每個框進行分類,用邏輯回歸替代softmax作為分類器:主要考慮因素有兩個:Softmax使得每個框分配一個類別(score最大的一個),而對於Open Images這種數據集,目標可能有重疊的類別標簽,因此Softmax不適用於多標簽分類。Softmax可被獨立的多個logistic分類器替代,且準確率不會下降。(在閾值較低的情況下可能會引入相同區域內可能出現多個標簽)且分類損失采用binary cross-entropy loss
(3)多尺度預測 , 三個尺度的輸出: 13 x 13 x [3 * (4 + 1 + 6)] = 13 x 13 x 33 同理 26 x 26 x 33 52 x 52 x 33 每個尺度預測3個框 再由每個框去預測對應的條件類別概率(位置 置信度 類別)

4、【從零開始PyTorch項目:YOLO v3目標檢測實現 (http://www.sohu.com/a/229164696_129720)】
(1)YOLOv3 僅使用卷積層,這就使其成為全卷積神經網絡(FCN)。它擁有 75 個卷積層,還有跳過連接和上采樣層。它不使用任何形式的池化,使用步幅為 2 的卷積層對特征圖進行下采樣。這有助於防止通常由池化導致的低級特征丟失。

(2)典型地(對於所有目標檢測器都是這種情況),卷積層所學習的特征會被傳遞到分類器/回歸器,從而進行預測(邊界框的坐標、類別標簽等)。

(3)中心坐標,註意:我們使用 sigmoid 函數進行中心坐標預測。這使得輸出值在 0 和 1 之間。原因如下:正常情況下,YOLO 不會預測邊界框中心的確切坐標。它預測:與預測目標的網格單元左上角相關的偏移;使用特征圖單元的維度(1)進行歸一化的偏移。以我們的圖像為例。如果中心的預測是 (0.4, 0.7),則中心在 13 x 13 特征圖上的坐標是 (6.4, 6.7)(紅色單元的左上角坐標是 (6,6))。但是,如果預測到的 x,y 坐標大於 1,比如 (1.2, 0.7)。那麽中心坐標是 (7.2, 6.7)。註意該中心在紅色單元右側的單元中,或第 7 行的第 8 個單元。這打破了 YOLO 背後的理論,因為如果我們假設紅色框負責預測目標狗,那麽狗的中心必須在紅色單元中,不應該在它旁邊的網格單元中。

(4)類別置信度表示檢測到的對象屬於某個類別的概率(如狗、貓、香蕉、汽車等)。在 v3 之前,YOLO 需要對類別分數執行 softmax 函數操作。但是,YOLO v3 舍棄了這種設計,作者選擇使用 sigmoid 函數。因為對類別分數執行 softmax 操作的前提是類別是互斥的。簡言之,如果對象屬於一個類別,那麽必須確保其不屬於另一個類別。這在我們設置檢測器的 COCO 數據集上是正確的。但是,當出現類別「女性」(Women)和「人」(Person)時,該假設不可行。這就是作者選擇不使用 Softmax 激活函數的原因。

(5)在不同尺度上的預測
YOLO v3 在 3 個不同尺度上進行預測。檢測層用於在三個不同大小的特征圖上執行預測,特征圖步幅分別是 32、16、8。這意味著,當輸入圖像大小是 416 x 416 時,我們在尺度 13 x 13、26 x 26 和 52 x 52 上執行檢測。該網絡在第一個檢測層之前對輸入圖像執行下采樣,檢測層使用步幅為 32 的層的特征圖執行檢測。隨後在執行因子為 2 的上采樣後,並與前一個層的特征圖(特征圖大小相同)拼接。另一個檢測在步幅為 16 的層中執行。重復同樣的上采樣步驟,最後一個檢測在步幅為 8 的層中執行。在每個尺度上,每個單元使用 3 個錨點預測 3 個邊界框,錨點的總數為 9(不同尺度的錨點不同)。作者稱這幫助 YOLO v3 在檢測較小目標時取得更好的性能,而這正是 YOLO 之前版本經常被抱怨的地方。上采樣可以幫助該網絡學習細粒度特征,幫助檢測較小目標。

(6)輸出處理
對於大小為 416 x 416 的圖像,YOLO 預測 ((52 x 52) + (26 x 26) + 13 x 13)) x 3 = 10647 個邊界框。但是,我們的示例中只有一個對象——一只狗。那麽我們怎麽才能將檢測次數從 10647 減少到 1 呢?目標置信度閾值:首先,我們根據它們的 objectness 分數過濾邊界框。通常,分數低於閾值的邊界框會被忽略。非極大值抑制:非極大值抑制(NMS)可解決對同一個圖像的多次檢測的問題。例如,紅色網格單元的 3 個邊界框可以檢測一個框,或者臨近網格可檢測相同對象。

(7)跳過連接層
[shortcut]
from= -3
activation=linear
跳過連接與殘差網絡中使用的結構相似,參數 from 為-3 表示捷徑層的輸出會通過將之前層的和之前第三個層的輸出的特征圖與模塊的輸入相加而得出。

(8)路由層(Route)
[route]
layers = -4
[route]
layers = -1, 61
路由層需要一些解釋,它的參數 layers 有一個或兩個值。當只有一個值時,它輸出這一層通過該值索引的特征圖。在我們的實驗中設置為了-4,所以層級將輸出路由層之前第四個層的特征圖。當層級有兩個值時,它將返回由這兩個值索引的拼接特征圖。在我們的實驗中為-1 和 61,因此該層級將輸出從前一層級(-1)到第 61 層的特征圖,並將它們按深度拼接。

(9)YOLO 層級對應於上文所描述的檢測層級。參數 anchors 定義了 9 組錨點,但是它們只是由 mask 標簽使用的屬性所索引的錨點。這裏,mask 的值為 0、1、2 表示了第一個、第二個和第三個使用的錨點。而掩碼表示檢測層中的每一個單元預測三個框。總而言之,我們檢測層的規模為 3,並裝配總共 9 個錨點。

(10)理解權重文件
官方的權重文件是一個二進制文件,它以序列方式儲存神經網絡權重。我們必須小心地讀取權重,因為權重只是以浮點形式儲存,沒有其它信息能告訴我們到底它們屬於哪一層。所以如果讀取錯誤,那麽很可能權重加載就全錯了,模型也完全不能用。因此,只閱讀浮點數,無法區別權重屬於哪一層。因此,我們必須了解權重是如何存儲的。首先,權重只屬於兩種類型的層,即批歸一化層(batch norm layer)和卷積層。這些層的權重儲存順序和配置文件中定義層級的順序完全相同。所以,如果一個 convolutional 後面跟隨著 shortcut 塊,而 shortcut 連接了另一個 convolutional 塊,則你會期望文件包含了先前 convolutional 塊的權重,其後則是後者的權重。

5、
(1)yolo標簽值意義:
計算標簽值函數中:返回值為ROI中心點相對於圖片大小的比例坐標,和ROI的w、h相對於圖片大小的比例
def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0 - 1
y = (box[2] + box[3])/2.0 - 1
w = box[1] - box[0]
h = box[3] - box[2]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
return (x,y,w,h)

(2)根據網絡層預測值計算輸出值:(網絡層預測坐標:tx ,ty , tw , th 都是相對於預測單元的比例)(cx , cy為預測單元左上角相對於圖片左上角偏移值 , pw , ph為先驗框的寬度和高度)
b.x = σ(tx) + cx
b.y = σ(ty) + cy
b.w = pw*exp(tw)
b.h = ph*exp(th)




yolo原理學習