首頁>技術>

在本文中,我們將學習使用主成分分析(PCA)和支援向量機(SVM)來建立人臉識別模型。

首先,我們來看看PCA和SVM的介紹:

主成分分析:

主成分分析(PCA)是一種機器學習演算法,廣泛應用於探索性資料分析和建立預測模型。它通常用於降維,方法是將每個資料點投影到前幾個主成分上,以獲得低維資料,同時儘可能保留資料的變化。

支援向量機

支援向量機(SVM)是一種用於兩組分類問題的有監督機器學習模型。在為每個類別提供一組帶標籤的訓練資料後,它能夠對新的測試資料進行分類。

支援向量機基於最大化間隔的平面對資料進行分類,它的決策邊界是直的,是一種很好的影象分類演算法。實驗結果表明,支援向量機在經過3-4輪相關反饋後,其搜尋精度明顯高於傳統的查詢最佳化方案,對於影象分割系統也是如此,包括那些使用改進的支援向量機的系統。

人臉識別

人臉是由許多畫素組成的高維資料。高維資料很難處理,也不能用二維資料的散點圖等簡單技術視覺化。

我們要做的是利用PCA對資料的高維進行降維處理,然後將其輸入到SVM分類器中對影象進行分類。

接下來進入編碼部分!

下面的程式碼示例取自關於eigenfaces的sklearn文件。我們將一步一步地檢查程式碼,以瞭解其複雜性和結果。

import pylab as plimport numpy as npfrom matplotlib import pyplot as pltfrom sklearn.model_selection import train_test_splitfrom sklearn.datasets import fetch_lfw_peoplefrom sklearn.model_selection import GridSearchCVfrom sklearn.metrics import classification_reportfrom sklearn.metrics import confusion_matrixfrom sklearn.decomposition import PCA as RandomizedPCAfrom sklearn.svm import SVC
將資料載入到Numpy陣列中

接下來將資料下載到磁碟中,並使用fetch_lfw_people將其作為NumPy陣列載入sklearn.datasets。

lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4)

lfw資料集包括一個用於研究無約束人臉識別問題的人臉照片資料庫,其中有從網路收集的13000多張包含人臉的照片。1680名照片中的人在資料集中有兩張或兩張以上不同的照片。

影象採用灰度(畫素值=0-255)。

影象Numpy陣列

接下來、尋找影象陣列圖片的形狀。我們將使用NumPy shape屬性,該屬性返回一個元組,每個索引都有對應元素的數量。

n_samples, h, w = lfw_people.images.shapenp.random.seed(42)

從變數explorer可以看到,我們有1288個樣本(圖片),高度為50px,寬度為37px(50x37=1850個特徵)。

Numpy陣列

我們將使用lfw_people 的data陣列,直接儲存在X中,我們將在以後的處理中使用這些資料。

X = lfw_people.datan_features = X.shape[1]

X中的資料有1288個樣本,每個樣本有1850個特徵。

目標名稱和標籤

接下來定義標籤,這些標籤是圖片所屬的人的id。

y = lfw_people.targettarget_names = lfw_people.target_namesn_classes = target_names.shape[0]

這裡,y代表目標,它是每個圖片的標籤。標籤由target_names變數進一步定義,該變數由7個要識別的人的姓名組成。

target是一個1288x1的NumPy陣列,它包含1288張圖片對應名稱的0–6值。因此,如果id 0的目標值為5,則表示“Hugo Chavez”,如target_names中所示:

因此,y是數字形式的目標,target_names是名稱中的任何目標/標籤,n_classes是儲存類數量的變數,在這個例子中有7個目標:

Ariel SharonColin PowellDonald RumsfeldGeorge W BushGerhard SchröderHugo ChavezTony Blair

打印出變數:

print("Total dataset size:")print("n_samples: %d", n_samples)print("n_features: %d", n_features)print("n_classes: %d", n_classes)

所以,我們有1288個樣本(圖片),每個樣本總共有1850個特徵(50px37px)和7個類(人)。

劃分訓練集和測試集

接下來,我們將使用sklearn.model_selection將資料(X-特徵和y-標籤)分為訓練資料和測試資料,其中25%用於測試,其餘75%用於訓練模型。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)

以下是變數X-train、X_test、y_train和y_test:

基於PCA的降維方法

現在,我們將從 sklearn.decomposition選擇PCA 以訓練模型。我們已經在第一段程式碼中匯入了PCA。

