1. 绪论
1.1. 研究的目的和意义
由于COVID-19的余波和季节性流感的传播,人们佩戴口罩出行已经成为生活的常态。与此同时,佩戴口罩造成的人脸大面积遮挡给人脸识别技术带来了新的挑战。为了解决这个问题,口罩人脸识别(MFR)系统应运而生。口罩对于人脸识别造成的影响主要体现在其对人脸的遮挡导致了大量用于分析人脸特征的信息缺失,从而影响人脸关键点定位的准确性进而影响对人脸特征的提取 [1] 。同时,在人脸特征缺失的情况下,口罩本身也对识别造成了干扰,人脸的特征表达发生改变,无法与系统存储的人脸特征记录相匹配,传统的快速人脸识别技术不再有效,戴口罩的人脸识别已经成为研究人员的重要任务。
1.2. 戴口罩人脸识别国内外的研究现状
1.2.1. 国内研究现状
国内许多大型科技公司和高校都在这个领域进行了相关研究和开发,但目前公开的数据集与实验细节并不多。国内的研究主要集中在数据集的采集和算法的优化方面,采用了许多国内外经典网络结构和预训练模型进行实验,并尝试对数据集进行增广、剪枝等操作,以提高模型的准确率。但是,国内的研究大多是基于小规模的数据集进行的,缺乏大规模的口罩下人脸识别数据集,这导致该技术的应用场景受到很大的限制。
1.2.2. 国外研究现状
口罩下的人脸识别技术在全球范围都得到了广泛的关注,越来越多的国外研究学者探索使用增量学习、迁移学习、轻量化等技术优化口罩下的人脸识别性能,以提升模型的识别精度。尽管采用已有的深度学习算法和技术已经取得了不错的结果,但在处理具有大面积遮挡情况下的面部识别时,模型的准确率和鲁棒性仍需进一步提高。
2. 深度残差网络
2.1. 传统神经网络面临的窘境
深度卷积神经网络的发展给图像分类带来一系列便利,更深层的网络就意味着拥有更多的参数,更多的参数会使得模型的训练效果更好,但是这些网络都面临最显著的梯度消失和梯度爆炸问题,适当的权重初始化或使用Batch Normalization层可以有效缓解梯度问题。虽然学者们尝试努力解决梯度消失和爆炸问题,但新的问题接踵而至。实验数据证明,随着网络深度的增加,训练集精确度变得饱和之后模型的准确度开始迅速退化,见图1。
![](//html.hanspub.org/file/8-1542957x7_hanspub.png?20230821104405908)
Figure 1. Deeper network model will have higher training errors and test errors (based on CIFAR-10 dataset) [2]
图1. 更深层的网络模型会有更高的训练误差和测试误差(基于CIFAR-10数据集) [2]
在以往的深度学习神经网络模型中,层数一般都不超过20层。研究人员已经在实验中证实,通过堆加层数并不能很好地优化模型,神经网络的退化问题表明不是所有的系统都很容易优化,因此,在避免梯度爆炸的同时研究如何优化网络模型是必要的。
2.2. 创新理论下诞生的残差学习模块
我们可以从浅层网络入手来构建模型,在此基础上不断叠加层数得到更深层的网络模型。假设我们的神经网络在层数为l的时候打到了最优的效果,那么在l层的基础上去构建更深层的网络是一个恒等映射,但是在深度学习中拟合一个恒等映射是非常困难的。如果用x来表示目前学到的内容,用H(x)表示期望得到的映射,那么拟合H(x)和x的残差也就是优化拟合H(x)-x [3] 。如果我们能将F(x)训练为0,理论上可以认为我们成功地构造出了难以拟合的恒等映射。
![](//html.hanspub.org/file/8-1542957x8_hanspub.png?20230821104405908)
Figure 2. Residual module structure diagram [2]
图2. 残差模块结构图 [2]
如图2的残差模块中,输入x分为两个方向进行,而不是像大多神经网络中层层传递的模型。首先输入x在主分支经过一层权重层并Relu激活,第二次通过权重层后不进行激活。侧分支方向通过shortcut使得x直接和主分支处理过后的结果相加,和在经过一次Relu激活后传给下一层。
2.3. 残差网络模型的架构
![](//html.hanspub.org/file/8-1542957x9_hanspub.png?20230821104405908)
Figure 3. ResNet model with five layer structures
图3. 五种层结构ResNet模型
ResNet开发者给出了五种网络架构模型,见图3,ResNet34中涉及最大池化和平均池化操作,最大池化是指对每一个块中的数据取最大值计算,平均池化是指对每一个块的数据进行平均值运算。
![](//html.hanspub.org/file/8-1542957x10_hanspub.png?20230821104405908)
Figure 4. Internal structure of the 3*3 residual module [2]
图4. 3*3的残差模块内部结构 [2]
通过主分支进行3*3卷积运算后经Relu函数激活,在进行3*3卷积运算,最后与原输入相加之后,在经过Relu函数激活之后输入至下一层,见图4。对于实线标注的残差结构,输入矩阵的shape和输出矩阵的shape是一模一样的。而对于虚线标注的残差结构,由于输入矩阵和输出矩阵的shape不同,我们必须对步长和卷积核进行处理来完成传递。
![](//html.hanspub.org/file/8-1542957x11_hanspub.png?20230821104405908)
Figure 5. Internal structure of the 3*3 residual module [2]
图5. 3*3的残差模块内部结构 [2]
对于shape为[56,56,64]的输入矩阵,见图5,在主分支上,由于stride为2,特征向量的高和宽缩减为原来的一半,之后经过该层128个卷积核的处理,使得特征矩阵的深度从64变为128,保证了本层的结果能够正确的传递至下一层。
2.4. 解决梯度问题算法——批标准化
传统神经网络中,我们主要使用反向传播算法来优化深度学习神经网络,即根据损失函数计算的误差通过梯度反向传播的方式指导深度网络权值的更新优化,但梯度消失和梯度爆炸问题会随着网络层数的增加变得越来越明显,网络会变得不稳定 [4] 。
使用Batch Normalization层可以显著加速深度神经网络的训练,并有效地解决网络不稳定问题。该层通过归一化修正层输入的均值和方差,从而降低了梯度对参数或它们的初始值尺度的依赖关系,有益于通过网络的梯度流动。
2.5. 激活函数的选择
引入激活函数的主要目的是增加网络的非线性特性,从而提高网络的表达能力和拟合能力。在卷积神经网络中,卷积操作和池化操作等线性操作只能对输入数据做线性变换,而激活函数可以将线性变换后的结果进行非线性映射,从而使网络能够更好地处理复杂的非线性关系。不引入激活函数的神经网络可能会退化为感知机模型,使它无法准确处理线性不可分数据。常用的激活函数包括Sigmoid、tanh、ReLU、softmax等。不同的激活函数具有不同的性质和适用场景,需要根据具体任务和网络结构选择合适的激活函数。
2.5.1. Sigmoid函数
Sigmoid函数公式:
如图6函数图像可以看出,Sigmoid函数可以将输入的连续数值变换为0到1之间的值,相当于进行数值压缩。当遇到较大或较小的输入值时,计算的梯度趋于0。反向过程中再进行链式法则叠乘就会造成梯度消失现象 [5] 。
2.5.2. tanh函数
tanh函数公式:
![](//html.hanspub.org/file/8-1542957x15_hanspub.png?20230821104405908)
Figure 7. Image of the tanhx function
图7. tanhx函数图像
相比Sigmoid函数,tanh激活函数的输出值在正负区间都有分布,但是仍然没有解决梯度消失问题。x的绝对值越大,其函数值的绝对值越接近1且越平滑,梯度消失问题依然会出现 [6] ,见图7。
2.5.3. ReLU函数
ReLU函数表达式:ReLU = max(0, x)
当输入的数据为负数时,神经元不会被激活,神经网络只会将大于0的数据输出并激活,极大地提高了计算效率。由此可见,ReLU函数在快速收敛的同时还可以缓解梯度消失并提高计算速度,见图8。
3. Residual Network的新理解与改进
3.1. 从集成学习角度理解ResNet
若从数学的角度解释,可以假设三个残差块模型f1、f2、f3,输入的数据为x0,由于残差网络具有递归性质,我们可以得出递推关系式:
。
![](//html.hanspub.org/file/8-1542957x18_hanspub.png?20230821104405908)
Figure 9. Visualization of three residual blocks [7]
图9. 三个残差块可视化 [7]
展开递推关系式:
通过以上表达式,我们可以将图9形象化为以下结构:
![](//html.hanspub.org/file/8-1542957x20_hanspub.png?20230821104405908)
Figure 10. Visualization of conventional three residual blocks [7]
图10. 常规三残差块形象化视图 [7]
从见图10我们可以发现,每一个模块都有两种路径选择:第一种选择跳过连接,第二种选择通过残差模块,对于n块残差模块,进行形象化视图后能得到2n条路径。通过上述分析,我们可以得知残差网络的路径并不是相互依赖的。
![](//html.hanspub.org/file/8-1542957x21_hanspub.png?20230821104405908)
Figure 11. Comparison experiment of deleting a single layer [7]
图11. 删除单个层的对比实验 [7]
图11表明,对于VGGNet,删除单个层会造成整个网络的性能降低至随机级别,而对于ResNet网络,删除某一层还会保留一半的路径,实验结果也表明删除某一层也能使得整个网络的训练效果不会发生较大幅度的变化。在训练过程中,由于每个残差模块都可以独立地进行训练,因此可以将ResNet看作一种集成学习的方法,将多个浅层模型集成一个深层模型,有效提高了网络的表达能力。
3.2. 改进型激活函数
ReLU激活函数被普遍应用于神经网络中,但在ReLU函数中,负数的输入会被激活函数映射为0,这将会导致某些神经元可能永远不会被激活,后续学习参数将不再更新,这种现象可以称为DEAD ReLU问题。为了解决DEAD ReLU问题,我们可以引进PReLU函数对ReLU函数进行一定幅度的改进 [8] 。
相比于ReLU函数,PReLU函数并不是直接将负值变为0,而是在负值区间内引进了系数α,这可以使得输入在负值区域内的数据能以微小的速度进行更新迭代。如果令系数α = 0.1,则称该函数为Leaky ReLU函数,如图12所示。
改进后的Leaky ReLU函数不仅具有ReLU函数的优点,还能解决参数停止更新的问题,使得ResNet模型的效果更加优秀。
4. PyTorch框架下的ResNet人脸口罩遮挡识别网络搭建
4.1. PyTorch简介
由于Torch开发语言并未得到广泛的应用,开发团队决定使用Python语言进行全面重构,PyTorch由此诞生。一经推出,PyTorch就在深度学习领域得到了广泛应用,特别是在计算机视觉与自然语言处理等领域。PyTorch提供CPU设备和GPU设备的支持和加速,能有效提高数据运行速度。另外,Pytorch也支持动态神经网络,其库函数中包含了大量已经封装完成的深度学习神经网络框架,为模型的构建和项目的研究提供了便利。
4.2. 数据集构建
将8000张公开的图像数据及网络上的人脸图片(部分图片实例见图13)分为佩戴口罩的和未佩戴口罩两类,利用LabelImg进行标注并进行数据预处理。
4.3. ResNet网络搭建
本实验基于PyCharm完成,实验所用框架为ResNet18框架,见图14。
![](//html.hanspub.org/file/8-1542957x25_hanspub.png?20230821104405908)
Figure 14. Residual structure of ResNet18 [2]
图14. ResNet18的残差结构 [2]
4.3.1. 残差结构块代码实现
![](//html.hanspub.org/file/8-1542957x26_hanspub.png?20230821104405908)
Figure 15. Residual structure block code implementation
图15. 残差结构块代码实现
图15中参数含义:
expansion:对应残差结构中主分支卷积核是否发生变化的参数
in_channel&out_channel:输入和输出特征矩阵的深度
stride:步长
downsample:下采样参数,默认为None
其中下采样参数对应前文图2、图5提出的残差网络中虚线和实线网络结构问题,设置该参数通过判断来完成降维工作。按照残差结构的顺序,构建conv1层并通过bn层由激活函数激活,传入bn层的参数是经过conv1层之后的矩阵深度,之后构建conv2层并通过bn层。在conv1和conv2中的stride设置不同,是因为每层的虚线结构要对矩阵的高和宽进行缩减一半的操作。
4.3.2. 传参并调用ResNet函数
![](//html.hanspub.org/file/8-1542957x27_hanspub.png?20230821104405908)
Figure 16. Passing parameters and calling ResNet function
图16. 传参并调用ResNet函数
调用ResNet18函数,传入已经定义完成的BasicBlock类,残差层个数为[2,2,2,2],最后输入类别个数即可完成调用,见图16。
4.4. 训练网络与实验验证
图片
进行数据预处理并构建ResNet网络架构之后,我们编译主函数构建训练过程,分别利用公有测试集和私有测试集进行验证。由于本实验使用CPU进行网络训练,训练速度较慢,所以仅进行两个epoch的学习并验证。
训练结果如图17。
![](//html.hanspub.org/file/8-1542957x28_hanspub.png?20230821104405908)
Figure 17. ReLU function ResNet18 network training results
图17. ReLU函数ResNet18网络训练结果
如图17所示,对于ResNet18,进行一个epoch共计14355的样本训练之后,在公开测试集上验证的准确率为30.844%,私有测试集的准确率为30.900%。进行训练两个epoch之后,在公开测试集上验证的准确率为39.287%,私有测试集的准确率为39.900%。
接下来更改为LeakyRelu函数并进行实验,在前向传播过程中直接调用LeakyRelu函数,得到实验结果如图18所示。
![](//html.hanspub.org/file/8-1542957x29_hanspub.png?20230821104405908)
Figure 18. LeakyReLU function ResNet18 network training result
图18. LeakyReLU函数ResNet18网络训练结果
对于使用LeakyReLU激活函数的ResNet18,进行一个epoch共计14,355的样本训练之后,在公开测试集上验证的准确率为34.188%,私有测试集的准确率为34.244%。进行两个epoch训练之后,在公开测试集上验证的准确率为43.940%,私有测试集的准确率为43.076%。
5. 结论
由于训练集比较庞大(一组训练集共计14,355个训练数据),完成一个epoch的训练所消耗的时间在1h左右,公开测试集和私有测试集的测试时间也在20 min左右。相较于经过充分训练的ResNet模型,本实验受硬件条件的限制,模型的训练还远远不够,精确度也没能达到较高水准。但无论是进行一个epoch训练还是两个epoch训练,使用LeakyReLU函数完成的实验的精确度的确比使用ReLU函数的精确度要高出3%左右,这说明改进型激活函数LeakyReLU存在对ResNet网络进行一定程度优化的可能性。
6. 口罩佩戴检测系统运行效果
用户界面有人脸录入、更新数据库和实时检测三大主要功能:人脸录入功能支持从数据库中选取图像数据和打开摄像头拍照录入两种方式。在更新数据库之后,打开摄像头进行实时检测,可以直观地看到系统不断地提示镜头中的人是谁以及她是否佩戴口罩,见图19。
致谢
感谢大连外国语大学软件学院及创新创业学院对本次研究的支持。
基金项目
大连外国语大学2023年大学生创新创业项目。