Sampling multiple observations from Likelihood

I’m new to Pyro. Trying to find an MCMC sample of the true posterior of the following problem:

The likelihood / Simulator / model - needs to sample 4 samples from this multivariate normal distribution.

Is there a way to specify this in pyro?

1 workaround that I did is expand the MVN from 2 to 8 dimensions, but this code throws an error and won’t run:

def model(obs):
    theta = pyro.sample("theta", dist.Uniform(lower*torch.ones(dim), high=upper*torch.ones(dim)))
    mu = theta[:2].repeat(1,4)
    s1 = theta[2]**2
    s2 = theta[3]**2
    r = torch.tanh(theta[4])
    S = torch.tensor([[s1**2, r*s1*s2],[r*s1*s2, s2**2]])
    Sigma = torch.block_diag(S,S,S,S)
    return pyro.sample("obs", dist.MultivariateNormal(mu[0,], S), obs=obs)

nuts_kernel = NUTS(model)
mcmc = MCMC(
    nuts_kernel,
    num_samples=1000,
    warmup_steps=1000,
    num_chains=1,
)
mcmc.run(x_obs)

UPDATE: Ok found the error - I didn’t change the S to Sigma in the distribution…

Still I wonder if there’s a way to do this without the workaround?

you want to wrap your distribution in a plate; see just about any (num)pyro example/tutorial

Hi @DavidRefaeli I think it will be easiest to use pyro.plate. Check out the tensor shapes tutorial.

def model(obs):
    assert obs.shape == (4, 2)
    with pyro.plate("thetas", 5):
        theta = pyro.sample("theta", dist.Uniform(-3, 3))
    m = theta[:2]
    s1 = theta[2]**2
    s2 = theta[3]**2
    rho = theta[4].tanh()
    s12 = rho * s1 * s2
    S = torch.stack([torch.stack([s1**2, s12]),
                     torch.stack([s12, s2**2])])
    with pyro.plate("data", 4):
        pyro.sample("obs", dist.MultivariateNormal(m, S), obs=obs)

Thank you both!