跳到主要內容區塊

ntuccepaper2019

專題報導

以深度學習進行人臉辨識
  • 卷期:v0043
  • 出版日期:2017-12-20

作者:周秉誼 / 趨勢科技 技術經理


影像辨識相關的應用一直是深度學習最為人所知、也最令人驚豔的應用,包括了手寫數字辨識、影像物件識別等等。而在影像相關的應用中,最關鍵的技術就是卷積神經網路 (CNN, Convolutional Neural Networks),因此卷積神經網路也在一般人心中成為深度學習的同義詞。
在Facebook上傳照片之後,常常連自己都還沒認出照片上的朋友,就被Facebook自動辨識出來,這就是影像辨識相關應用中,最神奇的一個應用-人臉辨識(Face Recognition)。本文將介紹怎麼使用深度學習的卷積神經網路,來完成這個被廣泛使用的影像辨識應用-人臉辨識。

 

人臉影像資料集

如果想要自己從頭訓練人臉辨識的深度學習神經網路,就要先有大量的人臉影像資料。網路上常見的人臉資料庫包括了VGG-Face Dataset以及LFW (Labeled Faces in the Wild)。
VGG-Face Dataset是牛津大學視覺幾何研究群(Visual Geometry Group, VGG)整理的人臉資料集,是2015年在Deep Face Recognition論文中發佈的,以創用授權 (CC, Creative Commons)的姓名標示─非商業性條款 (by-nc)釋出。資料集中收集了2622位公眾人物的人臉影像資料,大部份公眾人物都收集了近1000張的人臉影像,共有超過兩百六十萬張影像,而且大部份的資料跟其他常用的資料集並沒有重複。然而因為原始照片的著作權,資料集只提供了每個原始影像的下載連結,並沒有直接提供影像檔案,所以使用上會比較不方便。
LFW資料集是另一個常見的人臉資料集,歷史也是非常悠久,在2007年底就有相關的討論群,在深度學習還沒廣為人知之前,電腦視覺(Computer Vision)的研究就很常使用LFW資料集來進行人臉辨識的研究了,因此LFW網站上也整理了多達100種不同方法的效果。在LFW資料集中收錄了5749位公眾人物的人臉影像,總共有超過一萬三千多張影像檔案。但大部份公眾人物的影像都只有一張,只有1680位有超過一張照片,而極少數有超過10張照片,所以要使用LFW資料集來訓練人臉辨識的深度學習模型,並不是很合適。

 

VGG-Face模型

另一個方式是使用預先訓練好的深度學習模型,如前面提到的牛津大學視覺幾何研究群,除了發表了影像中的物件辨識模型VGG16及VGG19以外,也在2015年的Deep Face Recognition論文中提出了針對人臉辨識來使用的VGG-Face卷積神經網路模型。VGG-Face是以VGG16卷積神經網路的架構為基礎修改的,使用了先前提到的VGG-Face Dataset來進行訓練,所以可以辨識出2622位不同的公眾人物。論文中也使用LFW資料集進行效能的驗證,在LFW資料集最好可以達到小於1%的錯誤率。

 

 

更棒的是,牛津大學視覺幾何研究群也將訓練好的VGG-Face模型以創用授權的姓名標示─非商業性條款釋出,並提供了Torch及Caffe等深度學習套件的程式碼,也有人將程式碼改寫為使用Python中Keras深度學習套件。

 

Keras VGG-Face套件

安裝好tensorflow及Keras套件後,只要用Python套件管理系統pip安裝Keras_vggface套件,就可以用Keras的介面操作移植到Keras的VGG-Face模型。除了預測VGG_Face資料集中包括的公眾人物,也可以使用VGG-Face模型中神經網路的高層結果來抽取人臉的特徵值(features),就能用來比較不同人臉照片的相似程度。以下會分別介紹這兩個不同的使用方式。
表1中的程式碼可以用來判斷輸入的照片是VGG_Face資料集中的那一位公眾人物。在程式碼第5行中,使用VGGFace()函式就會產生一個以Keras套件為基礎的VGG-Face的深度學習模型,並且自動從github網站下載牛津大學視覺幾何研究群預先訓練好的VGG-Face模型。程式碼6到10行用來讀取輸入的照片檔案,並轉換為VGG-Face模型的輸入格式。第11行呼叫了predict()函式就會依據不同輸入照片及模型權重(weight)產生出最像的公眾人物的預測機率值,並在第12行印出結果。
表3中的程式碼可以利用預先訓練的VGG-Face模型抽取人臉照片的特徵值,用來比較兩張照片的相似程度。這樣就能夠在沒有足夠訓練資料的情況下,比對不同的人臉照片。程式碼第7到13行的extract()函式是用來讀取照片檔案、轉換格式,並產生特徵值。第15到17行設定將VGG-Face模型fc7層的結果作為特徵值,由這一層抽取出來的特徵值共有4096個浮點數,可以用來描述這張照片中的人臉。第18和19行呼叫了extract()函式分別將兩個人臉照片的特徵值抽取出來。21和22行使用了兩個不同的方式來評估兩張人臉的相似程度,第21行使用了numpy套件提供的norm()函數來計算兩個人臉照片的特徵值間的範數 (norm)、第22行使用的是scipy套件提供的cosine()函式,可以用來計算兩組特徵值的餘弦相似性 (Cosine Similarity)。

 

