YOLOV3 網絡結構學習筆記

注:本文非原創,文章內容都是引用以下文章中,本文只是記錄學習筆記。

https://blog.csdn.net/leviopku/article/details/82660381

https://blog.csdn.net/qq_41994006/article/details/88789566

https://blog.csdn.net/qq_37541097/article/details/81214953

https://blog.csdn.net/u010397980/article/details/85058630

https://blog.csdn.net/qq_34199326/article/details/84109828

https://blog.csdn.net/litt1e/article/details/88907542


前言:

yolo_v3作爲yolo系列目前最新的算法,對之前的算法既有保留又有改進。先分析一下yolo_v3上保留的東西:

  1. “分而治之”,從yolo_v1開始,yolo算法就是通過劃分單元格來做檢測,只是劃分的數量不一樣。
  2. 採用"leaky ReLU"作爲激活函數。
  3. 端到端進行訓練。一個loss function搞定訓練,只需關注輸入端和輸出端。
  4. 從yolo_v2開始,yolo就用batch normalization作爲正則化、加速收斂和避免過擬合的方法,把BN層和leaky relu層接到每一層卷積層之後。
  5. 多尺度訓練。在速度和準確率之間tradeoff。想速度快點,可以犧牲準確率;想準確率高點兒,可以犧牲一點速度。

網絡結構圖:

DBL: 如圖1左下角所示,也就是代碼中的Darknetconv2d_BN_Leaky,是yolo_v3的基本組件。就是卷積+BN+Leaky relu。對於v3來說,BN和leaky relu已經是和卷積層不可分離的部分了(最後一層卷積除外),共同構成了最小組件。
resn:n代表數字,有res1,res2, … ,res8等等,表示這個res_block裏含有多少個res_unit。這是yolo_v3的大組件,yolo_v3開始借鑑了ResNet的殘差結構,使用這種結構可以讓網絡結構更深(從v2的darknet-19上升到v3的darknet-53,前者沒有殘差結構)。對於res_block的解釋,可以在圖1的右下角直觀看到,其基本組件也是DBL。
concat:張量拼接。將darknet中間層和後面的某一層的上採樣進行拼接。拼接的操作和殘差層add的操作是不一樣的,拼接會擴充張量的維度,而add只是直接相加不會導致張量維度的改變。

我們可以借鑑netron來分析網絡層,整個yolo_v3_body包含252層,組成如下:

                                   表0. yolo_v3_layers


根據表0可以得出,對於代碼層面的layers數量一共有252層,包括add層23層(主要用於res_block的構成,每個res_unit需要一個add層,一共有1+2+8+8+4=23層)。除此之外,BN層和LeakyReLU層數量完全一樣(72層),在網絡結構中的表現爲:每一層BN後面都會接一層LeakyReLU。卷積層一共有75層,其中有72層後面都會接BN+LeakyReLU的組合構成基本組件DBL。看結構圖,可以發現上採樣和concat都有2次,和表格分析中對應上。每個res_block都會用上一個零填充,一共有5個res_block。

 

YOLOv3 模型結構:

 

Concatenate:Concatenate層與哪個層進行拼接。

Convolutional:Conv2d+BN+LeakyReLU。

Conv2d:最後三層生成預測結果。

 

簡單結構圖:

 


backbone:


整個v3結構裏面,是沒有池化層和全連接層的。前向傳播過程中,張量的尺寸變換是通過改變卷積核的步長來實現的,比如stride=(2, 2),這就等於將圖像邊長縮小了一半(即面積縮小到原來的1/4)。在yolo_v2中,要經歷5次縮小,會將特徵圖縮小到原輸入尺寸的1/2^5,即1/32。輸入爲416x416,則輸出爲13x13(416/32=13)。
yolo_v3也和v2一樣,backbone都會將輸出特徵圖縮小到輸入的1/32。所以,通常都要求輸入圖片是32的倍數。可以對比v2和v3的backbone看看:(DarkNet-19 與 DarkNet-53)

yolo_v2中對於前向過程中張量尺寸變換,都是通過最大池化來進行,一共有5次。而v3是通過卷積核增大步長來進行,也是5次。(darknet-53最後面有一個全局平均池化,在yolo-v3裏面沒有這一層,所以張量維度變化只考慮前面那5次)。
這也是416x416輸入得到13x13輸出的原因。從圖2可以看出,darknet-19是不存在殘差結構(resblock,從resnet上借鑑過來)的,和VGG是同類型的backbone(屬於上一代CNN結構),而darknet-53是可以和resnet-152正面剛的backbone。

