YOLOv1 深入理解


看了很多篇博客,這篇是對yolov1整體結構解釋最清楚的一個,特轉載過來:

YOLO v1深入理解

  YOLO(You Only Look Once)是一種基於深度神經網絡的對象識別和定位算法,其最大的特點是運行速度很快,可以用於實時系統。
現在YOLO已經發展到v5版本,不過新版本也是在原有版本基礎上不斷改進演化的,所以本文先分析YOLO v1版本。

  關於 YOLOv2/YOLO9000 的分析理解請移步 YOLO v2 / YOLO 9000

對象識別和定位

  輸入一張圖片,要求輸出其中所包含的對象,以及每個對象的位置(包含該對象的矩形框)。

圖1 對象識別和定位

  對象識別和定位,可以看成兩個任務:找到圖片中某個存在對象的區域,然后識別出該區域中具體是哪個對象。
  對象識別這件事(一張圖片僅包含一個對象,且基本占據圖片的整個范圍),最近幾年基於CNN卷積神經網絡的各種方法已經能達到不錯的效果了。所以主要需要解決的問題是,對象在哪里。

  最簡單的想法,就是遍歷圖片中所有可能的位置,地毯式搜索不同大小,不同寬高比,不同位置的每個區域,逐一檢測其中是否存在某個對象,挑選其中概率最大的結果作為輸出。顯然這種方法效率太低。

RCNN/Fast RCNN/Faster RCNN

  RCNN開創性的提出了候選區(Region Proposals)的方法,先從圖片中搜索出一些可能存在對象的候選區(Selective Search),大概2000個左右,然后對每個候選區進行對象識別。大幅提升了對象識別和定位的效率。

  不過RCNN的速度依然很慢,其處理一張圖片大概需要49秒。因此又有了后續的Fast RCNN 和 Faster RCNN,針對 RCNN的神經網絡結構和候選區的算法不斷改進,Faster RCNN已經可以達到一張圖片約0.2秒的處理速度。下圖來自 R-CNN, Fast R-CNN, Faster R-CNN, YOLO — Object Detection Algorithms

  圖2 RCNN系列處理速度

  但總體來說,RCNN系列依然是兩階段處理模式:先提出候選區,再識別候選區中的對象。

YOLO

  YOLO意思是You Only Look Once,創造性的將候選區和對象識別這兩個階段合二為一,看一眼圖片(不用看兩眼哦)就能知道有哪些對象以及它們的位置。

  實際上,YOLO並沒有真正去掉候選區,而是采用了預定義的候選區(准確點說應該是預測區,因為並不是Faster RCNN所采用的Anchor)。也就是將圖片划分為 7*7=49 個網格(grid),每個網格允許預測出2個邊框(bounding box,包含某個對象的矩形框),總共 49*2=98 個bounding box。可以理解為98個候選區,它們很粗略的覆蓋了圖片的整個區域。  

  也就是說,每個cell有兩個predictor,每個predictor分別預測一個bounding box的xywh和相應的confidence。但分類部分的預測卻是共享的。正因為這個,同個cell是沒辦法預測多個目標的。

  現在考慮兩個問題:

  1. 假設類別預測不是共享的,cell中兩個predictor都有各自的類別預測,這樣能否在一個cell中預測兩個目標?
  2. 為什么要預測兩個bounding box?

  對於第一個問題,答案是否定的。如果一個cell要預測兩個目標,那么這兩個predictor要怎么分工預測這兩個目標?誰負責誰?不知道,所以沒辦法預測。而像faster rcnn這類算法,可以根據anchor與ground truth的IOU大小來安排anchor負責預測哪個物體,所以后來yolo2也采用了anchor思想,同個cell才能預測多個目標。

  對於第二個問題,既然我們一個cell只能預測一個目標,為什么還要預測兩個bounding box(或者更多)?這個還是要從訓練階段怎么給兩個predictor安排訓練目標來說。在訓練的時候會在線地計算每個predictor預測的bounding box和ground truth的IOU,計算出來的IOU大的那個predictor,就會負責預測這個物體,另外一個則不預測。這么做有什么好處?我的理解是,這樣做的話,實際上有兩個predictor來一起進行預測,然后網絡會在線選擇預測得好的那個predictor(也就是IOU大)來進行預測。通俗一點說,就是我找一堆人來並行地干一件事,然后我選干的最好的那個。

