目標(biāo)檢測(cè)與YOLO算法(用Python實(shí)現(xiàn)目標(biāo)檢測(cè))
最近在聽Andrew Ng講解目標(biāo)檢測(cè)的視頻,包括目標(biāo)定位,特征點(diǎn)檢測(cè),卷積的滑動(dòng)窗口的實(shí)現(xiàn),Bounding Box預(yù)測(cè),交并比,非極大值抑制,AnchorBoxes,YOLO算法以及候選區(qū)域,并通過(guò)查閱相關(guān)的資料,對(duì)以上內(nèi)容有了初步的理解,趁熱打鐵,總結(jié)如下。
一、目標(biāo)定位(Object Localization)
圖片分類:圖片分類問(wèn)題已經(jīng)不陌生了,例如,輸入一張圖片到多層卷積神經(jīng)網(wǎng)絡(luò),它會(huì)輸出一個(gè)特征向量,并反饋給softmax單元來(lái)預(yù)測(cè)圖片的類型。
定位分類問(wèn)題:不僅要用算法判斷出圖中是否有一輛汽車,而且還要標(biāo)注汽車的位置,一般用邊框(Bounding Box)來(lái)標(biāo)注。通常只有一個(gè)較大的對(duì)象位于圖片的中間位置,我們要對(duì)它進(jìn)識(shí)別和定位。
對(duì)象檢測(cè)問(wèn)題:圖片可以含有多個(gè)對(duì)象 ,甚至單張圖片會(huì)有多個(gè)不同的分類對(duì)象。因此圖像分類的思路可以幫助我們學(xué)習(xí)對(duì)象定位,而對(duì)象定位的思路又可以幫助我們學(xué)習(xí)對(duì)象檢測(cè)。


舉個(gè)栗子(example):
如果你正在構(gòu)建汽車自動(dòng)駕駛系統(tǒng),那么對(duì)象可以包括以下幾類:行人、汽車、摩托車和背景,背景就是圖片中沒有行人、汽車、摩托車三類對(duì)象,輸出結(jié)果便會(huì)是背景對(duì)象,這四個(gè)對(duì)象就是softmax函數(shù)可能輸出的結(jié)果,這就是目標(biāo)分類的過(guò)程。但是如果你還想定位圖片中的位置,該怎么做呢?我們可以讓神經(jīng)網(wǎng)絡(luò)多輸出幾個(gè)單元,輸出一個(gè)邊界框。具體說(shuō)就是讓神經(jīng)網(wǎng)絡(luò)再多輸出 4 個(gè)數(shù)字,標(biāo)記,,,這四個(gè)數(shù)字是被檢測(cè)對(duì)象的邊界框的參數(shù)化表示。

圖片的左上角是(0,0),右下角是(1,1),要確定邊界框的具體位置,需要指定紅色方框的中心點(diǎn),這個(gè)點(diǎn)表示為 ( ,),邊界框的高度為,寬度為。因此訓(xùn)練集不僅包含神經(jīng)網(wǎng)絡(luò)要預(yù)測(cè)的對(duì)象分類標(biāo)簽,還要包含表示邊界框的這四個(gè)數(shù)字,接著采用監(jiān)督學(xué)習(xí)算法,輸出一個(gè)分類標(biāo)簽,還有四個(gè)參數(shù)值,從而給出檢測(cè)對(duì)象的邊框位置。此例中, 的理想值是 0.5,大約是 0.7,約為 0.3,約為 0.4。
目標(biāo)標(biāo)簽y的定義如下:

