SVI Manual guide with data argument that unpacks


#1

Hi!

I am trying to define my own guide for my already working model. I have a tiny problem, the model takes an argument data that unpacks into 3 as such:

def model (data):

max_var,data1, data2 = data

so…I wanted to keep the same structure in the guide:

def guide(data):

max_var,data1, data2 = data

but I get the following error:

TypeError: cannot unpack non-iterable method object

and I feel is something related to pyro not accepting this kind of arguments? I do have pyro.enable_validation(True) and I don’t get more errors to traceback, neither when I try to debug…

The context is that I am still figuring out exactly what I need for my guide, so I might be making some beginner’s mistakes. I am following several examples in Github, the forum and the docs.

So far I know we specify fixed parameters with pyro.param and sampled parameters with pyro.sample and we don’t specify the likelihood (observed variables) in the guide. I hope I am in the right direction.

Thank you very much for your attention and time


#2

Can you paste more code? In particular, how are you calling svi.step()?

Pyro models and guides can take any number of args and any combination of *args and **kwargs; the only restriction is that model and guide signatures must agree, and that svi.step(-) must take the same *args, **kwargs as the model and the guide. In you example, you should also be able to use:

def model(my_var, data1, data2):
    ...

def guide(my_var, data1, data2):
    ...

for epoch in range(1000):
    svi.step(my_var, data1, data2)

#3

Okey, thanks. I see that could be the problem. I am using a borrowed wrapper on the svi class:

class SVIEngine(Engine):
    def __init__(self, *args, step_args=None, **kwargs):
        self.svi = SVI(*args, **kwargs)
        self._step_args = step_args or {}
        super(SVIEngine, self).__init__(self._update)

    def _update(self, engine, batch):
        return -engine.svi.step(batch, **self._step_args)

but it is supposed to take the same arguments as the normal SVI…and then I call it like this (everything is inside a class):

 #GUIDE
 global_guide = self.guide(self.model)
 #OPTIMIZER
 optim =pyro.optim.AdagradRMSProp(dict())
 #ELBO
 elbo= Trace_ELBO()
svi_engine = SVIEngine(self.model,global_guide,optim,loss=elbo)

If you spot the problem quicker than me, probably hehe, I will appreciate it. Otherwise, you gave me a clue to work on, thanks!!! :slight_smile:


#4

Ok, I think I fixed ti :slight_smile:

global_guide = self.guide(data)

I confused my self