Yolo_v3使用了darknet-53的前面的52層(沒有全連接層),yolo_v3這個網絡是一個全卷積網絡,大量使用殘差的跳層連接,並且爲了降低池化帶來的梯度負面效果,作者直接摒棄了POOLing,用conv的stride來實現降採樣。在這個網絡結構中,使用的是步長爲2的卷積來進行降採樣。

爲了加強算法對小目標檢測的精確度,YOLO v3中採用類似FPN的upsample和融合做法(最後融合了3個scale,其他兩個scale的大小分別是26×26和52×52),在多個scale的feature map上做檢測。

作者在3條預測支路採用的也是全卷積的結構,其中最後一個卷積層的卷積核個數是255,是針對COCO數據集的80類:3*(80+4+1)=255,3表示一個grid cell包含3個bounding box,4表示框的4個座標信息,1表示objectness score。


Output:

 

 

yolov3一共有9個anchor,3個輸出,每個輸出用3個anchor,所以輸出的每個位置預測3個box。對於13x13的輸出,每個box的參數包括tx, ty, tw, th,及該box有物體的置信分數,該box中爲每類物體的概率。

因此,對於VOC數據集,類別爲20,帶入上圖的公式中yolov3的輸出3種尺寸的大小爲:13x13x(3*(20+5))=13x13x75, 26x26x(3*(20+5))=26x26x75, 52x52x(3*(20+5))=52x52x75。

 

下面我們具體看看y1,y2,y3是如何而來的:


網絡中作者進行了三次檢測,分別是在32倍降採樣,16倍降採樣,8倍降採樣時進行檢測,這樣在多尺度的feature map上檢測跟SSD有點像。在網絡中使用up-sample(上採樣)的原因:網絡越深的特徵表達效果越好,比如在進行16倍降採樣檢測,如果直接使用第四次下采樣的特徵來檢測,這樣就使用了淺層特徵,這樣效果一般並不好。如果想使用32倍降採樣後的特徵,但深層特徵的大小太小,因此yolo_v3使用了步長爲2的up-sample(上採樣),把32倍降採樣得到的feature map的大小提升一倍,也就成了16倍降採樣後的維度。同理8倍採樣也是對16倍降採樣的特徵進行步長爲2的上採樣,這樣就可以使用深層特徵進行detection。

作者通過上採樣將深層特徵提取,其維度是與將要融合的特徵層維度相同的(channel不同)。如下圖所示,85層將13×13×256的特徵上採樣得到26×26×256,再將其與61層的特徵拼接起來得到26×26×768。爲了得到channel255,還需要進行一系列的3×3,1×1卷積操作,這樣既可以提高非線性程度增加泛化性能提高網絡精度,又能減少參數提高實時性。52×52×255的特徵也是類似的過程。

 

 

 


 boundingbox迴歸:

在yolo_v2和yolo_v3中,都採用了對圖像中的object採用k-means聚類。 feature map中的每一個cell都會預測3個邊界框(bounding box) ,每個bounding box都會預測三個東西:(1)每個框的位置(4個值,中心座標tx和ty,,框的高度bh和寬度bw),(2)一個objectness prediction ,(3)N個類別,coco數據集80類,voc20類。

三次檢測,每次對應的感受野不同,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。

 

感受野:https://blog.csdn.net/program_developer/article/details/80958716

在卷積神經網絡中,感受野(Receptive Field)的定義是卷積神經網絡每一層輸出的特徵圖(feature map)上的像素點在輸入圖片上映射的區域大小。再通俗點的解釋是,特徵圖上的一個點對應輸入圖上的區域,如圖所示。

感受野的計算:

. 最後一層(卷積層或池化層)輸出特徵圖感受野的大小等於卷積核的大小。
. 第i層卷積層的感受野大小和第i層的卷積核大小和步長有關係,同時也與第(i+1)層感受野大小有關。
. 計算感受野的大小時忽略了圖像邊緣的影響,即不考慮padding的大小。

 

計算公式:

關於感受野大小的計算方式是採用從最後一層往下計算的方法,即先計算最深層在前一層上的感受野,然後逐層傳遞到第一層,使用的公式可以表示如下

其中,是第i層卷積層的感受野,是(i+1)層上的感受野,stride是卷積的步長,Ksize是本層卷積核的大小。

 

