人工智能导论——口罩佩戴检测详解(附带MTCNN论文精读)

一、问题重述

  随着人类的科技不断进步,病毒也在随之更新迭代;在19年席卷全球的新冠肺炎疫情给人们的生活带来了极大的灾难,造成了无数的人因此失去生命,同时也给高速增长的经济按下了暂停键。防止这种传染疾病的最常见的办法就是佩戴口罩;在人员密集的共同场合,如果只让工作人员来监督口罩佩戴检测的问题显然是极为困难的,所以我们考虑利用CV中深度学习技术来实现口罩佩戴检测。

  在本次实验中,我们一共需要完成两个任务目标,首先是针对给定图片进行检测,检测出其中的人脸,同时在检测出的人脸的前提下进行口罩佩戴检测。

二、设计思想

  本次实验我们采取的办法是在给定的模型的基础上进行微调,采用类似于迁移学习和小样本学习的办法来实现口罩佩戴的检测。我们选择的模型是MTCNN和MobileNet,在MTCNN已经检测出人脸的前提下,对MobileNet中已有的参数进行微调以适应我们的下游任务即实现口罩佩戴检测。

  首先我们需要阅读一下MTCNN的论文:MTCNN是由Kaiming Zhang、Zhepeng Wang、Shuo Yang和Xiaobo Zhou等人于2016年提出的一种人脸检测的方法;文章介绍了一种名为"Multi-task Cascaded Convolutional Networks"(MTCNN)的方法,用于联合进行人脸检测和人脸对齐。MTCNN是一种多任务学习的深度卷积神经网络框架,主要由三个级联的子网络组成,分别是Proposal Network(P-Net)、Refine Network(R-Net)和Output Network(O-Net)。

  P-Net是一个快速的人脸候选框生成网络,用于在输入图像中定位可能的人脸区域。R-Net对P-Net生成的候选框进行精细化的筛选和回归,以进一步提高人脸检测的准确性。最后,O-Net执行更加精细的人脸特征提取和对齐,同时输出人脸的关键点位置和人脸的边界框。

  这种级联结构的设计使得MTCNN方法在人脸检测和对齐任务中取得了很好的性能。该方法能够在不同尺度、姿态和光照条件下有效地检测和对齐人脸,具有较高的鲁棒性和准确性。因此,MTCNN方法成为了人脸相关任务中的重要基础方法之一,并在人脸识别、人脸验证、人脸分析等领域得到广泛应用。

  MobileNet是由谷歌研究团队的Andrew G. Howard、Menglong Zhu、Bo Chen、Dmitry Kalenichenko、Weijun Wang、Tobias Weyand和Marco Andreetto于2017年提出的。他们的研究成果被发布在论文《MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications》中。MobileNet的设计目标是创建一种轻量级的卷积神经网络架构,能够在移动设备等计算资源有限的环境中高效地进行图像识别和处理。MobileNet通过引入深度可分离卷积和逐点卷积等技术,有效减少了网络的参数数量和计算量,以提高模型的效率和性能。

  该论文中提出了MobileNet的基本架构和设计原则,并提供了一系列在不同计算资源限制下的模型变体。这些模型在保持相对较低的计算开销的同时,仍能在图像分类、目标检测等任务中取得不错的性能表现。

  我们这次实验就是基于MobileNet的网络结构和预调好的参数基础上进行微调设计,由于MobileNet是一种轻量级的卷积神经网络,具有较少的参数和计算量。它适用于计算资源有限的设备,如移动设备和嵌入式系统。通过微调MobileNet并结合MTCNN,可以在保持较低计算开销的同时进行高效的人脸检测和口罩佩戴检测;同时,MTCNN是一种专门用于人脸检测和对齐的多任务级联卷积神经网络。将MobileNet与MTCNN结合使用,可以利用MobileNet提取的特征进行人脸检测,从而实现高效而准确的人脸检测任务。

三、代码内容

  在本次实验中,我们使用了reduce_lr进行学习率的衰减具体来说,如下所示:

# 学习率下降的方式,acc三次不下降就下降学习率继续训练
reduce_lr = ReduceLROnPlateau(
                        monitor='accuracy',  # 检测的指标
                        factor=0.5,     # 当acc不下降时将学习率下调的比例
                        patience=3,     # 检测轮数是每隔三轮
                        verbose=2       # 信息展示模式
                    )

  通过上述学习率衰减,我们可以在效果不理想时及时调整学习率以更好的学习数据的特征来增强模型的泛化能力和鲁棒性。在训练部分,我们采用了以下代码:

from sklearn.utils import shuffle