在這個例子中,訓練集X_train中總共有966個特徵,我們將使用PCA(維數縮減)將它們減少到50個:

n_components = 50pca = RandomizedPCA(n_components=n_components, whiten=True).fit(X_train)

這個過程需要不到一秒鐘的時間,這可以透過使用時間函式進行驗證(這一點暫時跳過)。

現在我們將重塑PCA元件並定義特徵臉,這是在人臉識別的計算機視覺問題中使用的一組特徵向量的名稱:

eigenfaces = pca.components_.reshape((n_components, h, w))

如截圖所示,特徵臉是一個50×50×37的Numpy陣列。前50對應於特徵的數量。

接下來,我們將使用PCA在X_trainX_test 上的transform 函式來降低維數。

X_train_pca = pca.transform(X_train)X_test_pca = pca.transform(X_test)

從上面的截圖可以看出,透過PCA演算法,X_train和X_test的維數都被降低了。每一個都將特徵從1850個減少到50個(正如我們在演算法中定義的那樣)。

訓練SVM分類器

完成了降維,我們現在就開始分類。首先將訓練SVM分類模型。

我們將使用GridSearchCV,這是一個庫函式,它是一種調整超引數的方法。它將系統地為網格中指定的演算法引數的每個組合建立和評估模型,並在最佳估計量('best_estimator_')引數網格中給出:

print("Fitting the classifier to the training set")param_grid = {         'C': [1e3, 5e3, 1e4, 5e4, 1e5],          'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1],          }clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)clf = clf.fit(X_train_pca, y_train)print("Best estimator found by grid search:")print(clf.best_estimator_)

我們資料的最佳分類器是SVC,引數如下:

SVC(C=1000, class_weight = ‘balanced’, gamma=0.01)

預測

現在在測試資料上預測這些人的名字。我們將使用從GridSearchCV中找到的分類器,它已經在訓練資料擬合。

print("Predicting the people names on the testing set")y_pred = clf.predict(X_test_pca)
分類報告和混淆矩陣

預測完成後,列印分類報告,它將顯示模型的精度、召回率、F1分數和支援分數。這使我們對分類器的行為有了更深入的瞭解。

print(classification_report(y_test, y_pred, target_names=target_names))

列印混淆矩陣:

print(confusion_matrix(y_test, y_pred, labels=range(n_classes)))

在上面的例子中,混淆矩陣列印真正例、假正例和假反例的值,並提供分類器的概述。

繪圖

最後,繪製人物肖像和特徵臉!

定義兩個函式:title在測試集的一部分繪製預測結果,plot_gallery透過繪製它們來評估預測:

def title(y_pred, y_test, target_names, i):    pred_name = target_names[y_pred[i]].rsplit(' ', 1)[-1]    true_name = target_names[y_test[i]].rsplit(' ', 1)[-1]    return 'predicted: %s\ntrue:      %s' % (pred_name, true_name)def plot_gallery(images, titles, h, w, n_row=3, n_col=4):    """繪製肖像庫的幫助函式"""    plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))    plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)    for i in range(n_row * n_col):        plt.subplot(n_row, n_col, i + 1)        plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)        plt.title(titles[i], size=12)        plt.xticks(())        plt.yticks(())

現在我們在測試集的一部分繪製預測結果:

prediction_titles = [title(y_pred, y_test, target_names, i)                         for i in range(y_pred.shape[0])]plot_gallery(X_test, prediction_titles, h, w)

繪製特徵面。我們將使用在上面程式碼塊中定義的eigenfaces變數。

eigenface_titles = ["eigenface %d" % i for i in range(eigenfaces.shape[0])]plot_gallery(eigenfaces, eigenface_titles, h, w)plt.show()

最後,我們來繪製PCA+SVM模型用於人臉識別的精度:

from sklearn.metrics import accuracy_scorescore = accuracy_score(y_test, y_pred)print(score)

準確分數是0.81!雖然這並不是一個完美的分數,還有很大的改進空間,但PCA和SVM的人臉識別為我們提供了進一步強大演算法的起點!

結論

本文利用PCA和SVM建立了一個人臉識別模型。主成分分析演算法被用來減少資料的維數;影象有很多畫素值!然後利用支援向量機進行分類,透過超引數調整尋找最佳估計量。我們對這些肖像進行了分類,準確度得分為0.81。

13
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 使用Pandas從html表中爬取資料