用Python和深度学习实现iPhone X的Face ID

去年苹果的最新产品 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

第一步是分析 FaceID 是怎样在 iPhone X 上工做的。iPhone X 的白皮书能够帮助咱们理解 FaceID 的基本工做原理。使用 TouchID 的时候,用户须要先数次触碰传感器以记录指纹。 15 到 20 次触碰后,TouchID 就设置完成了。FaceID 也相似,用户须要先录入面部数据。过程很简单:用户只需和平时同样正向看着手机,以后缓慢转动头部以完成全方位采集。网络

就这么简单,FaceID 已经设置好,能够用来解锁手机了。录入过程的惊人速度能够告诉咱们不少关于其背后算法的信息。好比,驱动 FaceID 的神经网络并非只是在进行分类,我接下来会进一步解释。架构

对一个神经网络来讲,分类意味着学习预测它看到的脸是不是用户的。所以,简单来讲,它须要利用训练数据预测“是”或“否”。但和其余不少深度学习用例不一样,这个方法在这里行不通。首先,神经网络须要用从用户面部新得到的数据从头开始训练模型,这须要大量的时间、计算资源和不一样的人脸做为训练数据以得到反例(在迁移学习和对一个已经训练好的网络进行微调的状况下,变化是很小的)。机器学习

不只如此,这种方法使 Apple 没法“离线”训练一个更为复杂的网络,好比先在实验室里训练网络,再把训练好的、能够直接使用的网络放到手机里。所以,我认为 FaceID 是利用了一个被 Apple“离线”训练好的相似孪生网络的卷积神经网络,将人脸映射到低维的潜在空间,再利用对比损失将不一样人脸的距离最大化。这样,你就获得了一个能够进行一次性学习的架构,Apple 的 Keynote 里简要提到了这一点。我知道,可能有些看官会对不少名词感到陌生;别急,继续读下去,我会一步步解释的。

神经网络:从人脸到数字

孪生神经网络是由两个相同的神经网络组成的,这两个网络的权重也彻底同样。这个架构能够计算特定的数据类型之间的距离,好比图像。你让数据经过孪生网络(或者分两步让数据经过同一个网络),网络就会将其映射到一个低维的特征空间,好比一个n维的数组,你再训练网络,使映射可以让不一样类别的数据离得越远越好,相同类别的数据离得越近越好。长期来看,神经网络会学着提取最有意义的特征,将其压缩成一个数组,并创建一个有意义的映射。为了能更直观的理解,想象你须要用一个很小的向量来描述狗的品种,这样类似的狗的向量会更相近。你也许会用一个值表示狗的皮毛颜色,一个值表示狗的体型大小,另外一个值表示毛发长度,等等。这样,类似的狗就会有类似的向量。很聪明,不是吗?孪生神经网络就能够替你作这件事,就像一个自编码器。

上面这幅图出自 Yann LeCun 参与发表的一篇论文,神经网络能够学习数字之间的类似性,并以 2 维为它们自动分类。这样的技术也能够应用到人脸数据上。

利用这个技术,咱们能够利用大量的人脸训练出一个能够识别类似人脸的架构。只要有足够的预算和算力(就像 Apple 这样),神经网络的鲁棒性能够变得愈来愈强,能够处理双胞胎、对抗攻击等更困难的样本。这个方法的最后一个优势是什么呢?就是你有了一个即插即用的模型,它不须要进一步训练,只要在一开始录入时拍几张照片,计算出用户的脸在隐映射中的位置,就能够识别不一样用户。(想象一下,像刚才说的那样,为一只新的狗创建表明它品种的向量,再把它储存到什么地方)此外,FaceID 能够在用户这一方适应眼镜、帽子、化妆等忽然变化和面部毛发这样的缓慢变化——只须要在映射中添加参考的面部向量,再根据新的外貌进行计算。

用 Keras 实现 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 工具及其提供有哪些深度神经网络模块,能够看看我站的简明教程

相关文章
相关标签/搜索