当前位置: 首页 > 科技观察

【我是Jarvis】:说说FaceID背后的深度学习视觉算法

时间:2023-03-14 23:26:09 科技观察

在上周发布的iPhoneX中,最吸引我的不是傻兔耳朵,而是苹果的FaceID。苹果用FaceID取代TouchID的背后,是强大的视觉算法支持,让iPhoneX能够识别各种欺骗和伪装,从而敢于将FaceID作为最重要的安全验证手段。众所周知,近来深度学习算法发展迅速,带动了人工智能的发展。2012年AlexNet在ImageNet数据集上的成功,将人们的注意力带到了消亡已久的卷积神经网络(CNN)上,VGG、ResNet等一系列模型的推出赋予了计算机接近人类的视觉能力。.递归神经网络(RNN)在自然语言处理和语音识别领域的应用,突破了传统模型难以掌握时序数据的瓶颈。深度学习作为一项基础能力,推动了迁移学习、强化学习等一系列相关学科的发展。当然,也包括与视野相关的变化。为此,我们将多个经典的深度学习算法和模型整合到Jarvis算法库中,并通过Tesla平台开放给大家使用。目前,Jarvis的深度学习类已经集成了9种不同的算法,分布在以下三类:本文将重点介绍计算机视觉领域的几种经典算法,包括它们的原理、模型和适用场景。以后会有其他领域的文章,请继续关注~计算机视觉概述计算机视觉是一门研究如何让机器“理解”世界的科学。计算机视觉结合了图像处理、模式识别和人工智能技术,着重分析一幅或多幅图像以获得所需的信息。因此,计算机视觉也可以看做是如何让人工系统从图像或多维数据中“感知”的科学。具体来说,计算机视觉包括物体检测与识别、物体跟踪、图像复原(去除噪声等)、场景重建等。自从Alexnet在2012年拿下ILSVRC在视觉领域的桂冠后,DeepLearning就一发不可收拾,ILSVRC每年都被深度学习连续上榜。下图所示的这些模型代表了深度视觉领域发展的里程碑。随着模型越来越深,Top-5的错误率越来越低,在Resnet上的结果已经达到3.5%左右,而在同样的ImageNet数据集上,人眼的识别错误率在5.1左右%,也就是说深度学习模型的识别能力已经超越了人类。(http://ai.51cto.com/art/201704/538154.htm)Alexnet、VGG等经典算法和模型不仅在ImageNet上取得了不错的效果,也可以用于其他场景。为了方便用户灵活快速地训练这??些模型,我们在Jarvis中集成了这些算法。用户可以直接在Tesla上拖出相应的算法节点,无需编写复杂的网络定义和模型训练代码,就可以训练相应的图片得到一个基本可用的模型。当然,想要效果好,还是要有耐心,慢慢调试。下采样和全连接层是一层层构造的。图中诡异的“上下层”绘制方式其实指的是GPU的并行度。(https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf)AlexNet可以在ImageNet上取得更好的效果,除了使用更深更宽的网络之外结构来增强学习能力,以下数据处理和训练技巧值得学习:在一定程度上减少。AlexNet在ImageNet上训练时使用的数据增强方法有:水平翻转、随机裁剪、颜色/光照变化等从网络中丢弃。对于随机梯度下降,由于是随机丢弃的,可以看出每个mini-batch都在训练不同的网络。它是防止网络过拟合和增强模型泛化能力的有效途径。下图左边是commonlayerconnection,每一个dropout相当于从原来的网络中找一个“更薄”的结构,就像右边的图。在训练阶段,我们设置一个范围为0-1的dropoutfactorp,表示前向计算阶段需要随机断开连接的比例,反向传播时只更新未断开的权重值.在测试阶段,需要使用所有的连接,但是这些权重需要乘以1-p。需要注意的是,每次断开和更新都是以概率p随机实现的,所以每次迭代的断开都是不同的。对于一个有n个节点的神经网络,假设dropoutfactorp=0.5,那么在forward次数足够多的情况下,整个训练过程会得到2^n个连接组合,相当于训练了2^n个模型,***得到2^n个模型的组合。(http://blog.csdn.net/stdcoutzyx/article/details/49022443)ReLU激活函数ReLu激活函数与传统的Tanh或Logistic函数相比有以下优点:正向计算和反向偏导过程非常简单,有没有诸如指数或除法之类的复杂运算。不像tanh和logistic有“平点”,所以不容易出现梯度弥散的问题。左边是封闭的,可以让很多隐藏层输出为0,所以使得网络变得稀疏,具有一定的正则化作用,可以缓解Relu函数过拟合的缺点,这一点也体现在封闭的左边部分。如果某些节点的输出落在函数的左边,就会“永不翻身”。为了解决这个问题,后来出现了pRelu等改进的激活函数,即在函数左侧也赋予了一定的梯度,这样在保证非线性的情况下,某些节点不会“死掉”。(http://gforge.se/2015/06/benchmarking-relu-and-prelu/)LocalResponseNormalization(LRN)在神经生物学中有一个概念叫做“侧抑制(lateralinhibition)”,意思是被激活的神经元有对邻近的神经元有一定的抑制作用。LRN就是借鉴了侧抑制的思想,为局部神经元的活动创造了一种竞争机制,使得比较大的响应值比较大,从而提高模型的泛化能力。LRN有两种归一化模式:通道内和通道间。详情请参考这篇文章。在论文的ImageNet实验中,LRN可以将top-5错误率降低1.2%,但是从我们在其他数据集上的实验来看,LRN提升训练效果并没有那么显着,所以我们可以看出LRN的运行和是并不适用于所有场景,需要更多的实验才能出结果。顾名思义,overlappingpooling就是在做pooling的时候也有重叠的部分。一般来说,池化就是将输入结果分成块,通过提取块的最大值(maxpooling)或平均值(averagepooling)来实现降采样的过程。这里,块彼此不重叠。的。在AlexNet中,会有重叠部分。和LRN一样,这个trick不一定适用于所有场景。基于以上技术,综合来看,AlexNet还是一个非常经典的算法。所以我们将AlexNet整合到Jarvis的深度学习算法的视觉范畴。在实现上,基于AlexNet原有的构建和训练方式,参考Alex发表的文章《One weird trick for parallelizing convolutional neural networksc》,我们做了以下几件事,包括:去掉了LRN层,参数初始化改为xavier方法。激活函数使用Relu函数正则化选择L2正则化。fc6和fc7的两个全连接层使用系数为0.5的dropout操作自动resize:在数据输入上,给定的输入图像大小为224x224x3,如果读取到的图像大于这个大小,则将随机裁剪为224x224x3,如果读取的图像小于此尺寸,则会调整为224x224x3。此外,我们还提供了一些对输入图像的数据增强操作,包括水平翻转、颜色、光照变化等,相关参数将在文章后半部分进行说明。2.VGG16VGG16继承了alexnet的框架,但是通过加深卷积层数获得了比AlexNet更高的图像识别率。它是比AlexNet更深的网络结构。如下图所示,更详细的网络结构参数可以参考论文。(https://www.cs.toronto.edu/~frossard/post/vgg16/)VGG16与AlexNet相比,明显的不同在于:通过网络结构图可以看出连续的卷积块和更小的filtersize是可知的vgg16包含多个连续的卷积操作(图中的黑框),这些卷积层的卷积核大小为3x3,远小于AlexNet的7x7。可以理解为VGG通过减小filter的尺寸和增加卷积层数来达到同样的效果。这可以看作是对7×7conv进行正则化。filters,通过3×3的filters迫使它们进行分解较小的卷积核在一定程度上减少了需要训练的权重数量,假设输入通道数和输出通道数为C。在7x7的卷积核下size,该层的权重个数为7x7xCxC=49xCxC,此时VGG中连续三个卷积层的权重个数为3x3x3xCxC=27xCxC。权重数量的减少有利于网络的训练和泛化。频道(channels)的数量增加。对比AlexNet和VGG,可以发现AlexNet的通道数明显小于VGG。通过这种方式,网络可以从输入中提取更丰富的特征。VGG之所以能达到更高的准确率,与通道数的增加有很大关系。VGG16也集成在Jarvis深度学习算法的视觉模块下。除了网络结构的定义,它与Alexnet类似,包括全连接层的dropout设置、Relu激活函数和L2的正则化。3.上节描述的VGG19VGG19和VGG16其实来自同一篇论文,是一种方法的两种不同配置。VGG19的网络结构与VGG16非常相似。不同的是,VGG19在第3、4、5个“卷积块”上增加了一个额外的卷积层,因此比VGG16多了3个权重层。这里我就不细说了。除了上述AlexNet、VGG系列的网络结构,Jarvis还会逐步整合Googlenet、Resnet等,欢迎继续关注。自定义网络经典算法虽然好,但总有一定的局限性。为了提供更好的灵活性,Jarvis还集成了基于卷积神经网络的分类和回归算法。其最大的优势在于可以灵活定制网络结构,满足不同场景的需求。在TensorFlow中定义一个卷积+激活层通常需要以下几行代码:withtf.name_scope('conv2')asscope:kernel=tf.Variable(tf.truncated_normal([5,5,96,256],dtype=tf.float32,stddev=1e-1),name='weights')biases=tf.Variable(tf.constant(0.0,shape=[256],dtype=tf.float32),trainable=True,name='biases')conv2=tf.nn.conv2d(pool1,kernel,[1,1,1,1],padding='SAME')conv2=tf.nn.relu(tf.nn.bias_add(conv2,biases))这只是一个For卷积层的构建,如果我们要构建的网络由十几个或者几十个层组成,估计需要几百行代码,关键是即使你复制粘贴层同样的性质,你未必能准确找到它们眼花缭乱的参数啊。好在tensorflow还支持slim、keras、tensorlayer等部分接口的高级抽象,这样一句话就可以写出一个卷积层。例如,一个卷积层操作可以在slim中这样定义:net=layers.conv2d(inputs,64,[11,11],4,padding='VALID',scope='conv1')尽管这些高级接口使得网络的定义就容易多了,如果在训练过程中需要多次调整网络结构,硬编码的形式还是很不方便的。鉴于以上情况,我们在Tesla上实现CNN时,将网络结构单独提取出来,作为可修改的参数传入算法中。网络参数其实是一个json文件,文件中的每一行代表一层,最后几行代表数据输入的一些信息。一个CifarNet的网络结构如下图所示:(https://inclass.kaggle.com/c/computer-vision-cs543-ece549)将CifarNet转换成我们自定义的json文件后,示例如下:{“layer1”:{“operation”:“conv”,“maps”:64,“kernel_height”:5,“kernel_width”:5,“stride_height”:1,“stride_width”:1,“padding”:“SAME","activation_func":"relu"},"layer2":{"operation":"max_pool","kernel_height":3,"kernel_width":3,"stride_height":2,"stride_width":2,"padding“:”相同“},”layer3”:{“operation”:“conv”,“maps”:64,“kernel_height”:5,“kernel_width”:5,“stride_height”:1,“stride_width”:1,"padding":"SAME","activation_func":"relu"},"layer4":{"operation":"max_pool","kernel_height":3,"kernel_width":3,"stride_height":2,"stride_width":2,"padding":"SAME"},"layer5":{"operation":"fc","maps":384,"dropout_rate":1.0,"activation_func":"relu"},"layer6":{"operation":"fc","maps":192,"dropout_rate":1.0,"activation_func":"relu"},"layer7":{“operation”:“fc”,“maps”:100},“initial_image_height”:32,“initial_image_width”:32,“input_image_height”:32,“input_image_width”:32,“normalize”:1,“crop”:1,"whitening":1,"contrast":1,"flip_left_right":1,"brightness":1}比较懒的朋友甚至可以直接复制这个模板,然后根据自己的网络定义修改当tesla界面是运行中,如果需要修改网络结构,直接在界面右侧的参数配置中编辑json文件即可,无需修改上传代码~~基于上述自定义的特点网络结构,我们配置了CNN的分类和回归算法。1.CNNClassification是一种基于卷积神经网络CNN的分类算法。支持自定义上述网络结构,可以适应不同场景下的图像分类任务。2.CNNRegression基于卷积神经网络(CNN)回归算法,类似于CNN分类。不同的是使用欧式距离损失函数进行训练,可以接受float类型的标签。注意,在配置网络结构时,最后一层的featuremap数量为1,而不是分类中的类别数量。Jarvis视觉算法的使用目前,Jarvis主要通过Tesla平台进行曝光。它的训练和使用非常简单。一般来说可以分为三个步骤:数据准备、模型训练和模型使用1.数据准备在开始训练之前,我们需要准备好训练集和测试集数据。目前计算机视觉目录下的算法,输入的都是图像数据,都需要转成tfrecord格式。打开Tesla的工作界面,在Input->DataSource下拖出dataset节点,点击该节点,在界面右侧的参数配置选项中完整填写,完成一个数据节点的配置。可以在数据节点之后添加转换节点。为了方便用户,我们会提供一个image->tfrecord转换工具,放在input->data转换目录下。2.模型训练在Tesla工作流界面,从左侧深度学习算法下拖出你要训练的算法节点。点击节点,右侧会出现参数配置选项,包括算法IO参数、算法参数和资源配置参数。resource参数指定模型训练所需的GPU和CPU资源。算法IO参数用于指定数据集、模型存储、Tensorboard存储的ceph路径。这里我们只需要指定数据集所在的路径,而模型存储和Tensorboard的路径是Tesla默认指定的。如果算法节点上有对应的数据集节点,则该数据集节点的数据路径会自动匹配算法的数据输入路径。不想拖动数据集节点的用户也可以手动填写算法的数据输入路径。算法参数用于指定训练过程中需要的参数。深度学习算法的一些参数是共同的,例如批量大小、学习率和迭代次数。但是不同的算法也可能有自己特殊的参数。在后面的介绍中,我们会在各个算法的详细介绍链接中找到相应的参数解释。对于CNNClassification/Regression算法,由于支持自定义网络结构,参数会与上表略有不同。以工作流右侧的参数配置项为准。配置好参数后,右击算法节点,选择RunfromStart开始训练模型。训练过程中,可以通过tensorflow控制台查看日志信息和tensorboard可视化,方便掌握训练趋势。3.模型收集和使用模型使用是指使用训练好的模型做预测工作。除了在训练完成后对模型进行预测外,Tesla还贴心地提供了模型收集功能,可以为以后的预测预留。模型收藏:在模型操作下选择收藏模型,将模型保存到Tesla界面左侧的个人模型目录中。下次需要使用时,直接拖出模型节点,填写相应的配置参数,右键选择起点运行即可。结束语本文介绍了计算机视觉领域的几种经典深度学习算法,展示了如何在Tesla平台上快速灵活地训练和使用深度学习模型。AlgorithmDemo下有各个算法的示例工程供大家参考。***,再次提到苹果的FaceID。FaceID的成功运用,无疑是计算机视觉领域在人类生活应用中的一大进步。其破解率低于指纹解锁,离不开机器学习,尤其是其背后的深度学习算法。当然,FaceID背后的人脸识别技术肯定比本文简单介绍的几种算法要复杂,这里就不赘述了,因为就算你问我,我也不知道,呵呵~~一篇SimGAN文章《Learning from Simulated and Unsupervised Images through Adversarial Training》发表在CVPR的CVPR上。如果你有兴趣,你可以看看。此外,苹果在去年的NIPS上宣布将开始公开他们的研究成果。相信这一决定会给学术界和工业界带来很多惊喜。你可以期待它。***+1,本文是在andymhuang和royalli的指导下完成的,在此表示感谢。如果大家在使用算法时遇到相关问题,欢迎咨询我(joyjxu)或royalli,欢迎各种批评指正!原文链接:https://www.qcloud.com/community/article/648055作者:徐杰【本文为专栏作者《腾讯云技术社区》原创稿件,转载请联系原作者获得授权】点此查看该作者更多好文