前言
特征臉?biāo)惴ㄊ菇?jīng)典的人臉識別算法,特征臉?biāo)惴ㄊ褂昧薖CA方法。本文介紹了PCA算法和其應(yīng)用特征臉?biāo)惴?/p>
算法流程
特征臉?biāo)惴ǎ?/p>
設(shè)數(shù)據(jù)集D為
張
的圖片
,則將圖片展開,組成
大小的矩陣。
計算此矩陣的對均值向量
,此為
,對每個圖片,計算
。
計算
的協(xié)方差矩陣
,注意
的大小為
。
尋找的是像素之間的關(guān)系而不是圖片之間的關(guān)系
計算算
的特征值
與其對應(yīng)的特征向量
,找到前
個特征值所對應(yīng)的特征向量,組成新的矩陣
。
改變基。以特征向量作為新的基做新的圖片
使用KNN進(jìn)行分類
算法原理
如果我們要學(xué)習(xí)一組圖片的基
,讓
,其中
那么對于所有的圖片,找到一個圖片近似,對以下的
求最小值
其中是歐幾里得平方距離
是一個在
的基中的一張圖片
如果要使最小,則易得
是樣本圖片的均值
(偏導(dǎo))
其中 。所以
,此式獨(dú)立于
的零維呈現(xiàn)是一個點(diǎn)
的一維呈現(xiàn)是一條線
讓是通過
的一條線的方向。
回使
的方差達(dá)到最高
其中是任意圖像
是平均圖像
當(dāng)求出來的偏導(dǎo)為0的時候,可以將
用
代替
那么如何決定的方向呢?
其中為
的協(xié)方差矩陣
讓
由于是常數(shù)
其中
使用拉格朗日乘子法
當(dāng)的時候
所以選取前個
所對應(yīng)的
為什么選擇最大的:
最大的使
最小
最后新的基為
這種算法也被稱作PCA,可以看作是一個由原來維度的向量到大小的向量的投影
代碼
from sklearn.datasets import fetch_openml
import numpy as np
mnist = fetch_openml('mnist_784', cache=False)
x_train = mnist.data.astype('float32')[:2000] / 255
y_train = mnist.target.astype('int64')[:2000]
x_test = mnist.data.astype('float32')[2000:2500] /255
y_test = mnist.target.astype('int64')[2000:2500]
def zero_mean(x_train, x_test):
x_train_mean = np.mean(x_train, axis=0)
x_train_norm = x_train - x_train_mean
x_test_norm = x_test - x_train_mean
return x_train_norm, x_test_norm
def compute_basis(data, n=300):
C = data.T @ data
w, v = np.linalg.eig(C)
basis_indices = np.argsort(w)[::-1][:n]
eigenvectors = v[basis_indices]
return eigenvectors.T
def change_basis(data_matrix, eigenvectors):
I_eig = data_matrix @ eigenvectors
return I_eig
def knn_predict(eig_train_x, eig_test_x, y_train, y_test, k=1):
predictions = np.zeros_like(y_test)
for i in range(eig_test_x.shape[0]):
x = eig_test_x[i]
distance_vector = np.sum((eig_train_x - x) ** 2, axis=1)
nearest_indices = np.argsort(distance_vector)[:k]
a = y_train[nearest_indices]
uni, count = np.unique(a, return_counts=True)
predictions[i] = uni[np.argmax(count)]
return predictions
if __name__ == '__main__':
x_train_norm, x_test_norm = zero_mean(x_train, x_test)
eigenvectors = compute_basis(x_train_norm)
eig_train_x = change_basis(x_train_norm, eigenvectors)
eig_test_x = change_basis(x_test_norm, eigenvectors)