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 _buildYhat(self): """ Yhat = [Yhat_1, Yhat_2, ..., Yhat_C] where Yhat_c = Yc - Dc*Xcc """ Yhat = np.zeros_like(self.Y) for c in xrange(self.nclass): Yc = get_block_col(self.Y, c, self.Y_range) Dc = get_block_col(self.D, c, self.D_range) Xcc = utils.get_block(self.X, c, c, self.D_range, self.Y_range) Yhat[:, self.Y_range[c]:self.Y_range[c + 1]] = Yc - np.dot(Dc, Xcc) return Yhat
def _updateD(self): Yhat = np.zeros_like(self.Y) DCp1 = self._getDc(self.nclass) for c in range(self.nclass): Dc_range = range(self.D_range_ext[c], self.D_range_ext[c + 1]) Yc_range = range(self.Y_range[c], self.Y_range[c + 1]) Yc = self._getYc(c) Dc = self._getDc(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) Ychat = Yc - np.dot(self.D, Xc) + np.dot(Dc, Xcc) Ycbar = Yc - np.dot(DCp1, XCp1c) E = np.dot(Ychat + Ycbar, Xcc.T) F = 2 * np.dot(Xcc, Xcc.T) A = self.D.copy() A = np.delete(A, Dc_range, axis=1) self.D[:, Dc_range] = optimize.DLSI_updateD(Dc, E, F, A.T, self.eta) Yhat[:, Yc_range] = Yc - np.dot(self.D[:, Dc_range], Xcc) ## DCp1 XCp1 = utils.get_block_row(self.X, self.nclass, self.D_range_ext) Ybar = self.Y - np.dot(self.D[:, : self.D_range_ext[-2]], \ self.X[: self.D_range_ext[-2], :]) E = np.dot(Ybar + Yhat, XCp1.T) F = 2 * np.dot(XCp1, XCp1.T) A = self.D[:, :self.D_range_ext[-2]] DCp1_range = range(self.D_range_ext[-2], self.D_range_ext[-1]) self.D[:, DCp1_range] = optimize.DLSI_updateD(self.D[:, DCp1_range], E, F, A.T, self.eta)
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 set_class(self, c): self.c = c self.Yc = utils.get_block_col(self.Y, c, self.Y_range) self.Dc = utils.get_block_col(self.D, c, self.D_range_ext) ## for _grad function self.DctDc = utils.get_block(self.DtD, c, c, self.D_range_ext, self.D_range_ext) self.DCp1tDc = utils.get_block(self.DtD, self.nclass, c, self.D_range_ext, self.D_range_ext) self.DtYc = utils.get_block_col(self.DtY, c, self.Y_range) self.DtYc2 = self.DtYc.copy() self.DtYc2[self.D_range_ext[c]:self.D_range_ext[c+1], :] = \ 2*self.DtYc[self.D_range_ext[c]: self.D_range_ext[c+1], :] self.DtYc2[self.D_range_ext[-2]:self.D_range_ext[-1], :] = \ 2*self.DtYc[self.D_range_ext[-2]:self.D_range_ext[-1], :]
def _initialize(self): for c in range(self.nclass): Yc = utils.get_block_col(self.Y, c, self.Y_range) clf = ODL(k=self.D_range[c + 1] - self.D_range[c], lambd=self.lambd) clf.fit(Yc) self.D[:, self.D_range[c]:self.D_range[c + 1]] = clf.D self.X[c] = clf.X
def __init__(self, D, D_range_ext, Y, Y_range, lambd, iterations=100): self.D = D self.lambd = lambd self.DtD = np.dot(self.D.T, self.D) self.Y = Y self.Y_range = Y_range self.nclass = len(D_range_ext) - 2 self.DtY = np.dot(D.T, Y) self.DCp1 = utils.get_block_col(D, self.nclass, D_range_ext) self.DCp1tDCp1 = np.dot(self.DCp1.T, self.DCp1) self.D_range_ext = D_range_ext self.k0 = D_range_ext[-1] - D_range_ext[-2] if self.k0 > 0: self.L = utils.max_eig(self.DtD) + utils.max_eig(self.DCp1tDCp1) else: self.L = utils.max_eig(self.DtD) self.c = -1 self.DCp1 = utils.get_block_col(D, self.nclass, self.D_range_ext)
def predict(self, Y, verbose = True, iterations = 100): lasso = Lasso(self.D, self.lamb) lasso.fit(Y, iterations = iterations) X = lasso.coef_ E = np.zeros((self.C, Y.shape[1])) for i in range(self.C): Xi = utils.get_block_row(X, i, self.train_range) Di = utils.get_block_col(self.D, i, self.train_range) R = Y - np.dot(Di, Xi) E[i,:] = (R*R).sum(axis = 0) return utils.vec(np.argmin(E, axis = 0) + 1)
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 _updateX(self): updatxc = UpdateXc(self.D, self.D_range_ext, self.Y, self.Y_range, self.lambd, iterations=100) for c in range(self.nclass): updatxc.set_class(c) Xc = utils.get_block_col(self.X, c, self.Y_range) # updatxc.check_grad(Xc) self.X[:, self.Y_range[c]: self.Y_range[c+1]] = \ updatxc.solve(Xinit = Xc)
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 predict(self, Y): N = Y.shape[1] lambda_list = [self.lambd] for lambd in lambda_list: E = np.zeros((self.nclass, N)) for c in range(self.nclass): # Dc in D only Dc_ = get_block_col(self.D, c, self.D_range) # Dc in D and D0 Dc = np.hstack((Dc_, self.D0)) if self.k0 > 0 else Dc_ lasso = optimize.Lasso(Dc, lambd=lambd) lasso.fit(Y) Xc = lasso.solve() R = Y - np.dot(Dc, Xc) E[c, :] = 0.5*np.sum(R*R, axis = 0) + \ lambd*np.sum(np.abs(Xc), axis = 0) pred = np.argmin(E, axis=0) + 1 return pred pass
def _getDc(self, c): return utils.get_block_col(self.D, c, self.D_range_ext)
def _getYc(self, c): return utils.get_block_col(self.Y, c, self.Y_range)