机器学习原来如此有趣:用深度学习识别人脸

author author     2022-09-17     744

关键词:

本系列文章目前已经更新两期,分别是: 机器学习原来如此有趣!全世界最简单的机器学习入门指南、 机器学习原来如此有趣:如何故意欺骗神经网络

 

你是否有注意到Facebook最近开发了一个非同寻常的功能:将你照片中的好友识别出来。过去,Facebook 让你手动点击照片上的好友,输入他们的名字,然后加上标签。现在只要你上传一张照片,Facebook就会像变魔术一样为你自动标记出所有人:

技术分享

 

这项技术就叫做人脸识别。在你的朋友的脸被标记了几次之后,Facebook的算法就可以识别他了。这是一个让人惊艳的技术--Facebook识别人脸的正确率高达98%!这与人类的表现差不多了。

 

下面就让我们来学习一下人脸识别技术是如何实现的!但是只是识别你的朋友的脸就太简单了。 我们可以最大化扩展这项技术,来解决一个更具挑战性的问题——区分威尔·法瑞尔(Will Ferrell,著名演员)和查德·史密斯(Chad Smith,著名摇滚音乐家)!

技术分享

 

 

如何使用机器学习来解决复杂的问题

 

人脸识别由一个系列的相关问题组成:

 

1.首先:查看一张照片并找出上面所有的脸

2.将注意力放在每一张脸上面,即使这张脸被转到奇怪的方向或者是光线不好的情况下也依旧是同一个人。

3. 从这张脸上挑出一些特征用于和其他人区分来,比如像眼睛有多大,脸有多长等。

4.最后,将这张脸的特征和其他其他脸作比较,以最后确定这个人的名字。

 

作为一个人类,你的大脑会自动做这些事情。实际上,人类太擅长于识别人脸了,以至于他们在日常物品上面也会试图去寻找脸(好像是这样哦,人们总是喜欢去物品上找出练得形状,并且觉得这样很萌)。技术分享

 

计算机目前并不具备这种高水平的能力。。。所以我们需要一步步的教他们。

 

我们需要构建一个流水线(pipeline):我们将分别解决人脸识别的每一步,并将当前步骤的结果传入下一个步骤。换句话说,我们需要将几个机器学习算法链(chain)起来。

技术分享

 

人脸识别-一步一步来

 

我们一步一步地解决这个问题。在每一个步骤中,我们都将学习到不同的机器学习算法。我不会对算法的每一步都进行解释,但是你可以学习到每一个算法的主体思想,以及如何在 Python 中使用 OpenFace 和 dlib 来构建一个你自己的面部识别系统。

 

第一步:寻找所有的脸

 

在我们的流水线中的第一步是人脸检测。很明显在我们区分人脸之前需要在图片中将脸标记出来。

 

如果你有在最近十年里面用过相机的话,你可能已经见过正在运行中的人脸检测了:

技术分享

 

面部识别是相机的一个伟大的功能。当相机可以自动挑出面部的时候,这将确保在拍照片的瞬间所有的脸都对准焦点了。不过我们使用它是为了别的目的--寻找我们想在下一步要传递的照片区域。

 

2000年年初的时候,当Paul Viola和Michael Jones发明了一种可以在廉价相机上面快速运行的面部检测技术后,人脸检测成为了主流。然而现在更可靠的解决方案出现了。我们现在用的是2005年发明的一个叫做方向梯度直方图,简称为HOG

 

为了识别出图片中的脸,首先我们需要将图片转换为黑白色,因为在识别面部的时候我们不需要颜色数据。技术分享

 

然后我们需要依次遍历图片中的每个像素。对于单个像素,我们也需要看直接包围它的其他元素:

 

技术分享

 

我们的目标是比较这个像素与周围像素的深度。然后我们要画一个箭头来代表图像变暗的方向:

技术分享

 

 

如果你对这个图像中的每个像素都重复这个过程,最后每个像素,最终每个像素会被一个箭头取代。这些箭头被称为梯度(gradients),它们能显示出图像上从明亮到黑暗的流动过程:

技术分享

 

 

这看起来没有明确的目的,但其实这很有必要。如果我们直接分析像素,同一个人明暗不同的两张照片将具有完全不同的像素值。但是如果只考虑亮度变化方向(direction)的话,明暗图像将会有同样的结果。这使得问题变得更容易解决!

 

但是保存每个像素的梯度太过细节化了,我们最终很有可能捡了芝麻丢了西瓜。如果能从更高的角度上观察基本的明暗流动,我们就可以看出图像的基本规律,这会比之前更好。

 

