基于LDA+SVM实现人脸识别模型
描述
人脸识别(图像识别)是机器学习领域十经典的应用,在本质上,人脸识别属于监督学习中的分类问题。前面章节中我们已经学习了支持向量机(SVM),该算法在图像分类领域应用非常广泛,本任务要求结合学过的数据降维算法(LDA、PCA),使用SVM构建人脸识别模型,对比评估不同降维算法下的识别准确率。数据集采用lfw人脸数据集。
本任务的主要工作内容:
1、 lfw数据集的下载与加载查看
2、 应用LDA对数据集降维
3、 应用PCA对数据集降维
4、 对比降维前后模型的表现
5、 对比两种降维算法的区别
源码下载
环境
-
操作系统:Windows 10、Ubuntu18.04
-
工具软件:Anaconda3 2019、Python3.7
-
硬件环境:无特殊要求
-
依赖库列表
matplotlib 3.3.4 scikit-learn 0.24.2
分析
LFW (Labeled Faces in the Wild) 人脸数据集是由美国马萨诸塞州立大学阿默斯特分校计算机视觉实验室整理完成的经典数据集,主要用来研究人脸识别问题。该数据集包含5749个人的13233张脸部图片,每个人的图片数量不固定,图片尺寸为62×47,即数据的特征维度为62×47=2914,特征空间非常大,需要首先进行降维,之后再建模。
本任务涉及以下几个环节:
a)下载LFW人脸数据集
b)加载、查看数据集
c)分别使用LDA、PCA算法进行数据降维
d)在降维后的数据集上构建SVM模型并评估、预测
实施
1、下载LFW人脸数据集
下载地址:http://vis-www.cs.umass.edu/lfw/#download
打开页面,在下方找到下载链接,如图所示:
下载数据文件 lfw-funneled.tgz,保存到scikit-learn数据目录中,具体为:
Windows | C:\Users\实际用户名\scikit_learn_data\lfw_home |
---|---|
Linux | ~\scikit_learn_data\lfw_home |
2、加载、查看人脸数据集
from sklearn.datasets import fetch_lfw_people
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
import matplotlib.pyplot as plt
# 加载人脸数据集(选取具有不少于60张图片的人)
faces = fetch_lfw_people(min_faces_per_person=60)
print(faces.target_names) # 数据集中的人名(共8个,即8个类别)
print(faces.images.shape) # 图像大小:1348张图片,每张图片尺寸为62*47=2914
print(faces.data.shape) # 样本数据大小:1348张图片,每张图片包含2914个特征维度
print(faces.target.shape) # 标签数组(1348张图片每一张对应的姓名编号0~7)
# 查看部分人脸图片
fig, ax = plt.subplots(2,5) # 生成2行5列的子图,查看10张图片
for i, axi in enumerate(ax.flat):
axi.imshow(faces.images[i], cmap='bone') # 显示人脸图片
axi.set(xticks=[], yticks=[], xlabel=faces.target_names[faces.target[i]]) # 显示姓名
plt.show()
结果如下:
结果分析:
- 数据集中的八个人名,代表八个类别
- 样本图像大小:1348张图片,没张图片尺寸为62×47=2914
3、分别使用LDA、PCA算法进行数据降维
# LDA人脸数据降维,将2914个维度降为7个
# 注意LDA降维需要提供标签信息(target)
lda = LinearDiscriminantAnalysis(n_components=7).fit(faces.data, faces.target)
data_lda = lda.transform(faces.data) # 降维转换
print('LDA:', data_lda.shape) # 查看数据维度
# PCA降维(2914降为150)
pca = PCA(n_components=150).fit(faces.data) # 利用PCA算法降维
data_pca = pca.transform(faces.data) # 降维转换
print('PCA:', data_pca.shape) # 查看数据维度
结果如下:
LDA: (1348, 7)
PCA: (1348, 150)
4、使用SVM算法建立人脸识别模型,评估并预测
# 根据不同的数据集建立SVM模型并评估、预测
def build_eval(data, target, label, n=20, x=1):
X_train, X_test, y_train, y_test = train_test_split(data, target, random_state=9) # 拆分数据集
model = SVC(C=10, gamma='scale').fit(X_train, y_train) # 创建SVM分类模型
score = model.score(X_test, y_test) # 在测试集上评估模型成绩
print(label, score) # 打印模型成绩
y_pred = model.predict(X_test[:n]) # 预测前n张照片的姓名编号
print('人脸识别:', y_pred) # 预测结果
print('实际结果:', y_test[:n]) # 实际结果
# 预测第x张图片的姓名
y_name = faces.target_names[model.predict([X_test[x]])]
y_real = faces.target_names[y_test[x]]
print('第 {} 张人脸图片被识别为 {},实际为 {}\n'.format(x, y_name[0], y_real))
# 分别使用降维前、LDA降维和PCA降维后的数据进行建模、评估、预测
build_eval(faces.data, faces.target, '降维前,SVM模型识别准确率')
build_eval(data_pca, faces.target, 'PCA降维,SVM模型识别准确率')
build_eval(data_lda, faces.target, 'LDA降维,SVM模型识别准确率')
结果如下:
可以看到,LDA+SVM人脸识别模型的准确率达到99.7%,LDA降维在图像处理中具有较大的优势,相对于PCA算法,LDA在降维时考虑了样本的标签,因此在分类任务的数据降维中更常用。需要注意的是,LDA属于监督学习算法。