人臉辨識模型Google Facenet 介紹與使用 - MakerPRO

文章推薦指數: 80 %
投票人數:10人

本篇文章介紹Facenet 的辨識模型和架構,並在Keras 環境下實際測試。

近年來透過深度學習以及CNN,不但開啟了人臉辨識領域的新紀元,也讓傳統的LBP、HOG ... 人臉辨識模型GoogleFacenet介紹與使用 Home» 人工智慧»人臉辨識模型GoogleFacenet介紹與使用 Postedon12月27,2018in人工智慧,教學文,智慧演算 作者:CH.Tseng Google於2015年所提出的人臉辨識系統Facenet,由於演算原理容易理解且應用方便,成為目前最流行的臉部識別技術。

本篇文章介紹Facenet的辨識模型和架構,並在Keras環境下實際測試。

近年來透過深度學習以及CNN,不但開啟了人臉辨識領域的新紀元,也讓傳統的LBP、HOG搭配支援向量機SVM的辨識方法顯得落伍。

這些複雜的深度學習模型不但辨識率極高,而且能識別的人數級別與相片總量也都以萬級來計算,若侷限於學術的實驗情境下與人眼來比較,這成績已經遠遠抛開我們肉眼的能力了。

2015年由Google所提出的Facenet,在LFW人臉資料庫以99.63%的最佳成績刷新了記錄,由於其易於理解的演算原理以及應用方便,使得Facenet在眾多競爭者中(如DeepFace、DeepID、Face++…等)異軍突起,成為目前最流行的臉部識別技術。

下面,我們大致來瞭解一下Facenet,並且學習如何來使用它。

Ps.LFW資料集中收錄了5749位公眾人物的人臉影像,總共有超過一萬三千多張影像檔案。

但大部份公眾人物的影像都只有一張,只有1680位有超過一張照片,而極少數有超過10張照片(台大計算中心網站連結)。

輸出量化特徵值,而非輸出分類結果 下圖是標準的臉部辨識作業流程,首先1.針對輸入的影片或相片進行臉孔偵測FaceDetection,接著2.進行臉部校正對齊FaceAlignment,然後開始3.依據不同的算法來取得臉部的特徵FeatureExtraction,有了特徵,傳統的作法是4.據此來計算與匹配不同的臉孔圖片,最後5.透過softmax輸出至各分類結果,但Facenet則不然,模型所輸出的是該臉孔特徵的歐式距離總和。

臉部辨識作業流程 由於Facenet模型輸出的是量化的數值,因此我們就能利用此數值來比對多張臉孔的差異度,並應用於如下的人臉辨識領域,顯示出Facenet相較其它的技術更為通用。

FaceVerification驗証是否為同一人 FaceIdentification辨識身份或姓名 FaceCluster相似的人分類在一起 FaceSearch搜索相似的人 FaceTracking 跟蹤特定的人臉 TripletLoss:模型的核心 模型需要取得圖片不同的特徵並映射到歐幾里德的空間中(即計算特徵間的歐氏距離),所採用的作法是Tripletloss,如下圖原論文中的圖示說明。

Tripletloss的運作模式 TripletLoss想法在於,如果我們選取與該樣本最相像(差異最小)的錯誤臉孔,與最不像(差異度大)的正確臉孔,同時進行特徵訓練,迭代訓練至誤差降至最小,用以改進模型中的臉孔特徵定義,如此一來,便能得到最佳的辨識結果。

Facenet架構 Facenet主要由以下步驟所組成: Facenet的組成步驟 Batch→ Batchinputlayer將臉孔圖片輸入模型,這些圖片需已經Facialalignment及resize處理。

原開發者使用MTCNN來進行臉孔偵測及校準 DeepArchitecture→ 即用於特徵學習的CNN架構,具彈性可以採用不同的網路。

剛推出時使用Zeiler&Fergus架構和Google的Inceptionv1,今年最新版改為InceptionResNet-v2。

