机器学习实战-SVM模型实现人脸识别

文章目录

  • SVM建模进行人脸识别案例
    • 1、导包
    • 2、加载数据集
    • 3、直接使用SVM模型建模
    • 4、数据可视化
    • 5、网络搜索优化确定最佳性能
    • 6、使用最佳性能SVM建模
    • 7、优化后的数据可视化
    • 8、完整代码
      • 8.1未优化的完整代码
      • 8.2优化后的完整代码

SVM建模进行人脸识别案例

1、导包

首先进行导包

from sklearn.decomposition import PCA
import numpy as np
from sklearn.svm import SVC
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.model_selection import GridSearchCV

2、加载数据集

我们加载sklearn已经帮我们收集好的人脸数据

# 加载人脸数据 lfw->labled faces wild:野外标记的人脸
data = datasets.fetch_lfw_people(resize = 1, min_faces_per_person = 70)
data

查看结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yDMpFcVz-1653818578585)(D:/Desktop/%E5%A4%A7%E5%AD%A6/MSB/AIoT/python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96%E5%88%9D%E7%BA%A7%EF%BC%88%E4%B8%80%EF%BC%89/%E4%BB%A3%E7%A0%81/image-20220529154305037.png)]

我们取出其中的数据进行查看:

X = data['data']
y = data['target']
faces = data['images']
target_names = data['target_names']
display(X.shape,y.shape,faces.shape,target_names)

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rKGWsgIG-1653818578587)(D:/Desktop/%E5%A4%A7%E5%AD%A6/MSB/AIoT/python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96%E5%88%9D%E7%BA%A7%EF%BC%88%E4%B8%80%EF%BC%89/%E4%BB%A3%E7%A0%81/image-20220529154409221.png)]

我们随机选取一个人的图片并通过索引获取名字:

# 随机取出一个人脸
index = np.random.randint(0,1288,size = 1)[0]
face = faces[index]
name = y[index] # 根据索引获取名字
print(target_names[name])
display(face.shape)
plt.imshow(face, cmap = 'gray')

结果展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ofu3HKda-1653818578587)(D:/Desktop/%E5%A4%A7%E5%AD%A6/MSB/AIoT/python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96%E5%88%9D%E7%BA%A7%EF%BC%88%E4%B8%80%EF%BC%89/%E4%BB%A3%E7%A0%81/image-20220529154558548.png)]

3、直接使用SVM模型建模

由于原来的数据很大,而且数据量多,我们首先对原始数据进行PCA降维

%%time
# 进行数据的降维
pca = PCA(n_components=0.95)
X_pca = pca.fit_transform(X)
display(X.shape,X_pca.shape)

结果展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xVoJuXHo-1653818578588)(D:/Desktop/%E5%A4%A7%E5%AD%A6/MSB/AIoT/python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96%E5%88%9D%E7%BA%A7%EF%BC%88%E4%B8%80%EF%BC%89/%E4%BB%A3%E7%A0%81/image-20220529155055558.png)]

然后对降维后的数据集进行训练和预测结果:

其中的C代表的是惩罚系数,用来防止过拟合,我们先用默认的初始值测试下性能

%%time
# 降维之后的数据
X_train,X_test,y_train,y_test, faces_train,faces_test = train_test_split(X_pca,y,faces)
# C为惩罚项,越大,容忍错误越小
# C越大,趋势:想方设发,把数据分开,容易造成过拟合
svc = SVC(C = 1) 
svc.fit(X_train,y_train)
# 训练数据效果很好,测试数据效果不好就是过拟合现象
print('训练数据的得分:',svc.score(X_train,y_train))
print('测试数据的得分:',svc.score(X_test,y_test))
# 算法的预测值
y_pred = svc.predict(X_test)

结果展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZxBk4Cyt-1653818578588)(../../../%E5%A4%A7%E5%AD%A6/MSB/AIoT/python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96%E5%88%9D%E7%BA%A7%EF%BC%88%E4%B8%80%EF%BC%89/%E4%BB%A3%E7%A0%81/image-20220529155241420.png)]

4、数据可视化

然后我们随机加载50张图片,并可视化查看预测结果:

plt.figure(figsize=(5 * 2, 10 * 3))
for i in range(50):
    plt.subplot(10,5,i + 1) # 子视图
    plt.imshow(faces_test[i],cmap = 'gray')
    plt.axis('off') # 刻度关闭
    # 贴上标签,并且对比实际数据和预测数据
    true_name = target_names[y_test[i]].split(' ')[-1]
    predict_name = target_names[y_pred[i]].split(' ')[-1]
    plt.title(f'True:{true_name}\nPred:{predict_name}')

结果展示:



从结果来看,预测效果并不是很好,红色框选出来的都是预测错误的名字,因此我们不得不对原来的性能优化。

5、网络搜索优化确定最佳性能

sklearn为我们集成好了网络搜索确定最佳性能的方法,只要吧要传进的参数填进去,它会为我们自动搭配获得最优参数。

%%time
svc = SVC()
# C为惩罚系数(防止过拟合),kernel为核函数类型,tol为停止训练的误差值、精度
params = {'C':np.logspace(-10,10,50),'kernel':['linear', 'poly', 'rbf', 'sigmoid'],'tol':[0.01,0.001,0.0001]}
gc = GridSearchCV(estimator = svc,param_grid = params,cv = 5)
gc.fit(X_pca,y)
gc.best_params_

