
Mask2face
本文最后更新于 2024-08-19,文章内容可能已经过时。
🤔绪论
研究背景与意义
从 2019 年 12 月开始,我国境内爆发了 COVID-19(新型冠肺炎)疫情,疫情期间,公共场所内佩戴口罩预防病毒传播是每个人的责任,这不只是需要个人的自觉遵守,还需要采取一定的管理和监督手段。随着全球深度学习在机器视觉领域的飞速发展,基于人工神经网络的目标检测算法现阶段在行人脸检测、人目标检测、医学图像检测、自然场景文本检测和遥感图像目标检测等领域都有着广泛的应用。本文介绍了一种区别于传统口罩人脸识别算法, 更为有效的基于生成对抗的人脸检测算法。
国内外研究现状
随着新型冠状病毒的爆发和传播,越来越多的人意识到传统面部识别系统的局限性,其中一些人已经开始研究如何在 iPhone 设置中添加另一个人脸识别系统,但尚未实现。同时,汉王科技致力于打造「疫情报告 + 口罩检测 + 人形识别 + 大数据联动」的综合识别体系,一般采用「门禁考勤 + 社区管理」的混合模式。此外,百度还宣布,它将会是业内首个开源且免费的口罩人脸分类和检测模型。
国外对基于深度学习的人脸识别方法有丰富的研究成果。Ned Miller 的国外研究团队率先将深度学习应用于人脸识别领域,并且获得了一定准确的识别率,还带动了当时科研的发展。近年来,基于深度学习的人脸识别算法的识别精度有了明显的提高。Google 还推出了 FaceNet 报警技术,并且刷新了 LFW 上的人脸验证有效性的记录。此外 Facebook 也提出了一种基于关键点的人脸检测方法—DeepFace。近年来。国外也有基于深度学习的目标检测的算法研究,例如 Girshick 等人率先提出了基于 R-CNN 的变形模型,随后在此基础上又提出了 Fast-CNN 模型,引入目标区域池化 (RegionProposalNetwork,RPN) 和单层金字塔池化层来解决候选盒重复计算的问题。近年来,国外提出了 Fast-CNN 模型,该模型通过构建复杂的区域建议网络 (ROI) 来取代耗时的选择性搜索方法,使实时检测和识别成为可能。而上述三种模型都是基于区域建议的方法, 还有一种无区域建议的方法,具有代表性算法包括知名的 YOLO 和 SSD,其核心思想是利用 CNN 网络作用于整个图像直接预测目标的属性和位置,也称为第一阶段的目标检测。YOLO 和 SSD 是迄今为止最先进的两种目标检测方案,它们可以同时检测和分类单幅图像中的目标。通过不断改进,可以在原有的基础上参考锚点和残差网络,进一步提高模型的性能。在此基础上,将图像生成技术应用于掩模去除,探索人工智能的无限可能性和普用性。
研究主要内容与组织结构
通过训练模型让 AI 能够预测照片中口罩下的人脸。从具有预先计算的人脸特征点的人脸数据集开始,这些人脸特征点通口罩生成器进行处理。它使用地标将口罩定位在脸上。现在就有了包含图像对(带和不带口罩)的数据集,接着定义 ML 模型的架构。最后一部分是找到最佳损失函数和所有必要的脚本来将所有内容放在一起,以便训练和评估模型。
本文对人脸修复模型进行了分析,数据集由口罩生成器生成图像对,将卷积神经网络 (CNN)、RESNE 网络、U-NET 结合构建模型并训练。
📚数据集
生成数据集
为了训练深度学习模型,本文需要大量的数据。在这种情况下,本文需要大量的输入和输出图像对。当然,收集同一个人有和没有口罩的输入和输出图像是不切实际的。
人脸图像数据集很多,主要用于人脸检测算法的训练。可以采用这样的数据集,在脸上绘制一个口罩。
本文尝试了两个不同的数据集。本文使用的一个数据库是马萨诸塞大学的Label Faces in the Wild。这是 104MB 的 gzip tar 文件,其中包含超过 5,000 张图像的整个数据集。这个数据集非常适合本文的情况,因为它包含专注于人脸的图像。但是,对于最终结果,本文使用了CelebA数据集,该数据集更大(200,000 个样本),并且包含更高质量的图像。
接下来,本文需要定位面部特征点,以便将面具放置在正确的位置。为此,本文使用了预训练的dlib面部特征点检测器。您可以使用任何其他类似的数据集,只需确保可以找到预先计算的人脸地标点(此 GitHub 存储库可能是一个很好的来源)或自己计算地标。
口罩生成器
首先,需要从口罩成器的简单实现开始,方法是在面上放置一个多边形,多边形顶点与人脸地标的随机距离。这样,可以快速生成一个简单的数据集,并测试这个项目背后的想法是否有效。一旦确定它确实有效,就可以寻找一个更强大的解决方案,以更好地捕捉现实世界的场景。
有一个很棒的 GitHub 项目,Mask The Face,已经解决了面具生成问题。它从面部地标点估计面具位置,估计面倾斜角度以从数据库中选择最合适的蒙版,最后将面具放在脸上。可用口罩的数据库包括外科口罩、各种颜色和质地的布制口罩、几种类型的呼吸器甚至防毒面具。
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from utils.data_generator import DataGenerator
from utils.configuration import Configuration
# You can update configuration.json to change behavior of the generator
configuration = Configuration()
dg = DataGenerator(configuration)
# Generate images
dg.generate_images()
# Plot a few examples of image pairs
n_examples = 5
inputs, outputs = dg.get_dataset_examples(n_examples)
f, axarr = plt.subplots(2, n_examples, figsize=(20,10))
for i in range(len(inputs)):
axarr[1, i].imshow(mpimg.imread(inputs[i]))
axarr[0, i].imshow(mpimg.imread(outputs[i]))
🧬模型分析
模型的构建
现在已经准备好了一个数据集,是时候研究深度神经网络模型架构了。在这种情况下,没有人可以声称有一个客观的「最佳」选择。
选择合适的架构始终取决于许多因素,例如时间要求(是要实时处理视频还是要脱机预处理一批图像?),硬件要求(模型应该在高功率 GPU 集群上运行还是在低功耗移动设备上运行?)等等。始终是为您的特定情况找到正确的参数和设置。
模型 Pipeline
图 3-1 模型 Pipeline(流程)图展示了模型的工作流程
图 3-1 模型 Pipeline(流程)图
从具有预先计算的人脸特征点的人脸数据集开始,这些人脸特征点通过口罩生成器进行处理。它使用地标将面具定位在脸上。现在有了包含图像对(带和不带掩码)的数据集,可以继续定义 ML 模型的架构。最后,管道的最后一部分是找到最佳损失函数和所有必要的脚本来将所有内容放在一起,以便可以训练和评估模型。
卷积神经网络
卷积神经网络 (CNN) 是一种利用卷积核过滤器的神经网络架构。它们适用于广泛的问题 - 如时间序列分析,自然语言处理和推荐系统 - 但主要用于任何与图像相关的事物,如对象分类,图像分割,图像分析和图像修复。
CNN 的核心是能够检测输入图像的视觉特征的卷积层。当堆叠多个卷积层时,它们倾向于检测不同的特征。第一层通常提取更复杂的特征,例如角或边。随着您深入 CNN,这些层开始检测更高级别的特征,例如对象、面部等,如图 3-2 特征学习。
图 3-2 特征学习
上图显示了用于图像检测的 CNN 示例。这不是本文使用的模型架构,但 CNN 架构是任何图像修复架构的必要构建块。
ResNet 网络
ResNet 被称为 ResNet 网络或残差网络。在传统的神经网络或 CNN 中,每一层都连接到下一层。在具有残差块的网络中,层也连接到下一层,但也连接到两个或更多层。为此引入了 ResNet 网络来进一步提高性能,如图 3-3 展现了 ResNet 网络结构。
图 3-3 ResNet 网络结构
神经网络能够近似任何函数,可以认为增加层数将提高近似的准确性。然而,由于梯度消失或维度灾难等问题,添加更多层将在某些时候停止提高性能,并且实际上可以开始降低性能。这就是为什么许多研究都致力于这些问题的原因——而表现最好的解决方案之一就是残差网络。
残差网络允许使用跳过连接或恒等函数将信息从初始层流向下一层。通过赋予神经网络使用 RELU 函数的能力,可以构建性能更好的网络,而不仅仅是添加更多层。
编解码器
编解码器体系结构是由两个独立的神经网络组成:编码器会提取输入(嵌入)的固定长度表示式,解码器将从该表示形式中生成输出 如图 3-4 编码器。
图 3-4 编码器
经过验证的分类 CNN 通常用作编码器的基础,甚至直接用作编码器,没有最后一个(分类)层。这种架构能够生成新图像。然而,性能并不是那么好。
U-Net
U-Net 是卷积神经网络架构,最初是为图像分割而开发的,但它可用于更多任务,例如图像修复或图像着色,如图 3-5 U-Net 结构。
图 3-5 U-Net 结构
本文之前提到的 ResNet 网络有一个重要的原因。事实上,将 ResNet 块与 U-net 架构相结合可以说对整体性能的影响最大。图 3-6 为添加 ResNet 网络的架构。
图 3-6 ResNet 架构
将上面的 U-net 架构与上一节中的编解码器架构进行比较时,它们看起来非常相似 - 但有一个关键的区别。U-net 实现了一种称为「跳过连接」的东西,它将身份从反卷积网络传播到另一侧的相应上采样块(上图中的灰色箭头)。这是对编解码器的改进,在两个值得注意的方式上。
首先,已知跳过连接可以加快学习过程并帮助解决梯度消失问题。其次,它们将信息从编码器直接传递到解码器,帮助恢复下采样期间的信息丢失。本文可以说它们可以在面罩之外传播图像的所有部分,本文希望保持不变,同时还有助于生成面罩下方的面部部分。
跳过连接将有助于保留本文想要传播到输出的输入部分,而 U-net 的编解码器部分将检测口罩并将其替换为口罩下面的嘴巴。
损失函数
损失函数的选择是需要解决的最重要的问题之一。使用正确的损失函数可能意味着性能出色的模型与几乎不起作用的模型之间的差异非常大。这就是为什么本文花了很多时间选择最佳选项的原因。让本文讨论几种可能性。
均方误差(MSE)和平均绝对误差(MAE)
MSE 和 MAE 都是损失函数,基于将遮罩应用于面部之前,本文的模型生成的图像与数据集中的真实图像之间的每像素差异。这似乎正是本文所需要的,但本文并没有试图训练可以像素完美地重建隐藏在面具下的模型。
本文希望本文的模型能够理解口罩下面是一张嘴和一张鼻子,甚至可能从没有隐藏的东西(例如眼睛)中理解情绪,以产生悲伤、快乐或惊讶的脸。这意味着,即使不能完美捕获每个像素的输出实际上也可以是一个很好的结果; 而且,更重要的是,它可以学习如何在任何人脸上进行泛化,而不仅仅是训练数据集中的人脸。这就是为什么本文使用不同的损失函数可以获得更好的结果。
Structural Similarity Index (SSIM)
Structural Similarity Index (SSIM) 是一个用来衡量两张图像之间相似性的参考指标。由 Wang 等人(2004)提出,它侧重于解决 MSE / MAE 的确切问题。它为本文提供了一个数值表达式,表示两个图像彼此相似的程度,而不是有多少像素具有相同的强度。它通过比较图像之间的三个测量值来实现:亮度,对比度和结构。最终得分是从 0 到 1 的所有三个测量值的加权组合,其中 1 表示完全相似的图像。
图 3-7 说明了 MSE 的问题。左上角的图像是原始图像,没有任何修改。所有其他图像都以不同的方式失真。原始图像和所有其他图像之间的均方误差始终大致相同(约 480),而 SSIM 变化很大。例如,模糊图像和分割图像与原始图像的相似程度肯定低于其他任何图像,但 MSE 几乎相同 - 尽管头部和衣服上的面部特征和细节丢失。另一方面,色移图像和对比度拉伸的图像与人眼中的原始图像(和 SSID 度量)非常相似,但 MSE 不同意。
图 3-7 MSE
模型训练
使用 ADAM 优化器和 SSIM 损失函数使用 U-net 架构训练模型。将数据集分为测试部分(1000 张图像),训练部分(数据集其余部分的 80%)和验证部分(数据集其余部分的 80%)。
🛠️模型的改进方案
第一次实验为几张测试图像产生了不错但不是很清晰的输出图像。是时候尝试架构和损失函数以提高性能了。以下是尝试的一些更改:
尽管本文的 U-net 与 ResNet 块的结果很好,但本文可以看到蒙版下生成的图像不是很清晰。解决此问题的一种方法是使用细化网络扩展本文的网络。
卷积滤波器的层数和大小
更多的卷积过滤器和更深的网络意味着更多的参数(而大小为 [2, 8, 8] 的 256D 卷积层有 0 万个参数,大小为 [59, 4, 4] 的层有 512 万个参数)和更多的训练时间。由于每层中过滤器的深度和数量是本文模型架构构造函数的输入参数,因此尝试不同的值非常容易。
一段时间调试后发现,性能和模型大小之间的最佳平衡状态是以下设置:
# Train model with different number of layers and filter sizes
from utils.architectures import UNet
from utils.model import Mask2FaceModel
# Feel free to experiment with the number of filters and their sizes
filters = (64, 128, 128, 256, 256, 512)
kernels = ( 7, 7, 7, 3, 3, 3)
input_image_size=(256, 256, 3)
architecture = UNet.RESNET
training_epochs = 20
batch_size = 12
model = Mask2FaceModel.build_model(architecture=architecture, input_size=input_image_size, filters=filters, kernels=kernels)
model.summary()
model.train(epochs=training_epochs, batch_size=batch_size, loss_function='ssim_l1_loss')
经过一些实验,上面代码块中的设置整体来说效果最好。训练结果如图 4-2 所示:
图 4-2 模型输出
所提出的网络在本文的测试数据上产生了很好的结果。该网络能够泛化,而且它似乎也可以很好地发现情绪以产生微笑或悲伤的面孔。另一方面,肯定有一些改进的余地。
其他改进想法
尽管 U-net 与 ResNet 块的结果很好,但可以看到蒙版下生成的图像不是很清晰。还可以进行一些其他改进。
改进数据集
正如在实验中经历的那样,数据集的选择会对结果产生重大影响。可以结合不同的数据集,以获得更多的样本可变性,更好地模拟真实世界的数据。另一件可以改进的事情是口罩与面部相结合的方式,使它们看起来更自然。
Variational Autoencoders (VAEs)
关于编解码器架构,其中编码器部分将输入图像映射到嵌入层中。可以将嵌入层视为多维潜在空间中的单个点。VAEs 在许多方面类似于编解码器; 主要区别可能在于,使用变分自动编码器,映射到潜在空间中某个点周围的多元正态分布。这意味着根据设计,编码是连续的,并允许更好的随机采样和插值。这对于在网络输出上生成明显更平滑的图像有很大帮助。
生成对抗网络
生成相反的神经网络可以生成与实际图像不可区分的结果。这主要是由于完全不同的学习方法。尽管目前的模型试图减少训练损失,但反网络由两个独立的神经网络、一个伴随网络和一个生成器组成。生成器输出生成图像,并且标识符尝试确定该图像是实际的还是由生成器生成的。
在学习过程中,两个网络都会动态更新以越来越好地表现,直到最终,鉴别器无法确定生成的图像是否真实,并且生成器正在生成与真实图像无法区分的图像如图 4-3 所示。
图 4-3 GANs 从源 A 和 B 创建混合面的示例
Concat ImageNet 和 FaceNet Embedding
在许多方面,U-net 的瓶颈层充当特征提取嵌入层。连接不同网络的嵌入可以提高整体性能。
可以尝试将本文的嵌入层与来自 ImageNet 和 FaceNet 的两个不同嵌入相结合。这可以添加有关人脸及其特征的更多信息,以帮助 U-net 的上采样部分进行面部修复。这无疑提高了性能,但另一方面,它使整个模型变得更加复杂,并且性能提升比使用训练部分中提到的其他改进要小得多,如图 4-4 所示。
图 4-4 Concat ImageNet 和 FaceNet Embedding
🎏总结
现疫情时代,对于小区、地铁站、公交、机场、等人员密集的公共场所,人们不摘口罩就可以面部识别,有效减少对于新冠的感染率,对于安保来说也是很有利的工具,在不摘口罩的情况下,可以对人脸进行一个大概的预测,方便对相关人员备案,审核等工作的开展。这种面部重建带来了许多挑战。
🧸参考文献
本文为博主大专毕业论文,白嫖了以下文献
Mask2Face: How We Built AI That Shows the Face Beneath the Mask (strv.com)