機器學習之SVM人臉識別


操作平臺: windows10, python37, jupyter
任務目標: 使用SVC算法,識別人臉,姓名



1、導入圖片數據

import numpy as np

import matplotlib.pyplot as plt
%matplotlib inline

import sklearn.datasets as datasets

from sklearn.svm import SVC

#它加載圖片的位置在計算機用戶目錄下scikit_learn_data中,如果不存在它會自動從網上下載
faces = datasets.fetch_lfw_people(min_faces_per_person=70,resize=1) #只加載大於70張圖片的數據,resize原尺寸
faces
{'data': array([[254.      , 254.      , 254.66667 , ...,  87.666664,  86.333336,
          86.333336],
        [ 42.      ,  33.      ,  32.333332, ..., 122.      , 148.33333 ,
         185.33333 ],
        [ 94.      ,  72.      ,  74.      , ..., 182.66667 , 183.      ,
         182.33333 ],
        ...,
        [ 85.      ,  85.666664,  85.333336, ...,  44.      ,  36.333332,
          30.333334],
        [ 49.666668,  49.666668,  48.333332, ..., 178.33333 , 166.66667 ,
         126.333336],
        [ 31.333334,  33.333332,  26.666666, ...,  48.333332,  63.      ,
          99.      ]], dtype=float32),
 'images': array([[[254.      , 254.      , 254.66667 , ...,  42.      ,
           38.      ,  39.      ],
         [254.      , 254.33333 , 254.      , ...,  43.333332,
           38.      ,  39.      ],
         [254.66667 , 254.33333 , 253.33333 , ...,  44.      ,
           39.      ,  39.      ],
         ...,
         [ 44.      ,  41.333332,  42.333332, ...,  38.333332,
           50.666668,  60.666668],
         [ 47.      ,  45.333332,  51.333332, ...,  44.666668,
           61.666668,  84.666664],
         [ 46.      ,  45.333332,  47.333332, ...,  48.333332,
           63.      ,  99.      ]]], dtype=float32),
 'target': array([5, 6, 3, ..., 5, 3, 5], dtype=int64),
 'target_names': array(['Ariel Sharon', 'Colin Powell', 'Donald Rumsfeld', 'George W Bush',
        'Gerhard Schroeder', 'Hugo Chavez', 'Tony Blair'], dtype='<U17'),
 'DESCR': ".. _labeled_faces_in_the_wild_dataset:\ ...

結果分析: 我們導入的數據中有五個參數,分別爲data, images, target, target_names, DESCR。


取出目標值:

X = faces['data']

y = faces['target']

names = faces.target_names

image = faces['images']

image.shape
(1288, 125, 94)


2、隨機查看圖片

index = np.random.randint(1288,size = 1)[0]

plt.imshow(image[index],cmap = plt.cm.gray) #繪製圖片

print(y[index]) #文件夾

names[y[index]] #文件夾名稱,也就是人的名字
3
'George W Bush'

在這裏插入圖片描述



3、建模評估

%%time

from sklearn.model_selection import train_test_split

X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2)

svc = SVC(kernel='rbf') #高斯分佈

svc.fit(X_train,y_train)

print(svc.score(X_test,y_test))
0.7906976744186046
Wall time: 32.1 s

結果分析: 該方法訓練測試數據大約耗時32秒,用時較長,準確率約80%。



4、PCA數據處理

4.1、數據脫敏處理

from sklearn.decomposition import PCA

# 主成分分析
# Principal component analysis (PCA)
# whiten = True 白化,歸一化
pca = PCA(n_components=0.9,whiten = True) #降低9倍

# 代表原來的數據,經過矩陣運算,結果屬性看不懂(屬性,沒有實際的物理意義),脫敏數據
X_pca = pca.fit_transform(X)

X_pca.shape
(1288, 116)

結果分析: 經過脫敏處理後,它的數據量下降,主要是因爲捨棄了一些沒有意義的值,但是它的結果屬性很是看不懂的,沒有物理意義。


4.2、建模評估

%%time
X_train, X_test, y_train, y_test = train_test_split(X_pca,y,test_size = 0.2)

svc = SVC()

svc.fit(X_train, y_train)

print(svc.score(X_test,y_test))
0.7829457364341085
Wall time: 405 ms

結果分析: 它的精確率沒有發生明顯的變化,但是使用的時間卻在明顯的提升。



5、過採樣技術處理

  • 過採樣技術是通過原數據,來填充短缺數據的一種方法,可以讓比較少的數據升到多數據的量。

5.1、查看原始數據

for i in range(7):
    print(names[i],(y == i).sum())
Ariel Sharon 77
Colin Powell 236
Donald Rumsfeld 121
George W Bush 530
Gerhard Schroeder 109
Hugo Chavez 71
Tony Blair 144

結果分析: 我們用來學習的數據一共有7個人,少的有71張圖片,多的有530張圖片,接下來將使用過採量技術,把所有數據都填充到530張人臉圖片。



5.2、過採量

  • Synthetic Minority Over-sampling Technique(綜合少數過採樣技術)
from imblearn.over_sampling import SMOTE
smote = SMOTE()

X2,y2 = smote.fit_resample(X,y) #重新採樣

#查看採樣結果
for i in range(7):
    print(names[i],(y2 == i).sum())
Ariel Sharon 530
Colin Powell 530
Donald Rumsfeld 530
George W Bush 530
Gerhard Schroeder 530
Hugo Chavez 530
Tony Blair 530

結果分析: 現在所有人的臉部照片都是530張了。



5.3、建模評估

%%time
X_train,X_test,y_train,y_test = train_test_split(X2_pca,y2,test_size = 0.2)

svc = SVC()

svc.fit(X_train,y_train)

print(svc.score(X_test,y_test))
0.9824797843665768
Wall time: 1.65 s

結果分析: 現在的準確率高達98%,並且只需要約1.6秒鐘,已經相當不錯了。



5.4、批量展示預測圖片

%%time

#切分訓練集和測試集
face_train,face_test,X_train,X_test,y_train,y_test = train_test_split(X2,X2_pca,y2,test_size = 0.2)
y_ = svc.predict(X_test) #預測

plt.figure(figsize=(10*2,10*3)) #設置畫布
for i in range(100):
    
    ax = plt.subplot(10,10,i + 1)
    
    face = face_test[i].reshape(125,94) #image.shape = (1288, 125, 94)
    
    ax.imshow(face,cmap = 'gray') #展示圖片
    ax.axis('off') #隱藏x,y軸
    
    t = names[y_test[i]].split(' ')[-1] #真實名稱
    
    p = names[y_[i]].split(' ')[-1] # 預測出來的名稱
    
    ax.set_title('True:%s\nPredict:%s'%(t,p))

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章