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

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

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

数据集检索

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

预处理

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

import osimg_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 imreadpath_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 _imgfor 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:continueimages.append(crop_bounding_box(img, temp[i]["bndbox"]))target.append(temp[i]["name"])else:if temp["name"] not in class_names:continueimages.append(crop_bounding_box(img, temp["bndbox"]))target.append(temp["name"])

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

import torchfrom 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 npresult = 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_splitX, 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 LogisticRegressionclf = 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 GridSearchCVparam_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_scorefinal_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 picklepkl_filename = 'face_mask_detection.pkl'
with open(pkl_filename, 'wb') as file:pickle.dump(final_clf, file)

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是DOM?(详解)

什么是DOM? DOM的定义知识回顾什么是D?什么是O?什么是M?什么是DOM树?根节点对象与节点对象 DOM树简单举例DOM的主要用途 DOM的定义 DOM(Document Object Model,文档对象模型) W3C对…

系统性能提升70%!华润万家某核心系统数据库升级实践

华润万家是华润集团旗下优秀零售连锁企业,业务覆盖中国内地及香港市场,面对万家众多业务需求和互相关联的业务环境,亟需加强各业务耦合性,以适应线上、线下、物流、财务等各个业务环境的快速发展。 随着信息技术的快速发展和数字化…

设计模式(八)外观模式

相关文章设计模式系列 1.外观模式简介 外观模式介绍 当我们开发Android的时候,无论是做SDK还是封装API,我们大多都会用到外观模式,它通过一个外观类使得整个系统的结构只有一个统一的高层接口,这样能降低用户的使用成本。 外观…

【数据结构与算法】动态规划法解题20240227

动态规划法 一、什么是动态规划二、动态规划的解题步骤三、509. 斐波那契数1、动规五部曲: 四、70. 爬楼梯1、动规五部曲: 五、746. 使用最小花费爬楼梯1、动规五部曲: 一、什么是动态规划 动态规划,英文:Dynamic Pro…

qtcreator-ros 安装记录

文章目录 ros_qtc_pluginros_qt_demo参考链接ros_qtc_plugin ROS Qt Creator 插件是专门为 ROS 开发的,通过简化任务和为 ROS 工具创建集中位置来提高开发人员的效率。由于它建立在Qt Creator平台之上,用户可以访问其所有现有功能,例如:语法高亮,代码索引,编辑器(C++,…

Python 实现 CCI 指标计算:股票技术分析的利器系列(8)

Python 实现 CCI 指标计算:股票技术分析的利器系列(8) 介绍算法解释 代码rolling函数介绍核心代码计算 CCIapply 函数abs 函数 完整代码 介绍 CCI指标的数值波动通常在一个区间内,常见的情况是在-100到100之间。当CCI超过100时&a…

学习 LangChain 的 LCEL

学习 LangChain 的 LCEL 0. 引言1. 基本示例:提示模型输出解析器​1-1. Prompt​1-2. Model1-3. Output parser1-4. Entire Pipeline 0. 引言 LCEL(LangChain Expression Language) 可以轻松地从基本组件构建复杂的链,并支持开箱即用的功能,…

基于springboot+vue的精准扶贫管理系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 ​主要内容:毕业设计(Javaweb项目|小程序|Pyt…

Spring Bean 相关注解

目录 Autowired Component,Repository,Service, Controller RestController Scope Configuration Autowired 自动导入对象到类中,被注入进的类同样要被 Spring 容器管理比如:Service 类注入到 Controller 类中。 Service public class UserService …

「Qt Widget中文示例指南」如何实现文档查看器?(一)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 文档查看器是一个显…

IDEA配置有道翻译插件

目录 安装Translation插件有道云配置翻译APIIDEA配置有道翻译引擎 关于IDEA Translation插件中有道智云(有道翻译)应用ID,密钥申请教程 安装Translation插件 File -> Settings ->Plugins ->搜索Translation ->insatll 有道云…

Ubuntu上Jenkins自动化部署Gitee上SpringBoot项目

文章目录 安装安装JDK安装Maven安装GitNodeJS安装(可选)安装Jenkins 配置Jenkins为Jenkins更换插件源设置jenkins时区安装插件全局工具配置添加Gitee凭证Gitee项目配置 部署后端1.新建任务2.配置源码管理3.构建触发器4.到Gitee中添加WebHook5.构建环境6.…