Yolov3 詳細解說

物件偵測

How哥
8 min readJan 22, 2021

1. Yolov3 整體架構

Yolov3 整理架構,可以發現他從backbone中取了三種尺度的feature,丟掉dection model中做物件偵測
Yolov3 整理架構,可以發現他從backbone中取了三種尺度的feature,丟到dection model做物件偵測

2. 詳細結構

DarkNet53

左半邊是darknet53,比起yolov2的darknet19加入了許多convolution layers和residual block,residual block是為了效仿ResNet在網路太深的時候難以學習時,跳過該層layer

左半邊是backbone,右半邊是物件偵測

Detection Input

抓取darknet53其中三層輸出來做detection,大小分別是52x52、26x26、13x13。所以每丟入一張 圖片到網路中,detection model將會針對這三種尺寸算出三個loss。

多尺度偵測

52x52是其中最大的feature map,解析度最高,能夠偵測到較小的物件,13x13是最小的feature map,解析度最低,能夠偵測較大的物體。

抓取darknet53其中三層輸出來做detection,大小分別是52x52、26x26、13x13

所以每丟入一張 圖片到網路中,detection model將會針對這三種尺寸算出三個loss。

52x52是其中最大的feature map,能夠偵測到較小的物件,13x13是最小的feature map,能夠偵測較大的物體。

尺度融合

小feature map透過upsampling變成大feature map,並且跟大feature進行相加,把深層特徵跟淺層特徵融合,讓dection model一次能夠學到高維度和低維度的資訊。

3. 物件偵測

Anchor Box

直觀上偵測物件,會想用一個Boundingbox(Bbox)在一整張圖片上滑動,然後查看滑到的位子上有沒有物件,但這樣圖片上會有太多Bbox需要計算,而且大部分的Bbox重複的區域太多,容易發生很多Bbox框到同一個物件,或是大部分的Bbox都框不到物件的狀況。

Anchor Box的概念,是把圖片分成很多個Grid,每個Grid內生成固定數量的Bbox(以下以anchor稱呼),此時我們要做的事情,就是找到這些anchor中是否框到物件,並且依據物件的位子和大小更新這些現有anchor的位子和大小去符合物件就可以了。

在3 x 3中,假設一個grid有3個anchor,負責偵測中心點在該格的物件。總共只有3 x 9=27個anchor
最後框出的結果如圖,沒有框到或是重複框到物件的anchor都會被砍掉

在yolov3中,丟入的那個圖片大小分別為52 x 52、26 x 26以及13 x 13,並且設定每個grid中有3個anchor。由於尺度不同,所以設定的初始anchor大小也不同。

圖片原始輸入大小為416 x 416,在偵測時會把它變成以下三種尺度

13 x 13 (stride 32) 偵測大物件

在這個狀態下長寬從416變成13,縮小了32倍,所以GroundTruth的座標也會同步縮小32倍。可以想像成一個13 x 13的框框,在圖片上stride 32的結果。在原圖的anchor大小為(116 x 90)(156 x 198)(373 x 326),這些大小也要分別除以32,才有辦法放到13 x 13的feature map中。

26 x 26 (stride 16) 偵測中物件

在這個狀態下長寬從416變成26,縮小了16倍,所以GroundTruth的座標也會同步縮小16倍。可以想像成一個26 x 26的框框,在圖片上stride 16的結果。在原圖的anchor大小為(30 x 61)(62 x 45)(59 x 119),這些大小也要分別除以16,才有辦法放到26 x 26的feature map中。

52 x 52 (stride 8) 偵測小物件

在這個狀態下長寬從416變成52,縮小了8倍,所以GroundTruth的座標也會同步縮小8倍。可以想像成一個52 x 52的框框,在圖片上stride 8的結果。在原圖的anchor大小為(10 x 13)(16 x 30)(30 x 61),這些大小也要分別除以8,才有辦法放到52 x 52的feature map中。

dection model 輸出

下圖以13 x 13為例 :

detection模型輸出結果如圖下方
  • tx 預測中心點偏移量
  • ty預測中心點偏移量
  • tw預測寬度
  • th預測高度,
  • Po是否為物件
  • P1~Pc屬於哪一個物件的信心程度(80種物件)

