Exemplo n.º 1
0
def inexact_alm_lrr_l21(X, A, lamb, display=False):
    tol = 1e-8
    maxIter = 1e6
    d, n = X.shape
    m = A.shape[1]
    rho = 1.1
    max_mu = 1e10
    mu = 1e-6
    atx = A.T.dot(X)
    inv_a = np.linalg.inv(A.T.dot(A) + np.eye(m))
    # Initializing optimization variables
    # intialize
    J = np.zeros((m, n))
    Z = np.zeros((m, n))
    E = np.zeros((d, n))  # sparse

    Y1 = np.zeros((d, n))
    Y2 = np.zeros((m, n))
    # Start main loop
    iter = 0
    if display:
        print "initial,rank=%f" % np.linalg.matrix_rank(Z)

    while iter < maxIter:
        iter += 1
        # update J
        temp = Z + Y2 / mu
        U, sigma, V = np.linalg.svd(temp, 'econ')
        V = V.T
        svp = len(np.flatnonzero(sigma > 1.0 / mu))
        if svp >= 1:
            sigma = sigma[0:svp] - 1.0 / mu
        else:
            svp = 1
            sigma = np.array([0])

        J = U[:, 0:svp].dot(np.diag(sigma).dot(V[:, 0:svp].T))
        # udpate Z
        Z = inv_a.dot(atx - A.T.dot(E) + J + (A.T.dot(Y1) - Y2) / mu)
        # update E
        xmaz = X - A.dot(Z)
        temp = xmaz + Y1 / mu
        E = solve_l1l2(temp, lamb / mu)

        leq1 = xmaz - E
        leq2 = Z - J
        stopC = max(np.max(np.abs(leq1)), np.max(np.abs(leq2)))
        if display and (iter == 1 or np.mod(iter, 50) == 0 or stopC < tol):
            print "iter", iter, ",mu=", mu, ",rank=", \
                  np.linalg.matrix_rank(Z, tol=1e-3*np.linalg.norm(Z, 2)), \
                  ",stopALM=", stopC

        if stopC < tol:
            break
        else:
            Y1 += mu * leq1
            Y2 += mu * leq2
            mu = min(max_mu, mu * rho)

    return (Z, E)
Exemplo n.º 2
0
def exact_alm_lrr_l21v2(D, A, lamb, tol=1e-7, maxIter=1000, display=False):
    m, n = D.shape
    k = A.shape[1]

    maxIter_primal = 10000
    # initialize
    Y = np.sign(D)
    norm_two = np.linalg.norm(Y, 2)
    norm_inf = np.linalg.norm(Y.flatten(1), np.inf) / lamb
    dual_norm = max(norm_two, norm_inf)
    Y /= dual_norm

    W = np.zeros((k, n))

    Z_hat = np.zeros((k, n))
    E_hat = np.zeros((m, n))
    # parameters
    dnorm = np.linalg.norm(D, "fro")
    tolProj1 = 1e-6 * dnorm

    anorm = np.linalg.norm(A, 2)
    tolProj2 = 1e-6 * dnorm / anorm

    mu = 0.5 / norm_two  # this one can be tuned
    rho = 6  # this one can be tuned

    # pre-computation
    if m >= k:
        inv_ata = np.linalg.inv(np.eye(k) + A.T.dot(A))
    else:
        inv_ata = np.eye(k) - np.linalg.solve((np.eye(m) + A.dot(A.T)).T, A).T.dot(A)

    iter = 0
    while iter < maxIter:
        iter += 1

        # solve the primal problem by alternative projection
        primal_iter = 0

        while primal_iter < maxIter_primal:
            primal_iter += 1
            temp_Z, temp_E = Z_hat, E_hat

            # update J
            temp = temp_Z + W / mu
            U, S, V = np.linalg.svd(temp, "econ")
            V = V.T

            diagS = S
            svp = len(np.flatnonzero(diagS > 1.0 / mu))
            diagS = np.maximum(0, diagS - 1.0 / mu)

            if svp < 0.5:  # svp = 0
                svp = 1

            J_hat = U[:, 0:svp].dot(np.diag(diagS[0:svp]).dot(V[:, 0:svp].T))

            # update Z
            temp = J_hat + A.T.dot(D - temp_E) + (A.T.dot(Y) - W) / mu
            Z_hat = inv_ata.dot(temp)

            # update E
            temp = D - A.dot(Z_hat) + Y / mu
            E_hat = solve_l1l2(temp, lamb / mu)

            if np.linalg.norm(E_hat - temp_E, "fro") < tolProj1 and np.linalg.norm(Z_hat - temp_Z) < tolProj2:
                break

        H1 = D - A.dot(Z_hat) - E_hat
        H2 = Z_hat - J_hat
        Y = Y + mu * H1
        W = W + mu * H2
        mu = rho * mu

        # stop Criterion
        stopCriterion = max(np.linalg.norm(H1, "fro") / dnorm, np.linalg.norm(H2, "fro") / dnorm * anorm)
        if display:
            print "LRR: Iteration", iter, "(", primal_iter, "), mu ", mu, ", |E|_2,0 ", np.sum(
                np.sum(E_hat ** 2, 1) > 0
            ), ", stopCriterion ", stopCriterion

        if stopCriterion < tol:
            break

    return (Z_hat, E_hat)
