示例#1
0
    def loss(self):
        """
        cost = COPAR_cost(Y, Y_range, D, D_range_ext, X, opts):
        Calculating cost function of COPAR with parameters lambda and eta are
        stored in `opts.lambda` and `opts.rho`.
        `f(D, X) = 0.5*sum_{c=1}^C 05*||Y - DX||_F^2 +
                      sum_{c=1}^C ( ||Y_c - D_Cp1 X^Cp1_c - D_c X_c^c||F^2 +
                  sum_{i != c}||X^i_c||_F^2) + lambda*||X||_1 +
                  0.5*eta*sum_{i \neq c}||Di^T*Dc||_F^2`
        -----------------------------------------------
        Author: Tiep Vu, [email protected], 5/11/2016
                (http://www.personal.psu.edu/thv102/)
        -----------------------------------------------
        """
        cost = self.lambd * utils.norm1(self.X)
        cost1 = utils.normF2(self.Y - np.dot(self.D, self.X))
        DCp1 = self._getDc(self.nclass)
        for c in range(self.nclass):
            Dc = self._getDc(c)
            Yc = self._getYc(c)
            Xc = utils.get_block_col(self.X, c, self.Y_range)
            Xcc = utils.get_block_row(Xc, c, self.D_range_ext)
            XCp1c = utils.get_block_row(Xc, self.nclass, self.D_range_ext)

            cost1 += utils.normF2(Yc - np.dot(Dc, Xcc) - np.dot(DCp1, XCp1c))
            XX = Xc[:self.D_range_ext[-2], :]
            XX = np.delete(XX,
                           range(self.D_range_ext[c], self.D_range_ext[c + 1]),
                           axis=0)
            cost1 += utils.normF2(XX)

        cost += cost1 + .5*self.eta*utils.normF2(\
                utils.erase_diagonal_blocks(np.dot(self.D.T, self.D), \
                self.D_range_ext, self.D_range_ext))
        return cost
示例#2
0
def DLSI_updateD(D, E, F, A, lambda1, verbose=False, iterations=100):
    """
    def DLSI_updateD(D, E, F, A, lambda1, verbose = False, iterations = 100):
    problem: `D = argmin_D -2trace(ED') + trace(FD'*D) + lambda *||A*D||F^2,`
    subject to: `||d_i||_2^2 <= 1`
    where F is a positive semidefinite matrix
    ========= aproach: ADMM ==============================
    rewrite: `[D, Z] = argmin -2trace(ED') + trace(FD'*D) + lambda ||A*Z||_F^2,`
        subject to `D = Z; ||d_i||_2^2 <= 1`
    aproach 1: ADMM.
    1. D = -2trace(ED') + trace(FD'*D) + rho/2 ||D - Z + U||_F^2,
        s.t. ||d_i||_2^2 <= 1
    2. Z = argmin lambda*||A*Z|| + rho/2||D - Z + U||_F^2
    3. U = U + D - Z
    solve 1: D = argmin -2trace(ED') + trace(FD'*D) + rho/2 ||D - W||_F^2
                          with W = Z - U;
               = argmin -2trace((E - rho/2*W)*D') +
                  trace((F + rho/2 * eye())*D'D)
    solve 2: derivetaive: 0 = 2A'AZ + rho (Z - V) with V = D + U
    `Z = B*rhoV` with `B = (2*lambda*A'*A + rho I)^{-1}`
    `U = U + D - Z`
    -----------------------------------------------
    Author: Tiep Vu, [email protected], 5/11/2016
            (http://www.personal.psu.edu/thv102/)
    -----------------------------------------------
    """
    def calc_cost(D):
        cost = -2*np.trace(np.dot(E, D.T)) + np.trace(np.dot(F, np.dot(D.T, D))) +\
            lambda1*utils.normF2(np.dot(A, D))
        return cost

    it = 0
    rho = 1.0
    Z_old = D.copy()
    U = np.zeros_like(D)
    I_k = np.eye(D.shape[1])
    X = 2 * lambda1 / rho * A.T
    Y = A.copy()
    B1 = np.dot(X, utils.inv_IpXY(Y, X))

    # B1 = np.dot(X, LA.inv(eye(Y.shape[0]) + np.dot(Y, X)))
    tol = 1e-8
    for it in range(iterations):
        it += 1
        # update D
        W = Z_old - U
        E2 = E + rho / 2 * W
        F2 = F + rho / 2 * I_k
        D = ODL_updateD(D, E2, F2)
        # update Z
        V = D + U
        Z_new = rho * (V - np.dot(B1, np.dot(Y, V)))
        e1 = utils.normF2(D - Z_new)
        e2 = rho * utils.normF2(Z_new - Z_old)
        if e1 < tol and e2 < tol:
            break
        U = U + D - Z_new
        Z_old = Z_new.copy()

    return D
