去年蘋果的最新產品 iPhone X 最受熱議的莫過於全新的解鎖功能——取代了 TouchID 的FaceID。git
Apple 已經制造出了全面屏手機(雖然是備受吐槽和跟風的「劉海屏」),所以也得開發出與之對應能簡單迅速地解鎖手機的方法。github
正當 Apple 的競爭者們還在調整指紋傳感器的位置時,Apple 革新了手機解鎖方式——你只須要看着手機就能夠了。經過一個小巧先進的前置深度攝像頭,iPhone X 能夠創建一張用戶臉部的 3D 圖像。此外,紅外攝像頭也會拍攝一張用戶臉部的照片以適應不一樣環境下光線和顏色的變化。經過深度學習,手機能夠學習用戶的臉部,並在每次用戶舉起手機時辨識出來。使人驚訝的是,Apple 宣稱這項技術比 TouchID 更加安全,其錯誤率僅有百萬分之一。算法
隨着蘋果手機推出的這項革命性技術,市面上也出現了愈來愈多的採用人臉解鎖技術的手機,面部解鎖儼然成爲新的技術潮流。數據庫
那麼 iPhone X 的 FaceID 背後都有哪些祕密?做爲普通的開發者,咱們本身能實現它嗎?羅馬大學人工智能專業的一位叫 Norman Di Palo 的小夥最近就不斷琢磨了這個問題,最後通過一番探索後,藉助深度學習技術和 Python 編程,逆向破解了這項技術。下面咱們聽他嘮嘮怎麼作到的。編程
我(做者Norman Di Palo——譯者注)對 Apple 實現 FaceID 的技術十分感興趣——一切都是在設備上運行的,被用戶臉部稍微訓練一下就能在每次手機被舉起時順利地運行了。數組
個人關注點在於,怎樣利用深度學習實現這個過程以及如何優化每一個步驟。在本文,我將展現如何使用 Keras 實現相似 FaceID 的算法。我會詳細解釋我做出的各類架構決策並展現最終的實驗結果。我使用了 Kinect,一個很流行的 RGB 和深度攝像頭,它輸出的結果和 iPhone X 上的前置攝像頭很類似,只是設備體積要大一些。倒杯茶坐下來歇會兒,下面咱們一塊兒逆向破解 Apple 改變行業趨勢的這項新功能。安全
第一步是分析 FaceID 是怎樣在 iPhone X 上工做的。iPhone X 的白皮書能夠幫助咱們理解 FaceID 的基本工做原理。使用 TouchID 的時候,用戶須要先數次觸碰傳感器以記錄指紋。 15 到 20 次觸碰後,TouchID 就設置完成了。FaceID 也相似,用戶須要先錄入面部數據。過程很簡單:用戶只需和平時同樣正向看着手機,以後緩慢轉動頭部以完成全方位採集。網絡
就這麼簡單,FaceID 已經設置好,能夠用來解鎖手機了。錄入過程的驚人速度能夠告訴咱們不少關於其背後算法的信息。好比,驅動 FaceID 的神經網絡並非只是在進行分類,我接下來會進一步解釋。架構
對一個神經網絡來講,分類意味着學習預測它看到的臉是不是用戶的。所以,簡單來講,它須要利用訓練數據預測「是」或「否」。但和其餘不少深度學習用例不一樣,這個方法在這裏行不通。首先,神經網絡須要用從用戶面部新得到的數據從頭開始訓練模型,這須要大量的時間、計算資源和不一樣的人臉做爲訓練數據以得到反例(在遷移學習和對一個已經訓練好的網絡進行微調的狀況下,變化是很小的)。機器學習
不只如此,這種方法使 Apple 沒法「離線」訓練一個更爲複雜的網絡,好比先在實驗室裏訓練網絡,再把訓練好的、能夠直接使用的網絡放到手機裏。所以,我認爲 FaceID 是利用了一個被 Apple「離線」訓練好的相似孿生網絡的卷積神經網絡,將人臉映射到低維的潛在空間,再利用對比損失將不一樣人臉的距離最大化。這樣,你就獲得了一個能夠進行一次性學習的架構,Apple 的 Keynote 裏簡要提到了這一點。我知道,可能有些看官會對不少名詞感到陌生;別急,繼續讀下去,我會一步步解釋的。
孿生神經網絡是由兩個相同的神經網絡組成的,這兩個網絡的權重也徹底同樣。這個架構能夠計算特定的數據類型之間的距離,好比圖像。你讓數據經過孿生網絡(或者分兩步讓數據經過同一個網絡),網絡就會將其映射到一個低維的特徵空間,好比一個n維的數組,你再訓練網絡,使映射可以讓不一樣類別的數據離得越遠越好,相同類別的數據離得越近越好。長期來看,神經網絡會學着提取最有意義的特徵,將其壓縮成一個數組,並創建一個有意義的映射。爲了能更直觀的理解,想象你須要用一個很小的向量來描述狗的品種,這樣類似的狗的向量會更相近。你也許會用一個值表示狗的皮毛顏色,一個值表示狗的體型大小,另外一個值表示毛髮長度,等等。這樣,類似的狗就會有類似的向量。很聰明,不是嗎?孿生神經網絡就能夠替你作這件事,就像一個自編碼器。
上面這幅圖出自 Yann LeCun 參與發表的一篇論文,神經網絡能夠學習數字之間的類似性,並以 2 維爲它們自動分類。這樣的技術也能夠應用到人臉數據上。
利用這個技術,咱們能夠利用大量的人臉訓練出一個能夠識別類似人臉的架構。只要有足夠的預算和算力(就像 Apple 這樣),神經網絡的魯棒性能夠變得愈來愈強,能夠處理雙胞胎、對抗攻擊等更困難的樣本。這個方法的最後一個優勢是什麼呢?就是你有了一個即插即用的模型,它不須要進一步訓練,只要在一開始錄入時拍幾張照片,計算出用戶的臉在隱映射中的位置,就能夠識別不一樣用戶。(想象一下,像剛纔說的那樣,爲一隻新的狗創建表明它品種的向量,再把它儲存到什麼地方)此外,FaceID 能夠在用戶這一方適應眼鏡、帽子、化妝等忽然變化和麪部毛髮這樣的緩慢變化——只須要在映射中添加參考的面部向量,再根據新的外貌進行計算。
對於全部的機器學習項目來講,首先須要的就是數據。創建咱們本身的數據集須要時間和不少人的合做,是比較有挑戰的。所以,我在網上找到了一個看起來很合適的 RGB-D 人臉數據集。這個數據集由一系列人們面朝不一樣方向,作出不一樣表情的 RGB-D 圖片組成,就像 iPhone X 的用例同樣。
若是想看到最後的實現,能夠去個人 Github 庫,裏面有一個Jupyter Notebook。
另外,我在Colab Notebook也實驗過,你能夠試試看。
我基於 SqueezeNet 創建了一個卷積神經網絡,輸入是 RGB-D 人臉圖像,即 4 通道圖像,輸出是兩個嵌套之間的距離。神經網絡是根據對比損失函數訓練的,以減少同一我的的圖像之間的距離,加大不一樣人的圖像之間的距離。
圖爲損失對比函數。
通過一些訓練,神經網絡可以把人臉映射爲 128 維的數組,這樣同一我的的圖像會組在一塊兒,並遠離其餘人的圖像。這意味着,解鎖的時候,神經網絡只須要計算解鎖時拍下的照片和錄入時儲存下來的照片的距離。若是這個距離低於某個閾值(閾值越小越安全),設備就解鎖。
我利用 T-分佈隨機近鄰嵌入將 128 維的嵌套空間在 2 維空間可視化。每一個顏色表明了一我的:如你所見,神經網絡學會了把這些照片緊密的組在一塊兒。(在使用 T-分佈隨機近鄰嵌入的狀況下,集羣之間的距離是無心義的)使用 PCA 降維算法時也會出現頗有意思的圖像。
圖爲用t-SNE建立的嵌套空間中的人臉照片羣集。
圖爲用PCA建立的嵌套空間中的人臉照片羣集。
咱們如今能夠模擬一個 FaceID 的循環,來看看這個模型運行得怎麼樣了:首先,錄入用戶的臉;以後是解鎖,用戶的臉應當能夠成功解鎖設備而其餘人的臉則不行。如前所述,區別在於神經網絡計算出來的試圖解鎖設備的臉和錄入時的臉的距離是否小於某一個閾值。
咱們先從錄入開始:我從數據庫中提取了一系列同一我的的照片並模擬了設置面部識別的過程。設備會計算每一個姿態的嵌套,並儲存在本地。
圖爲模擬FaceID錄入人臉數據。
圖爲深度攝像頭看到的人臉數據錄入過程。
當同一個用戶試圖解鎖設備時,同一個用戶的不一樣姿態和表情的距離較低,平均大概在 0.3 左右。
圖爲嵌套空間中同一人物的臉部距離
而不一樣人的 RGB-D 圖像的距離則平均有 1.1。
圖爲嵌套空間中不一樣人物的臉部距離
所以,將閾值設置在 0.4 左右就能夠防止陌生人解鎖你的設備了。
在這篇博文中,我基於人臉嵌套和孿生卷積神經網絡,藉助 Keras 和 Python 實現了 FaceID 人臉解鎖的概念驗證。但願本文對你有所幫助和啓發,相關的 Python 代碼你也均可以在這裏找到。
對於本文所用的 Keras 工具及其提供有哪些深度神經網絡模塊,能夠看看我站的簡明教程。