为了做到这一点,我们将图像分割成一些 16×16 像素的小方块。在每个小方块中,我们将计算出每个主方向上有多少个梯度(有多少指向上,指向右上,指向右等)。然后我们将用指向性最强那个方向的箭头来代替原来的那个小方块。

 

最终的结果是,我们把原始图像转换成了一个非常简单的表达形式,这种表达形式可以用一种简单的方式来捕获面部的基本结构:

技术分享

 

原始图像被表示成了 HOG 形式,以捕获图像的主要特征,无论图像明暗度如何。

 

为了在这个 HOG 图像中找到脸部,我们要所需要做的,就是找到我们的图像中,与已知的一些 HOG 图案中,看起来最相似的部分。这些 HOG 图案都是从其他面部训练数据中提取出来的:

 

使用这种技术,我们现在可以轻松地在任何图片中找到脸部:

 

技术分享

 

 

如果你想用 Python 和 dlib 亲手试试看,这些代码显示了如何生成和查看 HOG 图像。

 

第二步:脸部的不同姿势和方位

 

当当当,我们把图片中的脸部分离出来了。 但现在,我们要处理的问题就是,对于电脑来说,面朝不同方向的同一张脸是两个人:

技术分享

人类可以很轻松地识别出到两个图片都是同一个人,但电脑会认为这两张图片是两个完全不同的人。

 

为了解决这一点,我们将试图扭曲每个图片,使得眼睛和嘴唇总是在图像中的样本位置(sample place)。 这将使我们在接下来的步骤中,更容易比较脸部之间的不同。

 

为此,我们将使用一种称为面部特征点估计(face landmark estimation)的算法。 很多方法都可以做到这一点,但这次我们会使用由 瓦希德·卡奇米(Vahid Kazemi)和约瑟菲娜·沙利文(Josephine Sullivan)在 2014 年发明的方法

 

基本思路是找到 68 个人脸上普遍存在的特征点( landmarks)——包括下巴的顶部、每只眼睛的外部轮廓、每条眉毛的内部轮廓等。接下来我们训练一个机器学习算法,让它能够在任何脸部找到这 68 个特定的点:

技术分享

 

 

我们将在每一张脸上定位的 68 个特征点。这张图片的作者是在OpenFace工作的卡内基梅隆大学 Ph.D. 布兰东·阿莫斯(Brandon Amos)。

 

这是在测试图片上定位 68 个特征点的结果:

技术分享

 

你也可以使用这一技术来实现自己的 Snapchat 实时 3D 脸部过滤器!

 

现在,我们知道了眼睛和嘴巴在哪儿,我们将图像进行旋转、缩放和错切,使得眼睛和嘴巴尽可能靠近中心。我们不会做任何花哨的三维扭曲,因为这会让图像失真。我们只会使用那些能够保持图片相对平行的基本图像变换,例如旋转和缩放(称为仿射变换):

 

现在无论人脸朝向哪边,我们都能将眼睛和嘴巴向中间挪动到大致相同的位置。这将使我们的下一步更加准确。

 

如果你想用 Python 和 dlib 亲手试试看这一步的话,这里有一些代码帮你寻找脸部特征点并用这些特征点完成图像变形

 

第三步:给脸部编码

 

现在我们要面临最核心的问题了——准确识别不同的人脸。这才是这件事的有趣之处!

 

最简单的人脸识别方法,是把我们在第二步中发现的未知人脸,与我们已经标注了的人脸图片作比较。当我们发现未知的面孔与一个以前标注过的面孔看起来及其相似的时候,它肯定是同一个人。这个想看起来很完美,对吧?

 

实际上这种方法有一个巨大的问题。像 Facebook 这种拥有数十亿用户和数万亿张照片的网站,是不可能去循环比较每张先前标记的脸的,这太浪费时间了。他们需要在毫秒内识别人脸,而不是几个小时。

 

我们需要的方法是从每张人脸上提取一些基本的测量数值。然后,我们可以用同样的方式测量未知的面孔,并找到最接近测量数值的那张已知的脸。例如,我们可以测量每个耳朵的大小、眼距、鼻子的长度等。如果你曾经看过像《犯罪现场调查》这样的电视剧,你就知道我在说什么了。

 

 

测量面部的最可靠方法

 

好的,所以为了建立我们的已知脸部数据库呢,我们应该测量面部的哪些数值?耳朵的大小?鼻子的长度?眼睛的颜色?还有什么?

 

