特征脸算法
2020-10-09 本文已影响0人
卡德尔先生
前言
特征脸算法使经典的人脸识别算法,特征脸算法使用了PCA方法。本文介绍了PCA算法和其应用特征脸算法
算法流程
特征脸算法:
-
设数据集D为张 的图片,则将图片展开,组成 大小的矩阵。
-
计算此矩阵的对均值向量 ,此为,对每个图片,计算。
-
计算的协方差矩阵,注意的大小为。寻找的是像素之间的关系而不是图片之间的关系
-
计算算的特征值与其对应的特征向量 ,找到前个特征值所对应的特征向量,组成新的矩阵。
-
改变基。以特征向量作为新的基做新的图片
-
使用KNN进行分类
算法原理
如果我们要学习一组图片的基,让,其中
那么对于所有的图片,找到一个图片近似,对以下的求最小值
其中是欧几里得平方距离
是一个在的基中的一张图片
如果要使最小,则易得是样本图片的均值(偏导)
其中 。所以 ,此式独立于
的零维呈现是一个点 的一维呈现是一条线
让是通过的一条线的方向。回使的方差达到最高
其中是任意图像
是平均图像
当求出来的偏导为0的时候,可以将用代替
那么如何决定的方向呢?
其中为的协方差矩阵
让
由于是常数
其中
使用拉格朗日乘子法
当的时候
所以选取前个所对应的
为什么选择最大的:
最大的使最小
最后新的基为
这种算法也被称作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)