在智能算法专题设计课中,我们学习了PCA算法,并学会利用PCA算法生成平均脸,下面是步骤以及我的一些思考

了解PCA算法

PCA算法本质上是一种降维算法。

**PCA的算法思路:**数据从原来的坐标系转换到新的坐标系,由数据本身决定。转换坐标系时,以方差最大的方向作为坐标轴方向,因为数据的最大方差给出了数据的最重要的信息。第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴选择的是与第一个新坐标轴正交且方差次大的方向。重复该过程,重复次数为原始数据的特征维数。
**PCA算法的要点:**通过这种方式获得的新的坐标系,我们发现,大部分方差都包含在前面几个坐标轴中,后面的坐标轴所含的方差几乎为0。于是,我们可以忽略余下的坐标轴,只保留前面的几个含有绝大部分方差的坐标轴。事实上,这样也就相当于只保留包含绝大部分方差的维度特征,而忽略包含方差几乎为0的特征维度,也就实现了对数据特征的降维处理。

生成特征脸的步骤

输入:训练样本集 D=x(1),x(2),…,x(m)D=x(1),x(2),…,x(m) ,低维空间维数 d′d′ ;
 过程:.
 第一步:对所有样本进行中心化(去均值操作): x(i)j←x(i)j−1m∑mi=1x(i)jxj(i)←xj(i)−1m∑i=1mxj(i) ;
 第二步:计算样本的协方差矩阵 XXTXXT ;
 第三步: 对协方差矩阵 XXTXXT 做特征值分解 ;
第四步:取最大特征值对应的特征向量(这里可以通过能量进行选择)
第五步:最终得到的特征向量便是特征脸

代码逐步分析

(1)对样本进行中心化:

这里包括读入所给的32张图片,将每张图片抽拉成一列(可以用a=a(:)的办法),averageFace为自己写的定义平均脸的函数。同时需要注意将原始脸数据转换一下数据类型,否则进行中心化相减时将会因为数据类型不一致而报错。

[averFace,oriFace]=averageFace(32,'s','.bmp');
averFace=averFace(:);%转成一列
oriFace=double(oriFace);
for i=1:32oriFace(:,i)=oriFace(:,i)-averFace;
end
计算平均脸的函数:
function [aver,originalFace] = averageFace(num,beforeName,endName)
%计算平均脸的函数
%输入:数据里的所有的脸,包括图片的张数,图片的前缀名,图片的后缀名
%输出:平均脸、原始的所有图片构成的矩阵、
%首先,构造一个矩阵,用于存放每个图片后来构成的图像
aver=ones(10000,1);
for i=1:numface=imread(strcat(beforeName,num2str(i),endName));%读入图片数据%每读一张,就将它转化为列向量column=face(:);%把转化后的列向量添加到一个矩阵中aver=[aver column];
end
%删除矩阵的第一列:为了构造矩阵而添加的一列
aver(:,1)=[];
originalFace=aver;
%计算该矩阵每一行的平均值,形成一列平均值的向量
aver=mean(aver,2);
%将平均值的向量还原成矩阵,即为平均脸,返回平均脸
aver=reshape(aver,100,100);
end

(2)计算样本的协方差矩阵:

这里是(10000,32)(3210000),所以得到的协方差矩阵为10000*10000,比较大。

%第二步:计算样本的协方差矩阵
covMatrix=oriFace*oriFace';

(3)计算样本的特征值和特征向量:

在matlab中可以使用函数eig得到协方差矩阵的特殊值,由于协方差矩阵比较大,所以计算过程十分耗时,下面有谈到另一种计算特征向量和特征值的办法。

%第三步:对协方差矩阵作特征值分解
%获得协方差矩阵的特征值的对角矩阵D
[V,D]=eig(covMatrix);
%取对角矩阵的特征值
featureValue=diag(D);

(4)根据能量找到最大的几个特征值,并找到最大特征值对应的特征向量。