不同架構對於辨識結果有顯著的影響,如下圖為使用不同的networkmodel的辨識成績差異。

使用不同的networkmodel的辨識成績差異 L2→ L2normalization歸一化,讓資料能對應到一個超平面。

Embedding→ 經過CNN模型以及L2歸一化後生成的特徵向量 ​TripletLoss→ 從向量中取得一個embedding函數f(x),讓相同孔之間的特徵距離要盡可能的小,而不同孔之間的特徵距離要盡可能的大。

在Keras環境使用Facenet Facenet使用Tensorflow開發,不過已有很多有心人士另外撰寫為Cafffe或Keras等版本,如果我們想要在Keras環境中使用,推薦可以採用 keras-facenet。

作者提供了一個預訓練好的Keras model可直接下載使用。

當然也可以下載其它的預訓練models,再透過作者提供的轉檔程式 tf_to_keras.ipynb轉為.h5 model來使用。

下載預訓練模型 作者提供的預訓練模型是使用MS-Celeb-1Mdataset訓練,用於一般環境的辨識來說效果已相當不錯,並不一定要自行搜集臉孔資料來訓練。

MS-Celeb-1M是微軟於2016年6月所公開發佈的人臉資料庫,包含100萬個名人總共約800多萬張人臉影像。

下面說明如何在使用Keras版本的Facenet: Step1.gitclone(載點) Step2.下載(載點)預訓練模型,將該檔 facenet_keras.h5放置於model/keras/目錄下 程式說明 我改編了作者用於示範的.pynb程式,可方便驗證compares列表中相片的人與valid相片中的人,其差異度為多少。

程式碼 importnumpyasnp importos,time importcv2 fromskimage.transformimportresize fromscipy.spatialimportdistance fromkeras.modelsimportload_model #驗證compares列表中相片的人與valid相片中的人 valid=“200127/200127_1.jpg” compares=[“200002/200002_1.jpg”,“200127/200127_1″,“200127/o.jpg”] #用OpenCV的Cascadeclassifier來偵測臉部,不一定跟Facenet一樣要用MTCNN。

cascade_path=‘haarcascade_frontalface_default.xml’ #我們的人像相片都放置於validPicPath validPicPath=‘members/’ #此版Facenetmodel需要的相片尺寸為160×160 image_size=160 #使用MS-Celeb-1Mdatasetpretrained好的Kerasmodel model_path=‘model/facenet_keras.h5’ model=load_model(model_path) #———————————————————— #圖像白化(whitening)可用於對過度曝光或低曝光的圖片進行處理,處理的方式就是改變圖像的平均像素值為0,改變圖像的方差為單位方差1。

defprewhiten(x): ifx.ndim==4: axis=(1,2,3) size=x[0].size elifx.ndim==3: axis=(0,1,2) size=x.size else: raiseValueError(‘Dimensionshouldbe3or4’) mean= np.mean(x,axis=axis,keepdims=True) std= np.std(x,axis=axis,keepdims=True) std_adj=np.maximum(std,1.0/np.sqrt(size)) y=(x–mean)/std_adj returny #使用L1或L2標準化圖像,可強化其特徵。

