Beispiel #1
0
        def ll_docs_f(docs):
            dixs, vixs = docs.nonzero()
            vfreqs = docs[dixs, vixs]
            ll_docs = (vfreqs *
                       (pmmath.logsumexp(tt.log(theta[dixs]) + tt.log(beta.T[vixs]),
                                                  axis=1).ravel() + tt.log(
                n[dixs]).ravel()) - tt.exp(
                pmmath.logsumexp(tt.log(theta[dixs]) + tt.log(beta.T[vixs], ), axis=1)).ravel() * n[
                           dixs].ravel() - pm.distributions.special.gammaln(vfreqs + 1)

                       )
            return tt.sum(ll_docs) / (tt.sum(vfreqs) + 1e-9)
Beispiel #2
0
    def logp(self, value):
        """
        Calculate log-probability of defined Mixture distribution at specified value.

        Parameters
        ----------
        value: numeric
            Value(s) for which log-probability is calculated. If the log probabilities for multiple
            values are desired the values must be provided in a numpy array or Aesara tensor

        Returns
        -------
        TensorVariable
        """
        w = self.w

        return bound(
            logsumexp(at.log(w) + self._comp_logp(value),
                      axis=-1,
                      keepdims=False),
            w >= 0,
            w <= 1,
            at.allclose(w.sum(axis=-1), 1),
            broadcast_conditions=False,
        )
Beispiel #3
0
 def logp_(value):
     logps = [
         tt.log(pi[i]) + logp_normal(mus[i, :], taus[i], value)
         for i in range(n_components)
     ]
     return tt.sum(
         logsumexp(tt.stacklists(logps)[:, :n_samples], axis=0))
Beispiel #4
0
        def ll_docs_f(docs):
            dixs, vixs = docs.nonzero()
            vfreqs = docs[dixs, vixs]
            ll_docs = (vfreqs * pmmath.logsumexp(tt.log(theta[dixs]) + tt.log(beta.T[vixs]),
                                                 axis=1).ravel())

            return tt.sum(ll_docs) / (tt.sum(vfreqs) + 1e-9)
Beispiel #5
0
 def ll_docs_f(docs):
     dixs, vixs = docs.nonzero()
     vfreqs = docs[dixs, vixs]
     ll_docs = vfreqs * pmmath.logsumexp(
         tt.log(theta[dixs]) + tt.log(beta.T[vixs]), axis=1).ravel()
     # Per-word log-likelihood times num of tokens in the whole dataset
     return tt.sum(ll_docs)
Beispiel #6
0
 def jacobian_det(self, y_):
     y = y_.T
     Km1 = y.shape[0] + 1
     sy = tt.sum(y, 0, keepdims=True)
     r = tt.concatenate([y + sy, tt.zeros(sy.shape)])
     sr = logsumexp(r, 0, keepdims=True)
     d = tt.log(Km1) + (Km1 * sy) - (Km1 * sr)
     return tt.sum(d, 0).T
Beispiel #7
0
    def jacobian_det(self, rv_var, rv_value):
        if rv_var.broadcastable[-1]:
            # If this variable is just a bunch of scalars/degenerate
            # Dirichlets, we can't transform it
            return at.ones_like(rv_value)

        y = rv_value.T
        Km1 = y.shape[0] + 1
        sy = at.sum(y, 0, keepdims=True)
        r = at.concatenate([y + sy, at.zeros(sy.shape)])
        sr = logsumexp(r, 0, keepdims=True)
        d = at.log(Km1) + (Km1 * sy) - (Km1 * sr)
        return at.sum(d, 0).T
