基于 ResNet50和 SVM + 决策树的人脸口罩检测

在这里插入图片描述
欢迎收看,这篇文章是关于我如何使用 ResNet50作为特征提取器来构建掩码检测,然后使用支持向量机(SVM) + 决策树和叠加集成方法作为分类器的一个快速解释。

为了向研究人员致敬,这个应用程序是基于研究论文,题目是“在2019冠状病毒疾病大流行时代用于面具检测的机器学习方法的混合深度转移学习模型”,作者是 Mohamed Loey,et al。

数据集检索

此应用程序使用来自 Kaggle 的数据集。该数据集包含属于3个类的853个图像,以及它们的 PASCAL VOC 格式的边界框。这些类是带面具的,没有面具的,戴面具的不正确。由于某些原因,我只使用了 with _ cover 和 without _ cover 标签。看看下面的图片样本。
在这里插入图片描述
在这里插入图片描述
您可以通过下面的网址访问此数据集。
点击前往

预处理

首先,我们需要从数据集文件夹中读取所有的 XML 文件和图像文件。然后,根据边界框信息对人脸区域进行裁剪,以完成预处理。

import os

img_names = []
xml_names = []
for dirname, _, filenames in os.walk('./face-mask-detection'):
  for filename in filenames:
    if os.path.join(dirname, filename)[-3:] != "xml":
      img_names.append(filename)
    else:
      xml_names.append(filename)

print(len(img_names), "images")

然后,根据每个图像的边界框裁剪所有图像,并读取标签信息。

import xmltodict
from matplotlib import pyplot as plt
from skimage.io import imread

path_annotations = "face-mask-detection/annotations/"
path_images = "face-mask-detection/images/"

class_names = ['with_mask', 'without_mask']
images = []
target = []

def crop_bounding_box(img, bnd):
  x1, y1, x2, y2 = list(map(int, bnd.values()))
  _img = img.copy()
  _img = _img[y1:y2, x1:x2]
  _img = _img[:,:,:3]
  return _img

for img_name in img_names[:]:
  with open(path_annotations+img_name[:-4]+".xml") as fd:
    doc = xmltodict.parse(fd.read())

  img = imread(path_images+img_name)
  temp = doc["annotation"]["object"]
  if type(temp) == list:
    for i in range(len(temp)):
      if temp[i]["name"] not in class_names:
        continue
      images.append(crop_bounding_box(img, temp[i]["bndbox"]))
      target.append(temp[i]["name"])
  else:
    if temp["name"] not in class_names:
        continue
    images.append(crop_bounding_box(img, temp["bndbox"]))
    target.append(temp["name"])

根据标签,该数据集包含了 3232 张佩戴口罩的人脸图像和 717 张未佩戴口罩的人脸图像。
在这里插入图片描述
这个预处理还包括了对图像进行 ImageNet 的调整和归一化的步骤。

import torch

from torchvision import transforms

# Define preprocessing
preprocess = transforms.Compose([
  transforms.ToPILImage(),
  transforms.Resize((128, 128)),
  transforms.ToTensor(),
  transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
])

# Apply preprocess
image_tensor = torch.stack([preprocess(image) for image in images])
image_tensor.shape

特征提取

需要进行特征提取以利用空间操作从图像中提取代表标签的信息。在这个应用中,我使用 ResNet50 作为特征提取器。ResNet 的最后一层是一个具有 1,000 个神经元的全连接层,需要被删除。

from torchvision import models

# Download model
resnet = models.resnet50(pretrained=True)
resnet = torch.nn.Sequential(*(list(resnet.children())[:-1]))

为了冻结并保持 ResNet50的卷积部分不变,我需要将 demand _ grad 设置为 False。

for param in resnet.parameters():
    param.requires_grad = False

我还需要调用 eval ()来将 ResNet50的批量标准化设置为禁用。这将干扰模型的准确性,并确保 ResNet50只作为一个特征提取器。

resnet.eval()

最后一步应用 ResNet50提取特征,然后 ResNet 将返回一个每幅图像有2048个特征的向量。

import numpy as np

result = np.empty((len(image_tensor), 2048))
for i, data in enumerate(image_tensor):
  output = resnet(data.unsqueeze(0))
  output = torch.flatten(output, 1)
  result[i] = output[0].numpy()

分割数据集

为了防止模型过拟合,我需要将数据分成 70% 的训练数据和 30% 的测试数据。训练数据将用于训练模型,而测试数据将用于测试或验证模型。

from sklearn.model_selection import train_test_split

X, y = result, np.array(target)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

print("Training data\n", np.asarray(np.unique(y_train, return_counts=True)).T)
print("Test data\n", np.asarray(np.unique(y_test, return_counts=True)).T)

定义模型分类器

正如我之前提到的,所提出的模型是一个堆叠分类器(集成方法),将使用支持向量机(SVM)和决策树作为弱学习器。逻辑回归将作为最终的估算器。简而言之,集成方法是一种创建多个模型然后将它们组合以产生改进结果的技术。集成方法通常比单个模型产生更准确的解决方案。

from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import StackingClassifier
from sklearn.linear_model import LogisticRegression

clf = StackingClassifier(
    estimators=[('svm', SVC(random_state=42)),
                ('tree', DecisionTreeClassifier(random_state=42))],
    final_estimator=LogisticRegression(random_state=42),
    n_jobs=-1)

调校模型

调整是在不过拟合或产生过高方差的情况下最大化模型性能的过程。在机器学习中,这是通过选择适当的“超参数”来实现的。您可以定义自己的调整方法,无论您想要什么。但是这是我的调整方法。

from sklearn.model_selection import GridSearchCV

param_grid = {
    'svm__C': [1.6, 1.7, 1.8],
    'svm__kernel': ['rbf'],
    'tree__criterion': ['entropy'],
    'tree__max_depth': [9, 10, 11],
    'final_estimator__C': [1.3, 1.4, 1.5]
}

grid = GridSearchCV(
    estimator=clf,
    param_grid=param_grid,
    scoring='accuracy',
    n_jobs=-1)

grid.fit(X_train, y_train)

print('Best parameters: %s' % grid.best_params_)
print('Accuracy: %.2f' % grid.best_score_)

根据调整过程,最佳的超参数是:

Best parameters: {'final_estimator__C': 1.3, 'svm__C': 1.6, 'svm__kernel': 'rbf', 'tree__criterion': 'entropy', 'tree__max_depth': 11}
Accuracy: 0.98

创建最终模型

最后,我可以用最好的超参数创建一个最终的模型。并且还要防止过拟合。

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

final_clf = StackingClassifier(
    estimators=[('svm', SVC(C=1.6, kernel='rbf', random_state=42)),
                ('tree', DecisionTreeClassifier(criterion='entropy', max_depth=11, random_state=42))],
    final_estimator=LogisticRegression(C=1.3, random_state=42),
    n_jobs=-1)

final_clf.fit(X_train, y_train)
y_pred = final_clf.predict(X_test)

print('Accuracy score : ', accuracy_score(y_test, y_pred))
print('Precision score : ', precision_score(y_test, y_pred, average='weighted'))
print('Recall score : ', recall_score(y_test, y_pred, average='weighted'))
print('F1 score : ', f1_score(y_test, y_pred, average='weighted'))

然后根据准确度、精确度、召回度和 f1得分对模型进行测试,结果如下:

Accuracy score :  0.9721518987341772
Precision score :  0.9719379890530496
Recall score :  0.9721518987341772
F1 score :  0.9717932606523529

结果还是很不错的!
在这里插入图片描述

部署真正的应用程序

此步骤不是必需的。但是如果您感兴趣,则必须首先导出模型。只有堆叠分类器模型,这是以前的训练。因此,您可以在另一个程序中再次加载。

import pickle

pkl_filename = 'face_mask_detection.pkl'
with open(pkl_filename, 'wb') as file:
  pickle.dump(final_clf, file)

需要记住的重要一点是,您需要实现自己的人脸检测模型并对其进行裁剪。程序示例请查看https://github.com/myxzlpltk/face-mask-detection

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/411375.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分布式应用:kylin 部署 zabbix 监控平台

目录 一、实验 1.环境 2. kylin 修改mysql数据库 3. kylin 部署 zabbix 监控平台 4. kylin 修改 zabbix 配置 5. kylin 修改zabbix web 二、问题 1. zabbix_server 查看版本报错 2.zabbix_server 文件如何去掉注释"#"和空行 3. zabbix图表显示异常 4.zabbi…

前端常见面试题之vue3

文章目录 1. vue3比vue2有哪些优势2. 描述vue3的生命周期3. 如何看待vue3中的Composition API 和 Options API4. 如何理解ref、 toRef、和toRefs?5. vue3升级了哪些功能6. Composition API如何实现代码逻辑的复用(hook)7. Vue3如何实现响应式的8.Vue3使用Proxy对象…

2-22 方法、面向对象、类、JVM内存、构造方法

文章目录 方法的重载面向对象类、属性和方法成员变量默认值属性JVM简单内存分析栈空间堆空间 构造方法执行过程构造器注意点 方法的重载 一个类中名称相同,但是参数列表不同的方法 参数列表不同是指: 形参类型形参个数形参顺序 面向对象 field —— …

linux系统---防火墙拓展

目录 一、iptables 1.基本语法 2.四表五链——重点记忆 2.1四表 2.2五链 2.3总结 3.iptables选项示例 3.1 -Z 清空流量计数 3.2 -P 修改默认规则 3.3 -D 删除规则 3.4 -R 指定编号替换规则 4.白名单 5.通用匹配 6.示例 6.1添加回环网卡 6.2可以访问端口 6.3 主…

架构设计实践:熟悉架构设计方法论,并动手绘制架构设计图

文章目录 一、架构设计要素1、架构设计目标2、架构设计模式(1)分而治之(2)迭代式设计 3、架构设计的输入(1)概览(2)功能需求 - WH分析法(3)质量 - “怎么”分…

都说了别用BeanUtils.copyProperties,这不翻车了吧

分享是最有效的学习方式。 博客:https://blog.ktdaddy.com/ 故事 新年新气象,小猫也是踏上了新年新征程,自从小猫按照老猫给的建议【系统梳理大法】完完整整地梳理完毕系统之后,小猫对整个系统的把控可谓又是上到可一个新的高度。…

Arduino中安装ESP32网络抽风无法下载 暴力解决办法 python

不知道什么仙人设计的arduino连接网络部分,死活下不下来。(真的沙口,第一次看到这么抽风的下载口) 操作 给爷惹火了我踏马解析json选zip直接全部下下来 把这个大家的开发板管理地址下下来跟后面python放在同一目录下&#xff0c…

【Java程序设计】【C00317】基于Springboot的智慧社区居家养老健康管理系统(有论文)

基于Springboot的智慧社区居家养老健康管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的智慧社区居家养老健康管理系统设计与实现,本系统有管理员、社区工作人员、医生以及家属四种角色权限 管…

理解这几个安全漏洞,你也能做安全测试!

如今安全问题显得越来越重要,一个大型的互联网站点,你如果每天查看日志,会发现有很多尝试攻击性的脚本。 如果没有,证明网站影响力还不够大。信息一体化的背后深藏着各类安全隐患,例如由于开发人员的不严谨导致为Web应…

基于24扇区细分的三电平逆变器异步电机直接转矩控制系统学习

导读:本期文章介绍异步电机三电平24扇区的直接转矩控制。三电平逆变器直接转矩控制中,传统的PWM控制方法存在错判区间等问题。本文在借鉴三电平逆变器单一矢量及合成矢量的直接转矩控制研究和两电平12扇区直接转矩控制的基础上,将两电平12扇区…

堆/堆排序(C/C++)

本篇文章将会较为全面的介绍堆的概念以及实现堆两个重要算法:向上调整算法和向下调整算法。接着实现了堆排序。 若想查看对应位置,可直接按照以下目录进行查看: 目录 1.堆的概念及结构 2.堆的实现 2.1 堆的向上调整算法 2.2 堆的向下调整算法…

beego代理前端web的bug

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、beego代理前端web的bug总结 一、beego代理前端web的bug *报错,为web压缩包index.html里面的注释被错误解析,删掉就行 2024/02/22 10:2…

解析Hadoop三大核心组件:HDFS、MapReduce和YARN

目录 HadoopHadoop的优势 Hadoop的组成HDFS架构设计Yarn架构设计MapReduce架构设计 总结 在大数据时代,Hadoop作为一种开源的分布式计算框架,已经成为处理大规模数据的首选工具。它采用了分布式存储和计算的方式,能够高效地处理海量数据。Had…

蛇形矩阵1

题目描述 把数1,2,3,…,N*N按照“蛇形1”放入N*N的矩形中,输出结果。 下面是N10的蛇形1的图示 输入格式 第一行1个正整数:N,范围在[1,100]。 输出格式 N行,每行N个整数。 输入/…

docker下gitlab安装配置

一、安装及配置 1.gitlab镜像拉取 docker pull gitlab/gitlab-ce:latest2.运行gitlab镜像 docker run -d -p 443:443 -p 80:80 -p 222:22 --name gitlab --restart always --privilegedtrue -v /home/gitlab/config:/etc/gitlab -v /home/gitlab/logs:/var/log/gitlab -v …

小家电—简易过零检测电路

趁刚开工时间有空,总结分析下,在工作项目中常用过零检测电路。 图一 图二 图一在项目中较为常用,两个电路都是通过钳位二极管限幅产生过零脉冲信号。 过零信号高电平被钳位在5.7V,低电平为-0.7V 高电平:VCC0.7V 低电…

LeetCode第七题: 整数反转

题目描述 给你一个 32 位的有符号整数 x​ ,返回将 x​ 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1]​ ,就返回 0。 假设环境不允许存储 64 位整数(有符号或无符号)。 示例 …

江大白 | 目标检测YOLOv9算法,重磅开源!(附论文及源码)

本文来源公众号“江大白”,仅用于学术分享,侵权删,干货满满。 原文链接:目标检测YOLOv9算法,重磅开源!(附论文及源码) 以下文章来源于知乎:cvprLab作者:cvp…

服务器防漏扫

什么是漏扫? 漏扫是漏洞扫描的简称。漏洞扫描是一种安全测试方法,用于发现计算机系统、网络或应用程序中的潜在漏洞和安全弱点。通过使用自动化工具或软件,漏洞扫描可以检测系统中存在的已知漏洞,并提供相关的报告和建议&#xf…

Nexus Repository Manager

Nexus Repository Manager https://s01.oss.sonatype.org/#welcome https://mvnrepository.com/-CSDN博客