例子:VGG16網絡有點複雜,我們先來計算一個簡單的例子,先學會計算感受野,在來分析複雜的網絡。

 

我們從最後一層的池化層開始計算感受野:

pool3:RF=2(最後一層池化層輸出特徵圖的感受野大小等於卷積核的大小)

conv4:RF=(2-1)*1+3=4。

conv3:RF=(4-1)*1+3=6。

pool2:RF=(6-1)*2+2=12。

conv2:RF=(12-1)*1+3=14。

pool1:RF=(14-1)*2+2=28。

conv1:RF=(28-1)*1+3=30。

因此,pool3輸出的特徵圖在輸入圖片上的感受野爲30*30。


下面感受一下9種先驗框的尺寸,下圖中藍色框爲聚類得到的先驗框。黃色框式ground truth,紅框是對象中心點所在的網格.

 

這裏注意bounding box 與anchor box的區別:
Bounding box它輸出的是框的位置(中心座標與寬高),confidence以及N個類別。
anchor box只是一個尺度即只有寬高。


邊框詳細預測分析:

 

其中,Cx,Cy是feature map中grid cell的左上角座標,在yolov3中每個grid cell在feature map中的寬和高均爲1。如圖,這個bbox邊界框的中心屬於第二行第二列的grid cell,它的左上角座標爲(1,1),故Cx=1,Cy=1.公式中的Pw、Ph是預設的anchor box映射到feature map中的寬和高。

最終得到的邊框座標值是bx,by,bw,bh即邊界框bbox相對於feature map的位置和大小,是我們需要的預測輸出座標。但我們網絡實際上的學習目標是tx,ty,tw,th這4個offsets,其中tx,ty是預測的座標偏移值,tw,th是尺度縮放,有了這4個offsets,自然可以根據之前的公式去求得真正需要的bx,by,bw,bh4個座標。至於爲何不直接學習bx,by,bw,bh呢?因爲YOLO 的輸出是一個卷積特徵圖,包含沿特徵圖深度的邊界框屬性。邊界框屬性由彼此堆疊的單元格預測得出。因此,如果你需要在 (5,6) 處訪問該單元格的第二個邊框bbox,那麼你需要通過 map[5,6, (5+C): 2*(5+C)] 將其編入索引。這種格式對於輸出處理過程(例如通過目標置信度進行閾值處理、添加對中心的網格偏移、應用錨點等)很不方便,因此我們求偏移量即可。那麼這樣就只需要求偏移量,也就可以用上面的公式求出bx,by,bw,bh,反正是等價的。另外,通過學習偏移量,就可以通過網絡原始給定的anchor box座標經過線性迴歸微調(平移加尺度縮放)去逐漸靠近groundtruth.爲何微調可看做線性迴歸看後文。

這裏需要注意的是,雖然輸入尺寸是416*416,但原圖是按照縱橫比例縮放至416*416的, 取 min(w/img_w, h/img_h)這個比例來縮放,保證長的邊縮放爲需要的輸入尺寸416,而短邊按比例縮放不會扭曲,img_w,img_h是原圖尺寸768,576, 縮放後的尺寸爲new_w, new_h=416,312,剩下的灰色區域用(128,128,128)填充即可構造爲416*416,需要的輸入尺寸是w,h=416*416.如圖所示:


如何匹配anchor

和YOLOv1一樣,對於訓練圖片中的ground truth,若其中心點落在某個cell內,那麼該cell內的3個anchor box負責預測它,具體是哪個anchor box預測它,需要在訓練中確定,即由那個與ground truth的IOU最大的anchor box預測它,而剩餘的2個anchor box不與該ground truth匹配。YOLOv3需要假定每個cell至多含有一個grounth truth,而在實際上基本不會出現多於1個的情況。與ground truth匹配的anchor box計算座標誤差、置信度誤差(此時target爲1)以及分類誤差,而其它的anchor box只計算置信度誤差(此時target爲0)。

有了平移(tx,ty)和尺度縮放(tw,th)才能讓anchor box經過微調與grand truth重合。如圖,紅色框爲anchor box,綠色框爲Ground Truth,平移+尺度縮放可實線紅色框先平移到虛線紅色框,然後再縮放到綠色框。邊框迴歸最簡單的想法就是通過平移加尺度縮放進行微調嘛。


關於使用sigmoid:

