基于PCA算法生成平均脸
在智能算法專題設計課中,我們學習了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了。也就是我們想要的特征臉。
問題:
使用兩種方法生成的特征臉卻不一樣?不由地思考到:原本是1000010000的矩陣,應該能夠得到10000個特征值和特征向量,但是使用簡化的辦法的話,生成3232的矩陣,只能得到32個特征值和特征向量,那么能否保證最大特征值保留下來了?在10000個特征值中得到的對應的最大的幾個特征向量被保留在了32個特征值對應的特征向量中了嘛?根據生成的特征臉不同,
可以初步斷定是沒有的。所以我覺得這種辦法只能夠生成特征臉,但是這個特征臉并不是最大的幾個特征值對應的特征向量所生成的,所以這應該得不到最優解。
結果展示
2.平均臉的數據集
3.界面展示
4.生成特征臉(用了兩種求特征向量的方法,之前的思考中有具體介紹)
總結
以上是生活随笔為你收集整理的基于PCA算法生成平均脸的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ElasticSearch: 使用Jav
- 下一篇: vue根据文件名后缀区分