RCNN:我們先來研究一下圖片,嗯,這些位置很可能存在一些對象,你們對這些位置再檢測一下看到底是哪些對象在里面。
YOLO:我們把圖片大致分成98個區域,每個區域看下有沒有對象存在,以及具體位置在哪里。 RCNN:你這么簡單粗暴真的沒問題嗎? YOLO:當然沒有......咳,其實是有一點點問題的,准確率要低一點,但是我非常快!快!快! RCNN:為什么你用那么粗略的候選區,最后也能得到還不錯的bounding box呢? YOLO:你不是用過邊框回歸嗎?我拿來用用怎么不行了。 

  RCNN雖然會找到一些候選區,但畢竟只是候選,等真正識別出其中的對象以后,還要對候選區進行微調,使之更接近真實的bounding box。這個過程就是邊框回歸:將候選區bounding box調整到更接近真實的bounding box。
  既然反正最后都是要調整的,干嘛還要先費勁去尋找候選區呢,大致有個區域范圍就行了,所以YOLO就這么干了。

  不過話說回來,邊框回歸為啥能起作用,我覺得本質上是因為 分類信息 中已經包含了 位置信息。就像你看到主子的臉和身體,就能推測出耳朵和屁股的位置。

圖3 邊框調整

下面具體看下YOLO的實現方案。

1)結構
  去掉候選區這個步驟以后,YOLO的結構非常簡單,就是單純的卷積、池化最后加了兩層全連接。單看網絡結構的話,和普通的CNN對象分類網絡幾乎沒有本質的區別,最大的差異是最后輸出層用線性函數做激活函數,因為需要預測bounding box的位置(數值型),而不僅僅是對象的概率。所以粗略來說,YOLO的整個結構就是輸入圖片經過神經網絡的變換得到一個輸出的張量,如下圖所示。

圖4 輸入 -> 神經網絡變換 -> 輸出

  因為只是一些常規的神經網絡結構,所以,理解YOLO的設計的時候,重要的是理解輸入和輸出的映射關系.

2)輸入和輸出的映射關系

圖5 輸入 -> 輸出

3)輸入
  參考圖5,輸入就是原始圖像,唯一的要求是縮放到448*448的大小。主要是因為YOLO的網絡中,卷積層最后接了兩個全連接層,全連接層是要求固定大小的向量作為輸入,所以倒推回去也就要求原始圖像有固定的尺寸。那么YOLO設計的尺寸就是448*448。

4)輸出
  輸出是一個 7*7*30 的張量(tensor)。

4.1)7*7網格
  根據YOLO的設計,輸入圖像被划分為 7*7 的網格(grid),輸出張量中的 7*7 就對應着輸入圖像的 7*7 網格。或者我們把 7*7*30 的張量看作 7*7=49個30維的向量,也就是輸入圖像中的每個網格對應輸出一個30維的向量。參考上面圖5,比如輸入圖像左上角的網格對應到輸出張量中左上角的向量。

  要注意的是,並不是說僅僅網格內的信息被映射到一個30維向量。經過神經網絡對輸入圖像信息的提取和變換,網格周邊的信息也會被識別和整理,最后編碼到那個30維向量中。

4.2)30維向量
  具體來看每個網格對應的30維向量中包含了哪些信息。

圖6 30維輸出向量