它是一個(gè)向量,第一個(gè)組件表示是否含有對(duì)象,如果對(duì)象屬于前三類(行人,汽車,摩托車),則 = 1,如果是背景,則圖片中沒有要檢測(cè)的對(duì)象,則 = 0,我們可以這樣理解,它表示被檢測(cè)對(duì)象屬于某一分類的概率,背景分類除外。,,表示對(duì)象屬于1-3類的哪一類,是行人,汽車,還是摩托車。神經(jīng)網(wǎng)絡(luò)中的損失函數(shù),其參數(shù)為類別y和網(wǎng)絡(luò)輸出,如果采用平方誤差策略,則:損失值等于每個(gè)元素相應(yīng)差值的平方和。當(dāng) = 1時(shí),平方誤差策略可以減少這 8 個(gè)元素預(yù)測(cè)值和實(shí)際輸出結(jié)果之間差值的平方。當(dāng)時(shí),y矩陣中的后 7 個(gè)元素都不用考慮,只需要考慮神經(jīng)網(wǎng)絡(luò)評(píng)估y1y1(即pcpc)的準(zhǔn)確度。
實(shí)際應(yīng)用中,你可以對(duì),,和 softmax 激活函數(shù)應(yīng)用對(duì)數(shù)損失函數(shù),并輸出其中一個(gè)元素值,通常做法是對(duì)邊界框坐標(biāo)應(yīng)用平方差或類似方法,對(duì)應(yīng)用邏輯回歸函數(shù),甚至采用平方預(yù)測(cè)誤差也是可以的。
二、特征點(diǎn)檢測(cè)
上面,我們講了如何利用神經(jīng)網(wǎng)絡(luò)進(jìn)行對(duì)象定位,即通過(guò)輸出四個(gè)參數(shù)值,,和給出圖片中對(duì)象的邊界框。更概括地說(shuō),神經(jīng)網(wǎng)絡(luò)可以通過(guò)輸出圖片上特征點(diǎn)的(x,y)坐標(biāo)來(lái)實(shí)現(xiàn)對(duì)目標(biāo)特征的識(shí)別,我們看幾個(gè)例子。

假設(shè)你正在構(gòu)建一個(gè)人臉識(shí)別應(yīng)用,出于某種原因,你希望算法可以給出眼角的具體位置。眼角坐標(biāo)為(x,y),你可以讓神經(jīng)網(wǎng)絡(luò)的最后一層多輸出兩個(gè)數(shù)字和,作為眼角的坐標(biāo)值。如果你想知道兩只眼睛的四個(gè)眼角的具體位置,那么從左到右,依次用四個(gè)特征點(diǎn)來(lái)表示這四個(gè)眼角。對(duì)神經(jīng)網(wǎng)絡(luò)稍做些修改,輸出第一個(gè)特征點(diǎn)(,)第二個(gè)特征點(diǎn)(,),依此類推,這四個(gè)臉部特征點(diǎn)的位置就可以通過(guò)神經(jīng)網(wǎng)絡(luò)輸出了。

也許除了這四個(gè)特征點(diǎn),你還想得到更多的特征點(diǎn)輸出值,這些(圖中眼眶上的紅色特征點(diǎn))都是眼睛的特征點(diǎn),你還可以根據(jù)嘴部的關(guān)鍵點(diǎn)輸出值來(lái)確定嘴的形狀,從而判斷人物是在微笑還是皺眉,也可以提取鼻子周圍的關(guān)鍵特征點(diǎn)。為了便于說(shuō)明,你可以設(shè)定特征點(diǎn)的個(gè)數(shù),假設(shè)臉部有 64 個(gè)特征點(diǎn),有些點(diǎn)甚至可以幫助你定義臉部輪廓或下頜輪廓。選定特征點(diǎn)個(gè)數(shù),并生成包含這些特征點(diǎn)的標(biāo)簽訓(xùn)練集,然后利用神經(jīng)網(wǎng)絡(luò)輸出臉部關(guān)鍵特征點(diǎn)的位置。
具體做法是,準(zhǔn)備一個(gè)卷積網(wǎng)絡(luò)和一些特征集,將人臉圖片輸入卷積網(wǎng)絡(luò),輸出1或0,1表示有人臉,0表示沒有人臉,然后輸出(,) ……直到(,)。這里我用l代表一個(gè)特征,這里有 129個(gè)輸出單元,其中1表示圖片中有人臉,因?yàn)橛?64個(gè)特征,64×2=128,所以最終輸出 128+1=129 個(gè)單元,由此實(shí)現(xiàn)對(duì)圖片的人臉檢測(cè)和定位。這只是一個(gè)識(shí)別臉部表情的基本構(gòu)造模塊,如果你玩過(guò) Snapchat 或其它娛樂(lè)類應(yīng)用,你應(yīng)該對(duì) AR(增強(qiáng)現(xiàn)實(shí))過(guò)濾器多少有些了解, Snapchat 過(guò)濾器實(shí)現(xiàn)了在臉上畫皇冠和其他一些特殊效果。檢測(cè)臉部特征也是計(jì)算機(jī)圖形效果的一個(gè)關(guān)鍵構(gòu)造模塊,比如實(shí)現(xiàn)臉部扭曲,頭戴皇冠等等。當(dāng)然為了構(gòu)建這樣的網(wǎng)絡(luò),你需要準(zhǔn)備一個(gè)標(biāo)簽訓(xùn)練集,也就是圖片和標(biāo)簽的集合,這些點(diǎn)都是人為辛苦標(biāo)注的。