Exemplo n.º 3
0
def exact_alm_lrr_l21v2(D, A, lamb, tol=1e-7, maxIter=1000, display=False):
    m, n = D.shape
    k = A.shape[1]

    maxIter_primal = 10000
    # initialize
    Y = np.sign(D)
    norm_two = np.linalg.norm(Y, 2)
    norm_inf = np.linalg.norm(Y.flatten(1), np.inf) / lamb
    dual_norm = max(norm_two, norm_inf)
    Y /= dual_norm

    W = np.zeros((k, n))

    Z_hat = np.zeros((k, n))
    E_hat = np.zeros((m, n))
    # parameters
    dnorm = np.linalg.norm(D, 'fro')
    tolProj1 = 1e-6 * dnorm

    anorm = np.linalg.norm(A, 2)
    tolProj2 = 1e-6 * dnorm / anorm

    mu = 0.5 / norm_two  # this one can be tuned
    rho = 6              # this one can be tuned

    # pre-computation
    if m >= k:
        inv_ata = np.linalg.inv(np.eye(k) + A.T.dot(A))
    else:
        inv_ata = np.eye(k) - np.linalg.solve((np.eye(m) + A.dot(A.T)).T,
                                              A).T.dot(A)

    iter = 0
    while iter < maxIter:
        iter += 1

        # solve the primal problem by alternative projection
        primal_iter = 0

        while primal_iter < maxIter_primal:
            primal_iter += 1
            temp_Z, temp_E = Z_hat, E_hat

            # update J
            temp = temp_Z + W / mu
            U, S, V = np.linalg.svd(temp, 'econ')
            V = V.T

            diagS = S
            svp = len(np.flatnonzero(diagS > 1.0 / mu))
            diagS = np.maximum(0, diagS - 1.0 / mu)

            if svp < 0.5:  # svp = 0
                svp = 1

            J_hat = U[:, 0:svp].dot(np.diag(diagS[0:svp]).dot(V[:, 0:svp].T))

            # update Z
            temp = J_hat + A.T.dot(D - temp_E) + (A.T.dot(Y) - W) / mu
            Z_hat = inv_ata.dot(temp)

            # update E
            temp = D - A.dot(Z_hat) + Y / mu
            E_hat = solve_l1l2(temp, lamb / mu)

            if np.linalg.norm(E_hat - temp_E, 'fro') < tolProj1 and \
               np.linalg.norm(Z_hat - temp_Z) < tolProj2:
                break

        H1 = D - A.dot(Z_hat) - E_hat
        H2 = Z_hat - J_hat
        Y = Y + mu * H1
        W = W + mu * H2
        mu = rho * mu

        # stop Criterion
        stopCriterion = max(np.linalg.norm(H1, 'fro') / dnorm,
                            np.linalg.norm(H2, 'fro') / dnorm * anorm)
        if display:
            print('LRR: Iteration', iter, '(', primal_iter, '), mu ', mu, \
                  ', |E|_2,0 ', np.sum(np.sum(E_hat ** 2, 1) > 0), \
                  ', stopCriterion ', stopCriterion)

        if stopCriterion < tol:
            break

    return (Z_hat, E_hat)