%对特征值进行从大到小的排序
bigToSmall=sort(featureValue,'descend');
%第四步:取最大的d个特征值所对应的特征向量
%这里通过能量确定d的取值
d=0;%d的初始取值为0
someEnergy=0;%前项的能量
allEnergy=sum(bigToSmall(:));%所有的特征能量
while(someEnergy/allEnergy<0.9)d=d+1;someEnergy=sum(bigToSmall(1:d,:));
end
%寻找特征值对应的特征向量
featureVector=zeros(10000,1);
for i=1:dnowNumber=bigToSmall(i);%从大到小找到此时的值[row,column]=find(D==nowNumber);%在原来的特征值数组中定位findVector=V(:,column);%根据原来的特征值数组位置找到其对应的特征向量featureVector=[featureVector findVector];
end
featureVector=featureVector(:,2:d+1);%删掉之前添加的数据

(5)最终找到的特征向量即为特征脸,只需要使用reshape函数转成原始图片大小即可。

matlab整体实现代码

function [] = PCACalculator()
%PCA算法计算出特征脸
%输入:训练样本集,低维空间维度:d
%输出:特征脸
%第一步:对所有样本进行中心化
%得到平均脸函数中,获得的原始所有脸矩阵+平均脸矩阵
[averFace,oriFace]=averageFace(32,'s','.bmp');
averFace=averFace(:);%转成一列
oriFace=double(oriFace);
for i=1:32oriFace(:,i)=oriFace(:,i)-averFace;
end
%第二步:计算样本的协方差矩阵
covMatrix=oriFace*oriFace';
%第三步:对协方差矩阵作特征值分解
%获得协方差矩阵的特征值的对角矩阵D
[V,D]=eig(covMatrix);
%取对角矩阵的特征值
featureValue=diag(D);
%对特征值进行从大到小的排序
bigToSmall=sort(featureValue,'descend');
%第四步:取最大的d个特征值所对应的特征向量
%这里通过能量确定d的取值
d=0;%d的初始取值为0
someEnergy=0;%前项的能量
allEnergy=sum(bigToSmall(:));%所有的特征能量
while(someEnergy/allEnergy<0.9)d=d+1;someEnergy=sum(bigToSmall(1:d,:));
end
%寻找特征值对应的特征向量
featureVector=zeros(10000,1);
for i=1:dnowNumber=bigToSmall(i);%从大到小找到此时的值[row,column]=find(D==nowNumber);%在原来的特征值数组中定位findVector=V(:,column);%根据原来的特征值数组位置找到其对应的特征向量featureVector=[featureVector findVector];
end
featureVector=featureVector(:,2:d+1);%删掉之前添加的数据
%第五步:将原样本矩阵与投影矩阵相乘即为降维后的数据集
%specialFace=oriFace*featureVector;
%将会生成多张特征脸,这里要将矩阵的每一列重新合成一张照片
%由于生成时间慢,这里可以把图片保存下来
for i=1:dname=strcat('featureFace',num2str(i),'.bmp');pic=featureVector(:,i);picToOri=reshape(pic,100,100);imwrite(picToOri,name);%保存图片
end
end

关于PCA算法中求特征向量的思考

找寻简单的求特征向量的方法:
在PCA算法的过程中,其中有一个步骤是生成样本的协方差矩阵,如果采用原始方法直接生成它的协方差矩阵的话,那么计算量将非常大,我在这里测试了一下,改改需要十多分钟到二十分钟左右。而能否有简单的办法呢?
在这里涉及到数学上的转化:可以通过其他办法得到原始协方差矩阵生成的特征向量。原始样本协方差矩阵为C=AA’(此实验中将生成1000010000的矩阵),而用C=A’A(此实验中将生成3232的矩阵)也可以得到对应的特征向量,为A*ei,而整个过程得到的矩阵大小大大减小,计算量也是大大减小。证明如下:


其中,ei是C’=ΦTΦ的第i个特征向量,vi是C=ΦΦT的第i个特征向量,由证明可以看到,vi=Φei。所以通过求解C’=ΦTΦ的特征值分解得到ei,再左乘Φ就得到C=ΦΦT的特征向量vi了。也就是我们想要的特征脸。

