【54】目標檢測之Bounding Box預測


Bounding Box預測(Bounding box predictions)

在上一篇筆記中,你們學到了滑動窗口法的卷積實現,這個算法效率更高,但仍然存在問題,不能輸出最精准的邊界框。在這個筆記中,我們看看如何得到更精准的邊界框。

 

在滑動窗口法中,你取這些離散的位置集合,然后在它們上運行分類器,在這種情況下,這些邊界框沒有一個能完美匹配汽車位置,也許這個框(編號1)是最匹配的了。還有看起來這個真實值,最完美的邊界框甚至不是方形,稍微有點長方形(紅色方框所示),長寬比有點向水平方向延伸,有沒有辦法讓這個算法輸出更精准的邊界框呢?

其中一個能得到更精准邊界框的算法是YOLO算法,YOLO(You only look once)意思是你只看一次,這是由Joseph Redmon,Santosh Divvala,Ross Girshick和Ali Farhadi提出的算法。

這個算法是這么做的:

比如你的輸入圖像是100×100的,然后在圖像上放一個網格。為了介紹起來簡單一些,我用3×3網格,實際實現時會用更精細的網格,可能是19×19。基本思路是使用圖像分類和定位算法(前幾個筆記中介紹過的),然后將算法應用到9個格子上。(基本思路是,采用圖像分類和定位算法,本周第一個筆記介紹過的,逐一應用在圖像的9個格子中。)

更具體一點,你需要這樣定義訓練標簽,所以對於9個格子中的每一個指定一個標簽y,y是8維的,和你之前看到的一樣,

p_c等於0或1取決於這個綠色格子中是否有圖像。

然后b_x、b_y、b_h和b_w作用就是,如果那個格子里有對象,那么就給出邊界框坐標。

然后c_1、c_2和c_3就是你想要識別的三個類別,背景類別不算,所以你嘗試在背景類別中識別行人、汽車和摩托車,那么c_1、c_2和c_3可以是行人、汽車和摩托車類別。這張圖里有9個格子,所以對於每個格子都有這么一個向量。

我們看看左上方格子,這里這個(編號1),里面什么也沒有,所以左上格子的標簽向量y是

然后這個格子(編號2)的輸出標簽y也是一樣,這個格子(編號3),還有其他什么也沒有的格子都一樣。

現在這個格子呢?

講的更具體一點,這張圖有兩個對象,YOLO算法做的就是,取兩個對象的中點,然后將這個對象分配給包含對象中點的格子

所以左邊的汽車就分配到這個格子上(編號4),然后這輛Condor(車型:神鷹)中點在這里,分配給這個格子(編號6)。所以即使中心格子(編號5)同時有兩輛車的一部分,我們就假裝中心格子沒有任何我們感興趣的對象,所以對於中心格子,分類標簽y和這個向量類似,和這個沒有對象的向量類似,即

 

而對於這個格子,這個用綠色框起來的格子(編號4),目標標簽就是這樣的,這里有一個對象,p_c=1,然后你寫出b_x、b_y、b_h和b_w來指定邊界框位置,然后還有

類別1是行人,那么c_1=0,

類別2是汽車,所以c_2=1,

類別3是摩托車,則數值c_3=0,即

右邊這個格子(編號6)也是類似的,因為這里確實有一個對象,它的向量應該是這個樣子的,

作為目標向量對應右邊的格子。

所以對於這里9個格子中任何一個,你都會得到一個8維輸出向量,因為這里是3×3的網格,所以有9個格子,總的輸出尺寸是3×3×8,所以目標輸出是3×3×8。因為這里有3×3格子,然后對於每個格子,你都有一個8維向量y,所以目標輸出尺寸是3×3×8。

對於這個例子中,左上格子是1×1×8,對應的是9個格子中左上格子的輸出向量。所以對於這3×3中每一個位置而言,對於這9個格子,每個都對應一個8維輸出目標向量y,其中一些值可以是dont care-s(即?),如果這里沒有對象的話。所以總的目標輸出,這個圖片的輸出標簽尺寸就是3×3×8。

如果你現在要訓練一個輸入為100×100×3的神經網絡,現在這是輸入圖像,然后你有一個普通的卷積網絡,卷積層,最大池化層等等,最后你會有這個,選擇卷積層和最大池化層,這樣最后就映射到一個3×3×8輸出尺寸。

所以你要做的是,有一個輸入x,就是這樣的輸入圖像,然后你有這些3×3×8的目標標簽y。當你用反向傳播訓練神經網絡時,將任意輸入x映射到這類輸出向量y。

