PCA+SVM实现基础的人脸识别
人工智能课程作业,顺便上传一下
本实验采用python编程实现,使用Olivette实验室的ORL人脸库作为数据集。ORL人脸库共有400幅人脸图像 (40人, 每人10幅, 大小为112像素×92像素) , 大多数图像的光照方向和强度相差不大, 其中人的脸部表情和脸部细节有着不同程度的变化, 尺度差异在10%左右, 人脸姿态也有相当程度的变化。将数据集中每个人的10张人脸图像分成两组前7张构成训练集, 另外3张构成测试集。训练集和测试集各有280个和120个人脸图像样本。
实验过程:
利用PCA降维去除像素之间的相关性,从训练集样本中提取主要成分,实验中将主成分的 数目确定为20。通过这样的处理,训练集中的每个人脸样本的特征向量由10304维降到20维,在后续的实验中就以20维的特征向量来代表该人脸样本。在后续的实验中就以20维的特征向量来代表该人脸样本
采用最为常用径向基核函数 (RBF) , 得到的支持向量机是一种径向基核函数分类器。在实验中采用python中SVM的默认值(C=1.0, kernel=“rbf”, degree=3, gamma=“scale”……),对测试集中的40个人的三张随机照片,共120张照片进行分类,显示实别正确率是95.8%
调用的库主要是Image 和sklearn
有一些是测试的时候随手复制的 没删
from PIL import Image;
import numpy as np;
import os;
import time
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.model_selection import StratifiedKFold,KFold
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import random
from sklearn import svm
读取图片,变为灰度形式,并以一维的形式存储每一张图片
rootdir = 'D:\网页\人工智能\orl_faces'
list1 = os.listdir(rootdir) #列出文件夹下所有的目录与文件
list_title = list()
list_pho =list()
for i in range(0,40):
#第一层 data下的目录
path1 = os.path.join(rootdir,list1[i])
list2 = os.listdir(path1)
for k in range(0,len(list2)):
#第2层 1下的目录
path2 = os.path.join(path1,list2[k])
raw_image=Image.open(path2).convert('L')
list_pho.append( list(raw_image.getdata()) )
list_title.append(i+1)
简单的PCA降维
每个人脸样本的特征向量由10304维降到20维
n_components = 20#这个降维后的特征值个数如果太大,比如100,结果将极其不准确,为何??
pca = PCA(n_components = n_components, svd_solver='auto',
whiten=True).fit(list_pho)
#PCA降维后的总数据集
list_pho_pca = pca.transform(list_pho)
将数据随机分成训练集和测试集
X_train = list()
y_train = list()
X_test = list()
y_test = list()
a = [0,1,2,3,4,5,6,7,8,9]
for i in range(0,400,10):
random.shuffle(a)
for k in range(0,7):
X_train.append(list_pho_pca[i+a[k]])
y_train.append(list_title[i+a[k]])
for k in range(7,10):
X_test.append(list_pho_pca[i+a[k]])
y_test.append(list_title[i+a[k]])
使用SVM分类器,全部为默认参数
model = svm.SVC(C=1)
model.fit(X_train, y_train)
print(model.score(X_test, y_test))
PCA可有效降维, 如实验中人脸图像样本的特征向量10304维降为20维, 这就将后续的分类问题变成一个在20维空间中的划分问题, 过程大大简化, 提高了运算速度。
降维以后, 分类的识别率没有明显下降。这是因为经过PCA处理后, 虽然特征向量的维数大大降低, 但是图像中那些差异最大的特征被最大程度的保留, 而那些相对一致、区分力较差的特征则被丢弃。PCA降维丢弃某些特征所损失的信息, 可以通过在低维空间中更加精确地映射得以补偿。
SVM选取不同参数进行分类, 得到了不同的识别结果, 说明参数的优化可提高识别率, 可以起到提高SVM分类器推广能力的作用。
from PIL import Image;
import numpy as np;
import os;
import time
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.model_selection import StratifiedKFold,KFold
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import random
from sklearn import svm
rootdir = 'D:\网页\人工智能\orl_faces'
list1 = os.listdir(rootdir) #列出文件夹下所有的目录与文件
list_title = list()
list_pho =list()
for i in range(0,40):
#第一层 data下的目录
path1 = os.path.join(rootdir,list1[i])
list2 = os.listdir(path1)
for k in range(0,len(list2)):
#第2层 1下的目录
path2 = os.path.join(path1,list2[k])
raw_image=Image.open(path2).convert('L')
list_pho.append( list(raw_image.getdata()) )
list_title.append(i+1)
n_components = 20#这个降维后的特征值个数如果太大,比如100,结果将极其不准确,为何??
pca = PCA(n_components = n_components, svd_solver='auto',
whiten=True).fit(list_pho)
#PCA降维后的总数据集
list_pho_pca = pca.transform(list_pho)
X_train = list()
y_train = list()
X_test = list()
y_test = list()
a = [0,1,2,3,4,5,6,7,8,9]
for i in range(0,400,10):
random.shuffle(a)
for k in range(0,7):
X_train.append(list_pho_pca[i+a[k]])
y_train.append(list_title[i+a[k]])
for k in range(7,10):
X_test.append(list_pho_pca[i+a[k]])
y_test.append(list_title[i+a[k]])
print(len(X_train))
print(len(X_test))
#Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset
# Create SVM classification object
model = svm.SVC(C=1)
# there is various option associated with it, like changing kernel, gamma and C value. Will discuss more # about it in next section.Train the model using the training sets and check score
model.fit(X_train, y_train)
print(model.score(X_test, y_test))
生活中用python比较少,主要是课程需要,所以代码写的可能有些奇怪,望海涵
使用Olivette实验室的ORL人脸库
可以直接github上搜索 orl 找到orl_faces 之类的直接下载就好了
分享了数据集
链接:https://pan.baidu.com/s/1gIpA-tsyw51fUbRqYMUBKg?pwd=fzpk 提取码:fzpk