稀疏表示中KL1p库的配置及Demo

来源:互联网 发布:决策树算法id3 python 编辑:程序博客网 时间:2024/06/14 08:08

最近打算在研究中尝试稀疏编码。稀疏表示的理论知识这里不具体补充,有兴趣的可以查看下面这篇用稀疏表示做人脸识别的文章,讲得很清楚。
http://blog.csdn.net/xiaoshengforever/article/details/14002843

稀疏表示中的关键是求解L2范数或者L1范数。L2范数的求解很简单,一个公式就搞定了; L1范数的求解就要复杂多了,求解的方式也有很多种。笔者做了实验后发现用L1求解出的结果确实比用L2求解出的结果稀疏多了。
通常求解L1范数都要借助第三方包。网上求解L1的MATLAB包比较多,但是C++包却相对很少,搜索后发现了KL1p这个好东西。

kl1p是一个压缩感知方面的C++库,里面封装了很多压缩感知方法,在稀疏表(SRC)示中主要是借助它来求取l1范数最小化问题。它的官方:http://kl1p.sourceforge.net/home.html 目前的版本是0.4.2

KL1p的配置

  1. 下载
    从上述官网下载KL1p包,不能访问的话可以从这里下载。下载后解压到D:\KL1p-0.4.2目录下。
  2. 编译生成库文件
    在目录D:\KL1p-0.4.2\build\win下用VS2010打开KLab.vcxproj文件进行编译,注意在Debug模式和Release模式下都要进行编译。编译成功后在D:\KL1p-0.4.2\bin\win目录会生成两个库文件,分别是KLab.lib和KLab_d.lib。带_d的库文件表示用于Debug。
    这里写图片描述
  3. 配置VS
    配置主要分为头文件配置和库文件配置。
    配置头文件:新建一个项目,然后点击项目属性,在“配置属性->C/C++->常规”中找到附加包含目录。然后添加如下图所示的几个目录。
    这里写图片描述
    配置库文件: 在属性对话框“配置属性->连接器->常规”中找到“附加库目录”,在其中加入以下条目:D: \KL1p-0.4.2\bin\win;
    这里写图片描述
    然后在属性对话框“配置属性->链接器->输入”的“附加依赖项”中,加入以下条目:
    KLab_d.lib(Release中则用KLab.lib)
    至此,配置已经完成,可以直接编代码测试了!!!
  4. 修改运行时库(可选)
    在完成前面三部的配置后,有可能编译代码时出现链接错误,编译不成功的情况。此时还需要修改一下运行时库。在属性对话框中“配置属性->C/C++ ->代码生成”中找到“运行库“,选择“多线程调试 (/MTd)”
    这里写图片描述

说明:从KL1p的配置可以看到,在KL1p在求解矩阵时实际上是通过Armadillo库来实现的,关于Armadillo库的矩阵操作手册可在这个网站查询:
http://arma.sourceforge.net/docs.html

最后给一个完整Demo程序

