How to avoid this error?

Hello,
I am test-running a Pyro model like below:

 model = nn.Sequential(
    nn.Linear(28 * 28, 100),
    nn.Sigmoid(),
    nn.Linear(100, 100),
    nn.Sigmoid(),
    nn.Linear(100, 10),
)

module.to_pyro_module_(model)

for m in model.modules():
    for name, value in list(m.named_parameters(recurse=False)):
        setattr(m, name, module.PyroSample(prior=dist.Normal(0, 1)
                                      .expand(value.shape)
                                      .to_event(value.dim())))

guide_diag_normal = guides.AutoDiagonalNormal(model)

optimizer_1 = Adam({"lr": 0.000000055}) 
scheduler_1 = pyro.optim.StepLR({'optimizer': optimizer_1, 'optim_args': {'lr': 0.000000055}})
svi_diag_normal = SVI(model, guide_diag_normal, optimizer_1, loss=Trace_ELBO())

input_ids=torch.tensor(random.normal(0,1,28*28))

# aritificial y value
y=torch.tensor(3.562684)

# error is generated here
svi_diag_normal.step(input_ids,y)

The error messages are:

Traceback (most recent call last):

  File "<ipython-input-23-9f299eedcfa7>", line 1, in <module>
    svi_diag_normal.step(input_ids,y)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/infer/svi.py", line 128, in step
    loss = self.loss_and_grads(self.model, self.guide, *args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/infer/trace_elbo.py", line 126, in loss_and_grads
    for model_trace, guide_trace in self._get_traces(model, guide, args, kwargs):

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/infer/elbo.py", line 170, in _get_traces
    yield self._get_trace(model, guide, args, kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/infer/trace_elbo.py", line 53, in _get_trace
    "flat", self.max_plate_nesting, model, guide, args, kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/infer/enum.py", line 44, in get_importance_trace
    guide_trace = poutine.trace(guide, graph_type=graph_type).get_trace(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/poutine/trace_messenger.py", line 185, in get_trace
    self(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/poutine/trace_messenger.py", line 165, in __call__
    ret = self.fn(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/nn/module.py", line 290, in __call__
    return super().__call__(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/torch/nn/modules/module.py", line 722, in _call_impl
    result = self.forward(*input, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/infer/autoguide/guides.py", line 679, in forward
    self._setup_prototype(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/infer/autoguide/guides.py", line 819, in _setup_prototype
    super()._setup_prototype(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/infer/autoguide/guides.py", line 577, in _setup_prototype
    super()._setup_prototype(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/infer/autoguide/guides.py", line 156, in _setup_prototype
    self.prototype_trace = poutine.block(poutine.trace(model).get_trace)(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/poutine/messenger.py", line 11, in _context_wrap
    return fn(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/poutine/trace_messenger.py", line 185, in get_trace
    self(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/poutine/trace_messenger.py", line 165, in __call__
    ret = self.fn(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/poutine/messenger.py", line 11, in _context_wrap
    return fn(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/poutine/messenger.py", line 11, in _context_wrap
    return fn(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/pyro/nn/module.py", line 290, in __call__
    return super().__call__(*args, **kwargs)

  File "/Users/hyunjindominiquecho/opt/anaconda3/lib/python3.7/site-packages/torch/nn/modules/module.py", line 722, in _call_impl
    result = self.forward(*input, **kwargs)

TypeError: forward() takes 2 positional arguments but 3 were given

How can I avoid this error?

Thank you,

Your model as written only takes one argument (input_ids), but you’re passing it two arguments (input_ids and y). What is y supposed to be here?

OK I’ve found the fix will write it out here to help someone in the future:

neural_network = nn.Sequential(
     nn.Linear(28 * 28, 100),
     nn.Sigmoid(),
     nn.Linear(100, 100),
     nn.Sigmoid(),
     nn.Linear(100, 1),
 )
 
module.to_pyro_module_(neural_network)
 
for m in neural_network.modules():
     for name, value in list(m.named_parameters(recurse=False)):
         setattr(m, name, module.PyroSample(prior=dist.Normal(0, 1)
                                       .expand(value.shape)
                                       .to_event(value.dim())))

This bit is important

class BayesianNeuralNetwork(PyroModule):
     def __init__(self, neural_network):
         super().__init__()
        self.neural_network= neural_network
 
     def forward(self, x, y=None):
         sigma = pyro.sample("sigma", dist.Uniform(0., 10.))
         mean = self.neural_network(x).squeeze(-1)
         with pyro.plate("data", x.shape[0]):
             obs = pyro.sample("obs", dist.Normal(mean, sigma), obs=y)
         return mean
model = BayesianNeuralNetwork(neural_network)
 
guide= guides.AutoDiagonalNormal(model)
 
optimizer = Adam({"lr": 0.03}) 
 
svi= SVI(model, guide, optimizer, loss=Trace_ELBO())
 
X=torch.rand(85,10)
y=torch.rand(85,1)

pyro.clear_param_store()
svi.step(X,y)

So the key is to realise as per @eb8680_2 's comment that when we turn a torch.nn into a pyromodule it still only takes 1 input, X.

When we do a bayesian regression as in the tutorial (Bayesian Regression - Introduction (Part 1) — Pyro Tutorials 1.8.4 documentation), we build on top of the nn.linears a model that also takes y.

When we use a bayesian neural network we need to do this too.

I’d be tempted to make a tutorial on this on github because this isn’t so clear to new users of pyro coming from pytorch (although this process has taught me a lot about the workings of pyro!)

3 Likes