首页
学习
活动
专区
工具
TVP
发布

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 创新功能的逆向工程吧。

理解 Face ID

“…驱动 Face ID 的神经网络并不仅仅是执行分类操作那么简单。”

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 还可以适应用户面容的变化,例如突发的变化(眼镜、帽子、化妆等)以及缓慢的变化(面部毛发)。这实际上是通过在映射中添加基于新外貌计算出的参考性质的面容向量实现的。

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 的操作过程:首先注册用户面容,随后分别使用用户本人(应该能成功)以及他人的面容(应该会失败)试着解锁。正如上文所述,两种情况的差异在于,网络对解锁时以及注册时拍摄的面容计算出的距离,以及这个距离到底是低于还是高于某个阈值。

首先注册:从数据集中挑选同一个人的不同照片,然后模拟注册过程。随后设备会开始计算不同姿势的嵌入,并将其存储在本地。

模拟 Face ID 的新用户注册环节

景深摄像头在注册阶段看到的内容

接着看看用户本人解锁设备时会发生什么。同一个人的不同姿势和面部表情产生的距离很小,平均仅为大约 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

一些粉丝朋友还没有养成阅读后点赞的习惯,希望大家在阅读后顺便点赞,以示鼓励!原创是一种信仰,专注是一种态度!

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180324G09QGD00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券