最后一個(gè)例子,如果你對(duì)人體姿態(tài)檢測(cè)感興趣,你還可以定義一些關(guān)鍵特征點(diǎn),如胸部的中點(diǎn),左肩,左肘,腰等等。然后通過(guò)神經(jīng)網(wǎng)絡(luò)標(biāo)注人物姿態(tài)的關(guān)鍵特征點(diǎn),再輸出這些標(biāo)注過(guò)的特征點(diǎn),就相當(dāng)于輸出了人物的姿態(tài)動(dòng)作。當(dāng)然,要實(shí)現(xiàn)這個(gè)功能,你需要設(shè)定這些關(guān)鍵特征點(diǎn),從胸部中心點(diǎn)(,)一直往下,直到(,)。
三、目標(biāo)檢測(cè)(多個(gè)目標(biāo))
學(xué)過(guò)了對(duì)象定位和特征點(diǎn)檢測(cè),我們來(lái)構(gòu)建一個(gè)對(duì)象檢測(cè)算法。我們將學(xué)習(xí)如何通過(guò)卷積網(wǎng)絡(luò)進(jìn)行對(duì)象檢測(cè),采用的是基于滑動(dòng)窗口的目標(biāo)檢測(cè)算法。

假如你想構(gòu)建一個(gè)汽車檢測(cè)算法,步驟是,首先創(chuàng)建一個(gè)標(biāo)簽訓(xùn)練集,也就是x和y表示適當(dāng)剪切的汽車圖片樣本,這張圖片(編號(hào) 1)x是一個(gè)正樣本. ,因?yàn)樗且惠v汽車圖片,這幾張圖片(編號(hào) 2、 3)也有汽車,但這兩張(編號(hào) 4、 5)沒有汽車。出于我們對(duì)這個(gè)訓(xùn)練集的期望,你一開始可以使用適當(dāng)剪切的圖片,就是整張圖片幾乎都被汽車占據(jù),你可以照張照片,然后剪切,剪掉汽車以外的部分,使汽車居于中間位置,并基本占據(jù)整張圖片。有了這個(gè)標(biāo)簽訓(xùn)練集,你就可以開始訓(xùn)練卷積網(wǎng)絡(luò)了,輸入這些適當(dāng)剪切過(guò)的圖片(編號(hào) 6),卷積網(wǎng)絡(luò)輸出y, 0 或 1 表示圖片中有汽車或沒有汽車。訓(xùn)練完這個(gè)卷積網(wǎng)絡(luò),就可以用它來(lái)實(shí)現(xiàn)滑動(dòng)窗口目標(biāo)檢測(cè),具體步驟如下:

假設(shè)這是一張測(cè)試圖片,首先選定一個(gè)特定大小的窗口,比如圖片下方這個(gè)窗口,將這個(gè)紅色小方塊輸入卷積神經(jīng)網(wǎng)絡(luò),卷積網(wǎng)絡(luò)開始進(jìn)行預(yù)測(cè),即判斷紅色方框內(nèi)有沒有汽車。