示例#3
0
 def loss(self):
     cost = 0
     for c in range(self.nclass):
         Yc = utils.get_block_col(self.Y, c, self.Y_range)
         Xc = self.X[c]
         Dc = utils.get_block_col(self.D, c, self.D_range)
         cost += 0.5 * utils.normF2(
             Yc - np.dot(Dc, Xc)) + self.lambd * utils.norm1(Xc)
     cost += 0.5*self.eta*utils.normF2(\
             utils.erase_diagonal_blocks(np.dot(self.D.T, self.D), self.D_range, self.D_range))
     return cost
示例#4
0
 def _discriminative(self, X):
     """
     * calculating the discriminative term in
     * $\|X\|_F^2 + \sum_{c=1}^C (\|Xc - Mc\|_F^2 - \|Mc - M\|_F^2) $
     """
     cost = normF2(X)
     m = np.mean(X, axis=1)
     for c in xrange(self.nclass):
         Xc = get_block_col(X, c, self.Y_range)
         Mc = build_mean_matrix(Xc)
         cost += normF2(Xc - Mc)
         M = matlab_syntax.repmat(m, 1, Xc.shape[1])
         cost -= normF2(Mc - M)
     return cost
示例#5
0
    def loss(self):
        Y = self.Y.copy()
        if self.k0 > 0:
            Y -= np.dot(self.D0, self.X0)
        cost = 0.5*normF2(Y - np.dot(self.D, self.X)) + \
                0.5*self._fidelity() + \
                0.5*self.lambd2*self._discriminative() + \
                self.lambd*norm1(self.X)

        if self.k0 > 0:
            cost += self.lambd*norm1(self.X0) + \
                    0.5*self.lambd2*normF2(self.X0 - build_mean_matrix(self.X0)) \
                    + self.eta*nuclearnorm(self.D0)
        return cost
示例#6
0
 def _calc_f(self, Xc):
     """
     optimize later
     """
     Xcc = utils.get_block_row(Xc, self.c, self.D_range_ext)
     XCp1c = utils.get_block_row(Xc, self.nclass, self.D_range_ext)
     cost = utils.normF2(self.Yc - np.dot(self.D, Xc))
     # pdb.set_trace()
     cost += utils.normF2(self.Yc - np.dot(self.Dc, Xcc) -\
             np.dot(self.DCp1, XCp1c))
     for i in range(self.nclass):
         if i != self.c:
             Xic = utils.get_block_row(Xc, i, self.D_range_ext)
             cost += utils.normF2(Xic)
     return .5 * cost
示例#7
0
 def _fidelity(self, X):
     """
     * Calculating the fidelity term in FDDL[[4]](#fn_fdd):
     * $\sum_{c=1}^C \Big(\|Y_c - D_cX^c_c\|_F^2 +
         \sum_{i \neq c} \|D_c X^c_i\|_F^2\Big)$
     """
     cost = 0
     Y = self.Y
     for c in xrange(self.nclass):
         Yc = get_block_col(Y, c, self.Y_range)
         Dc = get_block_col(self.D, c, self.D_range)
         Xc = get_block_row(X, c, self.D_range)
         Xcc = get_block_col(Xc, c, self.Y_range)
         cost += normF2(Yc - np.dot(Dc, Xcc))
         for i in xrange(self.nclass):
             if i == c:
                 continue
             Xci = get_block_col(Xc, i, self.Y_range)
             cost += normF2(np.dot(Dc, Xci))
     return cost
示例#8
0
 def calc_cost(D):
     cost = -2*np.trace(np.dot(E, D.T)) + np.trace(np.dot(F, np.dot(D.T, D))) +\
         lambda1*utils.normF2(np.dot(A, D))
     return cost
示例#9
0
 def _calc_f(self, X):
     return 0.5 * utils.normF2(self.Y - np.dot(self.D, X))
示例#10
0
 def _calc_f(self, X1):
     X, X0 = self._extract_fromX1(X1)
     Ybar = self.Y - np.dot(self.D0, X0)
     cost = 0.5*(normF2(Ybar - np.dot(self.D, X)) + self._fidelity(X)) + \
             0.5*self.lambd2*self._discriminative(X) + normF2(X0 - utils.buildMean(X0))
     return cost
示例#11
0
 def loss(self):
     l = 0.5*utils.normF2(self.Y - np.dot(self.D, self.X)) + \
             self.lambd*utils.norm1(self.X)
     return l