参考文献: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语言改写应该会更快。