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)
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, )
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))
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)
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)
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
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
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, )
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))
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))
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))
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))
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())