Exemple #1
0
    def partial_EM(self, data, cond_muh_ijk, indices, weights=None, eps=1e-4, maxiter=10, verbose=0):
        (i, j, k) = indices
        converged = False
        previous_L = utilities.average(
            self.likelihood(data), weights=weights) / self.N
        mini_epochs = 0
        if verbose:
            print('Partial EM %s, L = %.3f' % (mini_epochs, previous_L))
        while not converged:
            if self.nature in ['Bernoulli', 'Spin']:
                f = np.dot(data, self.weights[[i, j, k], :].T)
            elif self.nature == 'Potts':
                f = cy_utilities.compute_output_C(data, self.weights[[i, j, k], :, :], np.zeros([
                                                  data.shape[0], 3], dtype=curr_float))

            tmp = f - self.logZ[np.newaxis, [i, j, k]]
            tmp -= tmp.max(-1)[:, np.newaxis]
            cond_muh = np.exp(tmp) * self.muh[np.newaxis, [i, j, k]]
            cond_muh /= cond_muh.sum(-1)[:, np.newaxis]
            cond_muh *= cond_muh_ijk[:, np.newaxis]

            self.muh[[i, j, k]] = utilities.average(cond_muh, weights=weights)
            self.cum_muh = np.cumsum(self.muh)
            self.gh[[i, j, k]] = np.log(self.muh[[i, j, k]])
            self.gh -= self.gh.mean()
            if self.nature == 'Bernoulli':
                self.cond_muv[[i, j, k]] = utilities.average_product(
                    cond_muh, data, mean1=True, weights=weights) / self.muh[[i, j, k], np.newaxis]
                self.weights[[i, j, k]] = np.log(
                    (self.cond_muv[[i, j, k]] + eps) / (1 - self.cond_muv[[i, j, k]] + eps))
                self.logZ[[i, j, k]] = np.logaddexp(
                    0, self.weights[[i, j, k]]).sum(-1)
            elif self.nature == 'Spin':
                self.cond_muv[[i, j, k]] = utilities.average_product(
                    cond_muh, data, mean1=True, weights=weights) / self.muh[[i, j, k], np.newaxis]
                self.weights[[i, j, k]] = 0.5 * np.log(
                    (1 + self.cond_muv[[i, j, k]] + eps) / (1 - self.cond_muv[[i, j, k]] + eps))
                self.logZ[[i, j, k]] = np.logaddexp(
                    self.weights[[i, j, k]], -self.weights[[i, j, k]]).sum(-1)
            elif self.nature == 'Potts':
                self.cond_muv[[i, j, k]] = utilities.average_product(
                    cond_muh, data, c2=self.n_c, mean1=True, weights=weights) / self.muh[[i, j, k], np.newaxis, np.newaxis]
                self.cum_cond_muv[[i, j, k]] = np.cumsum(
                    self.cond_muv[[i, j, k]], axis=-1)
                self.weights[[i, j, k]] = np.log(
                    self.cond_muv[[i, j, k]] + eps)
                self.weights[[i, j, k]] -= self.weights[[i, j, k]
                                                        ].mean(-1)[:, :, np.newaxis]
                self.logZ[[i, j, k]] = utilities.logsumexp(
                    self.weights[[i, j, k]], axis=-1).sum(-1)

            current_L = utilities.average(
                self.likelihood(data), weights=weights) / self.N
            mini_epochs += 1
            converged = (mini_epochs >= maxiter) | (
                np.abs(current_L - previous_L) < eps)
            previous_L = current_L.copy()
            if verbose:
                print('Partial EM %s, L = %.3f' % (mini_epochs, current_L))
        return current_L
Exemple #2
0
 def likelihood(self, data):
     if data.ndim == 1:
         data = data[np.newaxis, :]
     if self.nature in ['Bernoulli', 'Spin']:
         f = np.dot(data, self.weights.T)
     elif self.nature == 'Potts':
         f = cy_utilities.compute_output_C(data, self.weights, np.zeros(
             [data.shape[0], self.M], dtype=curr_float))
     return utilities.logsumexp((f - self.logZ[np.newaxis, :] + np.log(self.muh)[np.newaxis, :]), axis=1)
Exemple #3
0
 def likelihood_and_expectation(self, data):
     if self.nature in ['Bernoulli', 'Spin']:
         f = np.dot(data, self.weights.T)
     elif self.nature == 'Potts':
         f = cy_utilities.compute_output_C(data, self.weights, np.zeros(
             [data.shape[0], self.M], dtype=curr_float))
     L = utilities.logsumexp(
         (f - self.logZ[np.newaxis, :] + np.log(self.muh)[np.newaxis, :]), axis=1)
     cond_muh = np.exp(
         f - self.logZ[np.newaxis, :]) * self.muh[np.newaxis, :]
     cond_muh /= cond_muh.sum(-1)[:, np.newaxis]
     return L, cond_muh
Exemple #4
0
    def expectation(self, data):
        if data.ndim == 1:
            data = data[np.newaxis, :]

        if self.nature in ['Bernoulli', 'Spin']:
            f = np.dot(data, self.weights.T)
        elif self.nature == 'Potts':
            f = cy_utilities.compute_output_C(data, self.weights, np.zeros(
                [data.shape[0], self.M], dtype=curr_float))

        tmp = f - self.logZ[np.newaxis, :]
        tmp -= tmp.max(-1)[:, np.newaxis]
        cond_muh = np.exp(tmp) * self.muh[np.newaxis, :]
        cond_muh /= cond_muh.sum(-1)[:, np.newaxis]
        return cond_muh
Exemple #5
0
def bilinear_form(W, X1, X2, c1=1, c2=1):
    xshape = X1.shape
    X1, xdim = reshape_in(X1, xdim=1)
    X2, xdim = reshape_in(X2, xdim=1)
    if (c1 == 1) & (c2 == 1):
        out = np.sum(X1 * np.tensordot(X2, W, axes=(-1, 1)), -1)
    elif (c1 == 1) & (c2 > 1):
        out = np.sum(
            X1 * cy_utilities.compute_output_C(
                X2, W, np.zeros(X1.shape, dtype=curr_float)), -1)
    elif (c1 > 1) & (c2 == 1):
        out = cy_utilities.dot_Potts2_C(
            X1.shape[1], c1, X1, np.tensordot(X2.astype(curr_float), W,
                                              (1, 1)))
    elif (c1 > 1) & (c2 > 1):
        out = cy_utilities.bilinear_form_Potts_C(X1, X2, W)
    return reshape_out(out, xshape, xdim=1)