滑動(dòng)窗口目標(biāo)檢測(cè)算法接下來(lái)會(huì)繼續(xù)處理第二個(gè)圖像,即紅色方框稍向右滑動(dòng)之后的區(qū)域,并輸入給卷積網(wǎng)絡(luò),因此輸入給卷積網(wǎng)絡(luò)的只有紅色方框內(nèi)的區(qū)域,再次運(yùn)行卷積網(wǎng)絡(luò),然后處理第三個(gè)圖像,依次重復(fù)操作,直到這個(gè)窗口滑過(guò)圖像的每一個(gè)角落,這就是所謂的圖像滑動(dòng)窗口操作。
注意:滑動(dòng)窗口目標(biāo)檢測(cè)算法也有很明顯的缺點(diǎn),就是計(jì)算成本,因?yàn)槟阍趫D片中剪切出太多小方塊,卷積網(wǎng)絡(luò)要一個(gè)個(gè)地處理。如果你選用的步幅很大,顯然會(huì)減少輸入卷積網(wǎng)絡(luò)的窗口個(gè)數(shù),但是粗糙間隔尺寸可能會(huì)影響性能。反之,如果采用小粒度或小步幅,傳遞給卷積網(wǎng)絡(luò)的小窗口會(huì)特別多,這意味著超高的計(jì)算成本。
在上述我們已經(jīng)說(shuō)過(guò)滑動(dòng)窗口目標(biāo)檢測(cè)算法也有很明顯的缺點(diǎn),如何解決這個(gè)算法的缺點(diǎn)呢?在卷積層上應(yīng)用滑動(dòng)窗口目標(biāo)檢測(cè)算法可以明顯的提高這個(gè)算法的效率。為了構(gòu)造滑動(dòng)窗口的卷積應(yīng)用,首先要知道如何把神經(jīng)網(wǎng)絡(luò)的全連接層轉(zhuǎn)化為卷積層。下圖可以直觀的解釋全連接層向卷積層轉(zhuǎn)化的過(guò)程。

第一部分(上面那部分)是全連接層的過(guò)程,第二部分(下面那部分)是全連接層向卷積層的轉(zhuǎn)化 。下面舉一個(gè)例子,解釋一下在卷積層上應(yīng)用滑動(dòng)窗口檢測(cè)的算法過(guò)程,如下圖所示。

在上圖中假設(shè)圖像大小為16×16×3,窗口的大小為14×14×3,假設(shè)步長(zhǎng)為2,那么窗口要經(jīng)過(guò)4次才能遍歷整個(gè)圖像,也就是在卷積層里進(jìn)行4次運(yùn)算,這樣也會(huì)使算法的效率很低。我們的解決辦法是,直接將整個(gè)圖像經(jīng)過(guò)卷積層、池化層這樣1次操作,在上圖中可以看出,最后輸出的2×2×4的結(jié)果便是經(jīng)過(guò)4次的結(jié)果,例如2×2×4圖像的左上角區(qū)域,對(duì)應(yīng)著圖像的左上角的滑動(dòng)窗口。
四、Bounding Box預(yù)測(cè)
在上述的在卷積層應(yīng)用窗口檢測(cè)算法雖然效率很高,但是其輸出的邊框的精準(zhǔn)度不是很高(如下圖展示,不能很精準(zhǔn)的輸出汽車的邊框),如何才能使輸出的邊框精準(zhǔn)度變高呢?用YOLO算法(You Only Look Once)便可解決這個(gè)問(wèn)題。

YOLO 算法做的就是,將圖像分成n×n的網(wǎng)格(下圖是分成3×3的網(wǎng)格),取兩個(gè)對(duì)象的中點(diǎn),然后將這個(gè)對(duì)象分配給包含對(duì)象中點(diǎn)的格子。所以左邊的汽車就分配到綠色框標(biāo)記的格子上,右邊的汽車就分配到黃色框標(biāo)記的格子上。即使中心格子同時(shí)有兩輛車的一部分,我們就假裝中心格子沒有任何我們感興趣的對(duì)象。

五、交并比
如評(píng)價(jià)目標(biāo)檢測(cè)算法的好壞呢?這里便可引入交并比。

