我用Python給自己手機寫了個人臉識別!拉開普通手機識別一萬倍!
本文首先會介紹人臉識別模型的內部工作原理。隨後結合一個簡單的案例,我們將通過Python進行案例實踐。在本文的最後部分,你將完成你的第一個人臉識別模型!
目錄
- 理解人臉識別的工作原理
- 案例學習
- Python應用
- 理解Python程式碼
- 人臉識別演算法的應用
理解人臉識別的工作原理
為了理解人臉識別演算法工作原理,我們首先來了解一下特徵向量的概念。(譯者注:此處的特徵向量指機器學習的概念,不同於矩陣理論。)
每個機器學習演算法都會將資料集作為輸入,並從中學習經驗。演算法會遍歷資料並識別資料中的模式。例如,假定我們希望識別指定圖片中人物的臉,很多物體是可以看作模式的:
進群:548377875 即可獲取數十套PDF以及大量的學習資料哦!
- 臉的長度(cm)
- 臉的寬度(cm)
- 臉的平均膚色(R,G,B)
- 脣部寬度(cm)
- 鼻子長度(cm)
當給定一個圖片時,我們可以標註不同的特徵並將其轉化為如下的特徵向量:
如此一來,我們的圖片現在被轉化為一個向量,可以表示為(23.1,15.8,255,224,189,5.2,4.4)。當然我們還可以從圖片中衍生出無數的其他特徵(如,頭髮顏色,鬍鬚,眼鏡等)。然而在這個簡單的例子中,我們只考慮這五個簡單的特徵。
現在,一旦我們將每個圖片解碼為特徵向量,問題就變得更簡單。明顯地,當我們使用同一個人的兩張面部圖片時,提取的特徵向量會非常相似。換言之,兩個特徵向量的“距離”就變得非常小。
此時機器學習可以幫我們完成兩件事:
- 提取特徵向量。由於特徵過多,手動列出所有特徵是非常困難的。一個機器學習演算法可以自動標註很多特徵。例如,一個複雜的特徵可能是:鼻子長度和前額寬度的比例。手動列出所有的這些衍生特徵是非常困難的。
- 匹配演算法:一旦得到特徵向量,機器學習演算法需要將新圖片和語料庫中的特徵向量進行匹配。
既然我們對人臉識別如何工作有了基本的理解,讓我們運用一些廣泛使用的Python庫來搭建自己的人臉識別演算法。
案例學習
首先給定一些人物臉部的圖片——可能是一些名人,如Mark Zuckerberg, Warren Buffett, Bill Gates, Shah Rukh Khan等,並把這些人臉看作我們的語料庫。現在,我們給定一些其他名人的新圖片(“新人物”),並判斷這些“新人物”是否在語料庫中。
以下是語料庫中的圖片:
如圖所示,我們所列舉的名人有Barack Obama, Bill Gates, Jeff Bezos, Mark Zuckerberg, Ray Dalio 和Shah Rukh Khan。
現在,假定“新人物”如下:
注:以上所有圖片均來自Google圖片。
顯而易見,這是Shah Rukh Khan。然而對電腦來說,這個任務很有挑戰性。因為對於我們來說,我們可以輕易地將圖片的多種特徵結合來判斷這是哪個人物。然而對電腦而言,學習如何識別人臉是非常不直觀的。
有一個神奇但是簡單的python庫封裝了以上提及的內容——可以根據臉部特徵生成特徵向量並且知道如何區分不同的臉。這個python庫叫做face_recognition。它應用了dlib——一個現代C++工具包,其中包含了一些機器學習演算法來幫助完成複雜的基於C++的應用。
Python中的face_recognition庫可以完成大量的任務:
- 發現給定圖片中所有的臉。
- 發現並處理圖片中的臉部特徵。
- 識別圖片中的臉。
- 實時的人臉識別。
接下來,我們將探討其中的第三種任務——識別圖片中的臉。
你可以在github的如下連結中獲取face_recognition庫的原始碼。
附連結:
https://github.com/ageitgey/face_recognition
事實上,這裡有一些如何安裝face_recognition庫的指導。
附連結:
https://github.com/ageitgey/face_recognition#installation-options
在你安裝face_recognition之前,還需要安裝dlib包。你可以從如下連結中找到安裝dlib的指導。
附連結:
https://gist.github.com/ageitgey/629d75c1baac34dfa5ca2a1928a7aeaf
Python應用
這部分包括使用face_recognition庫搭建簡單人臉識別系統的程式碼。這是一個應用操作的部分,我們將在下一部分解讀程式碼來理解更多細節。
# import the libraries import os import face_recognition # make a list of all the available images images = os.listdir('images') # load your image image_to_be_matched = face_recognition.load_image_file('my_image.jpg') # encoded the loaded image into a feature vector image_to_be_matched_encoded = face_recognition.face_encodings( image_to_be_matched)[0] # iterate over each image for image in images: # load the image current_image = face_recognition.load_image_file("images/" + image) # encode the loaded image into a feature vector current_image_encoded = face_recognition.face_encodings(current_image)[0] # match your image with the image and check if it matches result = face_recognition.compare_faces( [image_to_be_matched_encoded], current_image_encoded) # check if it was a match if result[0] == True: print "Matched: " + image else: print "Not matched: " + image
檔案結構如下:
facialrecognition:
- fr.py
- my_image.jpg
- images/
- barack_obama.jpg
- bill_gates.jpg
- jeff_bezos.jpg
- mark_zuckerberg.jpg
- ray_dalio.jpg
- shah_rukh_khan.jpg
- warren_buffett.jpg
我們的根目錄,facialrecognition包括:
- fr.py的形式的人臉識別程式碼。
- my_image.jpg – 即將被識別的圖片(“新人物”)。
- images/ –語料庫。
如果你按照前文建立檔案結構並執行程式碼,如下是你能得到的結果:
Matched: shah_rukh_khan.jpg Not matched: warren_buffett.jpg Not matched: barack_obama.jpg Not matched: ray_dalio.jpg Not matched: bill_gates.jpg Not matched: jeff_bezos.jpg Not matched: mark_zuckerberg.jpg
顯而易見,新名人是Shah Rukh Khan 並且我們的人臉識別系統可以識別!
理解Python程式碼
現在讓我們解讀程式碼來,並理解其工作原理:
# import the libraries import os import face_recognition
以上是引入操作。我們將通過已經建好的os庫來讀入語料庫中的所有圖片,並且通過face_recognition來完成演算法部分。
# make a list of all the available images images = os.listdir('images')
這個簡單的程式碼將幫助我們識別語料庫中所有圖片的路徑。一旦執行這些程式碼,我們可以得到:
images = ['shah_rukh_khan.jpg', 'warren_buffett.jpg', 'barack_obama.jpg', 'ray_dalio.jpg', 'bill_gates.jpg', 'jeff_bezos.jpg', 'mark_zuckerberg.jpg']
現在,以下程式碼將載入新人物的圖片:
# load your image image_to_be_matched = face_recognition.load_image_file('my_image.jpg')
為了保證演算法可以解析圖片,我們將人物臉部圖片轉化為特徵向量:
# encoded the loaded image into a feature vector image_to_be_matched_encoded = face_recognition.face_encodings( image_to_be_matched)[0]
剩餘的程式碼相對簡單:
# iterate over each image for image in images: # load the image current_image = face_recognition.load_image_file("images/" + image) # encode the loaded image into a feature vector current_image_encoded = face_recognition.face_encodings(current_image)[0] # match your image with the image and check if it matches result = face_recognition.compare_faces( [image_to_be_matched_encoded], current_image_encoded) # check if it was a match if result[0] == True: print "Matched: " + image else: print "Not matched: " + image
此時,我們:
- 對每個影象進行迴圈操作。
- 將影象解析為特徵向量。
- 比較語料庫中已經載入的圖片和被識別的新人物圖片。
- 如果兩者匹配,我們就顯示出來。如果不匹配,我們也要顯示結果。
如上所示,結果顯示這個簡單的人臉識別演算法進行得很順利。讓我們嘗試將my_image替換為另一個圖片:
當你再次執行這個演算法,將會看到如下結果:
Not matched: shah_rukh_khan.jpg Not matched: warren_buffett.jpg Not matched: barack_obama.jpg Not matched: ray_dalio.jpg Not matched: bill_gates.jpg Not matched: jeff_bezos.jpg Not matched: mark_zuckerberg.jpg
很明顯,系統沒有將馬雲識別為以上的任何一個名人。這意味著我們的演算法在以下方面都表現得很好:
- 正確地識別那些在語料庫中儲存的人。
- 對語料庫中不存在的人物進行標註。
人臉識別演算法的應用
人臉識別是一個成熟的研究方向,已被廣泛地應用在工業界和學術界。例如,一個罪犯在中國被捕可能就得益於人臉識別系統:系統識別了他的臉併發出警報。由此可見,面部識別可以用來減少犯罪。還有許多其他有趣的人臉識別案例:
- 面部身份驗證:Apple在iPhones中引入了Face ID以用於面部身份驗證。一些銀行也嘗試使用面部身份驗證來解鎖。
- 使用者服務:馬來西亞的一些銀行安裝了新的人臉識別系統,用於識別有價值的銀行客戶,以便銀行為其提供個人服務。進而銀行可以通過維持這類使用者並提升使用者滿意度來獲取更多收益。
- 保險行業:很多保險公司正在通過運用人臉識別系統來匹配人的臉和ID提供的照片,使賠付過程變得更簡單。
尾記
綜上所述,人臉識別是一個有趣的問題並且有很多強大的案例。這些應用可以有效地從各個方面為社會服務。儘管將這些技術商業化可能會帶來倫理風險,但我們會把這個問題留到下次討論。