事实证明,对于我们人类来说一些显而易见的测量值(比如眼睛颜色),对计算机来说没什么意义。研究人员发现,最准确的方法是让计算机自己找出它要收集的测量值。深度学习在寻找哪些部分的测量值比较重要方面表现的比人类更好。

 

所以,解决方案是训练一个深度卷积神经网络。但是,并不是让它去识别图片中的物体,这一次我们的训练是要让它为脸部生成 128 个测量值。

 

每次训练要观察三个不同的脸部图像:

 

1. 加载一张已知的人的面部训练图像

 

2. 加载同一个人的另一张照片

 

3. 加载另外一个人的照片

 

然后,算法查看它自己为这三个图片生成的测量值。再然后,稍微调整神经网络,以确保第一张和第二张生成的测量值接近,而第二张和第三张生成的测量值略有不同。

技术分享

 

 

在为几千个人的数百万图像重复该步骤几百万次之后,神经网络学习了如何可靠地为每个人生成 128 个测量值。对于同一个人的任何十张不同的照片,它都应该给出大致相同的测量值。

 

机器学习专业人士把每张脸的 128 个测量值称为一个嵌入(embedding)。将复杂的原始数据(如图片)缩减为可由计算机生成的一个数列的方法,在机器学习(特别是语言翻译)中出现了很多次。我们正在使用的这种脸部提取方法是由 Google 的研究人员在 2015 年发明的,但也有许多类似方法存在。

 

给我们的脸部图像编码

 

这个通过训练卷积神经网络来输出脸部嵌入的过程,需要大量的数据和强大的计算能力。即使使用昂贵的 Nvidia Telsa 显卡,你也需要大约 24 小时的连续训练,才能获得良好的准确性。

 

但一旦网络训练完成,它就可以为每一张脸生成测量值,即使之前它从未见过这张脸!所以这种训练只需一次即可。幸运的是,OpenFace 上面的大牛已经做完了这些,并且他们发布了几个训练过可以直接使用的网络。谢谢Brandon Amos他的团队!

 

所以我们需要做的,就是通过他们预训练的网络来处理我们的脸部图像,以获得 128 个测量值。这是我们测试图像的一些测量值:

技术分享

 

 

那么,这 128 个数字到底测量了脸部的哪些部分?我们当然不知道,但是这对我们并不重要。我们关心的是,当看到同一个人两张不同的图片时,我们的网络能得到几乎相同的数值。

 

如果你想自己尝试这个步骤,OpenFace 提供了一个 lua 脚本,它可以生成一个文件夹中所有图像的嵌入,并将它们写入 csv 文件。点此查看如何运行

 

第四步:从编码中找出人的名字

 

最后这一步实际上是整个过程中最简单的一步。我们要做的就是找到数据库中,与我们的测试图像的测量值最接近的那个人。

 

你可以通过任何基本的机器学习分类算法来达成这一目标。我们并不需要太花哨的深度学习技巧。我们将使用一个简单的线性 SVM 分类器,但实际上还有很多其他的分类算法可以使用。

 

我们需要做的是训练一个分类器,它可以从一个新的测试图像中获取测量结果,并找出最匹配的那个人。分类器运行一次只需要几毫秒,分类器的结果就是人的名字!

 

所以让我们试一下我们的系统。首先,我使用Will Ferrell, Chad Smith and Jimmy Falon三人每人 20 张照片的嵌入来训练分类器:

技术分享

 

嗯……就是这些训练数据!

 

接下来,我在这个分类器上运行了威尔·法瑞尔和查德·史密斯在吉米·法伦的节目上互相模仿的那个视频的每一帧:

 

https://cdn-images-1.medium.com/max/800/1*_GNyjR3JlPoS9grtIVmKFQ.gif

 

结果成功了!不同角度的脸部,甚至是侧脸,它都能捕捉到!

 

自己动手做一遍

 

让我们回顾一下我们的步骤:

 

1. 使用 HOG 算法给图片编码,以创建图片的简化版本。使用这个简化的图像,找到其中看起来最像通用 HOG 面部编码的部分。

 

2. 通过找到脸上的主要特征点,找出脸部的姿势。一旦我们找到这些特征点,就利用它们把图像扭曲,使眼睛和嘴巴居中。

 

3. 把上一步得到的面部图像放入神经网络中,神经网络知道如何找到 128 个特征测量值。保存这 128 个测量值。

 

4. 看看我们过去已经测量过的所有脸部,找出哪个人的测量值和我们要测量的面部最接近。这就是你要找的人!

 