# 打乱训练集的顺序
train_generator = shuffle(train_generator) model.summary()
# 一次的训练集大小
batch_size = _____
# 图片数据路径
data_path = basic_path + 'image'
# 图片处理
train_generator, test_generator = processing_data(data_path, height=160, width=160, batch_size=batch_size, test_split=0.1)
# 编译模型
model.compile(loss='binary_crossentropy',  # 二分类损失函数  
              optimizer=Adam(lr=_____),            # 优化器
              metrics=['accuracy'])        # 优化目标
# 训练模型
history = model.fit(train_generator,    
                    epochs=20   , # epochs: 整数,数据的迭代总轮数。
                    # 一个epoch包含的步数,通常应该等于你的数据集的样本数量除以批量大小。
                    steps_per_epoch=637 // batch_size,
                    validation_data=test_generator,
                    validation_steps=70 // batch_size,
                    initial_epoch=0, # 整数。开始训练的轮次(有助于恢复之前的训练)。
                    callbacks=[checkpoint_period, reduce_lr])
# 保存模型
model.save_weights(model_dir + 'temp.h5')

  我们采用shuffle来打乱训练集中样本出现的顺序以增强模型的学习力,防止出现过拟合的现象。具体来说,我们采取batch_size=64作为一次训练的训练集大小,每一次迭代中,模型通过前向传播将一批样本输入到网络中,计算出预测结果,并通过反向传播根据损失函数计算梯度并更新网络参数。这个批次的样本数量就是batch_size。

  使用较大的batch_size可以加快训练速度,因为可以同时处理多个样本,从而充分利用硬件(如GPU)的并行计算能力。此外,较大的批量大小还可以提供更稳定的梯度估计,有助于避免随机噪声对梯度的影响,使训练过程更稳定。

  然而,较大的batch_size也会占用更多的内存,可能导致GPU内存不足而无法训练较大的模型或处理更大的数据集。此外,较大的批量大小可能会导致收敛速度变慢,因为每次更新参数所用的梯度信息较少。在实验中采用了32、16、8等批量大小,最终发现,批量大小为___时效果是最佳的。

  学习率的选择对模型的训练和性能至关重要。学习率的大小直接影响参数更新的速度。较大的学习率可能导致参数在每次更新时跳过最优值,导致训练过程不稳定,甚至无法收敛。较小的学习率可以稳定训练,但可能需要更多的迭代次数才能达到最优解。在这里,我们选择一个比较小的量作为学习率,因为我们的模型相对而言数据较小,仅有600多个训练样本。在小样本情况下,模型往往更容易受到噪声和样本特异性的影响,较大的学习率可能导致参数在每次更新时跳过最优值,导致训练过程不稳定或无法收敛。

四、实验结果

  在本地测试时,我们采用了三张照片作为测试集,结果全部可以检测出正确的结果,提交到平台上分数为95分!

  由于不知道那五张照片到底是什么,我们也无法调整对应的超参数使得分数进一步提高了。不过达到95分,还需要调整MTCNN的参数,即self.threshold的值,不同的模型对于此参数的耐受性不同,我们需要根据模型动态调整该数值。

五、总结

  模型的性能较为理想,训练过程也比较合理,唯一的美中不足的地方在于,我们需要连续训练两次;在训练过程中,数据的顺序和批量选择可能会对模型的学习产生影响。连续训练两次可以通过改变数据扰动的方式和顺序,使得模型能够从不同的角度观察和学习数据,从而提高模型的鲁棒性和泛化能力。在实验中,我们使用了shuffle函数来打乱训练集中样本的顺序,从而增加数据的随机性和多样性。此外,还采用了适当的学习率和学习率衰减策略,以控制模型的参数更新速度和稳定性。

  综上所述,通过本次实验,我们成功地使用MTCNN和MobileNet结合的方法实现了口罩佩戴检测任务。我们采用迁移学习的思想,利用已有的预训练模型进行微调,并通过适当的数据处理和训练策略,使得模型能够在小样本和计算资源有限的情况下取得良好的性能。

  然而,仍然存在一些改进的空间。例如,我们可以进一步调整模型的超参数,尝试不同的学习率、批量大小等,以探索更优的模型配置。此外,可以尝试其他的深度学习模型和方法,如基于YOLO、SSD等的目标检测算法,进一步提升口罩佩戴检测的准确性和鲁棒性。

  总的来说,本次实验为口罩佩戴检测提供了一种有效的解决方案,具有实际应用的潜力。随着技术的不断发展和数据集的丰富,口罩佩戴检测可以在公共场合、工作环境等地方发挥重要的作用,帮助控制疫情的传播,并保障公众的健康安全。