结果展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z9dYEvQC-1653818578590)(../../../%E5%A4%A7%E5%AD%A6/MSB/AIoT/python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96%E5%88%9D%E7%BA%A7%EF%BC%88%E4%B8%80%EF%BC%89/%E4%BB%A3%E7%A0%81/image-20220529174137929.png)]

6、使用最佳性能SVM建模

从上面的结果来看,获得的最优惩罚系数C为1.8420699693267165e-07,最优核函数类型是linear线性模型,最优精度为0.001.

基于上面的最优参数,对SVM进行优化建模

svc = SVC(C = 1.8420699693267165e-07,kernel='linear',tol = 0.001)
# 随机划分的
X_pca_train,X_pca_test,y_train,y_test, faces_train,faces_test = train_test_split(X_pca,y,faces)
svc.fit(X_pca_train,y_train)
print('训练数据得分:',svc.score(X_pca_train,y_train))
print('测试数据的得分:',svc.score(X_pca_test,y_test))

结果展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TvoaiMyZ-1653818578591)(../../../%E5%A4%A7%E5%AD%A6/MSB/AIoT/python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96%E5%88%9D%E7%BA%A7%EF%BC%88%E4%B8%80%EF%BC%89/%E4%BB%A3%E7%A0%81/image-20220529174625742.png)]

从这个结果来看,相比于普通的SVM建模,优化后的SVM在得分上明显有提高。

7、优化后的数据可视化

plt.figure(figsize=(5 * 2, 10 * 3))
for i in range(50):
    plt.subplot(10,5,i + 1) # 子视图
    plt.imshow(faces_test[i],cmap = 'gray')
    plt.axis('off') # 刻度关闭
    # 贴上标签,并且对比实际数据和预测数据
    true_name = target_names[y_test[i]].split(' ')[-1]
    predict_name = target_names[y_pred[i]].split(' ')[-1]
    plt.title(f'True:{true_name}\nPred:{predict_name}')

结果展示:




从优化后的结果来看,虽然还是有分错的结果,但是准确率较原来的准确率提高了很多。

8、完整代码

8.1未优化的完整代码

from sklearn.decomposition import PCA
import numpy as np
from sklearn.svm import SVC
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.model_selection import GridSearchCV

# 加载人脸数据 lfw->labled faces wild:野外标记的人脸
data = datasets.fetch_lfw_people(resize = 1, min_faces_per_person = 70)
data

# 进行数据的降维
pca = PCA(n_components=0.95)
X_pca = pca.fit_transform(X)
display(X.shape,X_pca.shape)

# 降维之后的数据
X_train,X_test,y_train,y_test, faces_train,faces_test = train_test_split(X_pca,y,faces)
# C为惩罚项,越大,容忍错误越小
# C越大,趋势:想方设发,把数据分开,容易造成过拟合
svc = SVC(C = 1) 
svc.fit(X_train,y_train)
# 训练数据效果很好,测试数据效果不好就是过拟合现象
print('训练数据的得分:',svc.score(X_train,y_train))
print('测试数据的得分:',svc.score(X_test,y_test))
# 算法的预测值
y_pred = svc.predict(X_test)

plt.figure(figsize=(5 * 2, 10 * 3))
for i in range(50):
    plt.subplot(10,5,i + 1) # 子视图
    plt.imshow(faces_test[i],cmap = 'gray')
    plt.axis('off') # 刻度关闭
    # 贴上标签,并且对比实际数据和预测数据
    true_name = target_names[y_test[i]].split(' ')[-1]
    predict_name = target_names[y_pred[i]].split(' ')[-1]
    plt.title(f'True:{true_name}\nPred:{predict_name}')

8.2优化后的完整代码

from sklearn.decomposition import PCA
import numpy as np
from sklearn.svm import SVC
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.model_selection import GridSearchCV

# 加载人脸数据 lfw->labled faces wild:野外标记的人脸
data = datasets.fetch_lfw_people(resize = 1, min_faces_per_person = 70)
data

# 进行数据的降维
pca = PCA(n_components=0.95)
X_pca = pca.fit_transform(X)
display(X.shape,X_pca.shape)

svc = SVC()
# C为惩罚系数(防止过拟合),kernel为核函数类型,tol为停止训练的误差值、精度
params = {'C':np.logspace(-10,10,50),'kernel':['linear', 'poly', 'rbf', 'sigmoid'],'tol':[0.01,0.001,0.0001]}
gc = GridSearchCV(estimator = svc,param_grid = params,cv = 5)
gc.fit(X_pca,y)
gc.best_params_

svc = SVC(C = 1.8420699693267165e-07,kernel='linear',tol = 0.001)
# 随机划分的
X_pca_train,X_pca_test,y_train,y_test, faces_train,faces_test = train_test_split(X_pca,y,faces)
svc.fit(X_pca_train,y_train)
print('训练数据得分:',svc.score(X_pca_train,y_train))
print('测试数据的得分:',svc.score(X_pca_test,y_test))

plt.figure(figsize=(5 * 2, 10 * 3))
for i in range(50):
    plt.subplot(10,5,i + 1) # 子视图
    plt.imshow(faces_test[i],cmap = 'gray')
    plt.axis('off') # 刻度关闭
    # 贴上标签,并且对比实际数据和预测数据
    true_name = target_names[y_test[i]].split(' ')[-1]
    predict_name = target_names[y_pred[i]].split(' ')[-1]
    plt.title(f'True:{true_name}\nPred:{predict_name}')

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2023年12月14日
下一篇 2023年12月14日

相关推荐