基于PCA算法生成平均脸
在智能算法專題設(shè)計(jì)課中,我們學(xué)習(xí)了PCA算法,并學(xué)會(huì)利用PCA算法生成平均臉,下面是步驟以及我的一些思考
了解PCA算法
PCA算法本質(zhì)上是一種降維算法。**PCA的算法思路:**數(shù)據(jù)從原來的坐標(biāo)系轉(zhuǎn)換到新的坐標(biāo)系,由數(shù)據(jù)本身決定。轉(zhuǎn)換坐標(biāo)系時(shí),以方差最大的方向作為坐標(biāo)軸方向,因?yàn)閿?shù)據(jù)的最大方差給出了數(shù)據(jù)的最重要的信息。第一個(gè)新坐標(biāo)軸選擇的是原始數(shù)據(jù)中方差最大的方向,第二個(gè)新坐標(biāo)軸選擇的是與第一個(gè)新坐標(biāo)軸正交且方差次大的方向。重復(fù)該過程,重復(fù)次數(shù)為原始數(shù)據(jù)的特征維數(shù)。
**PCA算法的要點(diǎn):**通過這種方式獲得的新的坐標(biāo)系,我們發(fā)現(xiàn),大部分方差都包含在前面幾個(gè)坐標(biāo)軸中,后面的坐標(biāo)軸所含的方差幾乎為0。于是,我們可以忽略余下的坐標(biāo)軸,只保留前面的幾個(gè)含有絕大部分方差的坐標(biāo)軸。事實(shí)上,這樣也就相當(dāng)于只保留包含絕大部分方差的維度特征,而忽略包含方差幾乎為0的特征維度,也就實(shí)現(xiàn)了對(duì)數(shù)據(jù)特征的降維處理。
生成特征臉的步驟
輸入:訓(xùn)練樣本集 D=x(1),x(2),…,x(m)D=x(1),x(2),…,x(m) ,低維空間維數(shù) d′d′ ;
?過程:.
??第一步:對(duì)所有樣本進(jìn)行中心化(去均值操作): x(i)j←x(i)j?1m∑mi=1x(i)jxj(i)←xj(i)?1m∑i=1mxj(i) ;
??第二步:計(jì)算樣本的協(xié)方差矩陣 XXTXXT ;
??第三步:?對(duì)協(xié)方差矩陣 XXTXXT 做特征值分解 ;
?第四步:取最大特征值對(duì)應(yīng)的特征向量(這里可以通過能量進(jìn)行選擇)
?第五步:最終得到的特征向量便是特征臉
代碼逐步分析
(1)對(duì)樣本進(jìn)行中心化:
這里包括讀入所給的32張圖片,將每張圖片抽拉成一列(可以用a=a(:)的辦法),averageFace為自己寫的定義平均臉的函數(shù)。同時(shí)需要注意將原始臉數(shù)據(jù)轉(zhuǎn)換一下數(shù)據(jù)類型,否則進(jìn)行中心化相減時(shí)將會(huì)因?yàn)閿?shù)據(jù)類型不一致而報(bào)錯(cuò)。
[averFace,oriFace]=averageFace(32,'s','.bmp'); averFace=averFace(:);%轉(zhuǎn)成一列 oriFace=double(oriFace); for i=1:32oriFace(:,i)=oriFace(:,i)-averFace; end 計(jì)算平均臉的函數(shù): function [aver,originalFace] = averageFace(num,beforeName,endName) %計(jì)算平均臉的函數(shù) %輸入:數(shù)據(jù)里的所有的臉,包括圖片的張數(shù),圖片的前綴名,圖片的后綴名 %輸出:平均臉、原始的所有圖片構(gòu)成的矩陣、 %首先,構(gòu)造一個(gè)矩陣,用于存放每個(gè)圖片后來構(gòu)成的圖像 aver=ones(10000,1); for i=1:numface=imread(strcat(beforeName,num2str(i),endName));%讀入圖片數(shù)據(jù)%每讀一張,就將它轉(zhuǎn)化為列向量column=face(:);%把轉(zhuǎn)化后的列向量添加到一個(gè)矩陣中aver=[aver column]; end %刪除矩陣的第一列:為了構(gòu)造矩陣而添加的一列 aver(:,1)=[]; originalFace=aver; %計(jì)算該矩陣每一行的平均值,形成一列平均值的向量 aver=mean(aver,2); %將平均值的向量還原成矩陣,即為平均臉,返回平均臉 aver=reshape(aver,100,100); end(2)計(jì)算樣本的協(xié)方差矩陣:
這里是(10000,32)(3210000),所以得到的協(xié)方差矩陣為10000*10000,比較大。
%第二步:計(jì)算樣本的協(xié)方差矩陣 covMatrix=oriFace*oriFace';(3)計(jì)算樣本的特征值和特征向量:
在matlab中可以使用函數(shù)eig得到協(xié)方差矩陣的特殊值,由于協(xié)方差矩陣比較大,所以計(jì)算過程十分耗時(shí),下面有談到另一種計(jì)算特征向量和特征值的辦法。
%第三步:對(duì)協(xié)方差矩陣作特征值分解 %獲得協(xié)方差矩陣的特征值的對(duì)角矩陣D [V,D]=eig(covMatrix); %取對(duì)角矩陣的特征值 featureValue=diag(D);(4)根據(jù)能量找到最大的幾個(gè)特征值,并找到最大特征值對(duì)應(yīng)的特征向量。
%對(duì)特征值進(jìn)行從大到小的排序 bigToSmall=sort(featureValue,'descend'); %第四步:取最大的d個(gè)特征值所對(duì)應(yīng)的特征向量 %這里通過能量確定d的取值 d=0;%d的初始取值為0 someEnergy=0;%前項(xiàng)的能量 allEnergy=sum(bigToSmall(:));%所有的特征能量 while(someEnergy/allEnergy<0.9)d=d+1;someEnergy=sum(bigToSmall(1:d,:)); end %尋找特征值對(duì)應(yīng)的特征向量 featureVector=zeros(10000,1); for i=1:dnowNumber=bigToSmall(i);%從大到小找到此時(shí)的值[row,column]=find(D==nowNumber);%在原來的特征值數(shù)組中定位findVector=V(:,column);%根據(jù)原來的特征值數(shù)組位置找到其對(duì)應(yīng)的特征向量featureVector=[featureVector findVector]; end featureVector=featureVector(:,2:d+1);%刪掉之前添加的數(shù)據(jù)(5)最終找到的特征向量即為特征臉,只需要使用reshape函數(shù)轉(zhuǎn)成原始圖片大小即可。
matlab整體實(shí)現(xiàn)代碼
function [] = PCACalculator() %PCA算法計(jì)算出特征臉 %輸入:訓(xùn)練樣本集,低維空間維度:d %輸出:特征臉 %第一步:對(duì)所有樣本進(jìn)行中心化 %得到平均臉函數(shù)中,獲得的原始所有臉矩陣+平均臉矩陣 [averFace,oriFace]=averageFace(32,'s','.bmp'); averFace=averFace(:);%轉(zhuǎn)成一列 oriFace=double(oriFace); for i=1:32oriFace(:,i)=oriFace(:,i)-averFace; end %第二步:計(jì)算樣本的協(xié)方差矩陣 covMatrix=oriFace*oriFace'; %第三步:對(duì)協(xié)方差矩陣作特征值分解 %獲得協(xié)方差矩陣的特征值的對(duì)角矩陣D [V,D]=eig(covMatrix); %取對(duì)角矩陣的特征值 featureValue=diag(D); %對(duì)特征值進(jìn)行從大到小的排序 bigToSmall=sort(featureValue,'descend'); %第四步:取最大的d個(gè)特征值所對(duì)應(yīng)的特征向量 %這里通過能量確定d的取值 d=0;%d的初始取值為0 someEnergy=0;%前項(xiàng)的能量 allEnergy=sum(bigToSmall(:));%所有的特征能量 while(someEnergy/allEnergy<0.9)d=d+1;someEnergy=sum(bigToSmall(1:d,:)); end %尋找特征值對(duì)應(yīng)的特征向量 featureVector=zeros(10000,1); for i=1:dnowNumber=bigToSmall(i);%從大到小找到此時(shí)的值[row,column]=find(D==nowNumber);%在原來的特征值數(shù)組中定位findVector=V(:,column);%根據(jù)原來的特征值數(shù)組位置找到其對(duì)應(yīng)的特征向量featureVector=[featureVector findVector]; end featureVector=featureVector(:,2:d+1);%刪掉之前添加的數(shù)據(jù) %第五步:將原樣本矩陣與投影矩陣相乘即為降維后的數(shù)據(jù)集 %specialFace=oriFace*featureVector; %將會(huì)生成多張?zhí)卣髂?#xff0c;這里要將矩陣的每一列重新合成一張照片 %由于生成時(shí)間慢,這里可以把圖片保存下來 for i=1:dname=strcat('featureFace',num2str(i),'.bmp');pic=featureVector(:,i);picToOri=reshape(pic,100,100);imwrite(picToOri,name);%保存圖片 end end關(guān)于PCA算法中求特征向量的思考
找尋簡單的求特征向量的方法:
在PCA算法的過程中,其中有一個(gè)步驟是生成樣本的協(xié)方差矩陣,如果采用原始方法直接生成它的協(xié)方差矩陣的話,那么計(jì)算量將非常大,我在這里測(cè)試了一下,改改需要十多分鐘到二十分鐘左右。而能否有簡單的辦法呢?
在這里涉及到數(shù)學(xué)上的轉(zhuǎn)化:可以通過其他辦法得到原始協(xié)方差矩陣生成的特征向量。原始樣本協(xié)方差矩陣為C=AA’(此實(shí)驗(yàn)中將生成1000010000的矩陣),而用C=A’A(此實(shí)驗(yàn)中將生成3232的矩陣)也可以得到對(duì)應(yīng)的特征向量,為A*ei,而整個(gè)過程得到的矩陣大小大大減小,計(jì)算量也是大大減小。證明如下:
其中,ei是C’=ΦTΦ的第i個(gè)特征向量,vi是C=ΦΦT的第i個(gè)特征向量,由證明可以看到,vi=Φei。所以通過求解C’=ΦTΦ的特征值分解得到ei,再左乘Φ就得到C=ΦΦT的特征向量vi了。也就是我們想要的特征臉。
問題:
使用兩種方法生成的特征臉卻不一樣?不由地思考到:原本是1000010000的矩陣,應(yīng)該能夠得到10000個(gè)特征值和特征向量,但是使用簡化的辦法的話,生成3232的矩陣,只能得到32個(gè)特征值和特征向量,那么能否保證最大特征值保留下來了?在10000個(gè)特征值中得到的對(duì)應(yīng)的最大的幾個(gè)特征向量被保留在了32個(gè)特征值對(duì)應(yīng)的特征向量中了嘛?根據(jù)生成的特征臉不同,
可以初步斷定是沒有的。所以我覺得這種辦法只能夠生成特征臉,但是這個(gè)特征臉并不是最大的幾個(gè)特征值對(duì)應(yīng)的特征向量所生成的,所以這應(yīng)該得不到最優(yōu)解。
結(jié)果展示
2.平均臉的數(shù)據(jù)集
3.界面展示
4.生成特征臉(用了兩種求特征向量的方法,之前的思考中有具體介紹)
總結(jié)
以上是生活随笔為你收集整理的基于PCA算法生成平均脸的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ElasticSearch: 使用Jav
- 下一篇: 《开源安全运维平台-OSSIM最佳实践》