Generate samples using model function itself?

To do inference, I created a model(data) and guide(data), where data is the observed data.
Thus my model(data) contains the line: pyro.sample(‘obs’, dist.Normal(mu,1.), obs=data).
Then when I call log_prob_sum(), this will compute using the observed data.

However, I also would like to simulate some data by sampling from the model p(z,x), then compute log p(z,x):
Do I need to create a separate function without ‘obs=data’ (to generate z,x and then call log_prob_sum()?)
or is there a way that I can re-use model(data) while ignoring the observed data, to sample z,x and then compute log p(z,x)?

Could you please provide some code samples? thank you!

if i understand your question you want to take a look at uncondition: Poutine (Effect handlers) — Pyro documentation

unconditioned_model = poutine.uncondition(model)

1 Like

Thank you very much @martinjankowiak, this works! :smile:
I see it will ignore the data values in obs=data, and sample from the distribution.

Thanks for posting this question @pookie. I need to do something similar where I want to sample from the model itself.

Hi @martinjankowiak,
I need to sample from unconditioned model using MCMC-NUTS. So I modified the code available at Pyro-NUTS-docs based on poutine.uncondition(model) comment in this question thread.

def model(data):
      coefs_mean = torch.zeros(dim)
      coefs = pyro.sample('beta', dist.Normal(coefs_mean, torch.ones(3)))
      logits = coefs * data
      logits = logits.sum(-1)
      y = pyro.sample('y', dist.Bernoulli(logits=logits), obs=labels)
      return y

def uncondition_model(data):
      return poutine.uncondition(model)

I need the ‘y’ samples. Is it possible? If I use below code, I don’t get any value for beta or y.

nuts_kernel = NUTS(uncondition_model, adapt_step_size=True)
mcmc = MCMC(nuts_kernel, num_samples=50, warmup_steps=30)
mcmc.run(data)
mcmc.get_samples()[‘y’].mean(0)
mcmc.get_samples()[‘beta’].mean(0)

However, if I use NUTS(model, adapt_step_size=True) then mcmc.get_samples()['beta'].mean(0) does start to work (as in original Pyro-NUTS-docs example). But what I actually need is y with uncondition_model.

I guess poutine.trace(...).get_trace(...) can give me the ‘y’ samples (as discussed in this pyro-forum-post), but I am assuming that through trace function what I get are random samples from the distribution. What if I want samples via ‘NUTS’, is that possible?

Thanks for all the help!!

@rkmalaiya can you clarify whether you mean samples from the prior predictive distribution over y or the posterior predictive distribution over y given some observed values for y? If the latter, you can use pyro.infer.Predictive. See the baseball example for a complete worked example in the context of MCMC.

Is there a version of uncondition for NumPyro?

Hi @eb8680_2,

Thanks for your response!

My apologies I do not completely understand the predictive distribution concept yet.

What I need is to sample from my model without any observed data. Or we can say I need to simulate data from the model itself. I guess it may mean I need prior predictive distribution.

Below is how I tried to sample it from the baseball example (without providing any observed data).

nuts = NUTS(fully_pooled)
mcmc = MCMC(nuts, num_samples=100, warmup_steps=10)
mcmc.run(at_bats, None)
samples_fully_pooled = mcmc.get_samples()

I got the “phi” samples as below

{'phi': tensor([0.0015, 0.0279, 0.0971, 0.6689, 0.7645, 0.0379, 0.0799, 0.7924, 0.4293,
         0.4113, 0.0077, 0.6559, 0.6589, 0.4770, 0.4436, 0.2324, 0.1213, 0.9407,
         0.9388, 0.5535, 0.5535, 0.2001, 0.1861, 0.1063, 0.7354, 0.6615, 0.8080,

But what I need is “obs” site from the fully_pooled model. Basically I want to simulate “obs”.

So when I try

model_trace = pyro.poutine.trace(fully_pooled)
samples = model_trace.get_trace(at_bats, None)
samples.nodes[“obs”][“value”]

I do get the “obs” site values. I was wondering can I simulate the “obs” using MCMC?

@rkmalaiya I’m not sure I understand why you want to use MCMC if you’re not conditioning on data, can you explain? Pyro models that do not include observations or factor statements are “generative,” meaning that if what you want to do is sample parameter values from your priors and then simulate fake data given those values, you can set obs=None at all sample sites (either via uncondition or directly in the model code), then run the model and extract the resulting samples with trace as in your final snippet.

@GUIpsp no, not yet - feel free to open an issue or a pull request!

Thanks for the response @eb8680_2.

It’s an interesting point on why I want to use MCMC-NUTS when I am not conditioning on data?

Earlier, I used pymc3 MCMC (Metrapolis Hastings) to generate fake data and thought its the standard way to do it. My apologies, I am still learning all the Probability Programming concepts :slight_smile:

Coming back to current forum question, so earlier with the help of @fehiepsi in this other pyro-forum-question I built a model and wanted to test the invariance properties of the model. So I thought of a simple test.
First, hard code some parameters in the model (guess and slip parameters in the above model) and generate fake data.
Second, condition the model on the fake data and compare the mean and variance of parameters (guess and slip) with the initial hard coded value. I want to see how does the invariance of model holds particularly in small sample sizes of fake data. In real data scenario, I am probably going to get around 40-60 data points.

Now, given my model is using MCMC-NUTS to do inference, I naively thought let’s generate data using MCMC-NUTS as well or any other MCMC algo (like I used Metrapolis in PyMC3) so that in both the steps above, the MCMC algo remains the same.

However, when I think about it now, it should be fine to do Step 1 using Trace method and then Step 2 using MCMC-NUTS. I wonder though, is it mathematically not possible to sample fake data using MCMC-NUTS but possible using MCMC-Metrapolis? Or am I severely lacking some concepts :smiley:

Thanks for all the help and talking me through this issue. Have a great day ahead!

MCMC is an algorithm for sampling from unnormalized probability distributions, i.e. distributions whose joint density functions we only know up to a constant factor that may be expensive to compute. For example, in Bayesian inference we usually only know the posterior distribution up to a constant factor.

Pyro programs with no observations or pyro.factor statements represent normalized probability distributions, which we can sample from exactly without having to resort to approximate algorithms like MCMC, although doing so is not mathematically incorrect.

You can find detailed, intuitive explanations of these ideas in the first few chapters of the textbooks Probabilistic Models of Cognition or Bayesian Cognitive Modeling, which are introductions to probabilistic programming and Bayesian data analysis for psychologists and cognitive scientists.

1 Like

This is super helpful! Thanks for recommending the books :smiley:

I am a bit confused. I thought you can use Predictive to simulate a thousand data points with (optional) fixed parameters if you want. You can use NUTS to do the job but it will be unnecessarily slow.

Hi @fehiepsi,

Do you mean using Predictive function as discussed in this pyro-forum-question. I just used the Predictive function without providing posterior distribution and I am able to generate samples for “obs” site :slight_smile: . As I understand Predictive function is similar to “trace”.

Yes, you are right!