稀疏表示(SRC)

基于表示的分类方法(representation based classification method, RBCM)研究较多的就是John Wright等在2009年提出的稀疏表示分类(sparse representation based classification, SRC)方法了,Google已经有3778次引用了。
   Wright J, Yang A Y, Ganesh A, et al. Robust face recognition via sparse representation. PAMI, 2009, 31(2): 210-227. 

标准的SRC目标函数为:

 

当然还有其它形式,比如考虑小的噪声影响:

 

或者大的噪声或遮挡:

 

其中    

SRC相比于传统方法取得了较好的识别效果,尤其当样本受到随机像素污损(random pixel corruption)或者有遮挡(random block occlusion, wearing sunglasses or scarves)时,SRC也能准确识别。

然而SRC一个缺点就是求解1范数比较耗时,尤其当训练样本数目比较多或者求解扩展的SRC时,即处理样本受到随机像素污损或者遮挡时,计算时间明显增加。一个改进的方法就是把1范数换成2范数求解,即

 

上述目标函数对求导并令其为零,可以得到

,这个矩阵对所有的测试样本保持不变(独立于具体的测试样本),可以事先计算好。这个就是香港理工张磊组提出的协同表示分类(collaborative representation based classification, CRC)了。
   Zhang D, Yang M, Feng X. Sparse representation or collaborative representation: Which helps face recognition?[C]//ICCV, 2011: 471-478.

之前主要复现了CRC的代码,这几天看了下面这篇文章:

Shi Q, Eriksson A, Van Den Hengel A, et al. Is face recognition really a compressive sensing problem?[C]//CVPR, 2011: 553-560.

这篇文章是比较早提出用2范数替换1范数的,CRC应该是在这个基础上提出的。这篇文章的方法简单称为L2方法。

L2方法的目标函数为:

 

通过最小二乘估计,可以得到表示系数

 

如果对A进行QR分解,Q为正交矩阵,R为上三角矩阵,即

 

 

那么

 

这儿的对所有的测试样本也保持不变。

实现起来应该也比较简单,当和作者提供的代码比较时,发现自己复现的计算时间有点长,计算时间是作者提供的2.5倍左右。

仔细检查了一下,作者在重构每类样本时,使用了稀疏矩阵,即MATLABsparse命令,这样一方面存储空间少了,同时计算速度也加快了。

实验在Extended Yale B数据库上进行,图片是192*168的,38个人,每人取58幅,随机选择29幅训练,其余29幅测试。样本没有进行降维。

自己复现的和作者提供的代码识别率一样,不过作者的代码耗时96.322秒,我的有256.30秒。实现算法是一方面,算法的优化也比较重要。

    主函数(EYaleB.mat下载http://pan.baidu.com/s/1i3CEVad

clear all

clc

close all

 

load EYaleB

tic

[Q,R]=qr(train_data,0);%训练样本QR分解

R=pinv(R);

P = R*Q';%得到矩阵P,对所有的测试样本都一样

Coeff=P*test_data;%所有测试样本的表示系数

 

%作者提供,构造sparse矩阵加快计算速度

accuracy=computaccuracy(train_data,train_label,test_data,test_label,Coeff);

 

%自己复现,每类循环计算残差,速度相对慢一些

% [accuracy,xp,r]=computaccuracy1(train_data,train_label,test_data,test_label,Coeff);

fprintf(2,'识别率为:%g\n\n',accuracy);

toc


    computaccuracy.m

function accuracy=computaccuracy(train_data,train_label,test_data,test_label,Coeff)

ClassNum=length(unique(train_label));%样本类别数

test_tol=size(test_data,2);%测试样本总数

train_tol=size(train_data,2);%训练样本总数

 

h = waitbar(0,'Please wait...');

pre_label=zeros(1,test_tol);%预定义的测试样本标签向量

for i=1:test_tol

    %取出第i个测试样本数据及其表示系数

    x=Coeff(:,i);

    y=test_data(:,i);

    

    %构造sparse矩阵,大小为train_tol*ClassNum,最多有length(x)个非零值

    W=sparse([],[],[],train_tol,ClassNum,length(x));

    %得到每类对应的系数

    for j=1:ClassNum

        ind=(j==train_label);

        W(ind,j)=x(ind);

    end

    %计算测试样本和每类重构样本之间的残差

    temp=train_data*W-repmat(y,1,ClassNum);

    residual=sqrt(sum(temp.^2));

    

    %把测试样本分在最小残差对应的类别中

    [~,index]=min(residual);

    pre_label(i)=index;

    % computations take place here

    per = i / test_tol;

    waitbar(per, h ,sprintf('%2.0f%%',per*100))

end

close(h)

%计算正确识别率

accuracy=sum(pre_label==test_label)/test_tol;


    computaccuracy1.m

function [accuracy,xp,r]=computaccuracy1(train_norm,train_label,test_norm,test_label,Coeff)

test_tol=size(test_norm,2);

ClassNum=length(unique(train_label));

 

h = waitbar(0,'Please wait...');

pre_label=zeros(1,test_tol);

for i=1:test_tol

    y=test_norm(:,i);

    xp=Coeff(:,i);

    r=zeros(1,ClassNum);

    for j=1:ClassNum

        ind=(j==train_label);

        r(j)=norm(y-train_norm(:,ind)*xp(ind,:));

    end

    [~,index]=min(r);

    pre_label(i)=index;

    % computations take place here

    per = i / test_tol;

    waitbar(per, h ,sprintf('%2.0f%%',per*100))

end

close(h)

accuracy=sum(pre_label==test_label)/test_tol;  

 


©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页