在上圖中假設(shè)紅色區(qū)域是真實(shí)的汽車邊框,藍(lán)色區(qū)域是應(yīng)用目標(biāo)檢測(cè)算法所檢測(cè)的邊框,那么交并比(LoU)就可以如上圖所表示,即黃色區(qū)域 /綠色區(qū)域 。如果LoU>=0.5就可以認(rèn)定所檢測(cè)輸出的邊框合格,這里的0.5稱為閥門(人工定義的),也可以是0.6, 0.7等等。
六、非極大值抑制
到目前為止我們學(xué)習(xí)到的目標(biāo)檢測(cè)算法仍然存在一個(gè)問(wèn)題,就是當(dāng)我們使用目標(biāo)檢測(cè)算法時(shí),我們對(duì)同一個(gè)對(duì)象可能檢驗(yàn)多次,如同下面這個(gè)圖所示,同一對(duì)象可能檢測(cè)出多次。

我們分步介紹一下非極大值抑制是怎么起效的,因?yàn)槟阋?361 個(gè)格子上都運(yùn)行一次圖像檢測(cè)和定位算法,那么可能很多格子都會(huì)舉手說(shuō)我的Pc ,我這個(gè)格子里有車的概率很高,而不是 361 個(gè)格子中僅有兩個(gè)格子會(huì)報(bào)告它們檢測(cè)出一個(gè)對(duì)象。所以當(dāng)你運(yùn)行算法的時(shí)候,最后可能會(huì)對(duì)同一個(gè)對(duì)象做出多次檢測(cè),所以非極大值抑制做的就是清理這些檢測(cè)結(jié)果。這樣一輛車只檢測(cè)一次,而不是每輛車都觸發(fā)多次檢測(cè)。非極大值抑制可以確保我們對(duì)一個(gè)對(duì)象只檢驗(yàn)一次,非極大值抑制算法的具體細(xì)節(jié)如下圖所示。

非極大值抑制算法步驟:
1、將所有的輸出的進(jìn)行排序,選出最高的及其對(duì)應(yīng)輸出框。
2、遍歷其余的輸出框,如果和當(dāng)前最高的輸出框的重疊面積(IOU)大于一定閾值,我們就將框刪除。
3、從未處理的輸出框中繼續(xù)選一個(gè)最高的,重復(fù)上述過(guò)程。
七、Anchor Boxes
到目前為止我們所熟悉的目標(biāo)檢測(cè)算法每個(gè)格子只能檢測(cè)出一個(gè)對(duì)象,如果想讓一個(gè)格子檢測(cè)出多個(gè)對(duì)象,那么便可引出Anchor Boxes這個(gè)概念,舉個(gè)栗子:

對(duì)于上面那個(gè)圖像,我們將它分割為3×3,那么可以清楚的看到,人的中點(diǎn)和車的中點(diǎn)落到了同一個(gè)格子里,如果按照上述的目標(biāo)檢測(cè)算法,便不知道要輸出哪個(gè)結(jié)果,怎么解決這個(gè)問(wèn)題呢?

此時(shí)我們可以預(yù)先定義兩個(gè)不同形狀的Anchor Box ,并把預(yù)測(cè)結(jié)果與這兩個(gè)Anchor Box相關(guān)聯(lián),此時(shí)的y可以定義如下:

前8個(gè)的結(jié)果可以與Anchor Box1相關(guān)聯(lián),后8個(gè)的結(jié)果可以與Anchor Box2相關(guān)聯(lián)。下圖是無(wú)Anchor Box和有Anchor Box的對(duì)比過(guò)程。

八、YOLO算法
由上面所學(xué)習(xí)到的知識(shí)組裝起來(lái)構(gòu)成YOLO對(duì)象檢測(cè)算法。
假設(shè)我們要在圖片中檢測(cè)三種目標(biāo):行人、汽車和摩托車,同時(shí)使用兩種不同的Anchor box。
(1)訓(xùn)練集:
輸入X:同樣大小的完整圖片;
目標(biāo)Y:使用
對(duì)不同格子中的小圖,定義目標(biāo)輸出向量Y。
(2)模型預(yù)測(cè):
輸入與訓(xùn)練集中相同大小的圖片,同時(shí)得到每個(gè)格子中不同的輸出結(jié)果:

