MTCNN,multi task convolutional neural network,多任務卷積神經網絡;
它同時實現了人臉檢測和關鍵點識別,關鍵點識別也叫人臉對齊;
檢測和對齊是很多其他人臉應用的基礎,如人臉識別,表情識別;
網絡特點:
1. 級聯網絡
2. 在線困難樣本選擇 online hard sample dining
3. 速度非常快,可做實時檢測
MTCNN 主體架構為 3 個逐級遞進的級聯網絡,分別稱為 P-Net、R-Net、O-Net,P-Net 快速生成粗略候選框,R-Net 進行過濾得到高精度候選框,O-Net 生成邊界框和關鍵點坐標;
如圖
注意上圖是 測試過程,訓練過程略有不同
網絡解析
MTCNN 網絡的形象理解:
三個級聯網絡,我們可以理解為面試過程,
HR 面試為 P-Net,HR 面試不能太嚴格,因為這樣會漏掉很多合適的人選,故 P-Net 是一個簡單的網絡;
HR 面試完畢后,把通過的簡歷傳給 技術,技術面試為 R-Net,技術面基本就能確定人選是否被錄用,只是薪資可能無法確定,故 R-Net 基本就確定了是否為人臉,只是關鍵點沒有指定;
技術面試完畢后,把通過的簡歷傳給 boss,boss 面為終面,輸出是否錄用及薪資;
圖像金字塔
將樣本進行等比例的多次縮放,目的是為了檢測不同大小的人臉;
縮放比例一般為 0.7-0.8 之間,如果縮放比例太大,會導致小人臉檢測不到,如果太小,圖片過大,效率降低;
最小的圖片要大於 12x12,因為 P-Net 的輸入為 12;
P-Net
全稱 Proposal Netwrok,通過一個簡單的網絡快速得到粗略的建議框;
它是一個全卷積網絡,輸出分為 3 部分:是否為人臉(2)、建議框的 左上右下坐標(4)、人臉關鍵點(5個點*(x,y)=10);
上圖最后的輸出為 方框,因為他是卷積,而 R-Net、O-Net 的輸出為長條,因為他是全連接;
訓練階段:雖然是全卷積網絡,但是輸入仍需 resize 到 12x12;
測試階段:無需 resize 到 12x12,而是把圖像金字塔輸入網絡;
R-Net
全稱 Refine Network,主要作用是去除大量非人臉建議框
它的輸入是 P-Net 的輸出;
網絡最后加上了一個全連接層;
O-Net
全稱 Output Network,這一步對 建議框進行最終修正,並且對關鍵點進行回歸;
它的輸入是 R-Net 的輸出;
網絡多了一個卷積層和全連接層;
損失函數
人臉類別為 交叉熵
邊框和 關鍵點都是 均方差
由於在訓練時不是每一步都計算所有損失,因此用下式統一了模型的損失函數
N 表示樣本數;
α 表示任務權重,在整個模型中,我們始終最關注是不是人臉,故它的權重最大,一直為 1,邊框回歸是在識別為人臉的建議框上做的,故權重小於人臉,一直為 0.5,在 P-Net 和 R-Net 中,關鍵點的回歸幾乎不需要,權重很小,在 O-Net 中,人臉和邊框都差不多了,好好把關鍵點識別一下,權重變大;
β 取值 0,1,如果輸入為非人臉,只計算 人臉部分的損失,邊框和關鍵點不計算;
模型訓練
MTCNN 的訓練還是比較麻煩的,需要串行地訓練 三個網絡 【據說可以並行,沒試過,只是每個網絡的訓練數據不同】
首先明確以下幾點:
作者采用的數據集為 wider face 邊框 和 Celeba 關鍵點
訓練三個網絡都需要四種數據
- positive:正樣本,與 ground truth IOU > 0.65 的 bbox;
- negative:負樣本,與 ground truth IOU < 0.3 的 bbox;
- part:部分臉, 0.4 < 與 ground truth IOU < 0.65 的 bbox;
- landmark:關鍵點;
三種 任務 所需數據不同
- 分類任務:只需要 positive 和 negative;
- 回歸任務:只需要 positive 和 part;
- 對齊任務:只需要 landmark;
P-Net 訓練
第一步,生成數據集
隨機裁剪 不同 size 的正方形 bbox,計算與 GT 的 IOU,獲取以下訓練集:
- negative1:獲取 50 個,真的隨機裁剪;
- negative2:獲取 5 個,在人臉附近裁剪,保證 偏移量 < 裁剪框 size,這樣 bbox 與 人臉 的 IOU 是大於 0 的;
- positive and part:共約 20 個,在人臉附近裁剪;
- landmark:每個人臉區域附近生成10個框框,根據iou,保存有效的框框,隨機進行翻轉flip,或者旋轉rotate,旋轉 + 翻轉,中的1步或幾步進行數據增強;
把這些 裁剪 的圖片縮放成 12x12 大小;
第二步,生成 label
positive 的 label 有兩部分,是否為人臉,bbox 的坐標;
// 如果是人臉,label 為 1;
part 的 label 也是兩部分,是否為人臉,bbox 的坐標;
// 如果是人臉,label 為 -1,;
negative 的 label 只有一部分,是否為人臉;
landmark 的坐標也是兩部分,是否為人臉,關鍵點坐標;
// 如果是人臉,label 為 -2;
label 中所有 坐標都是 偏移量 offset
為什么要用 offset?
首先 offset 是個很小的值,方便我們做回歸,容易學習,其次 offset 是個相對位置,bbox 左上角 相對於 ground truth 左上角的偏移量,根據偏移量我們很容易獲取它在原圖的位置;
如何計算 offset?
positive 和 part 的 offset 計算方式如下,
假設真實 label 的坐標為 [x1,y1,x2,y2],裁剪框的坐標為 [xa,ya,xb,yb],那么裁剪框的 size = xb-xa = yb-ya,那么 offset 為
offset_xa = (x1-xa) / size
offset_ya = (y1-ya) / size
offset_xb = (x2-xb) / size
offset_yb = (y2-yb) / size
為什么是 x1-xa,而不是 xa-x1?為什么是 bbox 的 size,不是 gt 的 size?
首先 offset 是我們的 label,那么網絡的輸出就是我們預測的 offset,我們需要拿預測的 offset 計算出它在原圖的坐標,offset 需要乘以一個 size,然后 加上 一個 x ;
而 size 我們只有 預測出來的 bbox 的 size 啊,真實的 size 根本沒有啊,特別是 test 階段,所以 size 是 bbox 的 size;
然后 加上 一個 x 得到 另一個 x,需要得到的是 gt 的 x,所以加上的只能是 bbox 的 x 了;
offset 圖解
landmark 的 offset 計算同理與 bbox;
第三步,輸入樣本,計算 loss
注意,每種 loss 需要不同的數據集,我們可以選擇 分別輸入 各種數據集,
如 先 輸入 positive 和 negative 用作 分類任務,此時 回歸 loss 都是 0 就行了,然后 再 輸入 bbox 樣本,此時 分類 loss 都是 0 就行了;
但這種做法感覺怪怪的;
更好的做法是,把所有樣本 打亂,隨機輸入各種樣本,然后根據 label [0 1 -1 -2] 來判斷是哪種樣本,從而計算對應的 loss 即可;
在計算 loss 時,作者提出了一種 在線困難樣本選擇的 方法,其實很簡單,就是把 所有 loss 排序,取前面一部分大的 loss,后面小的 直接舍棄,具體參考我的博客 ohem
第四步,NMS,這一步可有可無,有的話可大大減少計算量
R-Net 訓練
與 P-Net 的隨機裁剪不同,R-Net 是把 P-Net 輸出的 bbox 在原圖上進行裁剪,從而根據與 ground truth 的 IOU 得到 各種樣本;
其他與 P-Net 相同;
O-Net 訓練
把 R-Net 的輸出作為 裁剪框,其他與 P-Net 相同;
模型應用
MTCNN 不僅可以做人臉檢測,也可以做其他檢測,如交通流檢測,人流檢測;
它與 Yolo 的區別在於,Yolo 是多目標檢測,MTCNN 是多個單目標檢測,MTCNN 在單目標檢測領域要優於 Yolo;
參考資料:
https://blog.csdn.net/qq_36782182/article/details/83624357 MTCNN工作原理
https://blog.csdn.net/u014380165/article/details/78906898 MTCNN算法及代碼筆記
https://blog.csdn.net/weixin_44791964/article/details/103530206
https://zhuanlan.zhihu.com/p/58825924 知乎總是最詳細
https://zhuanlan.zhihu.com/p/64989774
https://blog.csdn.net/sinat_28731575/article/details/80330631
https://www.cnblogs.com/helloworld0604/p/9808795.html 訓練
https://zhuanlan.zhihu.com/p/72308496 訓練講得很清楚的教程
https://www.zhihu.com/collection/231012127