【CV】MTCNN:3个CNN,胜过1个诸葛亮
作者簡介
CW,廣東深圳人,畢業于中山大學(SYSU)數據科學與計算機學院,畢業后就業于騰訊計算機系統有限公司技術工程與事業群(TEG)從事Devops工作,期間在AI LAB實習過,實操過道路交通元素與醫療病例圖像分割、視頻實時人臉檢測與表情識別、OCR等項目。
目前也有在一些自媒體平臺上參與外包項目的研發工作,項目專注于CV領域(傳統圖像處理與深度學習方向均有)。
前言
MTCNN(Multi-Task Cascaded Convolutional Networks)是2016年提出的,如其名,算法采用了級聯CNN的結構實現了多任務學習——人臉檢測 和 人臉對齊,最終能夠預測出人臉框(bounding box)和關鍵點(landmarks)的位置。
MTCNN在 FDDB、WIDER FACE 和 AFLW 數據集上均取得了當時(2016年4月)最好的效果,而且速度也快(在當時來說),被廣泛用于人臉識別流程中的前端部分。
總地來說,MTCNN的效果主要得益于以下幾點:
1. 級聯的CNN架構是一個coarse-to-fine(由粗到細)的過程;
2. 在訓練過程中使用了在線困難樣本挖掘(OHEM,Online Hard Example Mining)的策略;
3. 加入了人臉對齊的聯合學習(Joint Face Alignment Learning)
下面,請諸位客官進入MTCNN的世界里進行參觀。
MTCNN的“宣傳海報”
一
網絡結構
MTCNN由3個網絡組成,共同構成級聯的CNN架構。這3個網絡依次為 P-Net、R-Net 和 O-Net,前者的輸出會作為后者的輸入。
P-Net(Proposal Network)
P-Net
顧名思義,這個網絡主要用于輸出包含的人臉候選區域。輸出包含3部分:分類結果(二分類),代表是否人臉、檢測到的人臉框(bbox)位置 以及 定位到的關鍵點(landmarks)位置。
需要注意的是,這里回歸輸出的bbox和landmarks并非是坐標值本身,而是歸一化的offset,具體在后文會講解,這里先埋個坑~
另外,P-Net是一個FCN(Fully Convolutonal Network),輸出的是一個map,channel為2+4+10=16,2對應二分類的score,4對應bbox左上角和右下角橫縱坐標的offset,而10則對應5個關鍵點(左、右眼、鼻、左、右嘴角)橫縱坐標的offset,后續R-Net和O-Net的輸出意義也與此相同。
或許你會疑惑,為何P-Net要設計成FCN呢?從上圖可以看到,輸入圖像的size是12x12,最終輸出的size變為1x1,完全沒有必要嘛~其實仔細看下本文前言里展示的那幅圖的最上面部分,應該就知道答案了。
R-Net(Refine Network)
R-Net
R-Net不再是FCN,最后使用全連接層,相比于P-Net,其輸入size和每層的通道數也比較大,可以認為,其擬合的結果會更精確,主要作用是對P-Net的結果進行校正,消除其中的誤判(FP,False-Positive)。
O-Net(Output Network)
O-Net
O-Net的結構與P-Net較為類似,只不過輸入size、寬度以及深度都更大,因此可使最終輸出結果更加精確。
從上述展示的結構中我們可以feel到,P-Net->R-Net->O-Net 是一個coarse-to-fine的過程。
二
推理過程
推理過程的pipeline依次是:對輸入圖像進行處理生成圖像金字塔 -> 輸入到P-Net -> 對P-Net的輸出進行后處理 -> 輸入到R-Nnet -> 對R-Net的輸出進行后處理 -> 輸入到O-Net -> 對O-Net的輸出進行后處理得到最終預測結果。
另外,推理時P-Net和R-Net可以不必輸出landmarks分量,因為此時預測的人臉框位置還不準,根據offset計算出對應的landmarks位置沒有太大意義,而且也沒有必要,最終的輸出還是取決于O-Net。
圖像金字塔
由上一節展示的P-Net網絡架構可知,其是在單尺度(12x12 size)上做訓練的,為了檢測到不同尺寸的人臉,所以在推理時需要先生成圖像金字塔,而P-Net為何設計成FCN的原因也在于此。
首先,設置一個想要檢測的最小人臉尺寸min_size,比如20x20,其次,設定一個縮放因子fator,通常為0.707。
然后,將圖像的最短邊乘以 12 / 20,進行一次縮放,接著不斷對前面縮放的尺寸乘以fator進行縮放,比如最短邊初始為s,接下來就會縮放得到:s x 12 / 20、s x 12/ 20 x factor、s x 12 / 20 x factor ^2、...,直至s不大于12時停止。
記錄下以上縮放過程中(最短邊還大于12時)的各個scale:12 / 20、12 / 20 x factor、12 / 20 x factor^2、...,最后依次按照每個scale對圖像采用雙線性插值的方式進行縮放從而得到圖像金字塔。提問時間到!為何縮放因子是0.707?
這個數字不覺得有點眼熟嗎?是的,它約等于,那么這又代表什么呢?通常,按照我們凡夫俗子的思維,縮放系數都習慣于取0.5,如果邊長都縮放0.5倍的話,那么矩形框面積就縮小了1/4,跨度未免有點大,可能會漏掉許多要檢測的人臉。要知道,按照P-Net的意思,每個尺度對應的就是一張人臉。于是我們可以讓面積縮放1/2,減小這之間的跨度,相應地,邊長的縮放系數就為。
十萬個為什么系列之第二個靈魂拷問——min_size和factor對推理過程會產生什么樣的影響?
由小學數學知識可知,min_size越大、fator越小,圖像最短邊就越快縮放到接近12,從而生成圖像金字塔的耗時就越短,同時各尺度的跨度也更大。因此,加大min_size、減小factor能加速圖像金字塔的生成,但同時也更易造成漏檢。
好了,不問了,真要問十萬個估計我的手要碼到殘廢了..剩下的諸位自行yy。
由上述可知,圖像金字塔的缺點就是慢!慢在需要不斷resize生成各個尺寸的圖像,還慢在這些圖像是一張張輸入到P-Net中進行檢測的(每張的輸出結果代表一張人臉候選區域),相當于做了多次推斷過程,你說可不可怕..
P-Net獲取人臉候選區域
將圖像金字塔中每個尺寸的圖像依次輸入到P-Net,對于每個尺度的圖像都會對應輸出一個map,輸出map的每點都會有分類score和回歸的bbox offset。先保留置信度較高的一批位置點,然后將每點還原出對應的人臉區域,接著用NMS剔除重復的區域,得到所有尺寸圖像保留下來的結果后,再用一次NMS進行去重(CW做過實驗,不同scale下輸出的圖像之間NMS沒有效果,說明不同scale下沒有重復的,也符合不同scale檢測不同尺寸人臉的意思),最后使用回歸得到的offset對人臉候選區域進行校正得到bbox位置。十萬個為什么系列再次上線——如何還原出輸出map每點對應的人臉區域?
根據P-Net的結構設計可知,輸出feature map的一點實際對應的是輸入中12x12的區域,而P-Net中有一個池化層進行了2倍的下采樣(對卷積層帶來的尺寸損失不計),于是對于輸出feature map的一點(x, y),我們可以這么做來進行還原:
i). 先還原出其在輸入圖像的位置:(x*2, y*2);
ii). 將其作為人臉區域的左上角,對應地,右下角為:(x*2 + 12, y*2 + 12);
iii). 由于在生成圖像金字塔時進行了縮放,因此還要除以當時縮放的scale:(x1 = x*2 / scale, y1 = y*2 / scale)、(x2 = (x*2 + 12) / scale, y2 = (y*2 + 12) / scale)
以上(x1, y1, x2, y2)便是還原出來在原圖上對應的人臉區域。
你們應該還沒有吃飽,繼續問——如何用回歸得到的offset計算出人臉bbox位置?
x1_true = x1 + tx1*w
y1_true = y1 + ty1*h
x2_true = x2 + tx2*w
y2_true = y2 + ty2*h
使用以上公式就能計算得到結果,其中x*_true和y*_true代表人臉bbox的位置,tx*、ty*代表回歸得到的offset,w和h就是人臉區域(x1, y1, x2, y2)的寬和高。
至于為什么能這么計算,這是由訓練前制作label的時候決定的,在下一節講訓練過程時會說明,這里先hold著。
P-Net輸出的bbox不夠精準,僅作為包含人臉的候選區域,接下來交由R-Net進行校正。
R-Net基于P-Net的結果進一步校正
R-Net并不是直接將P-Net的輸出結果拿來用,他還是個細心boy,先對這些輸出“做了一番洗剪吹”,成為這條街上最靚的仔后再拿來用,處理過程如下:
i). 為了盡可能涵蓋到人臉,將P-Net輸出的候選區域都按其各自的長邊resize方形;
ii). 檢查這些區域的坐標是否在原圖范圍內,在原圖內的像素值設置為原圖對應位置的像素值,其它則置為0;
iii). 將以上處理得到的圖片區域使用雙線性插值resize到24x24大小
處理完后,所有輸入都是24x24大小,網絡輸出的后處理與P-Net類似,先篩選置信度較高的一批結果,然后用NMS剔除重復的,最后使用offset計算出bbox位置。此處使用offset計算時用到的(x1,y1,x2,y2)就是P-Net輸出的bbox。
又要問了——為何不直接對原圖有效范圍內的區域進行resize?
可以這么想,如果有效范圍內的區域剛好正是人臉區域,絲毫不差,那么resize后必定會有像素損失,從而丟失細節。
O-Net檢測出人臉和關鍵點位置
看到R-Net是個細心boy,O-Net當然也是很自覺地對R-Net的輸出結果做了處理,處理方式與R-Net類似,只不過最終resize到的大小是48x48。
由于O-Net會輸出landmarks的offset,因此還需要計算出landmarks的位置:
x_true = x_box + tx*w
y_true = y_box + ty*h
(x_true, y_true)代表一個關鍵點的位置,tx、ty代表對應的offset,(x_box, y_box)代表R-Net輸出bbox的左上角位置,w、h代表bbox的寬、高。至于bbox位置的計算、后處理等這些也都和之前的類似,這里不再闡述了。
哦,另外,在此處NMS計算IoU時,分母可以不取并集,而是取當前置信度最高的bbox和其余bbox面積的較小者,這樣分母會變大,從而導致IoU計算結果偏高,相當于變向降低NMS閥值,對重復檢測的要求更為苛刻。
三
訓練過程
MTCNN的三個網絡是依次分別訓練的,先訓練P-Net,待其訓練好后,將其檢測結果用于R-Net的訓練數據,然后對R-Net進行訓練。同樣地,R-Net訓練完后,將其檢測結果用于O-Net的訓練數據,最后訓練O-Net。
數據樣本分類
MTCNN是集成了人臉檢測和人臉對齊的多任務架構,通常使用兩個數據集來訓練,其中一個訓練人臉檢測,另一個訓練人臉對齊(這部分其實也能訓練人臉檢測)。在處理訓練數據時,會對圖像進行隨機裁剪,具體方法后文會講解,這里再埋個坑。可以將訓練樣本分為4類:
i). Positive:裁剪后圖片與人臉標注框 IoU >= 0.65,類別標簽為1;
ii). Part:裁剪后圖片與人臉標注框 IoU?[0.4, 0.65),類別標簽為-1;
iii). Negative:裁剪后圖片與人臉標注框 IoU < 0.3,類別標簽為0;
iv). Landmarks:來自訓練人臉對齊的數據集,類別標簽為-2
使用Positive和Negative樣本計算分類損失,使用Positive和Part樣本計算bbox回歸損失,而僅使用Landmarks樣本計算landmarks回歸損失。
十萬個為什么時間到——為何只使用Postive和Negative計算分類損失?
應該是考慮到這些正負樣本與標注框的IoU差別明顯,區分度大,使模型更易收斂。
標簽制作
填坑時間到!之前埋下的2個坑會在這里填上,打起精神咯!
P-Net、R-Net和O-Net的標簽處理過程有些許差別,下面依次介紹。
P-Net
負樣本Negative
1. 對圖像進行隨機裁剪,裁剪后為方形,邊長s=(12, min(H, W) ),H、W分別為圖像的高和寬。將圖像左上角向右下方進行移動,移動后橫、縱坐標分別為
(0, W - s)、?(0, H - s),于是裁剪后圖像右下角坐標為(x2=x1 + s, y2=y1 + s)。
2. 計算裁剪后圖像與原圖中所有標注框的IoU,若最大IoU<0.3,則將這張裁剪后的圖像作為負樣本Negative,resize至12x12大小,對應的類別標簽記為0,保存下來待訓練時用。
3. 重復1、2直至生成了50個負樣本圖像。
4. 對圖像中的每個標注框重復5次隨機裁剪,也是用于生成負樣本。裁剪后邊長s與1中的相同,移動bbox的左上角(x1, y1),移動后(nx1=x1 + delta_x, ny1=y1 + delta_y),其中delta_x?[max(-s, -x1), w),delta_y?[max(-s, -y1), h),也就是對標注框左上角隨機進行上下左右移動,w、h分別bbox的寬和高。對應地,bbox右下角坐標變為(nx2=nx1 + s, ny2=ny1 + s)。若右下角坐標超出原圖范圍,則舍棄該裁剪圖片,進行下一次裁剪。
正樣本Positive和Part
5. 緊接著4,在一個標注框隨機裁剪5次后,再重復隨機裁剪20次,用于生成正樣本Postive和Part。裁剪后圖像邊長s?即bbox短邊的0.8倍至長邊的1.25倍。對bbox的中心點隨機進行左右上下移動,移動范圍delta_[-0.2w, 0.2w),delta_?[-0.2h, 0.2h),于是移動后中心點坐標為, 相應地,左上角和右下角坐標為,
()若右下角坐標超出原圖范圍,則舍棄此次裁剪的結果,繼續執行下一次隨機裁剪。
6. 若裁剪后圖像與該bbox的IoU>=0.65,則作為正樣本Positive,resize到12x12大小,類別標簽記為1;否則若IoU>=0.4,則作為Part,同樣也resize成12x12,類別標簽記為-1;
7. 對于Postive和Part樣本,計算bbox左上角和右下角的offset標簽:
其中,(x, y)為標注框左上角/右下角的橫、縱坐標,(nx, ny)為裁剪圖片的左上角/右下角坐標,s為其邊長。也就是標注框兩個角相對于裁剪圖片對應兩角的歸一化位移。最后將Postive和Part樣本對應的裁剪圖像、類別標簽、offset標簽保存下來待訓練時用。
關鍵點樣本Landmarks
8. Landmarks樣本在另一個數據集中單獨處理,每張圖片是一個單獨的人臉,對每張圖重復10次隨機裁剪,裁剪方式與生成Positive和Part樣本時相同,若裁剪后圖像右下角坐標不在原圖范圍內,或者裁剪后圖像與標注框IoU<0.65,則舍棄此次裁剪結果,進行下一次隨機裁剪。
9. 計算bbox和landmarks的offset標簽,其中bbox的計算方式與Postive以及Part的相同,這里不再闡述,而landmarks的如下:
其中,(x, y)為標注的關鍵點坐標,為裁剪后圖像的左上角坐標,s為裁剪后圖像的邊長,即標注的關鍵點相對于裁剪圖像左上角的歸一化位移。
R-Net
在R-Net的標簽制作前需要使用訓練好的P-Net的數據集進行檢測,后續的數據處理過程與P-Net類似,下面進行介紹。
1. 使用訓練好的P-Net對數據集的圖片進行檢測,將原圖、標注框以及檢測出的bbox位置對應保存下來。
2. 將原圖、標注以及圖中檢測出的bbox依次取出,對每個bbox依次處理,若尺寸小于20(min_size,代表想要檢測的最小人臉size)或者?坐標不在原圖范圍內,則舍棄該檢測出的bbox,繼續處理下一個bbox;否則,將bbox對應的區域從原圖中裁出并resize到24x24備用。
負樣本Negative
3. 計算bbox與所有標注框的IoU,若最大IoU<0.3且當前生成的負樣本數量小于60個,則將裁剪出的圖像作為負樣本,類別標簽記為0,保存下來待訓練時用。
正樣本Positive和Part
4.?否則,若最大IoU>=0.65或0.4<=最大IoU<0.65,則對應地將裁剪出的圖像記為正樣本Positive或Part,類別標簽記為1或-1。同時,取出最大IoU對應的標注框,用于計算offset,計算方式與P-Net中提到的相同,最后將裁剪出的圖像、類別標簽、offset標簽保存好待訓練時使用。
O-Net
在制作O-Net的數據標簽前需要依次使用訓練好的P-Net和R-Net對數據集做檢測,然后將R-Net預測的bbox和對應的原圖以及標注保存下來供O-Net使用。
標簽制作過程和R-Net的幾乎相同,只不過沒有最小負樣本數量的限制(P-Net有50個、R-Net有60個)。另外,若landmarks數據集的標注框最長邊小于40或坐標不在原圖范圍內,則舍棄這個樣本。
Loss函數
loss由三部分組成:分類損失、bbox回歸損失、landmarks回歸損失。
每個網絡的loss都由這3種loss加權而成,其中分類損失使用交叉熵損失,回歸損失均使用L2距離損失。
上式中,j代表不同的任務(分類、bbox回歸、landmarks回歸),即不同任務對應的loss權重,對于P-Net和R-Net,它們的分類loss、bbox回歸loss、landmarks回歸loss的權重比為1:0.5:0.5,而O-Net中為1:0.5:1。是第i個樣本在任務j中是否需要貢獻loss,需要則為1,否則為0。例如,對于Negative樣本,它在回歸任務中這個β值就為0。
OHEM(Online Hard Example Mining)
在線困難樣本挖掘的策略僅在計算分類loss時使用。直白來說,就是挑選損失最大的前70%作為困難樣本,在反向傳播時僅使用這70%困難樣本產生的損失。作者在paper中的實驗表明,這樣做在FDDB數據集上能帶來1.5個點的性能提升。
四
總結
最后,總結下MTCNN的整個pipeline:
首先,對待檢測圖片生成圖像金字塔,輸入P-Net,得到輸出,通過分類置信度和NMS篩選出人臉候選區域;
然后,基于這些候選區域去原圖crop出對應的圖像,輸入R-Net,得到輸出后同樣是使用分類置信度和NMS,過濾掉false-positive,得到更精準的一批候選;
最后,基于得到的這批候選去原圖crop出對應的圖像,輸入O-Net,輸出最終預測的bbox和landmark位置。
本文來自作者CW的原創投稿,如有任問題請及時留言,我們會第一時間處理。
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯 本站qq群704220115,加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【CV】MTCNN:3个CNN,胜过1个诸葛亮的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows7电脑删除文件特别慢的解决
- 下一篇: Win11任务栏怎么隐藏