一、目標定位
這一小節視頻主要介紹了我們在實現目標定位時標簽該如何定義。

上圖左下角給出了損失函數的計算公式(這里使用的是平方差)
如圖示,加入我們需要定位出圖像中是否有pedestrian,car,motorcycles。注意在這里我們假設圖像中只肯呢個存在這三者中的一種或者都不存在,所以共有四種可能。
- \(P_c=1\)表示有三者中的一種
- \(C_1=1\)表示有pedestrian,反之沒有
- \(C_2=1\)表示有car
- \(C_3=1\)表示有motorcycles
- \(b_*\)用於標識所識別食物的位置
- \(b_x,b_y\):表示識別物體的中心坐標
- \(b_w,b_h\):表示識別物體的寬和高

注意:\(P_c=0\)表示三者都沒有,所以此時\(C_*,b_*\)的值我們並不在乎了。
二、特征點檢測
這一節的內容和上一節感覺很類似,所有就沒有記得很詳細了

三、目標檢測

目標檢測常使用的是滑動窗口技術檢測,即使用一定大小的窗口按照指定的步長對圖像進行遍歷


因為圖像中車輛的大小我們是不知道的,所以可以更改窗口大小,從而識別並定位出車輛的位置。


四、卷積的滑動窗口實現
注意:該節視頻的例子和上一節一樣,都是識別圖像中是否有pedestrian,car,motorcycles,background,所以最后輸出y是4個節點
1.全連接層→卷積層
在介紹卷積滑動窗口之前我們首先要知道如何把神經網絡的全連接層轉化成卷積層,下面是使用了全連接層的網絡結構

那么如何將全連接層轉化成卷積層呢?如下圖示

第二個FC層也是400個節點,由之前的1*1過濾器的特點,我們可以使用400個1*1的過濾器,也可以得到(1,1,400)的矩陣。至此,我們已經成功將全連接層轉化成了卷積層。
2.卷積滑動窗口實現
目標檢測一節中介紹了滑動窗口。要實現窗口遍歷,那么就需要很大的計算量,看起來似乎可操作性不強。But!這怎么可能難倒哪些newB的大神們呢,他們自然有辦法。
首先我們先看下圖,這個就是上面提到的將全連接層轉化成卷積層的示意圖,只不過畫的看起來更正規一些了2333,但是有個需要提醒的是吳大大為了方便只花了平面圖,就沒有畫出3D的效果了。

下面,假設我們的測試圖大小是16*16,並令滑動窗口大小是14*14的(為了方便理解,下圖用藍色清楚地表明了14*14窗口的大小),步長是2,所以這個測試圖可以被窗口划分成4個部分。隨后和上面執行一樣的操作,最后可以得到(2,2,4)的矩陣,此時我們不難看出測試圖被滑動窗口選取的左上角部分對應的結果也是輸出矩陣的左上角部分,其他3個部分同理。
所以這說明了什么?
說明我們沒有必要用滑動窗口截取一部分,然后帶入卷積網絡運算。相反我們可以整體進行運算,這樣速度就快很多了。

下圖很清楚的展示了卷積滑動窗口的實現。我們可以看到圖片被划分成了64塊


五、Bounding Box預測
上面介紹的滑動窗口方法存在一個問題就是很多情況下滑動窗口並不能很好的切割出車體,如下圖示:

為了解決這個問題,就有了YOLO(you only look once)算法,即只需要計算一次便可確定需要識別物體的位置的大小。
原理如下:
首先將圖像划分成3*3(即9份),每一份最后由一個向量表示,這個向量在本文最前面介紹過,即\(y=[P_c,b_x,b_y,b_h,b_w,c_1,c_2,c_3]\)

因為有9份,所以最后輸出矩陣大小是(3,3,8),如下圖示:

那么如何構建卷積網絡呢?
輸入矩陣是(100,100,3),然后是Conv,Maxpool層,……,最后只要確保輸出矩陣大小是(3,3,8)即可。

下圖是以右邊的車輛作為示例介紹該車輛所在框的輸出矩陣
- 很顯然\(P_c=1\),
- 然后\(b_x,b_y\)的值是右邊車輛的中心點相對於該框的位置,所以它們的值是一定小於1的,我們可以很容易的得到近似值\(b_x=0.4,b_y=0.3\)。
- \(b_h,b_w\)的值同理也是車輛的寬高相對於其所在框的比例,但是要注意的是這兩個值是可以大於1的,因為有可能部分車身在框外。但是也可以使用sigmoid函數將值控制在1以內。

六、交並比(Intersection over Union, IoU)
前面說到了實現目標定位時可能存在滑動窗口與真實邊框存在出入,如下圖示:
紅色框是車身邊界,紫色框是滑動窗口,那么此窗口返回的值是有車還是無車呢?

