机器学习之人脸识别-使用 scikit-learn 和人工神经网络进行高效人脸识别

news2024/11/19 3:23:40

文章摘要

本文将介绍如何使用 Python 的 scikit-learn 库和人工神经网络(ANN)来识别人脸。我们将使用 LFW 数据集(Labeled Faces in the Wild),这是一个广泛用于人脸识别基准测试的大型人脸数据库。我们将展示如何准备数据、构建模型,并评估模型的性能。此外,我们还会探讨一些提高模型准确率的方法。

引言

人脸识别是一项关键的技术,它在安全、监控、社交网络和移动应用等多个领域都有广泛应用。随着深度学习的发展,尤其是卷积神经网络(CNN)的进步,人脸识别的准确性已经达到了非常高的水平。然而,对于初学者而言,使用传统的机器学习方法,如人工神经网络,仍然可以达到不错的效果,并且更容易理解和实现。

基本原理

多层感知器(Multilayer Perceptron, MLP)是一种人工神经网络模型,它由一系列的层组成,包括输入层、一个或多个隐藏层以及输出层。MLP中的每个层都包含多个神经元,这些神经元之间是全连接的,即每个神经元的输出都会连接到下一层的每个神经元。

下面是一个简单的数学描述,用于解释MLP的工作原理:

前向传播

假设我们有一个具有 L L L 层的MLP,其中第 l l l层有 n l n_l nl个神经元。对于输入层 l = 1 l=1 l=1,有 n 1 n_1 n1 个输入单元;对于输出层 l = L l=L l=L,有 n L n_L nL 个输出单元。每个神经元除了接受来自上一层的输入外,还会有一个偏置项 b 。

单个神经元的计算

对于第 l l l 层中的第 j j j个神经元,其计算步骤如下:

  1. 加权求和:
    z j ( l ) = ∑ i = 1 n l − 1 w i j ( l ) a i ( l − 1 ) + b j ( l ) z^{(l)}_j = \sum_{i=1}^{n_{l-1}} w^{(l)}_{ij} a^{(l-1)}_i + b^{(l)}_j zj(l)=i=1nl1wij(l)ai(l1)+bj(l)
    其中, w i j ( l ) w^{(l)}_{ij} wij(l)是第 l l l 层中第 i i i 个神经元到第 j j j 个神经元的连接权重, a i ( l − 1 ) a^{(l-1)}_i ai(l1) 是第 l − 1 l-1 l1 层中第 i i i 个神经元的激活值, b j ( l ) b^{(l)}_j bj(l) 是第 l l l 层中第 j j j个神经元的偏置项。

  2. 激活函数:
    a j ( l ) = f ( z j ( l ) ) a^{(l)}_j = f(z^{(l)}_j) aj(l)=f(zj(l))
    其中, f ( ⋅ ) f(\cdot) f() 是激活函数,常见的激活函数有 Sigmoid 函数、ReLU 函数等。

层间传递

对于第 l l l 层,其输出 a ( l ) a^{(l)} a(l) 将作为第 l + 1 l+1 l+1 层的输入。

反向传播

反向传播算法用于计算损失函数相对于每个权重和偏置的梯度,并根据这些梯度来调整权重和偏置以最小化损失函数。

损失函数

假设我们的目标是使输出尽可能接近目标值 y y y,我们可以定义一个损失函数 E E E 来衡量这种差距。常见的损失函数有均方误差(MSE)、交叉熵损失等。

梯度计算

反向传播的关键在于使用链式法则计算损失函数关于权重和偏置的梯度。从输出层开始,逐步向前计算梯度。

  1. 输出层梯度:
    δ j ( L ) = ∂ E ∂ a j ( L ) f ′ ( z j ( L ) ) \delta^{(L)}_j = \frac{\partial E}{\partial a^{(L)}_j} f'(z^{(L)}_j) δj(L)=aj(L)Ef(zj(L))

  2. 隐藏层梯度:
    δ j ( l ) = ( ∑ k = 1 n l + 1 w k j ( l + 1 ) δ k ( l + 1 ) ) f ′ ( z j ( l ) ) \delta^{(l)}_j = \left( \sum_{k=1}^{n_{l+1}} w^{(l+1)}_{kj} \delta^{(l+1)}_k \right) f'(z^{(l)}_j) δj(l)=(k=1nl+1wkj(l+1)δk(l+1))f(zj(l))

参数更新

利用梯度下降或其变种(如动量梯度下降、Adam 等)更新权重和偏置:
w i j ( l ) ← w i j ( l ) − η ∂ E ∂ w i j ( l ) w^{(l)}_{ij} \leftarrow w^{(l)}_{ij} - \eta \frac{\partial E}{\partial w^{(l)}_{ij}} wij(l)wij(l)ηwij(l)E

b j ( l ) ← b j ( l ) − η ∂ E ∂ b j ( l ) b^{(l)}_j \leftarrow b^{(l)}_j - \eta \frac{\partial E}{\partial b^{(l)}_j} bj(l)bj(l)ηbj(l)E

其中, η \eta η 是学习率,决定了参数更新的步长。

原理小结

以上就是多层感知器的基本数学原理。通过前向传播计算网络的输出,并通过反向传播来调整网络中的权重和偏置,从而使得网络能够学习数据中的模式并进行预测。这个过程通常需要大量的训练数据以及适当的超参数设置来确保良好的性能。

步骤1: 准备环境

首先,确保您的Python环境中已经安装了scikit-learn和其他必要的库。可以通过以下命令安装:

pip install scikit-learn matplotlib

步骤2: 导入库

import numpy as np
from sklearn.datasets import fetch_lfw_people
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import classification_report, confusion_matrix
import matplotlib.pyplot as plt

步骤3: 加载数据集

# 加载LFW数据集
lfw_people = fetch_lfw_people(data_home=r"D:\\AICode\\ANN\\", download_if_missing=False, min_faces_per_person=70, resize=0.4)

# 获取数据集的基本信息
n_samples, h, w = lfw_people.images.shape
X = lfw_people.data
n_features = X.shape[1]
y = lfw_people.target
target_names = lfw_people.target_names
n_classes = target_names.shape[0]

# 打印数据集的一些基本信息
print("Total dataset size:")
print("n_samples: %d" % n_samples)
print("n_features: %d" % n_features)
print("n_classes: %d" % n_classes)

步骤4: 可视化数据

# 定义一个辅助函数来展示图像
def plot_gallery(images, titles, h, w, n_row=3, n_col=4):
    """Helper function to plot a gallery of portraits"""
    plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))
    plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)
    for i in range(n_row * n_col):
        plt.subplot(n_row, n_col, i + 1)
        plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)
        plt.title(titles[i], size=12)
        plt.xticks(())
        plt.yticks(())

# 展示一些样本
titles = ["%s" % target_names[i].split(' ')[-1] for i in lfw_people.target[:3 * 4]]
plot_gallery(lfw_people.images, titles, h, w)

plt.show()

步骤5: 数据分割

# 将数据集分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42)

步骤6: 构建和训练模型

# 使用MLP进行人脸识别
mlp = MLPClassifier(hidden_layer_sizes=(100,), max_iter=1000, alpha=1e-4,
                    solver='adam', verbose=10, tol=1e-4, random_state=1,
                    learning_rate_init=.1)

mlp.fit(X_train, y_train)
print("Model trained.")

步骤7: 模型评估

# 预测测试集
y_pred = mlp.predict(X_test)

# 打印分类报告
print(classification_report(y_test, y_pred, target_names=target_names,zero_division=1))

# 打印混淆矩阵
cm = confusion_matrix(y_test, y_pred)
print("Confusion matrix:\n%s" % cm)

步骤8: 可视化混淆矩阵

# 显示混淆矩阵
plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
plt.title("Confusion matrix")
plt.colorbar()
tick_marks = np.arange(len(target_names))
plt.xticks(tick_marks, target_names, rotation=45)
plt.yticks(tick_marks, target_names)

plt.tight_layout()
plt.ylabel('True label')
plt.xlabel('Predicted label')

plt.show()

解析:

  1. 加载数据集:
    • 使用fetch_lfw_people函数加载LFW数据集。
    • 我们设置min_faces_per_person=70,这意味着只保留至少有70张照片的人物。
    • 图像被缩放到resize=0.4的比例,以减少计算量。
  2. 查看数据集信息:
    • n_samples表示数据集中的人脸总数。
    • n_features是每个图像的特征数量(即像素数量)。
    • n_classes是数据集中人物的数量。
  3. 可视化:
    • plot_gallery 函数用于显示一些样本图像。
    • title 函数用于生成预测和真实标签的标题。
  4. 数据分割:
    • 使用train_test_split将数据集分割成训练集和测试集。
  5. 模型训练:
    • 使用MLPClassifier创建一个多层感知器模型。
    • 设置了隐藏层的大小、迭代次数、正则化参数等。
    • 模型使用Adam优化器。
  6. 模型评估:
    • 训练完成后,使用测试集评估模型性能。
    • 输出分类报告和混淆矩阵。
  7. 混淆矩阵可视化:
    • 使用matplotlib库来可视化混淆矩阵。

结论

通过上述步骤,我们成功地使用了scikit-learn中的MLPClassifier来构建一个人脸识别模型。模型的表现可以通过分类报告和混淆矩阵来评估。虽然使用人工神经网络进行人脸识别不是最先进的方法,但对于初学者来说,这是一个很好的起点。

进阶技巧

  • 特征提取:考虑使用PCA或LDA等降维技术来减少特征的数量,这样可以加快训练速度并且有时可以提高模型性能。
  • 超参数调整:使用网格搜索或随机搜索来寻找最优的模型参数,例如隐藏层的大小、学习率等。
  • 增强数据:通过数据增强技术(如旋转、翻转等)来增加数据集的多样性,从而提高模型的泛化能力。

代码总结

以上代码展示了如何使用scikit-learn和人工神经网络来进行人脸识别。您可以根据自己的需求调整模型参数,比如增加隐藏层的数量、改变学习率等,以获得更优的结果。

如果您想要进一步提高模型的性能,可以尝试使用更复杂的方法,例如卷积神经网络(CNN),这通常会带来显著的性能提升。不过,这对于初学者来说可能较为复杂,需要一定的深度学习背景知识。

执行效果

在这里插入图片描述
在这里插入图片描述
请添加图片描述

请添加图片描述

最后的建议

  • 持续学习:机器学习是一个快速发展的领域,保持学习的态度是非常重要的。
  • 实践项目:动手实践是最好的学习方式,尝试在不同的数据集上训练模型。
  • 社区参与:加入机器学习社区,与其他开发者交流经验和心得。

通过这篇文章,我们不仅学习了如何使用scikit-learn和人工神经网络进行人脸识别,还了解了一些提高模型性能的方法。希望这篇文章对您有所帮助!

别忘了给这篇帖子点个赞👍,如果喜欢的话,也可以收藏,关注我了解更多人工智能相关案例知识哦!😉


请记得,LFW数据集较大,下载和训练可能需要一定的时间,建议将LFW数据集下载到本地,本例中是先下载到本地的。如果您在运行代码时遇到任何问题,请随时提问!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RedHat Enterprise Linux 7 YUM源(本地/网络源)配置详解

目录 一、挂载 二、建立本地源 三、建立网络源 四、验证可行性 一、挂载 ——将光盘挂载到 /mnt 下 当/mnt中有如图内容时,即挂载成功 若挂载光驱/dev/sr0时报错:mount: no medium found on /dev/sr0 解决措施:查看该设备状态是否全部勾选…

数仓实践:一文读懂数仓 ODS 层模型设计

引言 OneData 体系中,数据划分为三层: ODS(Operational Data Store):操作数据层。它相当于数据中台通用数据模型层的一个数据准备区,同时又承担着基础数据的记录以及历史变化,主要完成业务系统、日志等结构化和半结构化数据引入到数据中台。保留业务系统原始数据,包括…

【HZHY-AI300G智能盒试用连载体验】设置RKNN的开发环境

目录 安装RKNN工具 安装pip3 安装RKNN Toolkit Lite2 安装RKNPU2运行库 本文首发于电子发烧友论坛:【新提醒】【HZHY-AI300G智能盒试用连载体验】 智能工业互联网网关 - 北京合众恒跃科技有限公司 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com) 前…

WordPress文章标题定制化前缀插件

引言 在当今互联网的海洋中,吸引读者眼球的第一步往往始于文章标题的设计。对于WordPress博主而言,如何让每篇文章的标题更加个性化和吸引人,成为了一项重要的任务。传统的自定义CSS方法虽然可行,但其繁琐的操作和有限的美学效果…

麦克斯韦方程组解析——电磁理论的基石与奥秘

麦克斯韦方程组解析——电磁理论的基石与奥秘 麦克斯韦方程组的核心作用 组件/步骤描述麦克斯韦方程组描述电磁场的基本方程组,由四个主要方程构成功能揭示电场、磁场与电荷、电流之间的关系,是电磁理论的基础应用领域广泛应用于电子学、光学、通信等领…

51单片机16(步进电机实验)

一、步进电机简介: 1、步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。 2、 3、 4、我们这个电机的旋转停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载的变化的影响,也就是说给我们的这个步进电机一个脉冲信号&#x…

大唐杯 5G LMT

一、比赛现场流程 比赛现场会给你一个册子,册子前边部分会告诉你要做什么,最后一页会给参数。 按照他告诉你要做什么一步步根据参数做就可以了。 他每组还会有个评分表,按照一步步的操作给你打分。 我们评分表这次是 基站登录—网络规划参…

猫用空气净化器测评分享,猫用空气净化器哪个牌子值得买?

作为一位5年资深铲屎官,很多铲屎官听过一丁半点宠物空气净化器,知道宠物空气净化器净化器对于养猫家庭的重要性。其实宠物空气净化器真的是养猫家庭必备的一款小家电。大面积进风口可以有效吸附空气中微小的浮毛、皮屑,专门的除臭技术有效净化…

DP 整数拆分不同的二叉搜索树 DAY21

整数拆分? 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k > 2 ),并使这些整数的乘积最大化。 返回 你可以获得的最大乘积。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。示例 2: 输入: n 10 输…

后端笔记(1)--javaweb简介

1.JavaWeb简介 ​ *用Java技术来解决相关web互联网领域的技术栈 1.网页:展现数据 2.数据库:存储和管理数据 3.JavaWeb程序:逻辑处理 2.mysql 1.初始化Mysql mysqld --initialized-insecure2.注册Mysql服务 mysqld -install3.启动Mysql…

数据结构第六讲:栈和队列

数据结构第六讲:栈和队列 1.栈1.1概念与结构1.2栈的实现1.2.1栈的基础框架1.2.2栈的初始化1.2.3栈的销毁1.2.4栈的插入(压栈)1.2.5栈的删除(出栈)1.2.6获取栈顶元素1.2.7获取栈中有效数据的个数 2.队列2.1概念与结构2.…

PyTorch 2.0 GPU Nvidia运行库的安装

【图书推荐】《PyTorch深度学习与计算机视觉实践》-CSDN博客 假设读者电脑带有NVIDIA 20 以上系列的显卡。 我们以CUDA 11.7cuDNN 8.2.0(其他更高版本的组合,读者可以执行查阅PyTorch官网获得)为例,讲解PyTorch 2.0 GPU版本的安…

Cocos Creator2D游戏开发(4)-飞机大战(2)-编辑器界面

编辑器几个重要板块 参考: https://docs.cocos.com/creator/3.8/manual/zh/editor/ (1) 场景编辑器: 仅看2D视图: 按钮作用依次是: 平移, 旋转,缩放,矩形变换,增量吸附工具,最后三个,前俩是变换工具,最后一个是布局组件 矩形变换: 中心点和锚点切换 以后用到慢慢整吧! (2)层…

大语言模型的Scaling Law:如何随着模型大小、训练数据和计算资源的增加而扩展

人工智能的世界正在经历一场革命,大型语言模型正处于这场革命的前沿,它们似乎每天都在变得更加强大。从BERT到GPT-3再到PaLM,这些AI巨头正在推动自然语言处理可能性的边界。但你有没有想过是什么推动了它们能力的飞速提升? 在这篇…

反向代理和负载均衡

目录 步骤1 代理技术介绍 代理技术常见的类型 正向代理的用途 反向代理的作用 步骤2 反向代理配置 步骤3 负载均衡 1、路由模式(推荐) 2、桥接模式 3、服务直接返回模式 4、负载均衡算法介绍 1、轮询法 2、随机法 3、最小连接法 步骤4 nginx…

数据结构:队列(顺序存储和链式存储)

文章目录 1. 队列的概念和结构2. 队列的链式存储实现2.1 初始化2.2 判断队列是否为空2.3 入队列2.4 出队列2.5 取队头数据2.6 取队尾数据2.7 队列有效数据的个数2.8 打印队列数据2.9 销毁2.10 源代码 3. 队列的顺序存储实现(循环队列)3.1 初始化3.2 判断队列是否为空3.3 判断队…

五、获取树形结构数据递归写法

1、mysql库表字段 学习:构建表结构时的规范,字段类型的选择 CREATE TABLE pms_category (cat_id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 分类id,name char(50) DEFAULT NULL COMMENT 分类名称,parent_cid bigint(20) DEFAULT NULL COMMENT 父分类…

2024年必知:9大项目成本管理系统推荐

本文将分享9大优质项目成本管理系统:PingCode、Worktile、中望软件、用友、智慧工地云平台、SAP ERP、Microsoft Project、Wrike、Zoho Projects。 在项目管理领域,控制成本往往是最挑战的一环,特别是在预算和资源受限的情况下。选择合适的项…