① 20個對象分類的概率
  因為YOLO支持識別20種不同的對象(人、鳥、貓、汽車、椅子等),所以這里有20個值表示該網格位置存在任一種對象的概率。可以記為 P(C_1|Object), ......, P(C_i|Object),......P(C_{20}|Object),之所以寫成條件概率,意思是如果該網格存在一個對象Object,那么它是C_i的概率是P(C_i|Object)。(記不清條件概率的同學可以參考一下 理解貝葉斯定理

② 2個bounding box的位置
  每個bounding box需要4個數值來表示其位置,(Center_x,Center_y,width,height),即(bounding box的中心點的x坐標,y坐標,bounding box的寬度,高度),2個bounding box共需要8個數值來表示其位置。

③ 2個bounding box的置信度
  bounding box的置信度 = 該bounding box內存在對象的概率 * 該bounding box與該對象實際bounding box的IOU
  用公式來表示就是
Confidence = Pr(Object) * IOU_{pred}^{truth}

  Pr(Object)是bounding box內存在對象的概率,區別於上面第①點的 P(C_i|Object)。Pr(Object)並不管是哪個對象,它體現的是 有或沒有 對象的概率。第①點中的P(C_i|Object)意思是假設已經有一個對象在網格中了,這個對象具體是哪一個。

  IOU_{pred}^{truth}是 bounding box 與 對象真實bounding box 的IOU(Intersection over Union,交並比)。要注意的是,現在討論的30維向量中的bounding box是YOLO網絡的輸出,也就是預測的bounding box。所以IOU_{pred}^{truth}體現了預測的bounding box與真實bounding box的接近程度。
  還要說明的是,雖然有時說"預測"的bounding box,但這個IOU是在訓練階段計算的。等到了測試階段(Inference),這時並不知道真實對象在哪里,只能完全依賴於網絡的輸出,這時已經不需要(也無法)計算IOU了。

  綜合來說,一個bounding box的置信度Confidence意味着它 是否包含對象且位置准確的程度。置信度高表示這里存在一個對象且位置比較准確,置信度低表示可能沒有對象 或者 即便有對象也存在較大的位置偏差。

  簡單解釋一下IOU。下圖來自Andrew Ng的深度學習課程,IOU=交集部分面積/並集部分面積,2個box完全重合時IOU=1,不相交時IOU=0。

圖7 IOU

  總的來說,30維向量 = 20個對象的概率 + 2個bounding box * 4個坐標 + 2個bounding box的置信度

4.3)討論
① 一張圖片最多可以檢測出49個對象
  每個30維向量中只有一組(20個)對象分類的概率,也就只能預測出一個對象。所以輸出的 7*7=49個 30維向量,最多表示出49個對象。

② 總共有 49*2=98 個候選區(bounding box)
  每個30維向量中有2組bounding box,所以總共是98個候選區。

③ YOLO的bounding box並不是Faster RCNN的Anchor
  Faster RCNN等一些算法采用每個grid中手工設置n個Anchor(先驗框,預先設置好位置的bounding box)的設計,每個Anchor有不同的大小和寬高比。YOLO的bounding box看起來很像一個grid中2個Anchor,但它們不是。YOLO並沒有預先設置2個bounding box的大小和形狀,也沒有對每個bounding box分別輸出一個對象的預測。它的意思僅僅是對一個對象預測出2個bounding box,選擇預測得相對比較准的那個。

  這里采用2個bounding box,有點不完全算監督算法,而是像進化算法。如果是監督算法,我們需要事先根據樣本就能給出一個正確的bounding box作為回歸的目標。但YOLO的2個bounding box事先並不知道會在什么位置,只有經過前向計算,網絡會輸出2個bounding box,這兩個bounding box與樣本中對象實際的bounding box計算IOU。這時才能確定,IOU值大的那個bounding box,作為負責預測該對象的bounding box。
  訓練開始階段,網絡預測的bounding box可能都是亂來的,但總是選擇IOU相對好一些的那個,隨着訓練的進行,每個bounding box會逐漸擅長對某些情況的預測(可能是對象大小、寬高比、不同類型的對象等)。所以,這是一種進化或者非監督學習的思想。

  另外論文中經常提到responsible。比如:Our system divides the input image into an S*S grid. If the center of an object falls into a grid cell, that grid cell is responsible for detecting that object. 這個 responsible 有點讓人疑惑,對預測"負責"是啥意思。其實沒啥特別意思,就是一個Object只由一個grid來進行預測,不要多個grid都搶着預測同一個Object。更具體一點說,就是在設置訓練樣本的時候,樣本中的每個Object歸屬到且僅歸屬到一個grid,即便有時Object跨越了幾個grid,也僅指定其中一個。具體就是計算出該Object的bounding box的中心位置,這個中心位置落在哪個grid,該grid對應的輸出向量中該對象的類別概率是1(該gird負責預測該對象),所有其它grid對該Object的預測概率設為0(不負責預測該對象)。

  還有:YOLO predicts multiple bounding boxes per grid cell. At training time we only want one bounding box predictor to be responsible for each object. 同樣,雖然一個grid中會產生2個bounding box,但我們會選擇其中一個作為預測結果,另一個會被忽略。下面構造訓練樣本的部分會看的更清楚。

④ 可以調整網格數量、bounding box數量
  7*7網格,每個網格2個bounding box,對448*448輸入圖像來說覆蓋粒度有點粗。我們也可以設置更多的網格以及更多的bounding box。設網格數量為 S*S,每個網格產生B個邊框,網絡支持識別C個不同的對象。這時,輸出的向量長度為:C個 P(Ci|Object), B個邊框置信度及4*B個坐標
C + B * (4+1)
  整個輸出的tensor就是:
S * S * (C + B * (4+1))

  YOLO選擇的參數是 7*7網格,2個bounding box,20種對象,因此 輸出向量長度 = 20 + 2 * (4+1) = 30。整個輸出的tensor就是 7*7*30。

  因為網格和bounding box設置的比較稀疏,所以這個版本的YOLO訓練出來后預測的准確率和召回率都不是很理想,后續的v2、v3版本還會改進。當然,因為其速度能夠滿足實時處理的要求,所以對工業界還是挺有吸引力的。

5)訓練樣本構造
  作為監督學習,我們需要先構造好訓練樣本,才能讓模型從中學習

圖8 輸入樣本圖片

  對於一張輸入圖片,其對應輸出的7*7*30張量(也就是通常監督學習所說的標簽y或者label)應該填寫什么數據呢。

  首先,輸出的 7*7維度 對應於輸入的 7*7 網格。

  然后具體看下30維向量的填寫(請對照上面圖6)。

  ① 20個對象分類的概率
    對於輸入圖像中的每個對象,先找到其中心點。比如圖8中的自行車,其中心點在黃色圓點位置,中心點落在黃色網格內,所以這個黃色網格對應的30維向量中,自行車的概率是1,其它對象的概率是0。所有其它48個網格的30維向量中,該自行車的概率都是0。這就是所謂的"中心點所在的網格對預測該對象負責"。狗和汽車的分類概率也是同樣的方法填寫。

  ② 2個bounding box的位置
    訓練樣本的bounding box位置應該填寫對象實際的bounding box,但一個對象對應了2個bounding box,該填哪一個呢?上面討論過,需要根據網絡輸出的bounding box與對象實際bounding box的IOU來選擇,所以要在訓練過程中動態決定到底填哪一個bounding box。參考下面第③點。

  ③ 2個bounding box的置信度
    上面討論過置信度公式
Confidence = Pr(Object) * IOU_{pred}^{truth}
    IOU_{pred}^{truth}可以直接計算出來,就是用網絡輸出的2個bounding box與對象真實bounding box一起計算出IOU。
    然后看2個bounding box的IOU,哪個比較大(更接近對象實際的bounding box),就由哪個bounding box來負責預測該對象是否存在,即該bounding box的Pr(Object) =1,同時對象真實bounding box的位置也就填入該bounding box。另一個不負責預測的bounding box的Pr(Object) =0
    總的來說就是,與對象實際bounding box最接近的那個bounding box,其Confidence=IOU_{pred}^{truth},該網格的其它bounding box的Confidence=0

    舉個例子,比如上圖中自行車的中心點位於4行3列網格中,所以輸出tensor中4行3列位置的30維向量如下圖所示。

圖9 訓練樣本的一個30維向量

    翻譯成人話就是:4行3列網格位置有一輛自行車,它的中心點在這個網格內,它的位置邊框是bounding box1所填寫的自行車實際邊框。

注意,圖中將自行車的位置放在bounding box1,但實際上是在訓練過程中等網絡輸出以后,比較兩個bounding box與自行車實際位置的IOU,自行車的位置(實際bounding box)放置在IOU比較大的那個bounding box(圖中假設是bounding box1),且該bounding box的置信度設為1。 (坐標2?)

6)損失函數

  損失就是網絡實際輸出值與樣本標簽值之間的偏差。

圖10 樣本標簽與網絡實際輸出

  YOLO給出的損失函數如下

