def compute_loss(self, V, y): m, C, H, W = V.shape alpha = C / (m * self.eps) cov = alpha * F.batch_cov(V, self.arch.batch_size) \ + np.eye(C)[..., np.newaxis, np.newaxis] loss_expd = np.sum([ np.linalg.slogdet(cov[:, :, h, w])[1] for h, w in product(range(H), range(W)) ]) / (2 * H * W) loss_comp = 0. Cs = np.empty((self.num_classes, C, C, H, W), dtype=np.complex) for j in range(self.num_classes): V_j = V[y == int(j)] m_j = V_j.shape[0] if m_j == 0: continue alpha_j = C / (m_j * self.eps) cov_j = alpha_j * F.batch_cov(V_j, self.arch.batch_size) \ + np.eye(C)[..., np.newaxis, np.newaxis] loss_comp += m_j / m * np.sum([ np.linalg.slogdet(cov_j[:, :, h, w])[1] for h, w in product(range(H), range(W)) ]) / (2 * H * W) return loss_expd - loss_comp, loss_expd, loss_comp
def compute_E(self, V): m, C, T = V.shape alpha = C / (m * self.eps) pre_inv = alpha * F.batch_cov(V, self.arch.batch_size) \ + np.eye(C)[..., np.newaxis] E = np.empty_like(pre_inv) for t in range(T): E[:, :, t] = alpha * np.linalg.inv(pre_inv[:, :, t]) self.E = E
def compute_E(self, V): m, C, H, W = V.shape alpha = C / (m * self.eps) I = np.eye(C)[..., np.newaxis, np.newaxis] pre_inv = I + alpha * F.batch_cov(V, self.arch.batch_size) E = np.empty_like(pre_inv).astype(np.complex) for h, w in product(range(H), range(W)): E[:, :, h, w] = alpha * np.linalg.inv(pre_inv[:, :, h, w]) self.E = E
def compute_Cs(self, V, y): m, C, T = V.shape Cs = np.empty((self.num_classes, C, C, T), dtype=np.complex) for j in np.arange(self.num_classes): V_j = V[y == j] m_j = V_j.shape[0] if m_j == 0: continue alpha_j = C / (m_j * self.eps) pre_inv = alpha_j * F.batch_cov(V_j, self.arch.batch_size) \ + np.eye(C)[..., np.newaxis] for t in range(T): Cs[j, :, :, t] = alpha_j * np.linalg.inv(pre_inv[:, :, t]) self.Cs = Cs