1
2
3
4
5
6
7
8
9
10
11
12

from Keras.preprocessing import image
from Keras_vggface.vggface import VGGFace
from Keras_vggface import utils

model = VGGFace()

img = image.load_img('face1.png', target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = utils.preprocess_input(x)
preds = model.predict(x)
print('Predicted:', utils.decode_predictions(preds))

表1. Keras_vggface人臉預測程式碼

 

('Predicted:', [[['Charles_Durning', 0.1836438], ['David_Attenborough', 0.071915463], ['Derek_Jacobi', 0.034831561], ['Richard_Attenborough', 0.028829174], ['Steven_Berkoff', 0.020872355]]])

表2. Keras_vggface人臉預測程式輸出

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

from Keras.engine import Model
from Keras.layers import Input
from Keras_vggface.vggface import VGGFace
from Keras.preprocessing import image
from Keras_vggface import utils

def extract(model, fn):
    img = image.load_img(fn, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = utils.preprocess_input(x)
    feats = model.predict(x)
    return feats

vgg_model = VGGFace()
out = vgg_model.get_layer('fc7').output
model = Model(vgg_model.input, out)
feats1=extract(model, 'face1.png')
feats2=extract(model, 'face2.png')

print(numpy.linalg.norm(feats1-feats2))
print(scipy.spatial.distance.cosine(feats1, feats2))

表3. Keras_vggface人臉特徵值抽取及比較程式碼

 

人臉辨識API

除了自行訓練或使用預先訓練的深度學習模型來進行人臉辨識,也可以使用各大雲端平台提供的人臉辨識API,就能直接利用到各個雲端平台架設、並訓練好的深度學習環境了,如Amazon的Rekognition服務、Microsoft的Cognitive服務都有提供人臉相似度的比對。

 


圖4. Amazon Rekognition服務

 


圖5. Microsoft Cognitive服務

 

以Amazon的Rekognition服務為例,Rekognition服務的API可以直接對AWS S3上的照片進行比對,所以在呼叫人臉比較之前,要先把照片上傳到S3。表6中的程式碼可以呼叫Rekognition服務的人臉比較API來比對兩張照片。程式碼第7行使用boto3套件中的client('rekognition')函式來產生一個可以使用Rekognition服務的物件。第9行呼叫compare_faces()函式,並在第10和11行設定要比對的兩張照片。第14及15行會取出Rekognition服務API的回應,在16和17行印出比對的結果。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

import boto3

bucket='S3-face'
sourceFile='face1.jpg'
targetFile='face2.jpg'

client=boto3.client('rekognition')

response=client.compare_faces(SimilarityThreshold=60,
    SourceImage={'S3Object':{'Bucket':bucket,'Name':sourceFile}},
    TargetImage={'S3Object':{'Bucket':bucket,'Name':targetFile}})

for faceMatch in response['FaceMatches']:
    position = faceMatch['Face']['BoundingBox']
    confidence = str(faceMatch['Face']['Confidence'])
    print('The face at (%d, %d)'%(position['Left'], position['Top']))
    print('matches with ' + confidence + '% confidence')

表6. AWS Rekognition服務程式碼範例

 

結語

人臉辨識目前已經被廣泛使用在各種不同用途,如照片自動標籤、打卡簽到、門禁系統、連手機都可以使用人臉辨識的方式來解鎖。因為相較於傳統電腦視覺的特徵抽取 (Feature Extraction),使用了深度學習的人臉辨識系統,可以達到更好的效果,也讓人臉辨識更能夠融入人們的日常生活中。