channel數為[5(tx、ty、tw、th、Po) + 80(80種物件)] x 3(3個anchor) = 255

  • 大物件偵測tensor : 13 x 13 x 255
  • 中物件偵測tensor : 26 x 26 x 255
  • 小物件偵測tensor : 52 x 52 x 255 (解析度最大)

tx、ty、tw、th代表的意思

我們擁有的4個參數tx、ty、tw、th到底代表甚麼呢?

假設中心點座標為(1.3, 1.4),此時

  • Cx = 1, Cy = 1 (左上角那個點的座標為1 , 1)
  • sigmiod(tx) = 0.3, sigmiod(ty) = 0.4
  • tw = log(Gw/Pw), 這裡的Pw是指預測出來的anchor應該要變多寬,與下圖Pw不是同一個,Gw代表GroundTruth的寬度W
  • th = log(Gh/Ph), 這裡的Ph是指預測出來的anchor應該要變多高,與下圖Ph不是同一個,Gh代表GroundTruth的寬度h
  • 圖中的Pw和Ph為anchor的框和高,要把他們調整的跟藍色框一樣大小
Pw、Ph代表anchor的w和h。Cx、Cy表示中心點左上方那個點的座標,這裡是(1, 1)。tx、ty代表中心點座標與Cx和Cy分別的距離

把tx和ty都取sigmoid是希望中心的變動不會跑出這個grid之外,sigmoid把值壓縮在0到1之間。

雖然論文裡面說tw是預測出來的寬度,但我們也可以說他其實是預測出Pw,接著跟groundtruth計算(Gw/Pw)後取log之後的結果也可以。取log是因為在訓練時會比較穩定,所以在還原真實寬度時,要把它變成e的次方還原回來。th也是相同道理。

計算anchor的Loss

在實際上,我們要想的問題是 :

如何把anchor更新到groundtruth的位置上

GroundTruth(紅色)和Anchor box(藍色)的位置,要把藍色擬合到紅色上

Gw、Gh為groundtruth的寬和高,Aw、Ah為anchor現在的寬和高

  • tw^(tw的groundtruth) = log(Gw/Aw), 意思是anchor的寬度真正要被放大多少
  • tw = log(Gw/Pw), 模型預測出來是Pw,所以他預測要放大Gw/Pw
  • th^(th的groundtruth) = log(Gh/Ah), 意思是anchor的高度真正要被放大多少
  • th = log(Gh/Ph), 模型預測出Ph,所以他預測要放大Gh/Ph
  • 在W和H的Loss可以記成(tw-tw^)² + (th-th^)²

至於中心點座標比較麻煩,以上圖為例

  • tx^ 不知道等於多少,但是我們知道sigmoid(tx^)是0.3,所以他groundtruth是用經過sigmoid的結果來看的,所以tx^=0.3
  • tx = sigmoid(tx),把預測的結果tx丟到sigmiod裡面
  • ty^ 不知道等於多少,但是我們知道sigmoid(ty^)是0.3,所以他groundtruth是用經過sigmoid的結果來看的,所以ty^= 0.3
  • ty = sigmoid(ty),把預測的結果ty丟到sigmiod裡面
  • X和Y偏移量的Loss可以記為 (tx^-sigmoid(tx))² -(ty^-sigmoid(ty))²

總結anchor座標的Loss :

(tw-tw^)² + (th-th^)² + (tx^-sigmoid(tx))² + (ty^-sigmoid(ty))²

Yolov3其他部分這裡就不講了,NMS那些其他人都講得很清楚,只有上面這些部分比較少人討論到。

3. Code

我看了兩個人的code,第一篇比較多stars,但是程式碼很難讀

https://github.com/ultralytics/yolov3

第二篇stars比較少,但程式碼易讀

https://github.com/DeNA/PyTorch_YOLOv3

--

--

How哥
How哥

Written by How哥

台灣科技大學資工所研究生,把有趣的電腦視覺論文整理上來,希望能幫助到有需要的人,聯絡信箱 b10515007@gmail.com

No responses yet