第十九课.基于sklearn的SVM人脸识别


实验为基于sklearn的SVM人脸识别,使用 SVM 算法对戴眼镜的人脸和不戴眼镜的人脸进行分类,从而完成 识别戴眼镜的人脸 的任务;实验涉及的支持向量机参数计算原理,回顾 第十八课

数据集

人脸图像数据集 olivetti_py3.pkz,保存在个人资源处,加载数据:

from sklearn.datasets import fetch_olivetti_faces

# 从当前目录下加载人脸数据集,若没有则联网下载到当前目录下
faces = fetch_olivetti_faces(data_home='./')

该数据集一共有 400 张人脸图片,每张图片的大小是:64x64:

faces.images.shape
# (400, 64, 64)

每张图片作为一个样本,一共有 400 个样本,每个样本的特征维度是:64x64 = 4096:

faces.data.shape
# (400, 4096)

400 张图片一共包含 40 个不同的人,每个人有 10 张人脸图片:

from collections import Counter

# 统计 target 中每个取值的数量
count=Counter(faces.target)
count
"""
Counter({0: 10,
         1: 10,
         2: 10,
         3: 10,
         4: 10,
         ...
         39: 10})
"""

展示前 4 张人脸图片:

%matplotlib inline 
import matplotlib.pyplot as plt

# 设置子图数量和画布大小
plt.figure(num=4,figsize=(20,5))
# 遍历前 4 张图片和对应的索引(索引从零开始)
for i,face in enumerate(faces.images[:4]):
    # 1行4列的第i+1个子图
    plt.subplot(1,4,i+1)
    # 在对应位置显示子图
    plt.imshow(face)

fig1

确定人脸的类别标记

戴眼镜人脸的图片索引范围:

# 下面的每个元组代表索引的起始和结束(闭区间)
segments = [(10, 19), (30, 32), (37, 38), (50, 59), (63, 64),(69, 69), (120, 121), (124, 129),
           (130, 139), (160, 161),(164, 169), (180, 182),(185, 185), (189, 189), (190, 192),
           (194, 194), (196, 199), (260, 269), (270, 279), (300, 309),(330, 339), (358, 359), (360, 369)]

创建类别标记,戴眼镜的人脸为 1,没戴眼镜的人脸为 0:

import numpy as np

# 先设置所有样本的标记值为 0 
target = np.zeros(faces.target.shape[0])
# 再将戴眼镜人脸索引位置的标记值设置为 1  
for seg in segments:
    target[seg[0]:seg[1]+1]=1
target

fig2

划分训练集和测试集与训练

划分数据集:

from sklearn.model_selection import train_test_split

# 设置测试集的大小为 20%
X_train, X_test, y_train, y_test = train_test_split(faces.data, target, test_size=0.2, random_state=0)
X_train.shape, X_test.shape, y_train.shape, y_test.shape
# ((320, 4096), (80, 4096), (320,), (80,))

SVM 模型训练:

from sklearn.svm import SVC

# 使用线性核函数进行模型训练
model = SVC(kernel='linear').fit(X_train,y_train)

模型准确率评估:

# 训练集的准确率
print('train_accuracy =',model.score(X_train,y_train))
# 测试集的准确率
print('test_accuracy =',model.score(X_test, y_test))
"""
train_accuracy = 1.0
test_accuracy = 0.9875
"""

识别结果可视化:

# 测试集的预测结果
y_pred = model.predict(X_test)
# 样本标记值对应的人脸类别
text = {1:'戴眼镜', 0:'没戴眼镜'}

# 设置子图数量和画布大小
plt.figure(num=16,figsize=(20,20))
# 设置显示中文字体(黑体)
plt.rcParams['font.family'] = ['SimHei']

# 遍历测试集的 16 张人脸图片对应的特征向量及其索引
for i,face in enumerate(X_test[:16]):
    # 4行4列的第i+1个子图 
    plt.subplot(4,4,i+1)
    # 将特征向量转为二维数组,shape=(64,64)
    face = face.reshape(64,64)
    # 将二维数组以图片的形式展现出来
    plt.imshow(face)
    # 取出当前人脸的类别标记预测值
    label = y_pred[i]
    # 在图片(35,60)的位置标出人脸类别(是否戴眼镜),字体大小为 24,字体颜色为棕色
    plt.text(x=35,y=60,s=text[label],fontdict={'fontsize':24 ,'color':'brown'})

fig3

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值