為了解決上面的問題引入了交並比(IoU),也就是兩個框之間的交集與並集之比,依據這個值可以評價定位算法是否精准。
示意圖如下,黃色區域表示紫色框和紅色框的交集,綠色區域表示紫色框和紅色框的並集,交並比(IoU)就等於黃色區域大小比上綠色區域大小。
如果\(IoU\geq0.5\),則表示紫色框中有車輛,反之沒有。
當然0.5這個閾值是人為設定的,沒有深入的科學探究,所以如果希望結果更加精確,也可以用0.6或0.7設為閾值,但是不建議用小於0.5的閾值。

七、非極大值抑制
1.算法大致思路
前面Bounding Box一節中介紹到將圖片划分成若干等分,例如3*3,那么一共就有9塊,如下圖示,我們可以很清楚的看到第二行第一塊和第三塊都有車,所以可以標出一個中心點坐標(\(b_x,b_y\)),這樣我們就能通過最終的輸出結果知道這兩個框中有車。

但是如果我們划分的數量變多之后呢?如下圖示划分成了19*19,圖中標出的3個黃框和3個綠框最終結果都會都會返回[\(P_x=1,b_x=,b_y=……\)],但是最后我們該信誰的呢?是這三個框真的有車,而且還不是同一輛車?還是只是同一輛車?所以就有了非極大值抑制來解決這個問題。

其思路大致如下(為了方便說明和理解,我們不使用19*19的方框):
- 首先每個框會對是否有目標返回一個\(P_c\)的概率值(也可以是\(P_c*C_1*C_2*C_3\)的概率之積),如下圖示:

- 然后找到\(P_c\)最大的一個框,顯然0.9的框有車的概率最大,所以該邊框顏色高亮

- 然后算法遍歷其他邊框,找出與上一個邊框的交並比大於0.5的邊框,很顯然右邊的剩余兩個邊框符合條件,所以這兩個邊框變暗

左邊的車同理,不加贅述

下面結合一個例子總結一下非極大值抑制算法的實現步驟:
注:在這里假設只需要識別定位車輛即可,所以輸出格式為[\(P_c,b_x,b_y,b_h,b_w\)]
這個例子中將圖像划分成19*19方格,假設每個方格都已經計算出\(P_c\)的概率值
1.去掉所有滿足\(P_c\leq0.6\)的方格 (0.6也可以進行人為修改)
2.對剩下的方格進行如下循環操作:
- 從剩下的方格中選取\(P_c\)最大的一個作為預測值輸出,假設這個方格為A
- 將與A方格交並比大於0.5的剔除

八、Anchor Boxes
前面介紹了那么多,都只是識別單個物體,如果要同時識別多個物體該怎么辦呢?而且識別的不同物體的中心點在同一個框中又該怎么呢(如下圖示,人和車的中心都在紅點位置,處於同一個框中)?這時就需要使用Anchor Boxes了。

Anchor Boxes的思路是對於不同的物體事先采用不同的框,例如人相對於車屬於瘦高的,所以使用下圖中的Anchor Box 1,相反車輛就使用Anchor Box 2.
之前的輸出值的格式都是\(y=[P_x,b_x,b_y,b_h,b_w,C_1,C_2,C_3]\),最后輸出的矩陣大小(以該圖為例)是(3,3,8),但是這樣只能確定一個物體。
所以為了同時檢測不同物體,很自然的我們可以重復輸出這個上面的值即可,即\(y=[P_x,b_x,b_y,b_h,b_w,C_1,C_2,C_3,P_x,b_x,b_y,b_h,b_w,C_1,C_2,C_3]\),所以輸出矩陣是(3,3,16),也可以是(3,3,2,8)。
要注意的是我們需要提前設定好輸出值前面的值對應Anchor Box 1,后面的對應Anchor Box 2.
例如我們得到了圖中人的邊框信息值,然后經過計算發現其邊框與Anchor Box 1更為接近,所以最后將人的邊框信息對應在前面,同理車輛邊框信息對應在后面。

總結起來Anchor Box算法和之前的算法區別如下:
- 之前的算法:
對於訓練集圖像中的每個對象,都根據那個對象的中點位置分配到對應的格子中,所以在上面的示例中輸出y就是(3,3,8)
- Anchor Boxes算法
現在每個對象都和之前一樣分配到同一個格子中,即對象中心所在的格子。不同的是也需要分配到和對象形狀交並比最高的Anchor Box.
例如下圖中的紅色框不僅要分配到其中心所在的圖像上的格子中,而且還需要分配到與其交並比最大的Anchor Box中,即豎條的紫色方格

回到本小節最開始的例子,最后的輸出值如下圖示:
圖中人的對應Anchor Box 1, 輸出值對應圖中的黃色字體;車輛同理,對應綠色字體