3)運(yùn)行非最大值抑制(NMS):
假設(shè)使用了2個(gè)Anchor box,那么對(duì)于每一個(gè)網(wǎng)格,我們都會(huì)得到預(yù)測(cè)輸出的2個(gè)bounding boxes,其中一個(gè)比較高;

拋棄概率值低的預(yù)測(cè)bounding boxes;

對(duì)每個(gè)對(duì)象(如行人、汽車、摩托車)分別使用NMS算法得到最終的預(yù)測(cè)邊界框。

九、python實(shí)現(xiàn)YOLO目標(biāo)檢測(cè)
我們將在這篇博客使用在COCO數(shù)據(jù)集上預(yù)訓(xùn)練好的YOLOv3模型。COCO 數(shù)據(jù)集包含80類,有people (人),bicycle(自行車),car(汽車)......,詳細(xì)類別可查看鏈接:https://github.com/pjreddie/darknet/blob/master/data/coco.names。
測(cè)試一:
經(jīng)過(guò)YOLO目標(biāo)檢測(cè)之后result:

測(cè)試二:
原圖:

經(jīng)過(guò)YOLO目標(biāo)檢測(cè)之后result:

十、 候選區(qū)域(region proposals)
R-CNN(Regions with convolutional networks),會(huì)在我們的圖片中選出一些目標(biāo)的候選區(qū)域,從而避免了傳統(tǒng)滑動(dòng)窗口在大量無(wú)對(duì)象區(qū)域的無(wú)用運(yùn)算。所以在使用了R-CNN后,我們不會(huì)再針對(duì)每個(gè)滑動(dòng)窗口運(yùn)算檢測(cè)算法,而是只選擇一些候選區(qū)域的窗口,在少數(shù)的窗口上運(yùn)行卷積網(wǎng)絡(luò)。
具體實(shí)現(xiàn):運(yùn)用圖像分割算法,將圖片分割成許多不同顏色的色塊,然后在這些色塊上放置窗口,將窗口中的內(nèi)容輸入網(wǎng)絡(luò),從而減小需要處理的窗口數(shù)量。

更快的算法:
(1)R-CNN:給出候選區(qū)域,對(duì)每個(gè)候選區(qū)域進(jìn)行分類識(shí)別,輸出對(duì)象 標(biāo)簽 和 bounding box,從而在確實(shí)存在對(duì)象的區(qū)域得到更精確的邊界框,但速度慢;
(2)Fast R-CNN:給出候選區(qū)域,使用滑動(dòng)窗口的卷積實(shí)現(xiàn)去分類所有的候選區(qū)域,但得到候選區(qū)的聚類步驟仍然非常慢;
(3)Faster R-CNN:使用卷積網(wǎng)絡(luò)給出候選區(qū)域。
AI學(xué)習(xí)不僅僅在于模型掌握了多少,更多的在于你的算法分析和設(shè)計(jì)能力、工程實(shí)踐能力、算法模型的優(yōu)化能力。
這里給大家準(zhǔn)備了一些我精心挑選的AI的學(xué)習(xí)資料。關(guān)注VX公眾H【咕泡AI】回復(fù)【333】即可領(lǐng)??!
①10G教學(xué)視頻包(附課件+代碼)
②AI人工智能:54份行業(yè)重磅報(bào)告匯總
③能寫進(jìn)簡(jiǎn)歷的企業(yè)級(jí)項(xiàng)目實(shí)戰(zhàn)。
④100篇+深度學(xué)習(xí)論文合集
⑤人工智能必讀書籍
⑥專屬學(xué)習(xí)路徑規(guī)劃
⑦不定期大神直播,學(xué)習(xí)和困惑解答
⑧拿來(lái)就能跑通的論文復(fù)現(xiàn)代碼講解及數(shù)據(jù)集
這些資料都比較珍貴,但是對(duì)自我的職業(yè)發(fā)展價(jià)值則是無(wú)價(jià)的!
別慌,這些資料這一次全部免費(fèi)分享給大家。覺得好,就不要吝嗇你的三連哦,這樣我才有動(dòng)力持續(xù)更新哦