//KL1p Demo#include"armadillo"#include <KL1pInclude.h>#include <KL1p.h>using namespace std;using namespace kl1p;using namespace arma;int main(){    arma::mat featureMat;   //839*156    featureMat.load("LBPPCANorFeatures.csv",csv_ascii);      arma::mat x0;          //1*156    x0.load("test.csv",csv_ascii);    //在读取的两个csv文件中,一个样本的特征占一行,所以需要取转置    arma::mat A1 = featureMat.t();     arma::mat y = x0.t();    std::cout<<"Start of KL1p compressed-sensing example."<<std::endl;    std::cout<<"Try to determine a sparse vector x "<<std::endl;    std::cout<<"from an underdetermined set of linear measurements y=A*x, "<<std::endl;    std::cout<<"where A is a random gaussian i.i.d sensing matrix."<<std::endl;    klab::UInt32 n = A1.n_rows;     // Size of the original signal x0.    klab::DoubleReal alpha = 0.5;   // Ratio of the cs-measurements.    klab::DoubleReal rho = 0.1;     // Ratio of the sparsity of the signal x0.    klab::UInt32 m = klab::UInt32(alpha*n); // Number of cs-measurements.    klab::UInt32 k = klab::UInt32(rho*n);   // Sparsity of the signal x0 (number of non-zero elements).    klab::UInt64 seed = 0;                  // Seed used for random number generation (0 if regenerate random numbers on each launch).    bool bWrite = true;                 // Write signals to files ?    // Display signal informations.    std::cout<<"=============================="<<std::endl;    std::cout<<"N="<<n<<" (signal size)"<<std::endl;    std::cout<<"M="<<m<<"="<<std::setprecision(5)<<(alpha*100.0)<<"% (number of measurements)"<<std::endl;    std::cout<<"K="<<k<<"="<<std::setprecision(5)<<(rho*100.0)<<"% (signal sparsity)"<<std::endl;    std::cout<<"=============================="<<std::endl;    kl1p::TMatrixOperator<klab::DoubleReal> * matrix = new kl1p::TMatrixOperator<klab::DoubleReal>(A1);    klab::TSmartPointer<kl1p::TOperator<klab::DoubleReal, klab::DoubleReal> > * A2 =new klab::TSmartPointer<kl1p::TOperator<klab::DoubleReal, klab::DoubleReal> >(matrix);    klab::TSmartPointer<kl1p::TOperator<klab::DoubleReal, klab::DoubleReal> >  A = *A2;    klab::DoubleReal tolerance = 1e-3;  // Tolerance of the solution.    arma::Col<klab::DoubleReal> x;      // Will contain the solution of the reconstruction.    klab::KTimer timer;    // Compute Basis-Pursuit.    std::cout<<"[BasisPursuit] Start."<<std::endl;    timer.start();    kl1p::TBasisPursuitSolver<klab::DoubleReal> bp(tolerance);    bp.solve(y, A, x);    timer.stop();    std::cout<<"[BasisPursuit] Done - SNR="<<std::setprecision(5)<<klab::SNR(x, x0)<<" - "        <<"Time="<<klab::UInt32(timer.durationInMilliseconds())<<"ms"<<" - "        <<"Iterations="<<bp.iterations()<<std::endl;    if(bWrite)        x.save("BasisPursuit-Signal.csv",csv_ascii);  // Write solution to a file.    // Compute OMP.    std::cout<<"------------------------------"<<std::endl;    std::cout<<"[OMP] Start."<<std::endl;    timer.start();    kl1p::TOMPSolver<klab::DoubleReal> omp(tolerance);    omp.solve(y, A, k, x);    timer.stop();    std::cout<<"[OMP] Done - SNR="<<std::setprecision(5)<<klab::SNR(x, x0)<<" - "        <<"Time="<<klab::UInt32(timer.durationInMilliseconds())<<"ms"<<" - "        <<"Iterations="<<omp.iterations()<<std::endl;    if(bWrite)        x.save("OMP-Signal.csv",csv_ascii);  // Write solution to a file.    // Compute ROMP.    std::cout<<"------------------------------"<<std::endl;    std::cout<<"[ROMP] Start."<<std::endl;    timer.start();    kl1p::TROMPSolver<klab::DoubleReal> romp(tolerance);    romp.solve(y, A, k, x);    timer.stop();    std::cout<<"[ROMP] Done - SNR="<<std::setprecision(5)<<klab::SNR(x, x0)<<" - "        <<"Time="<<klab::UInt32(timer.durationInMilliseconds())<<"ms"<<" - "        <<"Iterations="<<romp.iterations()<<std::endl;    if(bWrite)        x.save("ROMP-Signal.csv",csv_ascii);  // Write solution to a file.    // Compute CoSaMP.    std::cout<<"------------------------------"<<std::endl;    std::cout<<"[CoSaMP] Start."<<std::endl;    timer.start();    kl1p::TCoSaMPSolver<klab::DoubleReal> cosamp(tolerance);    cosamp.solve(y, A, k, x);    timer.stop();    std::cout<<"[CoSaMP] Done - SNR="<<std::setprecision(5)<<klab::SNR(x, x0)<<" - "        <<"Time="<<klab::UInt32(timer.durationInMilliseconds())<<"ms"<<" - "        <<"Iterations="<<cosamp.iterations()<<std::endl;    if(bWrite)        x.save("CoSaMP-Signal.csv",csv_ascii);  // Write solution to a file.    // Compute Subspace-Pursuit.    std::cout<<"------------------------------"<<std::endl;    std::cout<<"[SubspacePursuit] Start."<<std::endl;    timer.start();    kl1p::TSubspacePursuitSolver<klab::DoubleReal> sp(tolerance);    sp.solve(y, A, k, x);    timer.stop();    std::cout<<"[SubspacePursuit] Done - SNR="<<std::setprecision(5)<<klab::SNR(x, x0)<<" - "        <<"Time="<<klab::UInt32(timer.durationInMilliseconds())<<"ms"<<" - "        <<"Iterations="<<sp.iterations()<<std::endl;    if(bWrite)        x.save("SubspacePursuit-Signal.csv",csv_ascii);     // Write solution to a file.    // Compute SL0.    std::cout<<"------------------------------"<<std::endl;    std::cout<<"[SL0] Start."<<std::endl;    timer.start();    kl1p::TSL0Solver<klab::DoubleReal> sl0(tolerance);    sl0.solve(y, A, x);    timer.stop();    std::cout<<"[SL0] Done - SNR="<<std::setprecision(5)<<klab::SNR(x, x0)<<" - "        <<"Time="<<klab::UInt32(timer.durationInMilliseconds())<<"ms"<<" - "        <<"Iterations="<<sl0.iterations()<<std::endl;    if(bWrite)        x.save("SL0-Signal.csv",csv_ascii); // Write solution to a file.    // Compute AMP.    std::cout<<"------------------------------"<<std::endl;    std::cout<<"[AMP] Start."<<std::endl;    timer.start();    kl1p::TAMPSolver<klab::DoubleReal> amp(tolerance);    amp.solve(y, A, x);    timer.stop();    std::cout<<"[AMP] Done - SNR="<<std::setprecision(5)<<klab::SNR(x, x0)<<" - "        <<"Time="<<klab::UInt32(timer.durationInMilliseconds())<<"ms"<<" - "        <<"Iterations="<<amp.iterations()<<std::endl;    if(bWrite)        x.save("AMP-Signal.csv",csv_ascii); // Write solution to a file    system("pause");    return 0;}

程序的执行结果如下:
这里写图片描述
从结果可以看到,不同的算法所需的求解时间不同。
下面详细看看不同算法求解出的结果。
BasicPursuit的计算结果:
Basis Pursuit
OMP的求解结果:
这里写图片描述
ROMP的求解结果:
这里写图片描述
CoSaMP的求解结果:
这里写图片描述
SubspacePursuit的求解结果:
这里写图片描述
SL0的求解结果:
这里写图片描述
AMP的求解结果:
这里写图片描述

从以上结果可以看到,不同的算法求解出的结果稀疏度有较大的差别。

完成Demo程序及数据下载地址:
http://download.csdn.net/detail/computerme/9309285

Reference:
http://blog.csdn.net/jianjian1992/article/details/49387477 例子讲解
http://blog.csdn.net/u013088062/article/details/44566667 配置过程
http://blog.csdn.net/xiaoshengforever/article/details/14002843 人脸识别

1 0
原创粉丝点击