Apologizes for coming here with a basic question like this, but all the attempts has failed.
I am trying to draw a number of events using Poisson distribution:
N = pyro.sample(“N”, dist.Poisson(torch.as_tensor([10.]))
and then draw N times from a normal distribution and add the numbers.
At the end I want to sample from a model using Predictive with parallel=True.
Yes, this is just to get the distribution for sum of normals based on fixed N.
So I want to include torch.sum(results) inside a model() and make it all in a vectorised way, so that could draw k samples from resulting sum.
Here is a complete example:
def model():
p = pyro.sample("p", dist.Poisson(torch.as_tensor([10.])))
x = pyro.sample("x", dist.Normal(40*torch.ones(p.int().item()),10.))
y = pyro.sample("y", dist.Normal(35*torch.ones(p.int().item()),20.))
ev = torch.sum(x>y)
if ev>0:
reward = pyro.sample("reward", dist.Normal(torch.as_tensor([100.]),torch.as_tensor([5.])).expand([ev]))
s = torch.sum(reward)
else:
s = 0
return s
Executing model() works but Predictive(model, {}, num_samples=1000)() fails.
I’ve been working with variables of changing dimension in Pyro as well, so far I haven’t had much luck changing the dimension on-the-fly. Here’s a work-around that might fit in your use case:
The idea is to set your maximum theoretical N (30 seems to work fine for Poisson(10)) and send the whole loc and scale vectors (size = 30) through the Normal sampling operation. You then zero out M = 30 - N of your values, and use the Deterministic function to produce the sum of the normals.
The code worked for me - not the cleanest solution, but it might work for you.
Yes, that is a good workaround!
Can anyone advice if the same can be obtained with a more elegant approach? Problem seems to be pretty simple in theory…
This is likely an issue with Predictive – see this post and this associated issue. In particular, when I attempt to use Predictive, I get an error like
/opt/anaconda3/lib/python3.7/site-packages/pyro/infer/predictive.py in _predictive_sequential(model, posterior_samples, model_args, model_kwargs, num_samples, return_site_shapes, return_trace)
46 else:
47 return {site: torch.stack([s[site] for s in collected]).reshape(shape)
---> 48 for site, shape in return_site_shapes.items()}
which makes sense because the shape is itself an rv.