Hi all,
I am using the following (anti?) pattern to define a guide that returns computations required downstream. Some background: I have a model
and a guide
, and in both model
and guide
I need a sub_model
to compute some expected values (it’s a non-linear regression model). The sub_model
has it’s own parameters which I would like to encapsulate from the outer model
(so that I can easily swap the sub_model
for something else). I want to use an AutoMultivariateNormal
guide for the parameters of the sub_model
. However, this guide does not return the output of the sub_model
. So what I ended up doing is this (the crux is the guide method)
class SubModel(PyroModule):
def __init__(self):
self.auto_guide = AutoMultivariateNormal(self)
def forward(self, x):
# sample some parameters, compute tensor y
# ...
return y
def guide(self, x):
# call the auto_guide, and get a trace
guide_trace = poutine.trace(self.auto_guide).get_trace(x)
# then replay the model defined in forward with parameters sampled from auto_guide
# However, we have to hide pyro sites from the outside world!
y = poutine.block(poutine.replay(self, guide_trace))(x)
return y
Now I can use sub_model(x)
to compute the prediction required in model
, and sub_model.guide(x)
to do the same in my guide
, while also sampling from the multivariate normal.
My question is: Is this good practice? Does it result in additional computational cost? For instance because the forward method is run twice?
Let me know what you think, or if there are good alternatives. Thanks,
Chris