圖11 損失函數

  公式中
  1_i^{obj}意思是網格i中存在對象。
  1_{ij}^{obj}意思是網格i的第j個bounding box中存在對象。
  1_{ij}^{noobj}意思是網格i的第j個bounding box中不存在對象。

  總的來說,就是用網絡輸出與樣本標簽的各項內容的誤差平方和作為一個樣本的整體誤差。
  損失函數中的幾個項是與輸出的30維向量中的內容相對應的。

  ① 對象分類的誤差
    公式第5行,注意1_i^{obj}意味着存在對象的網格才計入誤差。

  ② bounding box的位置誤差
  公式第1行和第2行。
    a)都帶有1_{ij}^{obj}意味着只有"負責"(IOU比較大)預測的那個bounding box的數據才會計入誤差。
    b)第2行寬度和高度先取了平方根,因為如果直接取差值的話,大的對象對差值的敏感度較低,小的對象對差值的敏感度較高,所以取平方根可以降低這種敏感度的差異,使得較大的對象和較小的對象在尺寸誤差上有相似的權重。
    c)乘以 \lambda_{coord} 調節bounding box位置誤差的權重(相對分類誤差和置信度誤差)。YOLO設置 \lambda_{coord} = 5,即調高位置誤差的權重。

  ③ bounding box的置信度誤差
  公式第3行和第4行:
    a)第3行是存在對象的bounding box的置信度誤差。帶有1_{ij}^{obj}意味着只有"負責"(IOU比較大)預測的那個bounding box的置信度才會計入誤差。
    b)第4行是不存在對象的bounding box的置信度誤差。因為不存在對象的bounding box應該老老實實的說"我這里沒有對象",也就是輸出盡量低的置信度。如果它不恰當的輸出較高的置信度,會與真正"負責"該對象預測的那個bounding box產生混淆。其實就像對象分類一樣,正確的對象概率最好是1,所有其它對象的概率最好是0。
    c)第4行會乘以 \lambda_{noobj} 調節不存在對象的bounding box的置信度的權重(相對其它誤差)。YOLO設置 \lambda_{noobj} = 0.5,即調低不存在對象的bounding box的置信度誤差的權重。

7)訓練
  YOLO先使用ImageNet數據集對前20層卷積網絡進行預訓練,然后使用完整的網絡,在PASCAL VOC數據集上進行對象識別和定位的訓練和預測。YOLO的網絡結構如下圖所示:

圖12 YOLO網絡結構

  YOLO的最后一層采用線性激活函數,其它層都是Leaky ReLU。訓練中采用了drop out和數據增強(data augmentation)來防止過擬合。更多細節請參考原論文。

8)預測(inference)
  訓練好的YOLO網絡,輸入一張圖片,將輸出一個 7*7*30 的張量(tensor)來表示圖片中所有網格包含的對象(概率)以及該對象可能的2個位置(bounding box)和可信程度(置信度)。
為了從中提取出最有可能的那些對象和位置,YOLO采用NMS(Non-maximal suppression,非極大值抑制)算法。

9)NMS(非極大值抑制)
  NMS方法並不復雜,其核心思想是:選擇得分最高的作為輸出,與該輸出重疊的去掉,不斷重復這一過程直到所有備選處理完。

  YOLO的NMS計算方法如下。
  網絡輸出的7*7*30的張量,在每一個網格中,對象C_i位於第j個bounding box的得分:
Score_{ij} = P(C_i|Object) * Confidence_j
  它代表着某個對象C_i存在於第j個bounding box的可能性。

  每個網格有:20個對象的概率*2個bounding box的置信度,共40個得分(候選對象)。49個網格共1960個得分。Andrew Ng建議每種對象分別進行NMS,那么每種對象有 1960/20=98 個得分。

  NMS步驟如下:
    1)設置一個Score的閾值,低於該閾值的候選對象排除掉(將該Score設為0)
    2)遍歷每一個對象類別
      2.1)遍歷該對象的98個得分
        2.1.1)找到Score最大的那個對象及其bounding box,添加到輸出列表
        2.1.2)對每個Score不為0的候選對象,計算其與上面2.1.1輸出對象的bounding box的IOU
        2.1.3)根據預先設置的IOU閾值,所有高於該閾值(重疊度較高)的候選對象排除掉(將Score設為0)(避免同一對象的重復檢測,一個對象只允許存在一個bounding box中)
        2.1.4)如果所有bounding box要么在輸出列表中,要么Score=0,則該對象類別的NMS完成,返回步驟2處理下一種對象
    3)輸出列表即為預測的對象

10)小結
  YOLO以速度見長,處理速度可以達到45fps,其快速版本(網絡較小)甚至可以達到155fps。這得益於其識別和定位合二為一的網絡設計,而且這種統一的設計也使得訓練和預測可以端到端的進行,非常簡便。
  不足之處是小對象檢測效果不太好(尤其是一些聚集在一起的小對象),對邊框的預測准確度不是很高,總體預測精度略低於Fast RCNN。主要是因為網格設置比較稀疏,而且每個網格只預測兩個邊框,另外Pooling層會丟失一些細節信息,對定位存在影響。
  更多細節請參考原論文。

參考

You Only Look Once: Unified, Real-Time Object Detection
Andrew Ng的深度學習工程師 - 04卷積神經網絡
圖解YOLO
你真的讀懂yolo了嗎?
目標檢測|YOLO原理與實現

 

轉自:https://www.jianshu.com/p/cad68ca85e27


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM