中电网移动|移动中电网|高清图滚动区

PCA和SVM是什么?该如何建立人脸识别模型?

在本文中,我们将使用主成分分析和支持向量机来建立人脸识别模型。

首先,让我们了解 PCA 和 SVM 是什么:

主成分分析:主成分分析(PCA)是一种机器学习算法,广泛应用于探索性数据分析和建立预测模型,它通常用于降维,通过将每个数据点投影到前几个主成分上,以获得低维数据,同时尽可能保留数据的变化。

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b4ec68-thumb.jpg

Matt Brems 的文章全面深入地介绍了该算法。现在,让我们用更简单的术语来理解算法:假设我们现在正在收集数据,我们的数据集产生了多个变量、多个特征,所有这些都会在不同方面影响结果。我们可能会选择删除某些特征,但这意味着会丢失信息。因此我们开源使用另一种减少特征数量(减少数据维数)的方法,通过提取重要信息并删除不重要的信息来创建新的特征,这样,我们的信息就不会丢失,但起到减少特征的作用,而我们模型的过拟合几率也会减少。支持向量机支持向量机(SVM)是一种用于两组分类问题的有监督机器学习模型,在为每个类别提供一组带标签的训练数据后,他们能够对新的测试数据进行分类。

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b53dac-thumb.jpg

支持向量机基于最大化间隔的平面对数据进行分类,决策边界是直的。支持向量机是一种很好的图像分类算法,实验结果表明,支持向量机在经过 3-4 轮相关优化后,其搜索精度明显高于传统的查询优化方案,这对于图像分割来说也是如此,包括那些使用改进的支持向量机。Marco Peixeiro 的文章解释了需要有一个最大间隔超平面来分类数据,开源帮助你更好地理解 SVM!人脸识别人脸是由许多像素组成的高维数据。高维数据很难处理,因为不能用二维数据的散点图等简单技术进行可视化。我们要做的是利用 PCA 对数据的高维进行降维处理,然后将其输入到 SVM 分类器中对图像进行分类。下面的代码示例取自关于 eigenfaces 的 sklearn 文档,我们将一步一步地实现代码,以了解其复杂性和结果。导入相关库和模块首先,我们将导入所需的库和模块,我们将在后文深入讨论我们为什么要导入它们。

import pylab as pl
import numpy as np
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_lfw_people
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.decomposition import PCA as RandomizedPCA
from sklearn.svm import SVC

将数据加载到 Numpy 数组中接下来,我们将数据下载到磁盘中,并使用 fetch_lfw_people 将其作为 NumPy 数组加载到 sklearn.datasetslfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4)

lfw 数据集包括一个用于研究无约束人脸识别问题的人脸图像数据库,它从网络收集的 13000 多张照片中包含了超过 13000 张照片,每个人脸都贴上了照片,1680 个人脸在数据集中有两张或两张以上不同的照片。图像采用灰度值(像素值=0-255)。

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b551bd-thumb.jpg

图像 Numpy 数组接下来,我们将寻找图像数组图片的形状。我们使用 NumPy shape 属性,该属性返回一个元组,每个索引都有对应元素的数量。

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b586d7-thumb.jpg

n_samples, h, w = lfw_people.images.shape
np.random.seed(42)

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b4ba99-thumb.jpg

从变量 explorer 可以看到,我们有 1288 个样本(图片),高度为 50px,宽度为 37px(50x37=1850 个特征)Numpy 数组我们使用 lfw_people 的 data 数组,直接存储在 X 中,我们将在以后的处理中使用这些数据。X = lfw_people.data
n_features = X.shape[1]

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b53508-thumb.jpg

X 中的数据有 1288 个样本,每个样本有 1850 个特征。label 接下来,我们将定义 label,这些 label 是图片所属人的 id。y = lfw_people.target
target_names = lfw_people.target_names
n_classes = target_names.shape[0]

这里,y 代表目标,它是每个图片的标签。标签由 target_names 变量进一步定义,该变量由 7 个要识别的人的姓名组成。

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b4acb5-thumb.jpg

target 是一个 1288x1 的 NumPy 数组,它包含 1288 张图片对应名称的 0–6 值,因此,如果 id=0 的目标值为 5,则表示该人脸为“Hugo Chavez”,如 target_names 中所示:

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b454c3-thumb.jpg

因此,y 是数字形式的目标,target_names 是名称中的任何目标/标签,n_classes 是存储类数量的变量,在我们的例子中,我们有 7 个:Ariel SharonColin PowellDonald RumsfeldGeorge W BushGerhard Schr?derHugo ChavezTony Blair

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b65bff-thumb.jpg

让我们打印出变量:print("Total dataset size:")
print("n_samples: %d", n_samples)
print("n_features: %d", n_features)
print("n_classes: %d", n_classes)

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b413f3-thumb.jpg