人工智能导论——口罩佩戴检测详解(附带MTCNN论文精读)的更多相关文章

  1. APP漏洞扫描器之本地拒绝服务检测详解

    APP漏洞扫描器之本地拒绝服务检测详解 阿里聚安全的Android应用漏洞扫描器有一个检测项是本地拒绝服务漏洞的检测,采用的是静态分析加动态模糊测试的方法来检测,检测结果准确全面.本文将讲一下应用漏洞 ...

  2. Java版人脸检测详解下篇:编码

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. 全卷积神经网络FCN详解(附带Tensorflow详解代码实现)

    一.导论 在图像语义分割领域,困扰了计算机科学家很多年的一个问题则是我们如何才能将我们感兴趣的对象和不感兴趣的对象分别分割开来呢?比如我们有一只小猫的图片,怎样才能够通过计算机自己对图像进行识别达到将 ...

  4. SpringMVC异常处理机制详解[附带源码分析]

    目录 前言 重要接口和类介绍 HandlerExceptionResolver接口 AbstractHandlerExceptionResolver抽象类 AbstractHandlerMethodE ...

  5. JavaScript数据类型检测详解

    //JS该如何检测数据的类型呢? //使用关键字: typeof //输出结果依次为:'number','string','boolean'. console.log(typeof 17); cons ...

  6. [转]SpringMVC拦截器详解[附带源码分析]

      目录 前言 重要接口及类介绍 源码分析 拦截器的配置 编写自定义的拦截器 总结 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:ht ...

  7. Java版人脸检测详解上篇:运行环境的Docker镜像(CentOS+JDK+OpenCV)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  8. SpringMVC拦截器详解[附带源码分析]

    目录 前言 重要接口及类介绍 源码分析 拦截器的配置 编写自定义的拦截器 总结 总结 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:h ...

  9. Servlet容器Tomcat中web.xml中url-pattern的配置详解[附带源码分析]

    目录 前言 现象 源码分析 实战例子 总结 参考资料 前言 今天研究了一下tomcat上web.xml配置文件中url-pattern的问题. 这个问题其实毕业前就困扰着我,当时忙于找工作. 找到工作 ...

  10. SpringMVC视图机制详解[附带源码分析]

    目录 前言 重要接口和类介绍 源码分析 编码自定义的ViewResolver 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门bl ...

随机推荐

  1. 64位的单周期 RISC-V 模拟器

    分享一个我最近完成过的小项目--64位的单周期 RISC-V 模拟器,这个项目我最近参与一生一芯计划过程中完成的一个小项目. 需要用到的相关知识:Verilog.Verilator.计算机组成原理.汇 ...

  2. HashMap和ConcurrentHashMap扩容过程

    HashMap 存储结构 HashMap是数组+链表+红黑树(1.8)实现的. (1)Node[] table,即哈希桶数组.Node是内部类,实现了Map.Entry接口,本质是键值对. 下图链表中 ...

  3. 剑指offer 第18天

    第 18 天 搜索与回溯算法(中等) 剑指 Offer 55 - I. 二叉树的深度 输入一棵二叉树的根节点,求该树的深度.从根节点到叶节点依次经过的节点(含根.叶节点)形成树的一条路径,最长路径的长 ...

  4. MySQL explain 和 profiling 详解

    MySQL explain 和 profiling 详解 mysql explain MySQL 的 EXPLAIN 是一个用于查询优化的工具,它可以显示 MySQL 数据库如何执行查询.它返回一组关 ...

  5. 随机服务系统模拟—R实现(三)

    M/M/c随机服务系统的模拟 M/M/1服务系统:(1)队列长度没有限制:(2)顾客到达的时间间隔和服务时间均服从指数分布:(3)服务台数量为c. 一.M/M/c随机服务系统的模拟 在M/M/c排队系 ...

  6. 干掉复杂的工具类,国产Java工具类库 Hutool 很香!

    Hutool 大家已经比较熟悉了,这是一个超全的 Java 工具库,深受国内开发者的喜爱. 我之前其实是不太喜欢使用这种功能太多的工具类的,也比较担心稳定性和安全性,后面慢慢接受了就感觉其实也还好.而 ...

  7. vue高阶函数

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 中国省市区--地区SQL表

    SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for rc_district -- ---- ...

  9. MySQL(五)配置文件、系统变量与MySQL架构

    1 配置文件的使用 my.cnf配置文件 /etc/my.cnf: [root@hadoop103 ~]# cat /etc/my.cnf # For advice on how to change ...

  10. 频繁设置CGroup触发linux内核bug导致CGroup running task不调度

    1. 说明 1> 本篇是实际工作中linux上碰到的一个问题,一个使用了CGroup的进程处于R状态但不执行,也不退出,还不能kill,经过深入挖掘才发现是Cgroup的内核bug 2>发 ...