利用连体网络、Keras 和 TensorFlow 进行人脸识别
翻译自pyimagesearch的文章,原文连接:Face Recognition with Siamese Networks, Keras, and TensorFlow
目录
-
使用 Siamese Networks、Keras 和 TensorFlow 进行人脸识别
-
人脸识别
-
人脸识别:识别和验证
-
通过验证进行识别
-
指标学习:对比损失(Contrastive Losses)
-
对比损失
-
使用 Siamese Networks、Keras 和 TensorFlow 进行人脸识别
在本教程中,您将了解 Siamese Networks 以及如何使用它们来开发面部识别系统。我们将讨论不同类型的面部识别方法,并深入探讨Siamese Network的概念细节,这使它们成为强大的面部识别应用不可或缺的一部分。
具体来说,我们将详细讨论以下内容
- 人脸识别管道和各种类型的人脸识别方法
- 人脸识别和验证之间的区别
- 度量学习和对比损失
本课是关于暹罗网络及其在人脸识别中的应用的 5 部分系列中的第 1 部分:
- 使用 Siamese Networks、Keras 和 TensorFlow 进行人脸识别(本教程)
- 使用 Keras 和 TensorFlow 构建(Triplet Loss)三元损失数据集
- 使用 Keras 和 TensorFlow 计算(Triplet Loss)三元损失
- 使用Siamese Networks和(Triplet Loss)三元损失进行训练和预测
- 使用 Keras 和 TensorFlow 评估 Siamese Networks准确性(F1 分数、精确度和召回率)
在第一部分(本教程)中,我们将旨在全面了解不同的人脸识别方法,并讨论用于训练连体网络的对比损失背后的概念。
在第二部分中,我们将深入探讨在 Keras 和 TensorFlow 中使用 Siamese Networks构建端到端面部识别系统的代码。我们将首先在数据中加载标记的人脸,并为我们的人脸识别应用程序做准备。
接下来,在第三部分中,我们将了解三元损失的概念和数学公式,并在 Keras 和 TensorFlow 中编写我们自己的损失函数。
最后,在第四部分和第五部分中,我们将讨论如何使用端到端人脸识别系统进行推理,以实时识别新人脸。在本系列的最后一部分,我们还将讨论各种评估指标,以量化我们的人脸识别应用程序的性能。
使用 Siamese Networks、Keras 和 TensorFlow 进行人脸识别
深度学习模型倾向于对它们所训练的数据分布产生偏见。这是指数据集偏差问题,其中深度模型过度拟合训练图像的分布(例如,姿势、背景、颜色、纹理、照明条件),并且在测试时无法泛化到相同对象的新视图或实例。这个问题的一个简单的解决方案是在对象描述的所有可能的背景或视图中收集和标注数据。然而,这个过程是不可行的或乏味的,导致高额的标注成本。
因此,实际应用需要开发对滋扰具有鲁棒性的模型,并且可以推广到新的看不见的视图或物体的描述。例如,要比较两个图像是否属于同一对象类别,需要
- 开发不受姿势、背景、颜色、纹理等因素影响的深度模型
- 重点关注构成对象类别的基础属性
开发强大的深度模型的一项成功尝试是Siamese Networks的诞生。在之前的教程中,我们已经讨论了这些网络背后的直觉和机制的概述。在本教程中,我们将着眼于开发基于Siamese Networks的面部识别系统。
人脸识别
人脸识别是一项重要的计算机视觉任务,它使我们能够识别和验证一个人的身份。在行业中广泛用于考勤系统开发、医疗保健、安全验证等应用。
在之前的教程中,我们讨论了人脸识别任务的概述,以及用于构建有效人脸识别系统的各种传统和现代方法。
任何有效的面部识别系统的一个重要方面是它对描绘同一个人的不同观点或方式的不变性。例如,基于人脸识别的员工考勤系统应侧重于构成一个人身份的可推广特征,并且是姿势、外观(例如胡须、发型等)或给定人的看不见的视图的有力变化。这很重要,因为对系统进行每个员工外表的所有可能变化的培训是不可行的。
因此,人脸识别的最新进展使用对比损失来训练基于连体网络的架构,以构建强大的人脸识别模型。
人脸识别:识别和验证
图 1 显示了典型的人脸识别系统管道。正如我们所看到的,第一阶段是检测阶段,将人脸与背景区分开来。此阶段还可能包括重新调整面部姿势的对齐操作。
图 1:人脸识别管道 |
接下来,将裁剪检测到的人脸并将其传递到深度特征提取器。特征提取器输出人脸的特征向量,如图所示。深度网络经过训练,使得输出特征表示捕获区分性面部特征,并且对细微差别(例如,照明、颜色、纹理、胡须等)具有鲁棒性。
最后,学习到的特征表示用于识别或验证人的身份。
接下来,让我们详细了解一下人脸识别和人脸验证任务之间的区别。
人脸识别是指识别一个人的身份的任务,需要将一个人的身份分配给给定的输入图像。
图 2 显示了用于执行人脸识别的基本管道。识别管道将图像作为输入,并输出对可能的人员身份的概率分布。
图2:人脸识别 |
首先,输入图像通过深度特征提取器以获得特征表示$ f $ ,如图 2 所示。接下来,将特征传递到分类器网络,该分类器网络将人员的身份或 ID 分配给给定的输入图像。请注意,这需要一种简单的\(K\)方法,即对具有$ K $ 人员(此处为$ K=4 $ 人员或类)的数据库进行多类分类问题。
由于识别管道是一个简单的多类分类,因此它使用通常的 softmax 和交叉熵损失进行训练。
另一方面,验证任务需要验证两个图像是否属于同一身份。
图3 显示了用于执行人脸验证的基本管道。流水线的输入是人脸图像和要验证的人脸 ID,输出是图像x是否属于具有人脸 ID 的人的二进制决定。
图 3:人脸验证 |
在验证的情况下,我们会预先提取并存储所有人脸图像的特征表示,如图所示。给定一个新图像\(X\)和一个 Face ID(比如 id-1021,如图 3 所示),我们计算图像的特征表示,并将其与 Face ID-1021 的特征表示\(f\)进行比较。比较基于相似性指标,我们将在本文后面详细讨论。最后,根据阈值,我们可以找到给定的输入图像是否属于我们数据库中的特定人。
通过验证进行识别
正如本文前面所讨论的,识别需要我们训练一种\(K\)方式分类器,以从数据库中的\(K\)人员中为给定的输入人脸图像分配特定的身份。但是,如果我们数据库中的人数增加,这种类型的识别系统是不可扩展的。
例如,如果数据库中添加了一个新人,我们将不得不从头开始在新的\(K+1\)类上重新训练为K类构建的识别系统。这是因为以前分类器有\(K\)个神经元,现在我们需要一个有\(K+1\)个神经元的分类器。这抑制了系统的效率和可扩展性,因为每次添加新的人脸时,都必须重复整个训练过程。
因此,实现识别的更有效和有效的方法是在验证中使用基于相似性的比较方法。
图4显示了如何使用验证技术实现识别。给定一个输入图像\(X\),我们可以为数据库中的\(K\)个人脸ID中的每一个运行验证算法\(K\)次。我们可以找到给定人脸的身份作为验证算法的二进制输出为真的人脸ID(即,找到输入图像的匹配)。
图 4:通过验证进行识别 |
使用验证进行识别的好处是,如果我们将新人脸添加到\(K\)人脸数据库中,我们只需要运行验证算法\(K+1\)进行识别,而无需重新训练网络。
因此,我们观察到基于分类器的识别方法由于最后一层中神经元数量的固定而抑制了可扩展性。但是,当将新人脸添加到人脸数据库时,验证中使用的基于相似性的比较方法更加高效且可扩展。
指标学习:对比损失
如上一节所述,与基于分类的方法相比,基于相似性的人脸识别比较方法使我们能够构建更高效和可扩展的系统。
因此,为了构建有效的人脸识别系统,我们需要制定训练策略,使我们能够构建一个嵌入空间,在这个空间中,相似的人脸图像或给定的人的脸图像聚集在一起,并且不同人的人的脸图像相距更远。
对于神经网络来说,实现这一点的最常见方法是使用深度度量学习。
简单来说,度量学习是一种范式,我们的网络以这样一种方式进行训练,即相似图像的表示在嵌入空间中彼此接近,而不同对象的图像相距较远。这里的“相似性”概念是基于嵌入空间中的特定距离度量来定义的,该度量量化了语义相似性以及图像是否属于相同或不同的对象或人。
对比损失
对比损失是一组损失函数,它允许我们学习一个嵌入空间,与不同的输入相比,语义相似的输入或图像嵌入得更接近。这些损失通常用于训练神经网络学习距离测量,该测量可以比预定义的距离测量(例如,欧几里得距离、绝对距离等)更有效地量化输入图像之间的相似性。
对比损失有不同的公式(例如,排名损失(ranking loss)、成对对比损失(pairwise contrastive loss)、三元损失、四元损失(quadruplet loss)等)。但是,所有这些变体都具有相同的基本思想和属性。让我们借助一个例子来详细讨论这个问题。
图 5 显示了一个通用设置,显示了如何使用对比损失来学习特征表示。
图 5:对比损失学习 |
我们的目标是学习从输入空间\(X\)到特征空间\(f\)的映射\(G\)。在这里,该函数\(G\)使用权重进行参数化\(W\),权重在两个分支之间共享。这可以解释为在输入空间上应用复变换\(G\),将输入投影\(X\)到特征空间\(f\)。
目标是学习参数\(W\),使得高维输入\(X_1\)和\(X_2\)被映射到低维流形(或嵌入空间)\(f\)上。否则,它们应该相距更远。
在数学上,我们想要学习参数W,使得特征\(f_1=G_W(X_1)\)和\(f_2=G_W(X_2)\)之间的距离,即,
近似输入\(X_1\)和\(X_2\)之间的相似性。
可以使用对比损失函数来实现这一目标,该函数将
- 如果输入图像属于相同的类别或人,则将特征空间中的点(即\(f_1\)和\(f_2\))拉得更近
- 如果它们属于不同的阶级或人,请将它们进一步分开
让我们考虑最简单形式的对比度损失(即成对对比度损失)的例子,以更好地理解这一点
其中\(m>0\)是边距。
上面的方程显示了成对对比度损失的数学公式。这里,\(W\)表示映射函数\(G\)的参数,如果\(X_1\)和\(X_2\)属于同一类或人,则\(Y\)是等于0的二进制标识符,否则为1。
当\(Y=0\)时,即当\(X_1\)和\(X_2\)属于同一类别或人时,损失减少为
最小化该表达式将最小化\(D_W\),\(D_W\)是表示\(f_1\)和\(f_2\)之间的距离(即,它将使特征彼此靠近)。
另一方面,在Y=1的情况下,即当X_1和X_2属于不同的类别或人时,损失减少到
请注意,当\(m-D_{W}^2 \leq 0\)时,该表达式的最小值(即0)出现,即\(D_{W}^2 \geq m\)这意味着最小化这种损失,以确保特征\(f_1\)和\(f_2\)在特征空间中至少相隔\(m\)的距离。
因此,损失公式确保相似的点在特征空间中靠近在一起,并且不同的点在特性空间中至少分开\(m\)的距离。
请注意,允许我们学习这样一个系统的重要原则是,任何对比损失公式都应该满足这些原则
- 输入空间中语义相似的点应该在低维流形上映射为彼此接近
- 学习的距离度量应该能够映射未看到的或新的输入
- 所学习的映射对于复杂变换应该是不变的
下一篇: 多种类型的神经网络(孪生网络)
推荐阅读
-
利用连体网络、Keras 和 TensorFlow 进行人脸识别
-
[姿势估计] 实践记录:使用 Dlib 和 mediapipe 进行人脸姿势估计 - 本文重点介绍方法 2):方法 1:基于深度学习的方法:。 基于深度学习的方法:基于深度学习的方法利用深度学习模型,如卷积神经网络(CNN)或递归神经网络(RNN),直接从人脸图像中学习姿势估计。这些方法能够学习更复杂的特征表征,并在大规模数据集上取得优异的性能。方法二:基于二维校准信息估计三维姿态信息(计算机视觉 PnP 问题)。 特征点定位:人脸姿态估计的第一步是通过特征点定位来检测和定位人脸的关键点,如眼睛、鼻子和嘴巴。这些关键点提供了人脸的局部结构信息,可用于后续的姿势估计。 旋转表示:常见的旋转表示方法包括欧拉角和旋转矩阵。欧拉角通过三个旋转角度(通常是俯仰、偏航和滚动)描述头部的旋转姿态。旋转矩阵是一个 3x3 矩阵,表示头部从一个坐标系到另一个坐标系的变换。 三维模型重建:根据特征点的定位结果,三维人脸模型可用于姿势估计。通过将人脸的二维图像映射到三维模型上,可以估算出人脸的旋转和平移信息。这就需要建立人脸的三维模型,然后通过优化方法将模型与特征点对齐,从而获得姿势估计结果。 特征点定位 特征点定位是用于检测人脸关键部位的五官基础部分,还有其他更多的特征点表示方法,大家可以参考我上一篇文章中介绍的特征点检测方案实践:人脸校正二次定位操作来解决人脸校正的问题,客户在检测关键点的代码上略有修改,坐标转换部分客户见上图 def get_face_info(image). img_copy = image.copy image.flags.writeable = False image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = face_detection.process(image) # 在图像上绘制人脸检测注释。 image.flags.writeable = True image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) box_info, facial = None, None if results.detections: for detection in results. for detection in results.detections: mp_drawing.Drawing.detection = 无 mp_drawing.draw_detection(image, detection) 面部 = detection.location_data.relative_keypoints 返回面部 在上述代码中,返回的数据是五官(6 个关键点的坐标),这是用 mediapipe 库实现的,下面我们可以尝试用另一个库:dlib 来实现。 使用 dlib 使用 Dlib 库在 Python 中实现人脸关键点检测的步骤如下: 确保已安装 Dlib 库,可使用以下命令: pip install dlib 导入必要的库: 加载 Dlib 的人脸检测器和关键点检测器模型: 读取图像并将其灰度化: 使用人脸检测器检测图像中的人脸: 对检测到的人脸进行遍历,并使用关键点检测器检测人脸关键点: 显示绘制了关键点的图像: 以下代码将参数 landmarks_part 添加到要返回的关键点坐标中。
-
利用 Resnet 网络对人脸图像进行分类,识别男女性别(包括数据集制作 + 训练 + 测试)