您的位置:首页 > 编程语言 > MATLAB

人脸识别中用主成分分析PCA来将数据降维--MATLAB代码

2018-09-03 13:21 323 查看

人脸识别的数据集,维度一般都比较高,在自己的电脑上跑这么高维的数据集,很多个人计算机需要跑很长时间,因此一般都需要改变图像大小或者是降维。

常用的方式有以下几种,最普通的是改变图像的大小,是用的MATLAB自带的imresize函数来直接改变图像的大小,如何使用请自行查询。其次就是降维,基本的降维方式主要是PCA和LDA两种,复杂的我也曾用过自编码器降维。本文主要讲述的是用PCA的方式降维人脸数据集,因为我在查阅时,大多是分析原理,少有人能详细说明,如何实现训练集与数据集的处理。

一. PCA原理

 PCA的算法过程,用一句话来说,就是“将所有样本X减去样本均值m,再乘以样本的协方差矩阵C的特征向量V,即为PCA主成分分析”,其计算过程如下:
    [1].将原始数据按行组成m行n列样本矩阵X(每行一个样本,每列为一维特征)
    [2].求出样本X的协方差矩阵C和样本均值m;(Matlab可使用cov()函数求样本的协方差矩阵C,均值用mean函数)
    [3].求出协方差矩阵的特征值D及对应的特征向量V;(Matlab可使用eigs()函数求矩阵的特征值D和特征向量V)
    [4].将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P;(eigs()返回特征值构成的向量本身就是从大到小排序的)
    [5].Y=(X-m)×P即为降维到k维后的数据;

二. 实现方法

直接调用Matlab工具箱princomp( )函数实现,[COEFF SCORE latent]=princomp(X)

参数说明:
    1)COEFF 是主成分分量,即样本协方差矩阵的特征向量;
    2)SCORE主成分,是样本X在低维空间的表示形式,即样本X在主成份分量COEFF上的投影 ,若需要降k维,则只需要取前k列主成分分量即可
    3)latent:一个包含样本协方差矩阵特征值的向量;

三. 疑惑与解答

我在看完原理之后遇到以下疑惑,虽然感觉比较傻,但是可能也有人遇到同样的问题,因此说一下并解答:

①在使用PCA之前,是否需要先将数据归一化才可以?

②该方法可以得到训练的数据集,那么测试集怎么得到?如果也采用这样的方法,那不是本身就已经得到测试集的主成分了?

③COEFF分量与SCORE分量应该使用哪一个作为最终数据?为什么大多数代码两个都要保存?

关于第一个问题,使用之前是无需归一化的,因为使用之前本身就需要减去样本均值,注意此处是每一个维度减去每一个维度的均值。当然了,实际上对于图像数据,先进行归一化也是可以的,我尝试过,先归一化之后分类精度甚至更高了一个百分点左右(只尝试一次,不排除其随机性)。

第二个问题其实和第三个问题是一样的解决方法了,在下面的代码中也有体现。COEFF分量是主成分的特征矩阵,SCORE是训练集的主成分特征,即SCORE取其前K个就是将其降低到K维(此处看到有些文章说还需要继续处理,为保险起见,代码中训练集也是用的COEFF分量,但是直接使用SCORE分量应该也是没问题的),留下COEFF分量是因为得到测试集时需要用到主成分的特征矩阵。此外需要注意的是,测试集在与特征矩阵相乘前,需要做与训练集同样的数据处理工作,具体方法见代码

四. 详细代码

由于本人用的数据集是n×m,其中n为图像维度,m为图像张数,而MATLAB自带的PCA函数为每一行为一张图片,因此需要先做转置处理,具体视自己使用的数据集而定。最后得到的trainFeatures和testFeatures即为需要的k维的训练集和测试集。

[code]function [ trainFeatures, testFeatures ] = myPCA( trainData, testData, k )
%UNTITLED 此处显示有关此函数的摘要
%   此处显示详细说明
A = trainData';
B = testData';
%数据标准化:Z-标准化后的数据;mu-每列的均值;sigma-每列的标准差。
[Z,mu,sigma]=zscore(A);
%PCA降维:
[coeff,score,latent] = princomp(Z);

train = Z * coeff;
train = train(:,1:k);
rownum=size(B,1);
%按照训练样本的标准化参数,对测试数据进行处理:
%              Y=(X-mu)/sigma;
B = (B-repmat(mu,rownum,1))./repmat(sigma,rownum,1);
%再按照训练样本的PCA降维后所选择的系数矩阵对数据进行处理:
%               Y=X*coeff
%由于在标准化中,已经对数据进行了减去均值处理,所以在此可直接乘系数矩阵。
test = B * coeff;
test = test(:,1:k);
trainFeatures = train';
testFeatures = test';

end

参考博客

https://www.cnblogs.com/lutaitou/p/5535171.html

https://www.geek-share.com/detail/2701864599.html

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: