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
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
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
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
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
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
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
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
def _calc_f(self, X): return 0.5 * utils.normF2(self.Y - np.dot(self.D, X))
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
def loss(self): l = 0.5*utils.normF2(self.Y - np.dot(self.D, self.X)) + \ self.lambd*utils.norm1(self.X) return l