Beispiel #8
0
    def logp(self, value):
        """
        Calculate log-probability of defined ``MixtureSameFamily`` distribution at specified value.

        Parameters
        ----------
        value : numeric
            Value(s) for which log-probability is calculated. If the log probabilities for multiple
            values are desired the values must be provided in a numpy array or Aesara tensor

        Returns
        -------
        TensorVariable
        """

        comp_dists = self.comp_dists
        w = self.w
        mixture_axis = self.mixture_axis

        event_shape = comp_dists.shape[mixture_axis + 1:]

        # To be able to broadcast the comp_dists.logp with w and value
        # We first have to pad the shape of w to the right with ones
        # so that it can broadcast with the event_shape.

        w = at.shape_padright(w, len(event_shape))

        # Second, we have to add the mixture_axis to the value tensor
        # To insert the mixture axis at the correct location, we use the
        # negative number index. This way, we can also handle situations
        # in which, value is an observed value with more batch dimensions
        # than the ones present in the comp_dists.
        comp_dists_ndim = len(comp_dists.shape)

        value = at.shape_padaxis(value, axis=mixture_axis - comp_dists_ndim)

        comp_logp = comp_dists.logp(value)
        return bound(
            logsumexp(at.log(w) + comp_logp, axis=mixture_axis,
                      keepdims=False),
            w >= 0,
            w <= 1,
            at.allclose(w.sum(axis=mixture_axis - comp_dists_ndim), 1),
            broadcast_conditions=False,
        )
Beispiel #9
0
    def __call__(self, value):
        def logp_normal(mu, tau, value):
            # log probability of individual samples
            k = tau.shape[0]

            def delta(mu):
                return value - mu

            # delta = lambda mu: value - mu
            return (-1 / 2.) * (k * T.log(2 * np.pi) + T.log(1. / det(tau)) +
                                (delta(mu).dot(tau) * delta(mu)).sum(axis=1))

        logps = [
            T.log(self.pi[i]) + logp_normal(mu, self.tau, value)
            for i, mu in enumerate(self.mus)
        ]

        return T.sum(
            logsumexp(T.stacklists(logps)[:, :self.num_training_samples],
                      axis=0))
Beispiel #10
0
 def logp_(value):
     logps = [tt.log(pi[k]) + logp_normal(mus[k], taus[k], value)
              for k in range(K)]
     return tt.sum(logsumexp(tt.stacklists(logps)[:,:n_samples], axis=0))
Beispiel #11
0
def test_logsumexp(values, axis, keepdims):
    npt.assert_almost_equal(
        logsumexp(values, axis=axis, keepdims=keepdims).eval(),
        scipy_logsumexp(values, axis=axis, keepdims=keepdims),
    )
 def logp_(value):
     logps = [tt.log(pi[i]) + logp_normal(mus[i], sigmas[i], value)
              for i in range(3)]
     return tt.sum(logsumexp(tt.stacklists(logps), axis=0))
 def logp_(value):
     logps = [tt.log(pi[i]) + logp_normal(mu, Σ, value)
              for i, mu in enumerate(mus)]
     return tt.sum(logsumexp(tt.stacklists(logps)[:, :n_samples], axis=0))
Beispiel #14
0
 def logp_(value):
     logps = [
         tt.log(pi[k]) + logp_normal(mus[k], taus[k], value)
         for k in range(K)
     ]
     return tt.sum(logsumexp(tt.stacklists(logps)[:, :n_samples], axis=0))
Beispiel #15
0
    return beta * portion_remaining


'''
K = 3
with pm.Model() as model:
    #alpha = pm.Gamma('alpha', 1., 1.)
    #beta = pm.Beta('beta', 1, alpha, shape=K)
    #w = pm.Deterministic('w', stick_breaking(beta))
    w = pm.Dirichlet('w', np.ones(K))
    obs = pm.Mixture('obs', w, [multivariatenormal(init_mean, init_sigma, init_corr, k, dist=True) for k in range(K)], observed=data, shape=data.shape)

'''

from pymc3.distributions.dist_math import bound
from pymc3.math import logsumexp

K = 3
with pm.Model() as model:
    #alpha = pm.Gamma('alpha', 1., 1.)
    #beta = pm.Beta('beta', 1, alpha, shape=K)
    #w = pm.Deterministic('w', stick_breaking(beta))
    w = pm.Dirichlet('w', np.ones(K))
    comp_dists = [
        multivariatenormal(init_mean, init_sigma, init_corr, k, dist=True)
        for k in range(K)
    ]
    logpcomp = tt.stack(
        [comp_dist.logp(T.shared(data)) for comp_dist in comp_dists], axis=1)
    pm.Potential('logp', logsumexp(tt.log(w) + logpcomp, axis=-1).sum())