iphone x 的新解锁技术:用 python 编写 face id! -pg电子游戏网站

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 条 请登录后发表评论

发表评论

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

相关推荐

  • 其中一种常见的动画类型是逐帧动画,也就是连续播放一系列帧图像,从而创建出动画效果。通过定义 animation-list xml 文件和使用 animationdrawable 类加载并播放动画,我们可以在 android 应用程序中轻松实现逐帧动画效果。接下来,在需要显示动画的视图(如 imageview)中,我们可以使用 animationdrawable 类加载并播放 animation-list 动画。要注意的是,为了实现逐帧动画的循环播放,我们可以将 animation-list 的。

  • 本篇文章主要介绍了详解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...

  • 我们要实现的效果准备资源文件放到res/drawable文件下中 light01.png light02.png light03.png编写loading.xml 放到res/drawable animation-list :根标签 oneshot :代表着是否只展示一遍,设置为false会不停的循环播放动画 android :duration

  • 简介 帧动画(frame animation又称drawable animation)是最简单的android动画效果,其与电影多重连续帧播放原理相似,通过视觉残留来让人感知到动画效果。其实现方式是将一张张drawable图片按顺序排列并逐张按时播放来达到实现的动画效果,对应的实现类是animationdrawable。它有两种实现方式:代码实现和xml实现,其中xml实现方式较为简单。

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

  • 利用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...

  • 答案:现在最常用的进程间通信的方式有信号、信号量、消息队列、共享内存。所谓进程通信,就是不同进程之间进行一些“接触”。这种接触有简单,也有复杂。机制不同,复杂度也不一样。通信是一个广义上的意义,不仅仅指传递一些message。它们的使用方法是基本相同的,所以只要掌握了一种使用方法,然后记住其他的使用方法就可以了。信号和信号量是不同的,它们虽然都可用来实现同步和互斥,但前者是使用信号处理器...

  • 写在前面:   上一篇记录了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后强制关闭,不经

  • 第三步:编写测试代码   //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 元素列表动画渲染

  •             进程间通信有很多种方式,比如说 pipe,共享内存,dde,socket等,关于进程通信方面的知识我在这里就不讨论了,大家可以看我博客里的另一些文章有讲...今天我们主要讨论怎么样使用socket实现进程间通信。         本程序将使用socket 的wsaeventselect异步方式,使用多线程,建立一个服务器类,使用此类的时候只需要将处理数据的函数指针传给该类,...

  • mfc开发,socket异步通讯,非常实用,已在项目中测试过。。。。。。。。。。。。。。。。。。。。。。。。。。。

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