畢設竟然抽到了模擬iPhone X的解鎖技術!還好我有點Python功底!
最近大家談論最多的關於新款iPhone X的功能之一就是新的解鎖技術,即TouchID的後續技術:FaceID。
進群:548377875 即可獲取數十套PDF哦! 原始碼在文章末尾!
建立了無邊框手機後,蘋果不得不找出新方法簡單快捷地解鎖手機。雖然一些競爭對手繼續使用放在不同位置的指紋感測器,但蘋果決定對解鎖手機的方式進行創新和變革:只需看一眼,FaceID就能安全地解鎖iPhone X。藉助一款先進(而且非常小巧)的前置深度相機,iPhone X可以建立使用者臉部的3D模型。此外,iPhone X通過紅外攝像頭識別人臉,可以避免環境光和顏色對人臉識別的影響。通過深度學習,手機可以捕捉到使用者臉部的很多細節,因此在使用者拿著手機的時候,手機可以識別出它的主人。比較令人驚訝的是,蘋果表示這種方法比TouchID更安全,出錯率為百萬分之一。
我對蘋果的FaceID的實現技術非常感興趣,特別是它完全執行在裝置上,而且只需利用使用者的面部進行一點點訓練,就可以在每次拿起手機的時候順利地進行識別。我研究瞭如何使用深度學習來實現此過程,以及如何優化每個步驟。在這篇文章中,我將展示如何使用Keras實現一個類似FaceID的演算法。我會介紹採用的各種架構,並展示一些在Kinect(一種非常流行的RGB-D相機,擁有與iPhone X前置攝像頭非常相似的輸出,但裝置本身更大)上的最終實驗。倒杯咖啡,讓我們開始逆向工程蘋果的新技術。
對FaceID的初步瞭解
“……賦予FaceID力量的神經網路不是簡單的分類。”
FaceID註冊的過程
第一步我們來仔細分析FaceID在iPhone X上的工作原理。我們可以通過蘋果的白皮書理解FaceID的基本機制。使用TouchID的時候,使用者必須多次按感測器來註冊自己的指紋。大約需要15-20次不同的觸控,iPhone才能完成註冊,並準備好TouchID。同樣地,FaceID也需要使用者進行臉部註冊。過程非常簡單:使用者只需像往常一樣看著手機,然後慢慢地轉動頭部一圈,從不同的角度註冊臉部。如此,註冊過程就完成了,手機已經準備好解鎖了。這個超快的註冊過程可以告訴我們很多關於底層學習演算法的資訊。比如,FaceID背後的神經網路並不是簡單的分類。我會在後面進行詳細的解釋。
Apple Keynote推出iPhone X和FaceID
對於神經網路來說,分類的意思是學習如何預測看到的臉是不是使用者的臉。所以,它需要一些訓練資料來預測“是”或“否”,但與很多其他深度學習的應用場景不同,所以這種方式在這裡並不適用。首先,神經網路需要使用從使用者臉上捕捉到的資料重新進行訓練。而這需要消耗大量的時間和電量,還需要大量的不同面孔作為訓練資料以獲得負面的樣本,這也是不現實的。即使是試圖遷移並微調已經訓練好的神經網路,這些條件也幾乎不會變化。而且,蘋果也不可能在實驗室等地方“線下”訓練複雜的神經網路,然後再將訓練好的神經網路搭載在手機中。相反,我認為FaceID是由孿生卷積神經網路實現的(siamese-like convolutional neural network),該網路由蘋果公司進行“線下”培訓,將臉部對映到一個低維潛在空間(latent space),並通過對比損失函式(contrastive loss)最大化不同人臉之間的距離。通過本文,你可以瞭解Keynote中提到的體系結構。我知道,很多讀者對上述名詞很陌生,但是沒關係,我會逐步的進行詳細的解釋。
FaceID看起來會是TouchID之後的新標準。蘋果是否會把它帶到所有的新裝置上?
從人臉到神經網路的數字
孿生神經網路基本上由兩個完全相同的神經網路組成,它們所有的權重也都相同。這種結構可以計算特定型別的資料(如影象)之間的距離。基本思路是,將兩組資料傳遞給孿生網路(或簡單地將兩組資料分兩次傳遞給同一個神經網路),而這個網路會將資料對映到一個低維特徵空間(就像一個n維陣列),然後訓練神經網路將不同類別下的資料點對映到儘可能遠的地方,同時保證同一類的資料點又儘可能接近。從長遠來看,這個網路將學習如何從資料中提取最有意義的特徵,並將其壓縮成一個數組,從而建立一個有意義的對映。為了對此有一個直觀的理解,想象一下你如何使用小型向量來描述狗狗的品種,並保證類似的狗狗具有最接近的向量值。你可能會用一個數字來表示狗狗的毛色,另一個用來表示狗狗的大小,還有一個用於記錄毛的長度,等等。通過這種方法,彼此相似的狗狗就可以擁有相似的向量值。這個方法是不是很聰明?那麼,孿生神經網路也可以做到這一點,類似於一個自動編碼器。
Hadsell,Chopra和LeCun發表的論文“Dimensionality Reduction by Learning an Invariant Mapping”。請注意此架構是如何學習數字之間的相似性,並自動將它們分組在二維中。類似的技術也可以應用於面部識別。
通過這種技術,只需使用大量面部資料來訓練一個這種網路,就可以識別哪些面部最相似。如果擁有足夠的預算和計算能力(就像蘋果一樣),我們甚至可以使用越來越難的例子(比如雙胞胎)來強化這個神經網路,以便應對面具等惡意攻擊。那麼使用這種方法有什麼優勢呢?那就是我們終於有了現成的模型,只需要簡單計算出使用者的面部資料在潛在對映(latent map)中的位置,就可以識別出不同的使用者,而無需額外訓練。(就像前面說過的,我們記錄下新的狗狗品種的向量值,然後儲存起來。)此外,FaceID還可以適應臉部的變化,包括突發性變化(比如眼鏡、帽子、化妝等)以及緩慢變化(毛髮等)。這基本上是通過向對映中增加參考向量,並根據新外觀進行計算而實現的。
FaceID可以適應外觀的變化
接下來,讓我們看看如何利用Python和Keras實現。
使用Keras實現FaceID
就像所有的機器學習專案一樣,我們首先需要的是資料。建立自己的資料集需要花費大量時間和許多人的配合,這項工作本身可能非常具有挑戰性。因此,我搜索了網路上RGB-D的人臉資料集,找到了一個非常合適的資料集(http://www.vap.aau.dk/rgb-d-face-database/)。這個資料集是根據人臉面向不同的方向以及不同的表情製作出的RGB-D影象集,正好類似於iPhone X的情況。
最終的實現可以參考我的GitHub程式碼庫(https://github.com/normandipalo/faceID_beta),裡面有個Jupyter Notebook。我還進一步嘗試了使用Colab Notebook,你也可以試試看。
我建立了一個基於SqueezeNet架構的卷積網路。這個神經網路以兩組RGBD的面部影象(即4通道影象)作為輸入,並輸出兩組資料之間的距離。該網路用對比損失函式(constrastive loss)訓練,可以最大程度地減少同一人的照片之間的距離,同時最大程度地提高不同人的照片之間的距離。
對比損失函式
經過一段時間的訓練後,這個神經網路可以將人臉對映到128維陣列中,並將同一個人的照片分在一組,與其他人的照片分離。這意味著,該神經網路只需計算解鎖過程中拍攝的照片與註冊階段儲存的照片之間的距離,就可以實現解鎖裝置。如果距離低於某個閾值,則裝置解鎖(閾值越小,裝置越安全)。
我使用t-SNE演算法在二維空間中顯示了128維的嵌入空間。每種顏色都對應不同的人,可以看出,網路已經學會了將這些圖片分組並緊密排列。當使用t-SNE演算法時,簇之間的距離沒有意義。使用PCA降維演算法時也會看到一個有趣的圖。
使用t-SNE建立嵌入空間中的人臉的簇,每種顏色代表不同的面孔(但顏色被重複使用)
使用PCA建立嵌入空間中的人臉的簇,每種顏色都是不同的面孔(但顏色被重複使用)
實驗!
現在我們可以試試個模型,模擬一個常見的FaceID的流程:首先,註冊使用者的面部;然後在解鎖階段,需要驗證兩個方面——主人可以解鎖,而其他人不可以。 如前所述,區別在於神經網路會計算解鎖手機時和註冊時的臉部的距離,然後判斷是否在某個閾值以下。
下面我們來註冊:我從資料集中採集了同一人的一系列照片,並模擬了註冊階段。現在該裝置將計算每個姿勢的嵌入,並儲存在本地。
新使用者註冊階段,模仿FaceID的過程
在深度相機中觀察到的註冊階段
嵌入空間中同一個使用者的面部距離
嵌入空間中不同使用者的面部距離
因此,我們可以將閾值設定為大約0.4,就可以阻止陌生人解鎖裝置了。
結論
在這篇文章中,我展示瞭如何利用面部嵌入和孿生卷積神經網路,實現FaceID解鎖機制的原型。希望對你能有所幫助。如果你有任何問題都可以和我聯絡。你可以從以下連結找到所有相關的Python程式碼:
https://github.com/normandipalo/faceID_beta
此篇乃是參考!畢設等我完成了在給大家分享!