现在你知道这一切都是如何运行的了,这里是如何使用 OpenFace 在你自己的电脑上运行整个人脸识别系统的说明:

 

开始之前

 

确保你已经安装了 python、OpenFace 和 dlib。你也可以在这里手动安装,或者使用一个已经设定好的 docker image:

 

docker pull
bamos/openface
docker run -p 9000:9000
-p 8000:8000 -t -i bamos/openface /bin/bash
cd /root/openface

 

友情提示:如果你正在 OSX 上使用 Docker,你可以这样使你的 OSX /Users/

文件夹在 docker image 中可见:

 

docker run -v /Users:/host/Users -p 9000:9000 -p
8000:8000 -t -i bamos/openface /bin/bash
cd /root/openface

 

然后你就能访问你在 docker image 中 /host/Users/...的 OSX 文件

 

ls /host/Users/

 

第一步

在 openface 文件中建立一个名为 ./training-images/ 的文件夹。

 

mkdir training-images

 

第二步

为你想识别的每个人建立一个子文件夹。例如:

 

mkdir ./training-images/will-ferrell/
mkdir ./training-images/chad-smith/
mkdir ./training-images/jimmy-fallon/

 

第三步

将每个人的所有图像复制进对应的子文件夹。确保每张图像上只出现一张脸。不需要裁剪脸部周围的区域。OpenFace 会自己裁剪。

第四步

从 openface 的根目录中运行这个openface 脚本。

首先,进行姿势检测和校准:


./util/align-dlib.py
./training-images/ align outerEyesAndNose ./aligned-images/ --size 96

 

这将创建一个名为./aligned-images/的子文件夹,里面是每一个测试图像裁剪过、并且对齐的版本。

其次,从对齐的图像中生成特征文件:


./batch-represent/main.lua
-outDir ./generated-embeddings/ -data ./aligned-images/

运行完后,这个./generated-embeddings/子文件夹会包含一个带有每张图像嵌入的 csv 文件。

第三,训练你的面部检测模型:

./demos/classifier.py
train ./generated-embeddings/

 

这将生成一个名为 ./generated-embeddings/classifier.pkl的新文件,其中包含了你用来识别新面孔的 SVM 模型。

到这一步为止,你应该有了一个可用的人脸识别器!

 

第五步:识别面孔!

 

获取一个未知脸孔的新照片,然后像这样把它传递入分类器脚本中:

 

./demos/classifier.py
infer ./generated-embeddings/classifier.pkl your_test_image.jpg

你应该会得到像这样的一个预测:

 

===/test-images/will-ferrel-1.jpg ===
Predict will-ferrell with 0.73 confidence.

 

至此,你已经完成了一个预测了。你也可以修改./demos/classifier.py 这个 python 脚本,来让它匹配其他人的脸。

重要提示:

 

  • 如果你得到的结果不够理想,试着在第三步为每个人添加更多照片(特别是不同姿势的照片)。
  • 即使完全不知道这个面孔是谁,现在这个脚本仍然会给出预测。在真实应用中,低可信度(low confidence)的预测可能会被直接舍弃,因为很有可能它们就是错的。
 
via medium.com

人脸识别人脸识别损失函数学习笔记

目录一、sphereface:A-Softmax(CVPR2017)1.1传统的softmaxLoss(第二章中有更详细的公式解释):1.2sphereface对softmax进行了两点改进:1.3sphereface弊端二、CosFace(CVPR2018)1softmaxloss的不同变种1.1原始的softmaxloss:1.2归一化s 查看详情

使用分类器进行面部识别的迁移学习

】使用分类器进行面部识别的迁移学习【英文标题】:Transferlearningforfacialidentificationusingclassifiers【发布时间】:2020-03-0603:18:30【问题描述】:我想知道是否可以使用Inception或ResNet模型来识别人脸。我想知道迁移学习和培训对我... 查看详情

怎么快速入门深度学习

...回来,那到底要如何去学习深度学习,首先深度学习属于机器学习的一个分支,机器学习分为监督学习、无监督学习、强化学习、半监督学习和深度学习要想学习深度学习就必须先学习机器学习,学习机器学习,首先需要储备的... 查看详情

刷脸背后:人脸检测人脸识别人脸检索_张重生资料整理

...。本书中讲解的算法具有高度的可操作性和实用性。通过学习本书,研究人员、工程师能够在3~5个月内,系统了解、掌握人脸检测、人脸识别、人脸检索相关的原理和技术。本书内容新颖、层次清晰,适合高校教师、 查看详情

一种基于脑电图情感识别的新型深度学习模型

