Python新玩法!如何自己動手實現FaceID功能
作者 | Norman Di Palo
譯者 | 大愚若智
編輯 | Emily
AI 前線導讀:本文探討了 Face ID 功能是如何在設備本地,僅通過少量訓練就能實現極高識別率的,並介紹了基於面容嵌入和連體卷積網路,使用 Python 代碼實現類似機制的方法。
更多乾貨內容請關注微信公眾號「AI 前線」,(ID:ai-front)
對 iPhone X 的全新解鎖機制進行逆向工程。
本文涉及到的所有 Python 代碼可以在這裡獲取。
https://github.com/normandipalo/faceID_beta
圍繞新款 iPhone X 最熱議的話題之一就是用於取代觸控 ID 的全新解鎖機制:
Face ID。
為了順利打造出無邊框的全面屏手機,Apple 必須開發一種能快速簡單地解鎖手機的全新方法。雖然很多競品依然在全面屏手機上使用指紋感測器,但必須將感測器放置在其他位置,而 Apple 決定通過創新為手機開發一種革命性的全新解鎖方式:注視一眼就夠了。藉助先進(並且體積非常小巧)的前置原深感攝像頭,iPhone X 可以為用戶的面孔創建 3D 面譜,此外還會使用紅外鏡頭捕獲用戶面孔照片,這樣便可更好地適應環境光線與色彩的變化。藉助深度學習技術,這款手機可以學慣用戶面容的細節變化,確保用戶每次拿起自己的手機後都能快速解鎖。令人驚訝的是,Apple 宣稱這種方法甚至比觸控 ID 更安全,錯誤率可低至 1:1,000,000。
我對 Apple 實現 Face ID 所用的技術很好奇,尤其是考慮到這個功能完全是在設備本地實現的,只需要通過用戶面容進行少量訓練,就可以在用戶每次拿起手機後非常流暢自然地完成識別。於是我研究了如何使用深度學習技術實現這一過程,並對每個步驟進行優化。本文我將介紹如何使用 Keras 實現類似於 Face ID 的演算法。我會介紹在選擇最終架構時的考慮因素,以及通過 Kinect 這一流行的 RGB 和景深攝像頭(能獲得與 iPhone X 的前置攝像頭非常類似的輸出結果,但體積略大)進行實驗的過程。找個舒適的姿勢坐下來,端起茶杯,開始進行Apple 創新功能的逆向工程吧。
GIF
理解 Face ID
「…驅動 Face ID 的神經網路並不僅僅是執行分類操作那麼簡單。」
GIF
Face ID 的配置過程
首先需要細緻分析一下 iPhone X 中 Face ID 的工作原理。Apple 提供的白皮書可以幫助我們理解有關 Face ID 的基礎機制。在使用觸控 ID 時,用戶首先要觸碰感測器多次,以註冊自己的指紋。在進行過大約 15–20 次觸碰後,即可完成註冊過程,隨後就可以使用了。類似的,使用 Face ID 時,用戶也要註冊自己的面孔信息。整個過程非常簡單:按照正常使用時的操作注視自己的手機,隨後緩慢旋轉頭部畫圈,通過不同姿態註冊自己的面孔即可。就這麼簡單,隨後就可以用自己的面孔解鎖手機。這個極為快速的註冊過程可以讓我們深度了解該技術底層的學習演算法。例如,驅動 Face ID 的神經網路並不僅僅是執行分類操作那麼簡單,下文會介紹具體原因。
Apple Keynote 演示文稿中展示的 iPhone X 和Face ID
對於神經網路來說,執行分類操作意味著需要學著預測自己看到的面孔是否就是用戶本人的面孔。因此基本上,神經網路需要通過一些訓練數據來預測「真」或「假」,但是與很多其他深度學慣用例不同的地方在於,此時使用這種方法是不可行的。首先,網路需要通過從用戶面孔新獲得的數據,從頭開始重新進行訓練,這將需要花費大量時間並消耗大量電力,而不同面孔會產生數量多到不切實際的訓練數據,這也會產生消極的影響(就算使用遷移學習或對已訓練網路進一步優化,效果也不會有太大改善)。此外,這種方法將無法讓 Apple 以「離線」方式訓練更複雜的網路,例如在實驗室中訓練網路,然後將訓練好的網路包含在產品中交付給用戶使用。因此我認為,Face ID 是由一種連體(Siamese-like)卷積神經網路驅動的,該網路由 Apple「離線」訓練而來,可將面孔映射為低維隱空間(Low-dimensional latent space),並通過形狀調整,使用對比損失(Contrastive loss)的方式獲得不同用戶面孔間的最大距離。藉此打造的架構只需要通過一張照片即可學習,這一點在發布會的演講上也有提到。我知道,這其中涉及的某些技術可能對很多讀者而言還顯得挺陌生,下文將循序漸進地進行介紹。
Face ID 似乎會成為繼觸控 ID 之後的新標準,Apple 是否會讓以後的所有設備都支持它?
使用神經網路實現從面容到數據的轉換
簡單地說,連體神經網路實際上由兩個完全相同的神經網路組成,這兩個網路會共享所有權重。這種架構可以學著計算特定類型的數據,例如圖片間的距離。而其主要目的在於,向連體網路傳遞一對數據(或向同一個網路傳遞處於兩個不同階段的數據),網路會將其映射至一個低維特徵空間,例如 n 維陣列,隨後訓練網路實現所需映射關係,讓來自不同類的數據點能夠儘可能遠離,同時讓來自同一個類的數據點能夠儘可能接近。通過長時間運行,網路即可學習從數據中提取最有意義的特徵,並用這些特徵產生陣列,創建出有意義的映射。為了更直觀地理解這一過程,可以假設你自己使用小向量描述狗的種類的方法,越是類似的狗,它們就會有越接近的向量。你可能會使用某個數字代表狗毛顏色,用另一個數字代表狗的大小,並用其他數字代表狗毛長度,以此類推。通過這種方式,相似的狗將獲得相似的向量。很聰明對吧!而連體神經網路可以通過學習幫助我們做到這一點,這也有些類似 autoencoder 的功能。
Hadsell、Chopra 和 LeCun 撰寫的論文《Dimensionality Reduction by Learning an Invariant Mapping》中提供的插圖。請留意該架構學習不同數字之間相似性,並將其自動分組為兩個維度的方法。類似的方法也可以用於處理面容信息。
通過這種技術,我們可以使用大量面容照片訓練類似的架構來識別哪些面孔是相似的。只要(像 Apple 那樣)有足夠的預算和運算能力,任何人都可以使用難度越來越大的樣本改善網路的健壯性,成功應對雙胞胎、對抗性攻擊(面具)等場景。使用這種方式的最終優勢是什麼?我們終於可以通過一個即插即用模型直接識別不同用戶,而無需任何進一步的訓練,只要在初始配置時拍攝一些照片,隨後計算用戶的面孔與面孔的隱映射(Latent map)之間的距離就行了。(按照上文所述,這個過程可以類比為:對新出現的狗記錄下品種的相關向量,隨後將其存儲在某個地方。)此外 Face ID 還可以適應用戶面容的變化,例如突發的變化(眼鏡、帽子、化妝等)以及緩慢的變化(面部毛髮)。這實際上是通過在映射中添加基於新外貌計算出的參考性質的面容向量實現的。
GIF
Face ID 可以適應用戶外表的變化
最後,讓我們一起來看看如何使用 Python 在 Keras 中實現這一切。
在 Keras 中實現Face ID
對於所有機器學習項目,首先我們需要有數據。自行創建數據集需要花費大量時間,還需要很多人配合,這可能不太好實現。因此我在網上搜索現成的 RGB-D 面容數據集,並且還真找到了一個非常適合的。其中包含一系列 RGB-D 形式的人臉圖片,圖片採用不同角度和表情拍攝,完全符合 iPhone X 的實際用例。
為了直接看到最終效果,可以訪問我的 GitHub 代碼庫,我在這裡提供了一個 Jupyter Notebook。此外我還試驗過使用 Colab Notebook,你自己也可以試試。
隨後我創建了一個基於 SqueezeNet 架構的卷積網路。該網路可以接受 RGBD 格式的四通道人臉圖片作為輸入,並輸出兩個圖片之間的距離。該網路使用對比損失的方式訓練,藉此在同一個人的不同照片之間獲得最小距離,並在不同人的照片之間獲得最大距離。
對比損失
訓練之後,該網路可將面容映射為 128 維度的陣列,同一個人的不同照片可分組在一起,並會拉開不同人的照片之間的距離。這意味著如果要解鎖你的設備,網路只需要計算解鎖時所拍攝的照片以及註冊階段所存儲的照片間的距離即可。如果距離低於某個閾值(閾值越小,安全性越高),設備即可順利解鎖。
我使用t-SNE 演算法對 128 維度的嵌入空間進行二維可視化,並用每個顏色對應一個人員。如你所見,網路已經可以學著將圖片進行儘可能緊密的分組。(使用 t-SNE 演算法時,聚類間的距離已不再重要)。在使用PCA 降維演算法時還出現了一種有趣的分布。
使用 t-SNE 在嵌入空間中創建的面容聚類。每個顏色代表一個不同的人臉(不過顏色有重複使用)
使用 PCA 在嵌入空間中創建的面容聚類。每個顏色代表一個不同的人臉(不過顏色有重複使用)
開始實驗!
接著可以試試這個模型的效果了,我們將模擬 Face ID 的操作過程:首先註冊用戶面容,隨後分別使用用戶本人(應該能成功)以及他人的面容(應該會失敗)試著解鎖。正如上文所述,兩種情況的差異在於,網路對解鎖時以及註冊時拍攝的面容計算出的距離,以及這個距離到底是低於還是高於某個閾值。
首先註冊:從數據集中挑選同一個人的不同照片,然後模擬註冊過程。隨後設備會開始計算不同姿勢的嵌入,並將其存儲在本地。
GIF
模擬 Face ID 的新用戶註冊環節
GIF
景深攝像頭在註冊階段看到的內容
接著看看用戶本人解鎖設備時會發生什麼。同一個人的不同姿勢和面部表情產生的距離很小,平均僅為大約 0.30。
同一用戶在嵌入空間中的面容距離。
然而不同用戶的 RGBD 照片的平均距離高達 1.1。
不同用戶在嵌入空間中的面容距離。
因此將閾值設置為 0.4 左右就足以防止陌生人解鎖你的設備。
結論
本文介紹了基於面容嵌入和連體卷積網路,從概念證實的角度實現 Face ID 解鎖機制的方法。希望本文對你有所幫助。本文涉及到的 Python 代碼可在這裡獲取。
閱讀英文原文:
https://towardsdatascience.com/how-i-implemented-iphone-xs-faceid-using-deep-learning-in-python-d5dbaa128e1d
一些粉絲朋友還沒有養成閱讀後點贊的習慣,希望大家在閱讀後順便點贊,以示鼓勵!原創是一種信仰,專註是一種態度!
※python自學看什麼書?零基礎能自學Python嗎?
※零基礎小白,學習Python讓你也擁有大神一般的技能!
TAG:Python |