本文简单介绍了稀疏表示理论,然后从人脸识别领域的运用给出了代码示例。
稀疏表示理论
理论
为了简单说明,采用一维信号进行讲解。一维离散信号X是 RN 上的 维的列向量,记为 X=[x1,x2,x3.....xn] 。如果信号中非零值个数K远小于N,则该信号是稀疏信号。如果信号不稀疏的话,则在 RN 空间中寻找一组标准正交基: ψ=[ψ1,ψ2,ψ3.....ψn] 。这样信号X就可以表示为:
x=∑i=1Nψiθi=ψθ
对于稀疏表示现在发展了两个方向:
1. 早期的傅里叶变换、加窗傅里叶变换(也称作Gabor变换)、小波变换、离散余弦变换(DCT:Discrete Cosine Transform)等
2. 近年发展的完备字典和过完备字典。字典主要通过利用相似的样本训练得到。常用的算法有K均值算法、K-SVD算法、监督学方法、最大似然法等。
稀疏表示求解
稀疏表示求解是一个解欠定方程的问题,为了解决上面问题,不同的次最优算法被提出,包括贪婪搜索算法(OMP),基追踪算法(BP),梯度投影稀疏重构算法(GPSR),IST、TwIST等。算法可以精确的求解稀疏表示问题。但是随着维数的增加,计算所需的时间会显著增加。
稀疏表示用于人脸识别
理论
假设训练图像包含K类目标,每类有
nk
幅大小为
w∗h
的图像。将
nk
幅训练样本排列成矩阵
Dk=[dk,1,dk,2,dk,3.....dk,nk]∈Rm∗nk
其中 dk,nk 表示第 k 类图像中第
其中系数 αk,j∈R,j=1...nk 。因为测试样本的类别是未知的,具有所有类训练样本的矩阵为:
Dk=[D1,D1...Dk]=[dk,1,dk,2,dk,3.....dk,nk]∈Rm∗nk
则 x∈R 可以写成D中原子的线性组合:
X=D∗α
其中 α=[0,...0;αk,1...αk,nk;0,...0]T∈Rn ,除了与第K类对应的元素不为零,其余元素都设置为0的系数向量。
在人脸识别中,上面那的问题—般是欠定问题,所以它的解是不唯一的,最优解可以通过下面 l0 问题得到
α^=min||α||0 s.t.x=D∗α
其中 ||α||0 表示向量 α 的 l0 范数,即向量 α 中非零元素的数目。
一般情况下,求解 l0 范数优化问题是NP-难问题。然而,在某些条件下, 转化为下面的凸问题:
α^=min||α||1 s.t.x=D∗α
由于是一个凸优化问题,很多算法可以进行求解,例如迭代阈值算法,本原对偶算法,梯度投影稀疏重构算法(GPSR)。然后通过求解得到每个X的稀疏表示系数。得到的结果 α^ 是一个稀疏向量,它包含了测试图像的一些重要信息,因此可以通过稀疏系数 α^ 进行识别。对每类K定义 δk(α) 来选择中只有与第K类对应的元素不为零,其余都为零的一个向量。测试样本 Xt 可以通过 δk(α) 表示:
x^=D∗δk(α)
然后得到 Xt 与 x^ 之间的残差
rk(xt)=||Xt−D∗δk(α)||2
最后测试样本根据最小残差来确定最终的目标类。
代码
clc;
clear all;
tic
%%%%%%%%%%%%导入数据%%%%%%%%%%%%%%%%%%%%%
load HMAX_Alejandro_Toledo_39
load HMAX_Alvaro_Uribe_35
load HMAX_Amelie_Mauresmo_21
load HMAX_Andre_Agassi_36
load HMAX_Angelina_Jolie_20
load HMAX_Ariel_Sharon_77
load HMAX_Arnold_Schwarzenegger_42
load HMAX_Atal_Bihari_Vajpayee_24
load HMAX_Bill_Clinton_29
load HMAX_Carlos_Menem_21
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Y1=Alejandro_Toledo_39;
Y2=Alvaro_Uribe_35;
Y3=Amelie_Mauresmo_21;
Y4=Andre_Agassi_36;
Y5=Angelina_Jolie_20;
Y6=Ariel_Sharon_77;
Y7=Arnold_Schwarzenegger_42;
Y8=Atal_Bihari_Vajpayee_24;
Y9=Bill_Clinton_29;
Y10=Carlos_Menem_21;
%%%%%%%%%%%%%%%%%%生成字典%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
class=10;
n=10;%每个类选取10个训练样本
t1=randperm(size(Y1,1));
t1=t1(1:n)';%只取出前10个.
t2=randperm(size(Y2,1));
t2=t2(1:n)';%只取出前10个.
t3=randperm(size(Y3,1));
t3=t3(1:n)';%只取出前100个.
t4=randperm(size(Y4,1));
t4=t4(1:n)';%只取出前100个.
t5=randperm(size(Y5,1));
t5=t5(1:n)';%只取出前10个.
t6=randperm(size(Y6,1));
t6=t6(1:n)';%只取出前100个.
t7=randperm(size(Y7,1));
t7=t7(1:n)';%只取出前100个.
t8=randperm(size(Y8,1));
t8=t8(1:n)';%只取出前10个.
t9=randperm(size(Y9,1));
t9=t9(1:n)';%只取出前10个.
t10=randperm(size(Y10,1));
t10=t10(1:n)';%只取出前10个.
for i=1:n
train1(i,:)=Y1(t1(i,1),:);
Y1(t1(i,1),:)=0;
train2(i,:)=Y2(t2(i,1),:);
Y2(t2(i,1),:)=0;
train3(i,:)=Y3(t3(i,1),:);
Y3(t3(i,1),:)=0;
train4(i,:)=Y4(t4(i,1),:);
Y4(t4(i,1),:)=0;
train5(i,:)=Y5(t5(i,1),:);
Y5(t5(i,1),:)=0;
train6(i,:)=Y6(t6(i,1),:);
Y6(t6(i,1),:)=0;
train7(i,:)=Y7(t7(i,1),:);
Y7(t7(i,1),:)=0;
train8(i,:)=Y8(t8(i,1),:);
Y8(t8(i,1),:)=0;
train9(i,:)=Y9(t9(i,1),:);
Y9(t9(i,1),:)=0;
train10(i,:)=Y10(t10(i,1),:);
Y10(t10(i,1),:)=0;
end
Dictionary=[train1' train2' train3' train4' train5' train6' train7' train8' train9' train10'];%训练样本数据,即字典
test1=Y1;test2=Y2;test3=Y3;test4=Y4;test5=Y5;test6=Y6;test7=Y7;test8=Y8;test9=Y9;test10=Y10;
test1(all(test1==0,2),:)=[];%第1类数据
test2(all(test2==0,2),:)=[];%第2类数据
test3(all(test3==0,2),:)=[];%第3类数据
test4(all(test4==0,2),:)=[];%第4类数据
test5(all(test5==0,2),:)=[];%第5类数据
test6(all(test6==0,2),:)=[];%第6类数据
test7(all(test7==0,2),:)=[];%第7类数据
test8(all(test8==0,2),:)=[];%第8类数据
test9(all(test9==0,2),:)=[];%第9类数据
test10(all(test10==0,2),:)=[];%第10类数据
t=[test1' test2' test3' test4' test5' test6' test7' test8' test9' test10' ]'; %%测试样本集合
tlb1=1*ones(size(test1,1),1);
tlb2=2*ones(size(test2,1),1);
tlb3=3*ones(size(test3,1),1);
tlb4=4*ones(size(test4,1),1);
tlb5=5*ones(size(test5,1),1);
tlb6=6*ones(size(test6,1),1);
tlb7=7*ones(size(test7,1),1);
tlb8=8*ones(size(test8,1),1);
tlb9=9*ones(size(test9,1),1);
tlb10=10*ones(size(test10,1),1);
tlb=[tlb1' tlb2' tlb3' tlb4' tlb5' tlb6' tlb7' tlb8' tlb9' tlb10']';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
TotalType=10;
[row,col]=size(t);
result=zeros(row,1);
for i=1:row
fprintf('正在处理第%d张测试样本\n',i);
Data=t(i,:)';
Type=tlb(i,1);
alpha = getAlpha(Data,Dictionary);
result(i,1)=DecideType(Data,Type,Dictionary,alpha,TotalType);
end
rate=(sum(result(:)==1))/row;
fprintf('识别率为:%f\n',rate);
完整代码下载【[下载链接]】
说明:先运行里面的test_lean.m得到下一步需要用到的矩阵。
再运行my.m计算识别率。
参考文献
[1]魏丹. 基于稀疏表示和特征选择的人脸识别方法研究[D]. 湖南大学, 2012.
[2]张慕凡. 基于稀疏表示的人脸识别的应用研究[D]. 南京邮电大学, 2014.