所以這個算法的優點在於神經網絡可以輸出精確的邊界框,所以測試的時候,你做的是喂入輸入圖像x,然后跑正向傳播,直到你得到這個輸出y。然后對於這里3×3位置對應的9個輸出,我們在輸出中展示過的,你就可以讀出1或0(編號1位置),你就知道9個位置之一有個對象。如果那里有個對象,那個對象是什么(編號3位置),還有格子中這個對象的邊界框是什么(編號2位置)。只要每個格子中對象數目沒有超過1個,這個算法應該是沒問題的。一個格子中存在多個對象的問題,我們稍后再討論。但實踐中,我們這里用的是比較小的3×3網格,實踐中你可能會使用更精細的19×19網格,所以輸出就是19×19×8。這樣的網格精細得多,那么多個對象分配到同一個格子得概率就小得多。

重申一下,把對象分配到一個格子的過程是,你觀察對象的中點,然后將這個對象分配到其中點所在的格子,所以即使對象可以橫跨多個格子,也只會被分配到9個格子其中之一,就是3×3網絡的其中一個格子,或者19×19網絡的其中一個格子。在19×19網格中,兩個對象的中點(圖中藍色點所示)處於同一個格子的概率就會更低

所以要注意,首先這和圖像分類和定位算法非常像,我們在本周第一節課講過的,就是它顯式地輸出邊界框坐標,所以這能讓神經網絡輸出邊界框,可以具有任意寬高比,並且能輸出更精確的坐標,不會受到滑動窗口分類器的步長大小限制。其次,這是一個卷積實現,你並沒有在3×3網格上跑9次算法,或者,如果你用的是19×19的網格,19平方是361次,所以你不需要讓同一個算法跑361次。相反,這是單次卷積實現,但你使用了一個卷積網絡,有很多共享計算步驟,在處理這3×3計算中很多計算步驟是共享的,或者你的19×19的網格,所以這個算法效率很高。

事實上YOLO算法有一個好處,也是它受歡迎的原因,因為這是一個卷積實現,實際上它的運行速度非常快,可以達到實時識別。在結束之前我還想給你們分享一個小細節,如何編碼這些邊界框b_x、b_y、b_h和b_w,我們在下一張圖上討論。

這里有兩輛車,我們有個3×3網格,我們以右邊的車為例(編號1),紅色格子里有個對象,所以目標標簽y就是,p_c=1,然后b_x、b_y、b_h和b_w,然后c_1=0,c_2=1,c_3=0,即

你怎么指定這個邊界框呢?

Specify the bounding boxes:

在YOLO算法中,對於這個方框(編號1所示),我們約定左上這個點是(0,0),然后右下這個點是(1,1),要指定橙色中點的位置,b_x大概是0.4,因為它的位置大概是水平長度的0.4,然后b_y大概是0.3,然后邊界框的高度用格子總體寬度的比例表示,所以這個紅框的寬度可能是藍線(編號2所示的藍線)的90%,所以b_h是0.9,它的高度也許是格子總體高度的一半,這樣的話b_w就是0.5。換句話說,b_x、b_y、b_h和b_w單位是相對於格子尺寸的比例,所以b_x和b_y必須在0和1之間,因為從定義上看,橙色點位於對象分配到格子的范圍內,如果它不在0和1之間,如果它在方塊外,那么這個對象就應該分配到另一個格子上。這個值(b_h和b_w)可能會大於1,特別是如果有一輛汽車的邊界框是這樣的(編號3所示),那么邊界框的寬度和高度有可能大於1。

指定邊界框的方式有很多,但這種約定是比較合理的,如果你去讀YOLO的研究論文,YOLO的研究工作有其他參數化的方式,可能效果會更好,我這里就只給出了一個合理的約定,用起來應該沒問題。不過還有其他更復雜的參數化方式,涉及到sigmoid函數,確保這個值(b_x和b_y)介於0和1之間,然后使用指數參數化來確保這些(b_h和b_w)都是非負數,因為0.9和0.5,這個必須大於等於0。還有其他更高級的參數化方式,可能效果要更好一點,但我這里講的辦法應該是管用的。

這就是YOLO算法,你只看一次算法,在接下來的幾個筆記中,我會告訴你一些其他的思路可以讓這個算法做的更好。在此期間,如果你感興趣,也可以看看YOLO的論文,在前幾張幻燈片底部引用的YOLO論文(Redmon, Joseph, et al. "You Only Look Once: Unified, Real-Time Object Detection." (2015):779-788.)

 


免責聲明!

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



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