def compDklgaussian(mu1, C1, mu2, C2): """ Adapted from: http://pillowlab.cps.utexas.edu/code_iSTAC.html Local Variables: b, mu1, d, Term1, mu2, DD, Term2, Term3, n, C2, C1, C1divC2 Function calls: compDklgaussian, nargin, length, trace, logdet d = compDklgaussian(mu1, C1, mu2, C2) Computes the KL divergence between two multivariate Gaussians Inputs: mu1 = mean of 1st Gaussian C1 = covariance of 1st Gaussian mu2 = mean of 2nd Gaussian C2 = covariance of 2nd Gaussian Notes: D_KL = Integral(p1 log (p1/p2)) Analytically: (where |*| = Determinant, Tr = trace, n = dimensionality = 1/2 log(|C2|/|C1|) + 1/2 Tr(C1^.5*C2^(-1)*C1^.5) + 1/2 (mu2-mu1)^T*C2^(-1)*(mu2-mu1) - 1/2 n """ n = len(mu1) b = mu2 - mu1 C1divC2 = np.linalg.solve(C2, C1) # matrix we need Term1 = np.trace(C1divC2) # trace term Term2 = np.dot(b.conj().T, np.linalg.solve(C2, b)) # quadratic term #TEST THIS!!! Term3 = np.negative(ld.logdet(C1divC2)) d = np.dot(.5, Term1 + Term2 + Term3 - n) return d
def dual_obj(self, emp_covs, Ws=None): """ Compute value of dual objective function """ if Ws is None: Ws = self.dual_variables(emp_covs) dobj = 0.0 for emp_cov, W in zip(emp_covs, Ws): dobj += logdet(emp_cov + W) + W.shape[0] return dobj
def generator_loss(G_z, z, h_G_z, Int_f, p_z): #x_true = exp(h_z), x_pred <- G_z, x_in = z, dim = tf.shape(z)[1] N = tf.cast(tf.shape(z)[0], tf.float32) slogDJ = tf.reshape(logdet(jacobian(G_z, z)), (-1, 1)) #print(N, p_z, slogDJ) #D = 1/N*tf.reduce_sum(-tf.log(tf.exp(h_G_z)/Int_f) + tf.log(p_z) - slogDJ, (0,)) D = tf.log(2.0) + 1.0 / N * tf.reduce_sum( (tf.log(p_z) - slogDJ - tf.log(p_z / tf.exp(slogDJ) + tf.exp(h_G_z) / Int_f)), [0]) # return tf.reshape(D, [])
def my_gaussian_classify(Xtrn, Ctrn, Xtst, epsilon): # Input: # Xtrn : M-by-D ndarray of training data (dtype=np.float_) # Ctrn : M-by-1 ndarray of label vector for Xtrn (dtype=np.int_) # Xtst : N-by-D ndarray of test data matrix (dtype=np.float_) # epsilon : A scalar parameter for regularisation (type=float) # Output: # Cpreds : N-by-L ndarray of predicted labels for Xtst (dtype=int_) # Ms : D-by-K ndarray of mean vectors (dtype=np.float_) # Covs : D-by-D-by-K ndarray of covariance matrices (dtype=np.float_) trn_size, trn_feats = np.shape(Xtrn) test_size = np.shape(Xtst)[0] k = 26 #k = 2 Ms = np.zeros((k, trn_feats), dtype=np.float64) Cpreds = np.zeros((test_size, 1)) Covs = np.zeros((trn_feats, trn_feats, k)) for i in range(k): # choosing the training egs. belonging to class i bools = i == Ctrn.T[0] ps = np.compress(bools, Xtrn, axis=0) Ms[i] = np.sum(ps, axis=0, dtype=np.float64) / np.shape(ps)[0] #compute covariance of class i Covs[:, :, i] = np.dot( (ps - Ms[i]).T, ps - Ms[i]) * 1.0 / np.shape(ps)[0] Covs[:, :, i] += np.identity(trn_feats) * epsilon lll = np.zeros((test_size, k)) for i in range(k): X = np.dot(Xtst - Ms[i], np.linalg.inv(Covs[:, :, i])) Y = (Xtst - Ms[i]).T #computing log posterior probabilities lll[:, i] += -0.5 * (ld.logdet(Covs[:, :, i])) - 0.5 * np.einsum( 'ij,ji->i', X, Y) for i in range(test_size): # picking class with highest probability as prediction Cpreds[i][0] = lll[i].argsort()[-1] Ms = Ms.T return (Cpreds, Ms, Covs)
def negKLsubspace(k, mu, A, bv, va, vav, vecs, vecssize = 0): """ Adapted from: http://pillowlab.cps.utexas.edu/code_iSTAC.html Local Variables: A, vA, vAb, k, L, mu, v1, bv, vecs, vAv, b1 Function calls: trace, isempty, norm, negKLsubspace, logdet [L] = negKLsubspace(k, mu, A, bv, vA,vAv); loss function for computing a subapce which achieves maximal KL-divergence between a Gaussian N(mu,A) and N(0,I). Computes KL divergence within subspace spanned by [k vecs] inputs: k = new dimension mu = mean of Gaussian A = cov of Gaussian Quicker to pass these in than recompute every time: bV = mu' * vecs vA = vecs'*A vAv = vecs'*A*vecs vecs = basis for dimensions of subspace already "peeled off" """ if vecssize > 0: k = k - np.dot(vecs[:, np.arange(0, vecssize)], (np.dot(vecs[:, np.arange(0, vecssize)].T, k.T))) # orthogonalize k with respect to 'vecs' k = np.divide(k, np.linalg.norm(k)) # normalize k b1 = np.dot(k.T, mu) v1 = np.reshape(np.dot(k.T, np.dot(A, k)), (1, 1)) if bv.size > 0: b1 = np.vstack((np.hstack((b1)), bv)) vab = np.reshape(np.dot(va, k), (va.shape[0], 1)) v1 = np.vstack((np.hstack((np.reshape(np.dot(k.T, np.dot(A, k)), (1, 1)), vab.T)), np.hstack((vab, vav)))) L = ld.logdet(v1) - np.trace(v1) - np.dot(b1.T, b1) return L
def my_gaussian_classify(Xtrn, Ctrn, Xtst, epsilon): # Input: # Xtrn : M-by-D ndarray of training data (dtype=np.float_) # Ctrn : M-by-1 ndarray of label vector for Xtrn (dtype=np.int_) # Xtst : N-by-D ndarray of test data matrix (dtype=np.float_) # epsilon : A scalar parameter for regularisation (type=float) # Output: # Cpreds : N-by-L ndarray of predicted labels for Xtst (dtype=int_) # Ms : D-by-K ndarray of mean vectors (dtype=np.float_) # Covs : D-by-D-by-K ndarray of covariance matrices (dtype=np.float_) # Size of matrices D = Xtrn.shape[1] N = Xtst.shape[0] K = 26 # number of classes # Compute matrix of sample mean vectors # & 3D array of sample covariance matrices (including regularisation) Ms = np.zeros((D, K)) Covs = np.zeros((D, D, K)) for k in range(0, K): samples = Xtrn[(Ctrn == k)[:, 0], :] mu = myMean(samples) Ms[:, k] = mu Covs[:, :, k] = myCov(samples, mu) + np.eye(D) * epsilon # NB: No need to include the prior probability to compute the posterior # probability, since we assume a uniform prior distribution over class # Compute posterior probabilities for the test samples, in the log domain post_log = np.zeros((N, K)) for k in range(0, K): mu = Ms[:, k] sigma = Covs[:, :, k] diff = Xtst.T - mu[:, np.newaxis] pro = np.dot(np.dot(diff.T, np.linalg.inv(sigma)), diff) post_matrix = -0.5 * pro - 0.5 * logdet(sigma) post_log[:, k] = np.diag(post_matrix) # Choose the class corresponding to the max posterior probability, for each test sample Cpreds = np.argmax(post_log, axis=1) return (Cpreds, Ms, Covs)
def get_log_det_prec(self): return [logdet(precision) for precision in self.precisions]
def get_log_det_prec(self): return logdet(self.precision)
def dual_obj(self, emp_cov, A): B = A + emp_cov B *= 0.5 return logdet(B + B.T) + A.shape[0]
def abs_grad(self): return tf.reshape(tf.exp(logdet(jacobian(self.output, self.input))), (-1, 1))