...:脑机接口社区(微信号:Brain_Computer).QQ交流群:903290195机器学习的最新进展使得检测和识别人类情绪的技术也得到了快速的发展。其中一部分机器学习技术中是通过分析脑电图(EEG)信号来工作的,这些信号本质上是对从一个人的... 查看详情

深度学习——机器学习策略

1.误差分析manualerroranalysis对学习的结果进行人工误差分析。例:猫的分类器比如train结果的正确率为90%(10%的误差),对结果进行人工分析,如果发现有些狗被识别为猫导致错误,那是不是就可以考虑怎么来减少这种错误?如何... 查看详情

快速掌握深度学习(deeplearning)常用概念术语,常用模型

...什么是深度学习?深度学习的概念:深度学习是机器学习的一个分支,深度学习是使用了深度神经网络的机器学习。所以深度学习=深度神经网络+机器学习。神经网络,也叫作人工神经网络。是一种模拟人脑... 查看详情

机器学习资源个人汇总

一、初级介绍篇1.用Python,TensorFlow和Keras进行深度学习(作者SandipanDey)作者粗略介绍了LogisticRegression、SGD(withmomentum、RMSprop的公式其Python实现)以及使用Python、Keras搭建神经网络进行手写数字识别的例子。推荐指数:★★2.3.&nbs... 查看详情

为深度机器学习标记数据集

】为深度机器学习标记数据集【英文标题】:LabelingDatasetfordeepmachinelearning【发布时间】:2018-08-0410:04:40【问题描述】:我正在尝试创建用于文本识别的CNNTensor-flow,我已经按照如何使用MNIST数据集构建它的教程进行操作,我正在... 查看详情

学习笔记卷积神经网络

...卷积网络已经成功地识别人脸、物体、交通标志,应用在机器人和无人车等载具。&nb 查看详情

行人重识别在深度上有啥问题可以提

参考技术A现在深度学习在机器学习领域是一个很热的概念,不过经过各种媒体的转载播报,这个概念也逐渐变得有些神话的感觉:例如,人们可能认为,深度学习是一种能够模拟出人脑的神经结构的机器学习方式,从而能够让... 查看详情

机器学习深度学习数据集大汇总

...许可证。GravitiOpenDatasets:公开数据集下载,优质机器学习数据集,图像识别、NLP免费获取|格物钛,非结构化数据平台Huggingface数据集:HuggingFace–TheAIcommunitybuildingthefu 查看详情

机器学习--如何将nlp应用到深度学习

数据收集以后,我们下面接着要干的事情是如何将文本转换为神经网络能够识别的东西。 词向量 作为自然语言,只有被数学化才能够被计算机认识和计算。数学化的方法有很多,最简单的方法是为每个词分配一个编号,这... 查看详情

机器学习--如何将nlp应用到深度学习

数据收集以后,我们下面接着要干的事情是如何将文本转换为神经网络能够识别的东西。 词向量作为自然语言,只有被数学化才能够被计算机认识和计算。数学化的方法有很多,最简单的方法是为每个词分配一个编号,这种... 查看详情

如何使用地标点识别人脸?

】如何使用地标点识别人脸?【英文标题】:HowcanIrecognizeafaceusinglandmarkspoints?【发布时间】:2018-06-2606:18:13【问题描述】:我正在使用Eigenface算法进行人脸识别。但我需要使用面部各部分的距离或计算值之类的东西来识别面部。... 查看详情

mlp神经网络,grnn神经网络,svm神经网络以及深度学习神经网络对比识别人体健康非健康数据(代码片段)

目录一、理论基础二、案例背景1.问题描述2.思路流程三、部分MATLAB程序四、仿真结论分析五、参考文献一、理论基础   MLP多层感知器神经网络(Multi-layerperceptronneuralnetworks),其结构由输入层、一个或多个隐藏层、... 查看详情

基于python_opencv人脸录入识别系统(应用dlib机器学习库)(代码片段)

基于python_opencv人脸录入、识别系统(应用dlib机器学习库)近几年应用opencv机器学习方法识别人脸的技术成为了热潮,本人根据当今的识别技术与方法,历时四个多月开发出一套基于dlib机器学习库的识别项目。希... 查看详情

深度学习python怎么入门知乎

...积分背景,良好的Python编程技能,并扎实掌握数据科学、机器学习和数据工程。即便如此,在你开始将深度学习应用于现实世界的问题,并有可能找到一份深度学习工程师的工作之前,你可能需要一年多的学习和实践。然而,知... 查看详情