function [] = annotherPCA()
[averFace,oriFace]=averageFace(32,'s','.bmp');
averFace=averFace(:);%转成一列
oriFace=double(oriFace);
for i=1:32oriFace(:,i)=oriFace(:,i)-averFace;
end
%第二步:计算样本的协方差矩阵
covMatrix=oriFace'*oriFace;
%第三步:对协方差矩阵作特征值分解
%获得协方差矩阵的特征值的对角矩阵D
[V,D]=eig(covMatrix);
%取对角矩阵的特征值
featureValue=diag(D);
%对特征值进行从大到小的排序
bigToSmall=sort(featureValue,'descend');
%第四步:取最大的d个特征值所对应的特征向量
%这里通过能量确定d的取值
d=0;%d的初始取值为0
someEnergy=0;%前项的能量
allEnergy=sum(bigToSmall(:));%所有的特征能量
while(someEnergy/allEnergy<0.9)d=d+1;someEnergy=sum(bigToSmall(1:d,:));
end
%寻找特征值对应的特征向量
featureVector=zeros(10000,1);
for i=1:dnowNumber=bigToSmall(i);%从大到小找到此时的值featureVector=[featureVector oriFace*nowNumber];
end
featureVector=featureVector(:,2:d+1);%删掉之前添加的数据
%第五步:将原样本矩阵与投影矩阵相乘即为降维后的数据集
%specialFace=oriFace*featureVector;
%将会生成多张特征脸,这里要将矩阵的每一列重新合成一张照片
for i=1:dname=strcat('32featureFace',num2str(i),'.bmp');pic=featureVector(:,i);picToOri=reshape(pic,100,100);imwrite(picToOri,name);%保存图片
end

问题:
使用两种方法生成的特征脸却不一样?不由地思考到:原本是1000010000的矩阵,应该能够得到10000个特征值和特征向量,但是使用简化的办法的话,生成3232的矩阵,只能得到32个特征值和特征向量,那么能否保证最大特征值保留下来了?在10000个特征值中得到的对应的最大的几个特征向量被保留在了32个特征值对应的特征向量中了嘛?根据生成的特征脸不同,

可以初步断定是没有的。所以我觉得这种办法只能够生成特征脸,但是这个特征脸并不是最大的几个特征值对应的特征向量所生成的,所以这应该得不到最优解。

结果展示

  1. 实验生成的平均脸:根据每一维的特征取平均值生成

    2.平均脸的数据集

    3.界面展示

    4.生成特征脸(用了两种求特征向量的方法,之前的思考中有具体介绍)

