Robust PCA Low-rank(附matalb 代码)

最近在看的论文中,包括人脸识别,以及深度神经网络模型压缩等论文中,都会有low-rank(低秩),低秩稀疏分解等解决方法,感觉关于low-rank的研究还挺火的,这个问题和Robust PCA问题很像,都需要解决一下问题:
1
在此之前,我需要先把一些资料的链接放出来,这些资料很有用。
Robust PCA 原理:原理1
原理2
Robust PCA matlab code:code
这个code里面有很多有趣的例子
包括:


视频分解:将视频中的前景与背景分离。(我试了下,代码可以跑起来)
修复:通过低秩表示学习恢复损坏的图像。
玩具数据示例:小玩具矩阵分解成低秩和稀疏分量。


原理里讲了很多范数的优化问题,我觉得需要认真看一下,最好自己推导一下,里面有详细的推导过程,还有软阈值函数等的推导,在Robust PCA求解问题中,这些会用到。(这两篇原理看懂了,我觉得基本可以了)
在文章里要讲的求解算法是:交替方向法(ADM)
算法更新步骤如下:
2
注意 D1/μk,Sλ/μk 都是阈值函数,在原理中有详细的推导,你可以画出函数长什么模样。
下面是matlab code,我设计了一个低秩+稀疏矩阵测试了一下:

function [L, S] = RobustPCA(X, lambda, mu, tol, max_iter)
    % - X is a data matrix (of the size N x M) to be decomposed
    %   X can also contain NaN's for unobserved values
    % - lambda - regularization parameter, default = 1/sqrt(max(N,M))
    % - mu - the augmented lagrangian parameter, default = 10*lambda
    % - tol - reconstruction error tolerance, default = 1e-6
    % - max_iter - maximum number of iterations, default = 1000

    [M, N] = size(X);
    unobserved = isnan(X);
    %在使用Matlab做仿真的时候难免会出现数据不是数字的情况,就是NaN的情况,这些数据是不能使用的,用isnan函数解决。
    %tf=isnan(A):返回一个与A相同维数的数组,若A的元素为NaN(非数值),在对应位置上返回逻辑1(真),否则返回逻辑0(假)。
    %对虚数z,如果z的实部或虚部都是NaN,那么isnan函数返回逻辑1,如果实部和虚部都是inf,则返回逻辑0。
    X(unobserved) = 0;
    normX = norm(X, 'fro');%n=norm(A),返回A的最大奇异值,即max(svd(A))

    % default arguments
    if nargin < 2%matalb 提供两个获取函数参数数目的函数,nargin返回函数输入参数的数量
        lambda = 1 / sqrt(max(M,N));
    end
    if nargin < 3
        mu = 10*lambda;
    end
    if nargin < 4
        tol = 1e-6;
    end
    if nargin < 5
        max_iter = 1000;
    end

    % initial solution
    L = zeros(M, N);
    S = zeros(M, N);
    Y = zeros(M, N);

    for iter = (1:max_iter)
        % ADMM step: update L and S
        L = Do(1/mu, X - S + (1/mu)*Y);%更新低秩矩阵
        S = So(lambda/mu, X - L + (1/mu)*Y);%更新稀疏矩阵
        % and augmented lagrangian multiplier
        Z = X - L - S;
        Z(unobserved) = 0; % skip missing values
        Y = Y + mu*Z;

        err = norm(Z, 'fro') / normX;
        if (iter == 1) || (mod(iter, 10) == 0) || (err < tol)
            fprintf(1, 'iter: %04d\terr: %f\trank(L): %d\tcard(S): %d\n', ...
                    iter, err, rank(L), nnz(S(~unobserved)));
        end
        if (err < tol) break; end
    end
end

function r = So(tau, X)
    % shrinkage operator
    r = sign(X) .* max(abs(X) - tau, 0);
end

function r = Do(tau, X)
    % shrinkage operator for singular values
    [U, S, V] = svd(X, 'econ');
    r = U*So(tau, S)*V';
end

i=[1  2  4];j=[1  3  5];s = [6  7  8]; 
A = sparse(i,j,s)
B=full(A)
C=ones(4,5)
D=1.0*(B+C)
[m,n]=size(D)
lambda=1.0/sqrt(max(m,n))
mu = 10*lambda
tol = 1e-6
max_iter = 1000
[L, S] = RobustPCA(D, lambda, mu, tol, max_iter)

速度挺快的,这个代码看起来还是挺简洁的,但是需要认真看一下一些原理推导。
注:其实这里面的内容都不是我自己的,我之前找的Robust PCA很多都是讲原理,没有代码,我就整合了一下。大家可以在网上多找找代码。
如有错误,欢迎指出。

  • 20
    点赞
  • 105
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值