海日冬晴
這個肯定不一定啊。github上大牛多的是,而且很多大學也有很厲害的人,我下面主要介紹下人臉識別的主要算法,同時提供具體實現代碼與模型文件,瞭解了算法之後你自己也可以封裝SDK,我先在這裡貼兩個github鏈接,文章後面再細講。
1.openface https://github.com/cmusatyalab/openface
2.insightface https://github.com/deepinsight/insightface
下面我將從以下幾個方面為大家介紹人臉識別算法的發展與怎樣應用算法構建sdk:
- 傳統的人臉識別算法
- 引入CNN後的人臉識別
- FaceNet算法的出現
- 其他loss算法
- 人臉識別模型輕量化的研究
- 人臉檢測的主流方式
傳統的人臉識別算法
在深度學習熱門以前,人臉識別主要是用一些傳統的方式在進行研究,之前比較主流的就是PCA降維後進行人臉識別,但是傳統方式侷限性很大,需要環境比較理想,對於光線,姿勢等的魯棒性太差,而且是一個閉合的分類識別,也就是隻能做分類,判斷是否屬於某個特定的預知的人。傳統的方法在opencv上有了很好的實現,自己也可以基於opencv做一定的封裝。
引入CNN之後的人臉識別
而在深度學習熱門以後,也開始逐漸有人用CNN來做人臉識別。但是這時候僅僅停留在使用利用CNN的siamese網絡來提取人臉特徵 ,然後利用SVM等方法進行分類,本質上還是一個分類問題,還是隻能對預先放置的人臉進行識別。
這種情況直到谷歌推出了一個叫做FaceNet的算法,使人臉識別的方式發生了巨大的改變。
FaceNet算法的出現
FaceNeta主要有兩大兩點,第一是利用DNN直接學習到從原始圖片到歐氏距離空間的映射,從而使得在歐式空間裡的距離的度量直接關聯著人臉相似度。這可是具有劃時代意義的進步,使用距離度量的方式就可以讓系統可以認識之前沒有參加過訓練的人,需要比較兩個人是否為同一個人時,只需要將兩張圖片方式網絡,得到輸出,再計算兩個輸出之間的距離,如果小於某一閾值就為同一個人。這種算法本質上將一個分類問題轉變成了一個距離度量問題,使得識別系統具有了開放性。
第二是引入triplet損失函數,使得模型的學習能力更高效。下面就是triplet損失函數的示意圖。
triplet loss的主要思想是通過LDA思想訓練分類模型,使得類內特徵間隔小,類間特徵間隔大。即使目標圖像 與類內圖片(同一個人)特徵距離小,與類間圖片(不同一個人)特徵距離大。更多關於這個算法細節讀者可以自行谷歌搜索一下研究。
我在文章開頭寫的openface是Brandon Amos等人基於FaceNet開發的一種深度學習人部識別系統,模型基於文章:FaceNet:為人臉識別統一的嵌入和聚類,通過Python和Torch來實現,以便能在在CPU或GPU上運行,並且支持也建議通過docker進行安裝。
其他loss算法
在FaceNet提出了triplet loss之後,業界逐漸也出現了其他的loss算法,有些已經達到了目前state-of-art的效果,我在這裡只是羅列下,具體各位可以關注我,後面我會推出人臉識別綜述,與各種損失函數總結。主要有:
- centerLoss
- contrastiveLoss
- rangeLoss
- large-margin
- l2-norm
- AM-softmax
- CosFace
- ArcFace
在我文章開頭貼出來的insightface裡,對於主流的幾個loss的算法都有識別,同時也提供了模型下載,各位可以關注一下。
人臉識別模型的優化
之前的FaceNet在訓練完成後,模型文件將近100M,在手機端部署將變得非常難,主要太消耗用戶流量。最近出現了一個新的算法,叫做MobileFaceNet,訓練完成後模型只有4M左右,同時準備度也和FaceNet非常接近,裡面主要是大量使用了1*1卷積和可分離卷積來減小模型大小。具體算法在上面的insightface中也有實現。
主流的人臉檢測算法
目前主流的人臉檢測算法為MTCNN,一個多任務級聯的CNN,能夠用於人臉檢測與人臉對齊,同時網絡結構也非常簡單,訓練完成後的模型也非常小,只有幾M的大小。算法主要有有P-Net,R-Net,O-Net等CNN級聯而成,不同的CNN具有不同的任務。以P-Net為例,它的主要結構如下圖所示:
P-Net採用全卷積神經網絡,去獲得候選窗體和邊界迴歸向量。同時,候選窗體根據邊界框進行校準。然後,利用NMS方法去除重疊窗體。
整體的檢測流程如下圖所示:
具體MTCNN的原理以及更多人臉識別算法的介紹,歡迎大家關注我,我後面會發表文章進行詳細講解。