基于PCA算法生成平均脸相关推荐

  1. 基于PCA 人脸识别/人脸识别算法/人脸检测程序源码MATLAB ELM+PCA人脸识别 PCA人脸识别matlab代码 基于PCA算法的人脸识别

    1.基于PCA的人脸识别代码 2.MATLAB ELM+PCA人脸识别 2.基于PCA的人脸识别(matlab)(采用PCA算法进行人脸识别,通过抽取人脸的主要成 分,构成特征脸空间,识别时将测试图像 ...

  2. 数据集特征提取_基于PCA算法实现鸢尾花数据集的特征提取任务

    PCA算法的必要性 多变量大数据集无疑会为研究和应用提供丰富的信息,但是许多变量之间可能存在相关性,从而增加了问题分析的复杂性.如果分别对每个指标进行分析,分析往往是孤立的,不能完全利用数据中的信息, ...

  3. 基于雪花算法生成用户id

    8.1 为啥这样做 1.全局唯一性,不会出现重复的id.如果通过id自增来保证id不重复,则该表 无法分表操作例如 服务器A的数据库的user表 数据如下1 小明 男2 小红 女2 张三 男此时 进行 ...

  4. 基于 PCA 的人脸识别系统及人脸姿态分析

    文章目录 1 PCA 1.1 原理 1.2 算法流程 1.2.1 零均值化 1.2.2 计算协方差矩阵 1.2.3 特征值和特征向量 1.2.4 降维得到 K 维特征 1.2.5 PCA 的优缺点 2 ...

  5. 基于PCA与LDA的数据降维实践

    基于PCA与LDA的数据降维实践 描述 数据降维(Dimension Reduction)是降低数据冗余.消除噪音数据的干扰.提取有效特征.提升模型的效率和准确性的有效途径, PCA(主成分分析)和L ...

  6. Matlab实现PCA算法(附上完整仿真源码)

    主成分分析(PCA)是一种常用的数据降维技术,可以将高维数据转化为低维数据,并保留数据的主要特征.在机器学习和数据分析中,PCA被广泛应用于特征提取.数据可视化和模型训练等领域.本文将介绍如何使用Ma ...

  7. 京东智能内容创作算法的演进与实践:基于关键词自动生成摘要

    来源 | 京东智联云开发者 导读:京东商城背后的 AI 技术能力揭秘: 基于关键词自动生成摘要 过去几十年间,人类的计算能力获得了巨大提升:随着数据不断积累,算法日益先进,我们已经步入了人工智能时代. ...

  8. aes子密钥生成c语言_一种基于流密码算法的子密钥生成方法与流程

    本发明涉及一种用于分组加解密算法的子密钥的生成方法. 背景技术: 随着信息技术的发展,信息安全性的问题却愈来愈显得突出,保证信息安全的一个重要技术就是密码学.密码学在信息安全技术中扮演着基础的角色,是 ...

  9. SVPWM仿真和基于DSP28335的PIL(处理器在环) 仿真模型(将matlab仿真算法生成代码在DSP中在线运行返回数据给Matlab)验证算法可行性和实时性

    SVPWM仿真和基于DSP28335的PIL(处理器在环) 仿真模型(将matlab仿真算法生成代码在DSP中在线运行返回数据给Matlab)验证算法可行性和实时性. 对于数字信号处理很有用. ID: ...

  10. ANSYS多孔材料孔隙介质建模教程 基于蒙特卡洛算法Voronoi图生成

    首先通过CAD Voronoi插件建立孔隙的几何模型,该插件是基于蒙特卡洛随机生成算法,进行随机布置控制点,同时具有控制区块尺寸的功能.在CAD中生成相应图形的面域,并将生成的孔隙导出为.sat文件备 ...

最新文章

  1. Udacity机器人软件工程师课程笔记(二十四) - 控制(其二) - PID优化,梯度下降算法,带噪声的PID控制
  2. java创建读取文件_Java实现文件的创建、读取、写入操作-Fun言
  3. android复习第二天------布局
  4. 数据部门如何All In AI
  5. 终极广告拦截者软件——AdGuard
  6. 物联网标识管理系统源码
  7. html 整体架构框架 源码,上 中 下结构网页模板布局框架代码
  8. 关于Jenkins下载代码失败,“Error cloning remote repo ‘origin‘“
  9. Verilog全加器
  10. Linux虚拟机克隆后网络冲突解决办法
  11. sessionid java_java如何获取sessionid
  12. springboot项目多moudle打包到一个jar
  13. 2-管理Audio焦点(Managing Audio Playback)
  14. 平面设计零基础怎么设计出一个完美的名片
  15. 基于Vue移动音乐webapp跨域获取QQ音乐歌单接口
  16. excel怎么设置打印区域_用offset函数设置打印区域(有新增内容时自动扩展)
  17. python机器学习常用模型
  18. EXCEL宏编程纪念
  19. 监控系统架构设计分层
  20. 指定目录下创建二级子目录

热门文章

  1. 如何利用炒股中的L2行情数据功能对比,以及用途数据分析。(附代码)
  2. 2022考研资料每日更新(2021.07.28)
  3. linux 分卷压缩及解压缩
  4. 复合辛普森公式matlab,复合梯形公式、复合辛普森公式 matlab
  5. 1236mysql,MySQL1236错误的恢复
  6. MTK6577+Android启动----pre-loader
  7. redhat红帽官方软件仓库同步方案
  8. 视频文件格式、视频封装格式、视频编码方式
  9. 在线FLV播放器实现方法
  10. exchange创建邮箱组_在 Exchange Server 中创建用户邮箱