Shape mismatch error in 'sample_ppc'


I am trying to use PPC to do the criticism for mixture model but encountered shape mismatch error in sample_ppc.

The data generation process is:

def build_toy_dataset(N, K):
    pi = np.array([0.2, 0.5, 0.3])
    mus = [[1, 1], [-1, -1], [2,-2]]
    stds = [[0.1, 0.1], [0.1, 0.2], [0.2, 0.3]]
    x = np.zeros((N, 2), dtype=np.float32)
    y = np.zeros((N,),
    for n in range(N):
        k = np.argmax(np.random.multinomial(1, pi))
        x[n, :] = np.random.multivariate_normal(mus[k], np.diag(stds[k]))
        y[n] = k

    return x,y

N = 500  # number of data points
D = 2  # dimensionality of data

X, y = build_toy_dataset(N, 3)

Model and NUTS inference:

# set up model
K = 3
with pm.Model() as model:
    pi = pm.Dirichlet('pi', np.ones(K))

    comp_dist = []
    mu = []
    packed_chol = []
    chol = []
    for i in range(K):
        mu.append(pm.Normal('mu%i'%i, 0, 10, shape=2))
        chol.append(pm.expand_packed_triangular(2, packed_chol[i], lower=True))
        comp_dist.append(pm.MvNormal.dist(mu=mu[i], chol=chol[i]))

    xobs = pm.Mixture('x_obs', pi, comp_dist,
with model:
    trace = pm.sample(1000, tune=1000, chains=1)

However, when I use sample_ppc to generate posterior predictive samples, I get the following error:

with model:
    ppc = pm.sample_ppc(trace, 2)
IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (1000,) (500,2)

It seems like somehow ppc flattens X of shape(500,2) into (1000,). But I don’t know how to fix that.

I would really appreciate if you guys could help me fix this!

Can confirm - the random for multidimensional mixture is wrong :cold_sweat:
I opened an issue: but I am not sure if it would really be fixed - as I have modified this code multiple times and each time I thought that I fixed everything…

Thanks. Hope this could be fixed soon :slight_smile:

FYI, are the inference results for GMM still reliable?

Yes, but be careful of model switching - with sampling one chain only and check the result carefully you should be fine.

Thanks! Do you have any suggestions for hand coding PPC for GMM since I am going to use that for my project?

extracting the posterior from trace, and simulate it in scipy/numpy should work.
Otherwise, you can try setting up a gmm from scikit-learn, using the posterior mean as parameter input - I never actually do it this way, but it should work as well.

I have run into this problem as well - is it still unfixed?

Ah ok - when cloning the most recent version from github, things seem to work. Thanks for fixing!