iphone x 的新解锁技术:用 python 编写 face id! -凯发k8国际

2顶
0踩

引用
原文:
作者:norman di palo
译者:马晶慧
责编:言则

最近大家谈论最多的关于新款iphone x的功能之一就是新的解锁技术,即touchid的后续技术:faceid。

创建了无边框手机后,苹果不得不找出新方法简单快捷地解锁手机。虽然一些竞争对手继续使用放在不同位置的指纹传感器,但苹果决定对解锁手机的方式进行创新和变革:只需看一眼,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的人脸数据集,找到了一个非常合适的。这个数据集是根据人脸面向不同的方向以及不同的表情制作出的rgb-d图像集,正好类似于iphone x的情况。

最终的实现可以参考我的github,里面有个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代码:
  • 大小: 296.5 kb
  • 大小: 167.9 kb
  • 大小: 258.9 kb
  • 大小: 19.6 kb
  • 大小: 195.7 kb
  • 大小: 764.9 kb
  • 大小: 19.7 kb
  • 大小: 118 kb
  • 大小: 176 kb
  • 大小: 193.4 kb
  • 大小: 178.4 kb
  • 大小: 167 kb
  • 大小: 189 kb
来自:
2
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 本篇文章主要介绍了详解android 中animation-list 动画的应用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  • android animation-list动画 放置一系列图片资源放到res/drawable下面,然后写一个res/drawabale/loading_anim_image.xml文件,定义animation-list动画,animation-list定义的动画将顺次从上往下执行,设置oneshot=false则反复循环执行,true则执行一次,res/drawable/loading_an...

  • android 用animation-list实现逐帧动画

  • 在merlin之前,编写socket程序是比较繁琐的工作.因为输入输出都必须同步.这样,对于多客户端客户/服务器模式,不得不使用多线程.即为每个连接的客户都分配一个线程来处理输入输出.由此而带来的问题是可想而知的.程序员不得不为了避免死锁,线程安全等问题,进行大量的编码和测试.很多人都在抱怨为什么不在java中引入异步输入输出机制?

  • 使用animation-list实现等待加载动画效果,简单demo,适合新手学习使用animation-list

  • 来自同事_smile的封装应用,记录学习一下,分享给大家,具体如下:1、animimageviewloader类的封装/*** 适用于animation-list 动画* created by _smile on 2016/6/13.*/public class animimageviewloader extends imageview {private animationdrawable fra...

  • 1>定义一个动画的xml文件 如下

  • 1.在res\drawable目录下创建两个文件,分别为animation1.xml及animation2.xml分别用于顺序和倒序显示动画文件,具体创建步骤: (1) (2) 加上文件名 (3) 发现初始这样: (4)改成 然后可以具体改写了,最终animation1.xml: xml version="1.0" enc

  • 首先注明下:本文章来自于网络,我只是按照人家的例子写代码运行了一下地址现在找不到了以后找到后给加上去。 animation_list用户补间动画是用的,直接上例子了。 第一步创建android工程把用到的图片添加到羡慕中图片资源也给大家贴出来。   第二步:编写animation_list文件 下面的是反

  • android中实现帧动画,一般我们会用到的一个drawable:animationdrawable 先编写好drawable,然后代码中调用start()以及stop()开始或停止播放动画~1、 在drawable文件夹中创建animation-list.xml2、 声明animationdrawable 现在写一个drawable,。命名为:animation_frameanimation_f...

  • 写在前面:   上一篇记录了socket聊天程序的客户端设计,为了记录的完整性,这里还是将socket聊天的最后一个模块——common模块记录一下。common的设计如下: 功能说明: common模块主要是数据交互,这里使用json数据进行交互,common模块定义了各类交互信息,sendhelper实现的socket信息的传送,i18n是语言话,constantvalue...

  • 1.closesocket(一般不会立即关闭而经历time_wait的过程)后想继续重用该socket: bool breuseaddr=true; setsockopt(s,sol_socket ,so_reuseaddr,(const char*)&breuseaddr,sizeof(bool)); 2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经

  • 做loading的时候,帧动画我们经常用到,主要是一些比较复杂的动画,比如小人跑动,人物翻转等等; 可以发现这些写了之后可以基本上满足常用手机的需求,但是最近我发现在一些手机上会出现如下2个问题: 1,在android6.0上此动画和6.0以下在显示上有区别(已解决); 2,在加载动画的时候中兴v5以及其他某些机型会产生只加载第一张图余下的几张都不加载的情况;

  • 第三步:编写测试代码   //test1.java package com.hode.thread; /** * @author 泰伯子仪 * * test1建立一个一般线程,并和socket信号的服务端邦定 * 这意味着test1线程可以通过socket于其他进程进行通讯 */public class test1 extends commthread{     /**     * test1必须

  • 相信对于那些基础android的人来说对于帧动画或补间动画应该并不陌生了吗?今天我给大家讲的是android逐帧动画比较简单! 先上效果图! 下面仔细讲一下animationdrawable这个类 object是所有类的父类毋庸置疑,其次它的间接父类是drawablecontainer 下面看下他们的构造方法以及函数 public class animationdrawable ex

  • animation-list vue 元素列表动画渲染

  • 通过animation-list可以实现帧切换形成动画。在anim文件夹下建立一个xml文件,添加animation-list标签,实现方法如下: android:oneshot 代表着

  • 利用animation-list实现帧动画

global site tag (gtag.js) - google analytics
网站地图