吳恩達深度學習筆記(99)-目標檢測之Anchor Boxes

Anchor Boxes

到目前為止,對象檢測中存在的一個問題是每個格子只能檢測出一個對象,如果你想讓一個格子檢測出多個對象,你可以這麼做,就是使用anchor box這個概念。

我們還是先吃一顆栗子:

吳恩達深度學習筆記(99)-目標檢測之Anchor Boxes

假設你有這樣一張圖片,對於這個例子,我們繼續使用3×3網格,注意行人的中點和汽車的中點幾乎在同一個地方,兩者都落入到同一個格子中。

所以對於那個格子,如果 y 輸出這個向量y

吳恩達深度學習筆記(99)-目標檢測之Anchor Boxes

你可以檢測這三個類別,行人、汽車和摩托車,它將無法輸出檢測結果,所以我必須從兩個檢測結果中選一個。

吳恩達深度學習筆記(99)-目標檢測之Anchor Boxes

而anchor box的思路是:預先定義兩個不同形狀的anchor box,或者anchor box形狀,你要做的是把預測結果和這兩個anchor box關聯起來。一般來說,你可能會用更多的anchor box,可能要5個甚至更多,但對於這個筆記中,我們就用兩個anchor box,這樣介紹起來簡單一些。

吳恩達深度學習筆記(99)-目標檢測之Anchor Boxes

你要做的是定義類別標籤,用的向量不再是上面這個:

吳恩達深度學習筆記(99)-目標檢測之Anchor Boxes

而是重複兩次:

吳恩達深度學習筆記(99)-目標檢測之Anchor Boxes

前面的p_c,b_x,b_y,b_h,b_w,c_1,c_2,c_3(綠色方框標記的參數)是和anchor box 1關聯的8個參數,後面的8個參數(橙色方框標記的元素)是和anchor box 2相關聯。

因為行人的形狀更類似於anchor box 1的形狀,而不是anchor box 2的形狀,所以你可以用這8個數值(前8個參數),這麼編碼p_c=1,是的,代表有個行人,用b_x,b_y,b_h和b_w來編碼包住行人的邊界框,然後用c_1,c_2,c_3(c_1=1,c_2=0,c_3=0)來說明這個對象是個行人。

然後是車子,因為車子的邊界框比起anchor box 1更像anchor box 2的形狀,你就可以這麼編碼,這裡第二個對象是汽車,然後有這樣的邊界框等等,這裡所有參數都和檢測汽車相關(p_c=1,b_x,b_y,b_h,b_w,c_1=0,c_2=1,c_3=0)。

吳恩達深度學習筆記(99)-目標檢測之Anchor Boxes

總結一下,用anchor box之前,你做的是這個,對於訓練集圖像中的每個對象,都根據那個對象中點位置分配到對應的格子中,所以輸出y就是3×3×8,因為是3×3網格,對於每個網格位置,我們有輸出向量,包含p_c,然後邊界框參數b_x,b_y,b_h和b_w,然後c_1,c_2,c_3。

現在用到anchor box這個概念,是這麼做的。

現在每個對象都和之前一樣分配到同一個格子中,分配到對象中點所在的格子中,以及分配到和對象形狀交併比最高的anchor box中。所以這裡有兩個anchor box,你就取這個對象,如果你的對象形狀是這樣的(編號1,紅色框),你就看看這兩個anchor box,anchor box 1形狀是這樣(編號2,紫色框),anchor box 2形狀是這樣(編號3,紫色框),然後你觀察哪一個anchor box和實際邊界框(編號1,紅色框)的交併比更高,不管選的是哪一個,這個對象不只分配到一個格子,而是分配到一對,即(grid cell,anchor box)對,這就是對象在目標標籤中的編碼方式。

所以現在輸出 y 就是3×3×16,上一張幻燈片中你們看到 y 現在是16維的,或者你也可以看成是3×3×2×8,因為現在這裡有2個anchor box,而 y 是8維的。y 維度是8,因為我們有3個對象類別,如果你有更多對象,那麼y 的維度會更高。

吳恩達深度學習筆記(99)-目標檢測之Anchor Boxes

所以我們來看一個具體的例子,對於這個格子(編號2),我們定義一下y,:

吳恩達深度學習筆記(99)-目標檢測之Anchor Boxes

所以行人更類似於anchor box 1的形狀,所以對於行人來說,我們將她分配到向量的上半部分。是的,這裡存在一個對象,即p_c=1,有一個邊界框包住行人,如果行人是類別1,那麼 c_1=1,c_2=0,c_3=0(編號1所示的橙色參數)。車子的形狀更像anchor box 2,所以這個向量剩下的部分是 p_c=1,然後和車相關的邊界框,然後c_1=0,c_2=1,c_3=0(編號1所示的綠色參數)。所以這就是對應中下格子的標籤 y,這個箭頭指向的格子(編號2所示)。

現在其中一個格子有車,沒有行人,如果它裡面只有一輛車,那麼假設車子的邊界框形狀是這樣,更像anchor box 2,如果這裡只有一輛車,行人走開了,那麼anchor box 2分量還是一樣的,要記住這是向量對應anchor box 2的分量和anchor box 1對應的向量分量,你要填的就是,裡面沒有任何對象,所以 p_c=0,然後剩下的就是don’t care-s(即?)(編號3所示)。

現在還有一些額外的細節,如果你有兩個anchor box,但在同一個格子中有三個對象,這種情況算法處理不好,你希望這種情況不會發生,但如果真的發生了,這個算法並沒有很好的處理辦法,對於這種情況,我們就引入一些打破僵局的默認手段。

還有這種情況,兩個對象都分配到一個格子中,而且它們的anchor box形狀也一樣,這是算法處理不好的另一種情況,你需要引入一些打破僵局的默認手段,專門處理這種情況,希望你的數據集裡不會出現這種情況,其實出現的情況不多,所以對性能的影響應該不會很大。

這就是anchor box的概念,我們建立anchor box這個概念,是為了處理兩個對象出現在同一個格子的情況,實踐中這種情況很少發生,特別是如果你用的是19×19網格而不是3×3的網格,兩個對象中點處於361個格子中同一個格子的概率很低,確實會出現,但出現頻率不高

也許設立anchor box的好處在於anchor box能讓你的學習算法能夠更有徵對性,特別是如果你的數據集有一些很高很瘦的對象,比如說行人,還有像汽車這樣很寬的對象,這樣你的算法就能更有針對性的處理,這樣有一些輸出單元可以針對檢測很寬很胖的對象,比如說車子,然後輸出一些單元,可以針對檢測很高很瘦的對象,比如說行人。

最後,你應該怎麼選擇anchor box呢?

人們一般手工指定anchor box形狀,你可以選擇5到10個anchor box形狀,覆蓋到多種不同的形狀,可以涵蓋你想要檢測的對象的各種形狀。還有一個更高級的版本,我就簡單說一句,你們如果接觸過一些機器學習,可能知道後期YOLO論文中有更好的做法,就是所謂的k-平均算法,可以將兩類對象形狀聚類,如果我們用它來選擇一組anchor box,選擇最具有代表性的一組anchor box,可以代表你試圖檢測的十幾個對象類別,但這其實是自動選擇anchor box的高級方法。如果你就人工選擇一些形狀,合理的考慮到所有對象的形狀,你預計會檢測的很高很瘦或者很寬很胖的對象,這應該也不難做。

所以這就是anchor box,在下一個筆記中,我們把學到的所有東西一起融入到YOLO算法中。


分享到:


相關文章: