您现在的位置是:网站首页> 编程资料编程资料

基于Python实现口罩佩戴检测功能_python_

2023-05-26 435人已围观

简介 基于Python实现口罩佩戴检测功能_python_

口罩佩戴检测

一 题目背景

1.1 实验介绍

今年一场席卷全球的新型冠状病毒给人们带来了沉重的生命财产的损失。有效防御这种传染病毒的方法就是积极佩戴口罩。我国对此也采取了严肃的措施,在公共场合要求人们必须佩戴口罩。在本次实验中,我们要建立一个目标检测的模型,可以识别图中的人是否佩戴了口罩。

1.2 实验要求

  • 建立深度学习模型,检测出图中的人是否佩戴了口罩,并将其尽可能调整到最佳状态。
  • 学习经典的模型 MTCNN 和 MobileNet 的结构。
  • 学习训练时的方法。

1.3 实验环境

实验使用重要python包:

import cv2 as cv import numpy as np import matplotlib.pyplot as plt from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping

由于担心平台GPU时长不够用,所以在自己电脑上搭建了配套实验环境,由于电脑显卡CUDA版本较老,所以最终本地配置如下:

  • Python: 3.8
  • Tensorflow-GPU: 2.3.0
  • Keras: 2.7.0

1.4 实验思路

针对目标检测的任务,可以分为两个部分:目标识别和位置检测。通常情况下,特征提取需要由特有的特征提取神经网络来完成,如 VGG、MobileNet、ResNet 等,这些特征提取网络往往被称为 Backbone 。而在 BackBone 后面接全连接层***(FC)***就可以执行分类任务。但 FC 对目标的位置识别乏力。经过算法的发展,当前主要以特定的功能网络来代替 FC 的作用,如 Mask-Rcnn、SSD、YOLO 等。我们选择充分使用已有的人脸检测的模型,再训练一个识别口罩的模型,从而提高训练的开支、增强模型的准确率。

常规目标检测:

本次案例:

图1 实验口罩佩戴检测流程

二 实验内容

2.1 已知文件与数据集

首先,导入已经写好的python文件并对数据集进行处理。

  • image 文件夹:图片分成两类,戴口罩的和没有戴口罩的
  • train.txt: 存放的是 image 文件夹下对应图片的标签
  • keras_model_data 文件夹:存放 keras 框架相关预训练好的模型

2.2 图片尺寸调整

将图片尺寸调整到网络输入的图片尺寸

2.3 制作训练时需要用到的批量数据集

图片生成器的主要方法:

  • fit(x, augment=False, rounds=1):计算依赖于数据的变换所需要的统计信息(均值方差等)。
  • flow(self, X, y, batch_size=32, shuffle=True, seed=None, save_to_dir=None, save_prefix='', save_format='png'):接收 Numpy 数组和标签为参数,生成经过数据提升或标准化后的 batch 数据,并在一个无限循环中不断的返回 batch 数据。
  • flow_from_directory(directory): 以文件夹路径为参数,会从路径推测 label,生成经过数据提升/归一化后的数据,在一个无限循环中无限产生 batch 数据。

结果:

Found 693 images belonging to 2 classes.
Found 76 images belonging to 2 classes.
{'mask': 0, 'nomask': 1}
{0: 'mask', 1: 'nomask'}

2.4 调用MTCNN

通过搭建 MTCNN 网络实现人脸检测

  • keras_py/mtcnn.py 文件是在搭建 MTCNN 网络。
  • keras_py/face_rec.py 文件是在绘制人脸检测的矩形框。

这里直接使用现有的表现较好的 MTCNN 的三个权重文件,它们已经保存在datasets/5f680a696ec9b83bb0037081-momodel/data/keras_model_data 文件夹下

2.5 加载预训练模型MobileNet

# 加载 MobileNet 的预训练模型权重 weights_path = basic_path + 'keras_model_data/mobilenet_1_0_224_tf_no_top.h5'

2.6 训练模型

2.6.1 加载和保存

为了避免训练过程中遇到断电等突发事件,导致模型训练成果无法保存。我们可以通过 ModelCheckpoint 规定在固定迭代次数后保存模型。同时,我们设置在下一次重启训练时,会检查是否有上次训练好的模型,如果有,就先加载已有的模型权重。这样就可以在上次训练的基础上继续模型的训练了。

2.6.2 手动调整学习率

学习率的手动设置可以使模型训练更加高效。这里我们设置当模型在三轮迭代后,准确率没有上升,就调整学习率。

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

2.6.3 早停法

当我们训练深度学习神经网络的时候通常希望能获得最好的泛化性能。但是所有的标准深度学习神经网络结构如全连接多层感知机都很容易过拟合。当网络在训练集上表现越来越好,错误率越来越低的时候,就极有可能出现了过拟合。早停法就是当我们在检测到这一趋势后,就停止训练,这样能避免继续训练导致过拟合的问题。

early_stopping = EarlyStopping( monitor='val_accuracy', # 检测的指标 min_delta=0.0001, # 增大或减小的阈值 patience=3, # 检测的轮数频率 verbose=1 # 信息展示的模式 )

2.6.4 乱序训练数据

打乱txt的行,这个txt主要用于帮助读取数据来训练,打乱的数据更有利于训练。

 np.random.seed(10101) np.random.shuffle(lines) np.random.seed(None)

2.6.5 训练模型

一次训练集大小设定为64,优化器使用Adam,初始学习率设定为0.001,优化目标为accuracy,总的学习轮次设定为20轮。(通过多次实验测定,在这些参数条件下,准确率较高)

# 一次的训练集大小 batch_size = 64 # 编译模型 model.compile(loss='binary_crossentropy', # 二分类损失函数 optimizer=Adam(lr=0.001), # 优化器 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])

三 算法描述

3.1 MTCNN

  • 三阶段的级联(cascaded)架构
  • coarse-to-fine 的方式
  • new online hard sample mining 策略
  • 同时进行人脸检测和人脸对齐
  • state-of-the-art 性能

图2 MTCNN架构

3.2 MobileNet

图3 MobileNet架构

MobileNet的网络结构如图3所示。首先是一个3x3的标准卷积,然后后面就是堆积depthwise separable convolution,并且可以看到其中的部分depthwise convolution会通过strides=2进行down sampling。然后采用average poolingfeature变成1x1,根据预测类别大小加上全连接层,最后是一个softmax层。

四 求解结果

最终确定最佳取值为batch_size=64lr=0.0001epochs=20,其它参数如下,连续训练两次,可以获得最佳结果。此处仅展示两个参数条件下的结果作为对比

# 一次的训练集大小 batch_size = 64 # 编译模型 model.compile(loss='binary_crossentropy', # 二分类损失函数 optimizer=Adam(lr=0.001), # 优化器 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])

条件1: 取batch_size=48, lr=0.001epochs=20,对训练之后的模型进行测试,得到结果如下:

图4 条件1 loss曲线

loss曲线可以看出,随着训练迭代次数的加深,验证集上的损失在逐渐的减小,最终稳定在0.2左右;而在训练集上loss始终在0附近。

图5 条件1 acc曲线

从验证集和测试集的准确率变化曲线上可以看出,随着训练轮次的增加,验证集的准确率逐渐上升,最终稳定在96%左右,效果还是不错的。

图6 条件1 测试样例1

使用样例照片进行测试,首先人脸识别部分顺利识别到了五张人脸,但是口罩识别部分将一个没有带口罩的人识别成了带着口罩的人,说明还有进步空间,实际错误率达到了20%。

图7 条件1 测试样例2

另一张样例照片的测试结果同样是人脸识别部分没有出现问题,正确识别到了四张人脸,但是同样将一个没有带口罩的人识别成了带有口罩的人。

平台测试:

后续通过调整各项参数并打乱测试集和训练集图片顺序来进行了多次实验,最终确定的最佳状态如下:

条件2: 取batch_size=64, lr=0.0001epochs=20提示: 本文由整理自网络,如有侵权请联系本站删除!
本站声明:
1、本站所有资源均来源于互联网,不保证100%完整、不提供任何技术支持;
2、本站所发布的文章以及附件仅限用于学习和研究目的;不得将用于商业或者非法用途;否则由此产生的法律后果,本站概不负责!

-六神源码网