所以,我们有 1288 个样本(图片),每个样本总共有 1850 个特征(50px37px)和 7 个类(人)。划分训练集和测试集接下来,我们使用 sklearn.model_selection 将数据(X-特征和 y-标签)分为训练数据和测试数据,其中 25%用于测试,其余 75%用于训练模型。X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
以下是变量 X-train、X_test、y_train 和 y_test:

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b40cc4-thumb.jpg

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b406d8-thumb.jpg

基于 PCA 的降维方法现在,我们从 sklearn.decomposition 中选择 PCA 以训练模型。我们已经在第一段代码中导入了 PCA 在我们的例子中,我们在训练集 X_train 中总共有 966 个特征,我们使用 PCA(维数缩减)将它们减少到 50 个:n_components = 50
pca = RandomizedPCA(n_components=n_components, whiten=True).fit(X_train)

这个过程需要不到一秒钟的时间,这可以通过使用时间函数进行验证(让我们暂时跳过它)。现在我们将重塑 PCA 组件并定义特征脸,这是在人脸识别的计算机视觉问题中使用的一组特征向量的名称:eigenfaces = pca.components_.reshape((n_components, h, w))

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b4e6b6-thumb.jpg

如截图所示,特征脸是一个 50×50×37 的 Numpy 数组,50 对应于特征的数量。接下来,我们使用 PCA 在 X_train 和 X_test 上的 transform 函数来降低维数。X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b40c2e-thumb.jpg

从上面的截图可以看出,通过 PCA 算法,X_train 和 X_test 的维数都被降低了,每一个都将特征从 1850 个减少到 50 个(正如我们在算法中定义的那样)。训练 SVM 分类器一旦我们完成了降维,就开始分类了。首先,我们将训练 SVM 分类模型。我们使用 GridSearchCV,这是一个库函数,它是一种调整超参数的方法,它将系统地为网格中指定的算法参数的每个组合建立和评估模型,并在最佳估计量,参数在参数网格中给出:print("Fitting the classifier to the training set")
param_grid = {
        'C': [1e3, 5e3, 1e4, 5e4, 1e5],
         'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1],
         }
clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)
clf = clf.fit(X_train_pca, y_train)
print("Best estimator found by grid search:")
print(clf.best_estimator_)

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b33e8a-thumb.jpg

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b459f9-thumb.jpg

我们数据的最佳分类器是 SVC,参数如下:SVC(C=1000, class_weight = ‘balanced’, gamma=0.01)预测现在让我们在测试数据上预测这些人的名字,我们使用从 GridSearchCV 中找到的分类器,它已经在训练数据拟合。print("Predicting the people names on the testing set")
y_pred = clf.predict(X_test_pca)

分类报告和混淆矩阵一旦预测完成,让我们打印分类报告,它显示了模型的精度、召回率、F1 分数和支持分数,这使我们对分类器的行为有了更深入的直觉。print(classification_report(y_test, y_pred, target_names=target_names))

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b45a95-thumb.jpg

让我们打印混淆矩阵:print(confusion_matrix(y_test, y_pred, labels=range(n_classes)))

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b3b59c-thumb.jpg

混淆矩阵打印真正例、假正例和假反例的值,并提供分类器的概述。绘图最后,我们将绘制人物肖像和特征脸!我们将定义两个函数:title 在测试集的一部分绘制预测结果,plot_gallery 通过绘制它们来评估预测:def title(y_pred, y_test, target_names, i):
   pred_name = target_names[y_pred[i]].rsplit(' ', 1)[-1]
   true_name = target_names[y_test[i]].rsplit(' ', 1)[-1]
   return 'predicted: %strue:      %s' % (pred_name, true_name)
   
def plot_gallery(images, titles, h, w, n_row=3, n_col=4):
   """绘制肖像库的帮助函数"""
   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(())

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b4a7ee-thumb.jpg

现在让我们在测试集的一部分绘制预测结果:prediction_titles = [title(y_pred, y_test, target_names, i)
                        for i in range(y_pred.shape[0])]
                       
plot_gallery(X_test, prediction_titles, h, w)

现在让我们绘制特征面。我们使用在上面代码块中定义的 eigenfaces 变量。eigenface_titles = ["eigenface %d" % i for i in range(eigenfaces.shape[0])]
plot_gallery(eigenfaces, eigenface_titles, h, w)
plt.show()

https://upload.semidata.info/new.eefocus.com/article/image/2021/01/04/5ff29a0b32a4f-thumb.jpg

最后,我们来绘制 PCA+SVM 模型用于人脸识别的精度:from sklearn.metrics import accuracy_score
score = accuracy_score(y_test, y_pred)
print(score)

我们的准确分数是 0.81!虽然这并不是一个完美的分数,还有很大的改进空间,但 PCA 和 SVM 的人脸识别为我们提供了进一步强大算法的起点!结论本文利用 PCA 和 SVM 建立了一个人脸识别模型。主成分分析算法被用来减少数据的维数,然后利用支持向量机进行分类,通过超参数调整寻找最佳估计量。我们对这些肖像进行了分类,准确度得分为 0.81。

猜你喜欢
中电网移动|移动中电网|频道导航区