defl2_normalize(x,axis=-1,epsilon=1e-10): output=x/ np.sqrt(np.maximum(np.sum(np.square(x),axis=axis,keepdims=True),epsilon)) returnoutput #偵測並取得臉孔area,接著再resize為模型要求的尺寸(下方例子並未作alignment) defalign_image(img,margin): cascade=cv2.CascadeClassifier(cascade_path) faces=cascade.detectMultiScale(img,scaleFactor=1.1,minNeighbors=3) if(len(faces)>0): (x,y,w,h)=faces[0] face=img[y:y+h,x:x+w] faceMargin= np.zeros((h+margin*2,w+margin*2,3),dtype=“uint8″) faceMargin[margin:margin+h,margin:margin+w]=face cv2.imwrite(str(time.time())+”.jpgceMargin) aligned=resize(faceMargin,(image_size,image_size),mode=’reflect’) cv2.imwrite(str(time.time())+”_aligned.jpgigned) returnaligned else: returnNone #圖像的預處理(即前述的幾項步驟) defpreProcess(img): whitenImg=prewhiten(img) whitenImg=whitenImg[np.newaxis,:] returnwhitenImg #————————————————- imgValid=validPicPath+valid aligned=align_image(cv2.imread(imgValid),6) if(alignedisNone): print(“Cannotfindanyfaceinimage:{}”.format(imgValid)) else: faceImg=preProcess(aligned) #–>model會輸出128維度的臉孔特徵向量,接著我們將它們合併並進行L2正規化。

Z embs_valid=l2_normalize(np.concatenate(model.predict(faceImg))) #同上方的valid圖片,依序取得各圖片人臉的臉孔特徵向量,再與valid進行歐氏距離計算。

formemberincompares: img_file=validPicPath+member aligned=align_image(cv2.imread(img_file),6) if(alignedisnotNone): faceImg=preProcess(aligned) embs=l2_normalize(np.concatenate(model.predict(faceImg))) distanceNum=distance.euclidean(embs_valid,embs) print(“Diffwith{}is{}”.format(member,distanceNum)) 程式測試 我們將一些不同人的相片放置於members目錄下,目錄名稱為其人名或代表工號,接著來測試看看。

正面臉孔: 1.082138 0.493925 效果看來不錯,只憑左邊一張相片,Facenet就能判斷出右下方臉孔與左圖較為相似,雖然其拍攝角度的差異更大。

這次測試下方往上的正面臉孔: 1.0013418 1.0399750 0.7001376 毫無懸念的Facenet又猜對了,雖然我們肉眼感覺下圖中間的人臉其構圖上更為近似。

側面的臉孔: 0.36971601843833923 0.9557983875274658 0.7647050619125366 0.6167847514152527     使用一張側面的臉孔來預測其它角度的臉孔,果然差異值最小的那兩張與上方的確是同一人沒錯。

小結 本文簡單的介紹了Facenet,並且示範如何於Kerasframework使用。

dataset並非自行訓練而是使用微軟MS-Celeb-1Mdataset,雖然如此,單張相片的verify能力已相當令人驚豔,如果希望應用在公司內部並提昇到更高的辨識率,建議應考慮加入自行搜集的相片重新訓練以製作更符合公司人員的model。

另外,如果在一般的PC上執行,您會發現Facenet速度不是很快速,此時可以考慮改為在GPU上執行,在迅速的辨識速度下,可作出各種有趣且實用的人臉辨識專案。

(本文經作者同意轉載自CH.TSENG部落格、原文連結;責任編輯:葉于甄) AboutLatestPosts曾成訓人到中年就像沒對準的描圖紙,一點一點的錯開,我只能當個Maker來使它復位。

Latestpostsby曾成訓(seeall) 【模型訓練】訓練馬賽克消除器-274月,2020 【AI模型訓練】真假分不清!訓練假臉產生器-134月,2020 【AI防疫DIY】臉部辨識+口罩偵測+紅外線測溫-233月,2020 Like0 相關文章 Author:曾成訓 人到中年就像沒對準的描圖紙,一點一點的錯開,我只能當個Maker來使它復位。

ShareThisPostOn GoogleFacebookTwitter 發表 取消回覆 訂閱MakerPRO週報! 我們為您設計了電子報: 只需留下E-Mail,即可獲得最新的知識文章分享和第一手的活動資訊! 加入MakerPRO粉專線上課程專區近期活動 DesignedbyMakerPRO LoginIDPassword RememberMe ForgotPassword?   Login 跳至工具列 關於WordPressWordPress.org台灣繁體中文線上說明技術支援意見反應登入註冊搜尋



請為這篇文章評分?