目錄
- 目標定位
就是人工標注數據,然后讓機器學習目標位置框; - 特征點檢測
擴展一下,我不再單一定位框了(也就是一個特征),而是直接定位n個特征點的坐標; - 目標檢測
這里提出了我們移動窗口目標檢測算法的原理,大概是怎么做的:拿個框在這個圖片里面一步一步移動著找目標。 - 卷積的滑動窗口實現
講了下計算量的性能熱點,并給出解決方案;
就是我們把后面的全連接換成卷積后,發現被測圖在進行滑動檢測的時候是有大量的計算量是重合的,因此把這部分計算量給一次性處理了,時間花銷大大降低啊!
注意這里是不能輸出bounding box的。 - bounding box預測
- 交并比
- 非極大值抑制
- Anchor boxes
- YOLO 算法
- RPN網絡
P3.1 目標定位
目標檢測分為定位跟分類;
我們之前整的都是分類,都是輸入一張圖,然后輸出這個圖是哪一類的結果,沒有涉及到定位問題,因此這里我們引入了研究。
我們不僅要檢測一個目標,有時可能還要檢測多個目標,比如,自動駕駛的時候,我們要檢測出前面是否有人、汽車、摩托車等等,并且還要準確框出其位置,這樣子才不會撞上去啊!所以整出個定位完全就是工業需求嘛!
- 分類定位,是最基本的情況,其圖中一般是一個對象(如上圖中間圖所示),且對象占圖面積很大;
- 對象檢測則包括很多對象,以及很多種類的對象,情況更復雜(上圖右)。
思路是這樣的:分類 --》分類定位 --》對象檢測,這個過程是思路的延續。
我們來看下上述的思路是如何延續的:常規的分類如圖所示,輸入圖片,然后卷積,最后通過softmax直接輸出類別的概率值(這里假設有4類)。
注意咯!開始思路延續了!doge~
我們把softmax那個地方改一下,除了輸出四類之外,還增加bounding box參數;
這里注意一下,bx,by是框的中心坐標,坐標原點是你整張圖的左上角,右下角為(1,1),因此坐標值都是圖片里面的百分比位置;bw和bh就是對應的長寬值,當然也按比例輸出值就好了。
那么問題來了,我們怎么做呢?
首先得標注數據集,就是把圖片打標,給每張圖貼上類別標簽,同時還給出框的參數,然后喂給卷積網絡進行有監督訓練,這樣子反向傳播梯度下降一整,就讓網絡不僅學會如何識別類別,同時還學會了如何去框定圖片的位置,bingo!網絡又增加一項技能!反正都是學,技多不壓身啊!
插句嘴:我們做數據集的時候,根據經驗,目標在圖中的位置參數最好是bx=0.5,水平中間,by=0.7,目標在中下位置,bw=0.4,bh=0.3也就是說目標占圖片面積的比例也不要太大了的好啊!這是吳恩達大佬給出值,估計是他們的經驗之談吧!(如有誤解,煩請指出!抱拳)
上面講了我們要把分類問題的softmax輸出值改造一下具體如何改造呢
- 首先定義輸出y,y由八個變量構成(打標的數據也是按這樣子來):
- Pc表示是否含有目標,有為1,沒有為0;
- bx,by,bw,bh是定位框的參數;
- c1,c2,c3是目標分別三個類別的概率;
注意:當圖片中沒有目標的時候,除了Pc參數外的其他參數我們都不關心,因為沒必要嘛!這在設計損失函數的時候需要注意。
- 然后設計損失函數
- 當圖片中有目標存在時,也就是Pc=1時,損失函數就是所有參數的平方誤差相加,如圖所示;然后利用反向傳播和梯度下降來有監督地訓練中間的網絡;
- 當Pc=0的時候,其他參數就沒意義了,因此損失函數就單單是訓練Pc的了,也就是一個邏輯回歸了!
就喜歡插嘴: 實際中 c1,c2,c3可以選擇log損失函數, bx,by,bw,bh選用平方誤差損失函數,Pc用邏輯回歸損失函數、平方差損失函數都是ok的!
P3.2 特征點檢測
之前講到了,通過訓練框參數來獲取目標的位置,既然位置參數都出來了,那么我們可不可以直接輸出某些特征點參數,以人臉識別為例,我們可以直接先訓練出網絡可以輸出人眼左邊點的位置參數lx和ly;
既然一點出來了,那么我們是不是可以輸出右眼角坐標,眼睛輪廓點(特征點集合)坐標、鼻子輪廓點的坐標、嘴巴輪廓點的坐標、臉輪廓的坐標乃至直接輸出人臉特征點==組合==的坐標,如下圖所示,哪些紅色的描點是可以人為設定的,
(ps. 以前不是網上有篇文章說的是國外有個哥們設計了一套反人臉識別系統的東東,就是拿一些黑色膠帶,把臉上部分區域貼上,類似下圖中的描點區域,然后人臉識別算法就失效了,我認為這深層次的原因就是把特征點給抹去了吧!從側面也能說明,人臉特征區域基本上都是類似的了!)
- 人臉檢測基本構造模塊就是:輸入圖片(人為辛苦標注的數據集,包含特征點位置參數),然后用該數據集來訓練卷積網絡,教會它識別圖片中是否有人臉,以及教會它輸出人臉的特征點(是標注集時人為選定的)位置參數;
- 上面說到了數據集,這里需要特別說明一下,這些數據集全部都是人為打標的,標注出人臉關鍵位置的坐標,送入給神經網絡進行學習,也就是說數據集是關鍵啊!
- 還可以做人體的姿勢識別,核心點就是特征點的選擇及打標,比如下圖右三。
P3.3 目標檢測
之前講到了目標定位及特征點檢測(也就是框出圖中目標的位置,并且對應的特征點參數,如人臉位置坐標,也已經輸出),那么現在就應該進行目標檢測了!
基于滑動窗口目標檢測算法:
我們首先要做的是搞出訓練集,如下圖所示,我們從圖中剪切出車子的圖片并打好標簽,注意剪切出來的都是車子在中央的標準圖片集!
然后將這些訓練集來訓練出一個卷積網絡,接下來才是采用滑動窗口目標檢測算法來進行目標檢測了!
- 理解起來超級直觀,就是先設定一個選擇框(紅色),然后從左上角開始,跟卷積一樣的移動(其中移動的一些參數都是超參數來的),框內的圖片送入上面訓練好的網絡,輸出一個值表示當前紅色框內是否有汽車,然后依次滑完整個圖片。
- 很顯然,一個尺寸的框很有可能框不到圖中汽車,因此要準備好幾種尺寸的框,依次檢測直到檢測出汽車,當然了具體用幾個框?框的尺寸用多大?這都是要調的,且看這里會不會講到這些!?
image.png
總結:很顯然,這樣子做計算量超級大,因為每移動一步產生的小圖都是要送去卷積網絡的啊!
既然每移動一步產生的圖片送入卷積網絡,那么我們可以選擇大一點的stride嘛!這樣子就可以減少圖片的數量以及卷積計算量,同時需要清醒的認識到的是,這樣子做會使得檢測粒度變大,性能有可能降低。反之,小步幅小粒度就會增加計算量。
ps. 卷積之前采用的是線性分類器,因此滑動檢測的計算量還是可以的,但是卷積的計算量太巨大,因此檢測速度太慢,好在后面的研究講到了如何優化使得速度得以提升!(我想這就是人類存在的意義吧!不斷想出新的優化的辦法,不斷使得“系統”得以螺旋上升,這應該就是寫在人類基因代碼里面的算法吧!人類因此而不斷地向前走、進化。我們得從人類之上俯瞰“能量”的流動規律,抓住規律把握baseline,獲得靈感的觸發,天道即行。)
P3.4 卷積滑動窗口的實現
首先講的是如何將全連接層轉換為卷積層,當然這么做的好處,在后面進行滑動窗口的時候就可以看出來。
從下圖第一行中可以看出,全連接層那個地方是直接把5X5X16=400個點直接解開成單獨的像素點,有點類似于降維的味道啊,本來好好的二維信息,你這里直接給解成1維的了;然后softmax輸出四類信息(車子,人,馬路,山啊啥的)的概率。
而第二行的操作,不同之處在于全連接那,我們不損失二維信息,但是要做到最終的輸出還是四類的值,跟上面的輸出一樣,因此我們采用400個5*5的卷積核直接卷積輸出的就是1X1X400的卷積層了,雖然跟上面的全連接形似,但是這個是卷積層,計算方式是不同的,后面的話就是類似了,總之全部都是卷積操作。
這里你就不關心為啥我們要將全連接替換成卷積的模式嘛?
我認為有兩點:第一就是這樣子轉換成卷積的模式跟全連接是等效,或者說效果相差不大的;其二這樣子做使得計算方式統一了,因此在后面的加速優化方面可以更方便(實際情況也是如此,對每次的卷積統一整體優化)。
厲害了,細心了我的哥:
第一行是14*14*3的圖片進行的訓練,得到的模型;
第二行拿16*16*3的圖片進行目標檢測,當我們以stride = 2進行切割圖片時會切割成四個子圖,然后依次將這四個子圖送入上面訓練出來的模型進行前向傳播計算,然后最后得到四組輸出值。
等等。。。能發論文的人就是比我們更懂這個游戲啊,知曉游戲的所有基本操作,知道這個游戲里面的每一個細節,然后還愛著這個游戲,有著探索欲望,因此作者就發現這四個操作有計算重合的部分啊!因為四個子圖本來就有重合的部分啊!當然咯!僅僅發現這個大部分人還是可以做到的,但是要給出解決方案的還屬牛人!掌握這個召喚師戰場每一個細節的牛人,作者發現我直接把一整張圖送入上面的模型直接前向傳播,輸出的就是2\*2\*4的輸出,也就是2\*2組輸出,跟上面還是一樣的啊!
-
要點:子圖的公共區共享計算。
我們可以看到,實際使用過程中,我們滑動窗口時不需要每個子圖都進行前向傳播,直接整張圖進行卷積,然后輸出一組結果,比如下圖輸出的是8X8X4,也就是說輸出了64組結果(即64個框匹配后的結果),每個結果中有四個值,分別對應四類目標的概率值。
注:框的大小是由你的卷積網絡訓練完后決定的(檢測之前的預訓練那)。
問題:
1、這個框的大小如何確定?假如選幾個scaling的話,那怎么選?
2、這么移動不一定能剛好選擇到汽車,那么stride如何選(權衡粒度跟性能)如何能保證一定框中汽車(也即如何使得選擇框精準選定目標)?
P3.5 bounding box預測
上一節講到我們滑動窗口進行檢測的時候很有可能是無法剛好把你的框框住圖中的目標的,因為有可能目標是長方形的,而你的框是正方形的,因此最有可能的情況是窗口滑動過程中,其中一個框中出現目標的面積比其他的要大,因此我們可以從這個點入手進行思考,是否有合適的算法可以解決該問題!
當然咯!別人已經想出了一個解決方案了,那就是YOLO算法,這里摘錄如下:
- 將圖像進行切割,這里假設是3X3的切割(實際使用時將會更精細),然后切割出的每個圖片進行卷積操作直接輸出[是否目標*1,坐標*4,類別*3]的向量,比如你將圖片3X3分割,那么最終輸出的就是3X3X8的輸出;
注:打標簽的時候是這樣打的,你看沒有汽車的方格子,比如左第一個,是直接輸出Pc=0的,其他的參數值我們是不關注的;其次綠色框中/黃色框是有大部分汽車的,因此汽車分別歸屬于這個框,而中間這個框雖然有一部分汽車,但是還是認定為沒有汽車的。
由此可見這里框出來的不一定剛還完美適配車子的大小外形的,這里只做到你出現在那個剪切塊內,關于具體的bonding box參數完美適配還得要優化且還得后面研究。
- 類似常規的分類和定位算法,因為這也是直接顯示輸出類型及bounding box;
box參數定義跟之前還是差不多的,也是以最小單位方格的尺寸比例為值的。其次長寬參數是可能大于1的,因為這個車子很大,但是歸屬到當前切割區時,就會出現大于1的情況
- 可以使得神經網絡輸出的bounding box具有任意的寬高比,并且能輸出更精確的坐標,并且不會受到滑動窗口法分類器的步長大小限制,其次我們并沒有在每個分隔出的圖片中跑卷積算法(比如3X3分割出來九張小圖,我們就要做9次卷積),而是直接整張圖全部進行卷積操作,因此速度很快!
疑問:不受滑動窗口法分類器的步長大小限制?這句話怎么理解?
這玩意跟滑動窗口法本質上不是一樣的么?
P3.6 交并化
解決如何判斷算法運行良好的問題。
背景:
- 實際完美的框應該是圖中的紅色框,而我們算法實際框出來的是紫色那個框;
定義:
- ioU就是交并比,也就是兩個框的交集比上并集,一般人為設定大于0.5,當然了,要是你要求嚴格點也可以設為0.6或者0.7,并以此來評估你的定位算法是否精確。
-
特別的ioU = 1就表示算法框出來的跟理想框完全一樣,這個是完美的狀態。
P3.7 非極大值抑制
我們之前的做法都是對某個對象檢測出多次?
- 滑動窗口是這樣的;
這個肯定會檢測出多次的。 - YOLO分隔后不也是如此嘛?
是的,也是如此,因此才提出非極大值抑制。
我們實際操作的時候,比如這里做19X19de切割圖片,然后運行檢測算法,然后每個格子都會輸出一組向量,來表示我這個格子里面是不是含有汽車。
然后,有一部分格子(如圖中綠色、橙色那些)都會認為自己這個格子里面含有汽車的概率很高,車子的中心點應該在我這個格子內部。但是我們從全局來看是知道只有一個理論中心點的。
非極大值抑制:保證每個對象只檢測一次。
就是只輸出概率極大的結果,抑制很接近但不是極大值的預測結果(也就是一簇框中選出定位效果最好的那個,其他的淘汰掉)
如下圖所示就是:選中0.9的框作為老大,其他0.6和0.7的就可以去掉了;0.8那邊的也是同理。
具體算法步驟是:
- 假設我們只識別汽車這一類,因此輸出向量只有5維;
- 在算法跑了一遍之后,直接把Pc<=0.6的全部去掉,"你們這些吊車尾,淘汰,淘汰!" ---火影
- 選擇Pc最大的那個框,然后跟這個框重疊度大于0.5(也就是這一簇的框)的全部去掉,這樣就找到了一個目標了!
- 重復上述步驟,繼續找下一個目標,直至沒有了。
當要檢測很多類的時候,每個類都要這樣子進行一次操作。
我的問題是:
- 你這樣剪成19X19的大小,然后輸出19X19個結果向量,也就是說每一個格子最終會輸出一個結果,那么你這是默認檢測框的大小就是這個格子的大小啊,那么這樣子的話**跟滑動窗口比起來是不是就是把stride加大了?
- 這里也沒有體現出每個對象只檢測一次啊?不是也重復多次檢測了么?
你看啊,目標附近的每個格子都認為他是真命天子,都要搶著計算資源來回歸他的框參數,但是這么多計算量太大了嘛!因此我們提前預選一下,選出一個最有可能的代表,然后再對其進行框位置的回歸。
- 那個邊框超過你當前格子,這個算法是怎么做到識別出框的?是傳說中的全局視角么?
識別框大于格子大小這個問題應該是:反向傳播學來的全局視角能力了!!!
我們標注訓練集的時候,在一張大圖中會給出目標的中心點以及框的參數的,那么我們在運行YOLO算法的時候就會基于反向傳播來直接回歸,因此這里體現的是全局的視角;回到微觀的每個格子,都會輸出一個目標概率值和位置框參數,我們有策略地選擇一些做處理,最終得到一個目標框,然后基于此框進行反向回歸,因此這里體現只檢測一次;最終這個格子的框大小參數開始可能是隨機的,通過訓練是可以回歸出標注數據集的位置的,因此說這里體現了學大框的全局能力。
P3.8 Anchor Boxes
之前是每個格子只能檢測出一個對象,假如我們要每個格子檢測出多個類別的話,就要用這里的Anchor Boxes了。
如下圖所示,車子跟人的中心點是在一起的,也就是說打標的時候就已經合在一起了,那么我反向傳播的時候就根本不可能把網絡訓練得識別出這兩個物種,因為網絡的基本規則之一就是一個框中只能有一個目標;
而解決方案就是預先設定不同形狀的框,然后把框跟目標關聯起來,不就是相當于加了一維信息嘛!(如圖所示,編碼由原來的一組就變成了兩組,由于豎著的更符合人的特征,因此我們可以把第一組跟人關聯起來,第二組橫著的跟汽車關聯起來)
之前的做法是:標注數據的時候圖像的中心點在哪個格子我們就把它分配給哪個格子;
現在Anchor boxes的做法是:我還是中心在那個格子我就分配給那個格子,但這樣就區分不出來了嘛,所以我就又增加一個參數(grid cell,anchor boxes)這樣子就能識別出一個格子類的兩個對象了。同時輸出向量是原來的兩倍了,之前是8(因為我們有三類輸出+位置參數四個+是否有目標的概率),現在兩組值就是16了。
是為了解決一個格子出現兩個對象的問題,但是假如我們取19X19分割的話,那么出現這種場景的概率還是蠻低的。
好處就是我們可以更進一步地定制化目標檢測算法,比如我們加上anchor之后就可以提前告訴網絡,汽車就是躺著的長條形狀的物體,這樣子機器會學得更快一些,類似于機器學習里面的正則嘛~
P3.9 YOLO算法
終于到正主了,終于可以融匯貫通了!
- 第一步:構建數據集
為了簡單示例,這里取3X3切割(實際中一般要取到19*19這個級別的),然后遍歷這9個格子,每個格子輸出1個16個參數的向量,共計3X3個;
16個參數是因為選用了兩組anchor(實際中可能更多),每組8個是因為如圖所示是要分三類的。
第二步:構建網絡
比如輸入的是100X100的圖片,那么我們最終要的輸出是3X3X16的輸出,此為大前提。第三步:神經網絡的預測過程
如圖所示,你把圖片丟給網絡后就輸出3X3X16的向量,只有綠色框的那個里面的其中一個anchor box是有輸出的,會告訴你Pc=1:對象在這個框內;具體的位置參數預測輸出;這個對象屬于哪一個類別;
-
非極大值抑制
每個格子都會輸出兩個anchor框(我們選擇兩個的嘛),可以看到二行三列這個格子的框是超出格子的了(這里可能會有疑問:我們運算單元是格子,為什么算法可以知道格子之外的信息呢?我的理解是,當時我們標注這個格子的時候,由于中心點在這個格子,因此人這個對象就配給這個格子了,然后對應標注的框參數肯定是最合適的豎長方形啊,然后把這種全局信息給到網絡去學習,網咯的學習是作為一個整體的回歸學習的,給的信息里面就有全局信息,所以學習肯定也會學習到全局信息的啊!因此這里直接預測出框是大于格子的沒什么好驚訝的!)
運用非極大值抑制后,就把其他格子的框給消掉了,但是還是有兩個anchor我們要選擇最合適的那個,因此再對每個類別單獨做非極大值選出最合適的框來就是最終的輸出值了,這里人是豎框,車子是橫框。
P3.10 RPN網絡
region proposal network:候選區域(區域建議)網絡
R-CNN:帶區域的卷積網絡
- 滑動窗口的時候由于沒有目標的區域也進行了計算,因此這是時間和計算力等資源的浪費;
- 因此只對部分區域進行計算,那如何找到這個區域呢?那就是圖像分割啦!
- 在分割出的框上跑分類器,這樣子計算量可能會減少!
- 一般流程是先把圖片通過某種算法進行分割出框,然后送入分類型輸出(輸出也是包含bounding box喲,這樣子更精準了),單數速度還是有點慢。
我的問題是:框的大小不是一樣的,你怎么丟到分類器里面去?
- 優點是:他自己也會輸出一個bouding box,這樣子的話定位單數是更準的。
- 缺點是:太太太太慢了!!!
Fast R-CNN:
后來出現了Fast R-CNN,因為之前R-CNN都是每個區域逐一分類的,因此速度慢,這個Fast R-CNN就是借鑒了滑動窗口的卷積實現,因此速度提升了!
- 缺點是:得到候選區域的聚類步驟還是非常緩慢。
Faster R-CNN:
獲得候選區域色塊的操作是圖像分割這塊的核心,之前采用的是傳統的分割算法,而這篇論文里面采用的是卷積神經網絡。
雖然你加速了,但還是比YOLO慢很多哇!
總結
傳統目標檢測系統采用deformable parts models (DPM)方法,通過滑動框方法提出目標區域,然后采用分類器來實現識別。
近期的R-CNN類方法采用region proposal methods,首先生成潛在的bounding boxes,然后采用分類器識別這些bounding boxes區域。最后通過post-processing來去除重復bounding boxes來進行優化。這類方法流程復雜,存在速度慢和訓練困難的問題。
YOLO提供了另一種更為直接的思路: 直接在輸出層回歸bounding box的位置和bounding box所屬的類別(整張圖作為網絡的輸入,把 Object Detection 的問題轉化成一個 Regression 問題)。
缺陷:
YOLO對相互靠的很近的物體(挨在一起且中點都落在同一個格子上的情況),還有很小的群體 檢測效果不好,這是因為一個網格中只預測了兩個框,并且只屬于一類。
測試圖像中,當同一類物體出現的不常見的長寬比和其他情況時泛化能力偏弱。
由于損失函數的問題,定位誤差是影響檢測效果的主要原因,尤其是大小物體的處理上,還有待加強。