用sigmoid將tx,ty壓縮到[0,1]區間內,可以有效的確保目標中心處於執行預測的網格單元中,防止偏移過多。舉個例子,我們剛剛都知道了網絡不會預測邊界框中心的確切座標而是預測與預測目標的grid cell左上角相關的偏移tx,ty。如13*13的feature map中,某個目標的中心點預測爲(0.4,0.7),它的cx,cy即中心落入的grid cell座標是(6,6),則該物體的在feature map中的中心實際座標顯然是(6.4,6.7).這種情況沒毛病,但若tx,ty大於1,比如(1.2,0.7)則該物體在feature map的的中心實際座標是(7.2,6.7),注意這時候該物體中心在這個物體所屬grid cell外面了,但(6,6)這個grid cell卻檢測出我們這個單元格內含有目標的中心(yolo是採取物體中心歸哪個grid cell整個物體就歸哪個grid celll了),這樣就矛盾了,因爲左上角爲(6,6)的grid cell負責預測這個物體,這個物體中心必須出現在這個grid cell中而不能出現在它旁邊網格中,一旦tx,ty算出來大於1就會引起矛盾,因而必須歸一化。

 看最後兩行公式,tw爲何要指數呀,這就好理解了嘛,因爲tw,th是log尺度縮放到對數空間了,當然要指數回來,而且這樣可以保證大於0。 至於左邊乘以Pw或者Ph是因爲tw=log(Gw/Pw)當然應該乘回來得到真正的寬高。

記feature map大小爲W,H(如13*13),可將bbox相對於整張圖片的位置和大小計算出來(使4個值均處於[0,1]區間內)約束了bbox的位置預測值到[0,1]會使得模型更容易穩定訓練(如果不是[0,1]區間,yolo的每個bbox的維度都是85,前5個屬性是(Cx,Cy,w,h,confidence),後80個是類別概率,如果座標不歸一化,和這些概率值一起訓練肯定不收斂啊)

只需要把之前計算的bx,bw都除以W,把by,bh都除以H。即

 

confidence:

如果某個grid cell無object則Pr(Object) =0,否則Pr(Object) =1,則此時的confidence=𝐼𝑂𝑈 ,即預測的bbox和ground truth的IOU值作爲置信度。因此這個confidence不僅反映了該grid cell是否含有物體,還預測這個bbox座標預測的有多準。在預測階段,類別的概率爲類別條件概率和confidence相乘:

Pr(Classi|Object) ∗ Pr⁡(Object) ∗ IOU(pred&groundtruth) = Pr(Classi) ∗ IOU(pred&groundtruth)

這樣每個bbox具體類別的score就有了,乘積既包含了bbox中預測的class的概率又反映了bbox是否包含目標和bbox座標的準確度。


損失函數:

YOLOv3的損失函數主要分爲三個部分:目標定位偏移量損失,目標置信度損失以及目標分類損失,其中是平衡係數。

目標置信度損失:
目標置信度可以理解爲預測目標矩形框內存在目標的概率,目標置信度損失採用的是二值交叉熵損失(Binary Cross Entropy),其中,表示預測目標邊界框i中是否真實存在目標,0表示不存在,1表示存在。表示預測目標矩形框i內是否存在目標的Sigmoid概率(將預測值通過sigmoid函數得到)。

 

目標類別損失
目標類別損失同樣採用的是二值交叉熵損失(採用二值交叉熵損失的原因是,作者認爲同一目標可同時歸爲多類,比如貓可歸爲貓類以及動物類,這樣能夠應對更加複雜的場景。但在本人實踐過程中發現使用原始的多類別交叉熵損失函數效果會更好一點,原因是本人針對識別的目標都是固定歸於哪一類的,並沒有可同時歸於多類的情況),其中,表示預測目標邊界框i中是否真實存在第j類目標,0表示不存在,1表示存在。表示網絡預測目標邊界框i內存在第j類目標的Sigmoid概率(將預測值通過sigmoid函數得到)。

 

目標定位損失:
目標定位損失採用的是真實偏差值與預測偏差值差的平方和,其中表示預測矩形框座標偏移量(注意網絡預測的是偏移量,不是直接預測座標),表示與之匹配的GTbox與默認框之間的座標偏移量,爲預測的目標矩形框參數,爲默認矩形框參數,爲與之匹配的真實目標矩形框參數,這些參數都是映射在預測特徵圖上的。

 

結語:

本文並非原創,純屬學習筆記。有不正確的地方,歡迎指正。大家一起進步,一起學習。

 

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