变分贝叶斯求解0.01范数稀疏编码问题

参考文献:http://research.microsoft.com/en-us/people/davidwip/tutorials.aspx


虽说公式推导很复杂,用了很多技巧,但最终的算法异常简单,在matlab中只需要几行程序。

m=50;%y的维数
n=100;%x的维数
s=30;%稀疏度
lambda=0.1;%公式中稀疏惩罚项前的系数

Fai=randn(m,n);%随机生成过完备矩阵
x=full(sparse(ones(s,1),randi(n,s,1),randn(s,1),1,n))';%随机生成稀疏矩阵
y=Fai*x+randn(m,1)/100;%加入高斯噪声

fprintf('MAP l1:\n');
clear mu Epsilon z i j;
munorm=0;
W=eye(n);
p=1;
tic;
for i=1:10000
    mu=W*Fai'*((lambda*eye(m)+Fai*W*Fai')\y);
    W=diag(abs(mu));
    if abs(munorm-norm(mu))<1e-12
        break;
    end;
    munorm=norm(mu);
end;
toc;


fprintf('step count:%d\n',i);
xHat1=mu;
fprintf('Final MSE:%f\n',norm(x-xHat1)/norm(x));


fprintf('VB l0.01:\n');
clear mu Epsilon z i j;
munorm=0;
W=eye(n);
p=0.01;
tic;
for i=1:10000
    mu=W*Fai'*((lambda*eye(m)+Fai*W*Fai')\y);
    Epsilon=W-W*Fai'*((lambda*eye(m)+Fai*W*Fai')\Fai*W);
    z=sqrt(mu.^2+diag(Epsilon));
    W=diag(z.^(2-p));
    if abs(munorm-norm(mu))<1e-12
        break;
    end;
    munorm=norm(mu);
end;
toc;


fprintf('step count:%d\n',i);
xHat001=mu;
xHat001(abs(xHat001)<0.001)=0;
fprintf('Final MSE:%f\n',norm(x-xHat001)/norm(x));
figure;
subplot(3,1,1);
stem(x);
ylabel('Original');
subplot(3,1,2);
stem(xHat1);
ylabel('MAP L1');
subplot(3,1,3);
stem(xHat001);
ylabel('VB L0.01');



效率还算可以,不过由于涉及到迭代,用c语言改写应该会更快。

你可能感兴趣的:(matlab,稀疏编码,变分贝叶斯)