Passing parameters into Sampled

Is it possible to pass parameters into a Sampled model? For example, adapting the first few lines of the model in the readme:

@sampled
def student():
difficulty = pm.Beta(‘difficulty’, alpha=5, beta=5)

and instead doing

@sampled
def student(alpha, beta):
difficulty = pm.Beta(‘difficulty’, alpha=alpha, beta=beta)

Calling the subsequent

with student(alpha=5, beta=5):
prior = pm.sample()

leads to the error:

TypeError: wrapped_f() takes exactly 0 arguments (2 given)

Is this feature not implemented or is there another way to achieve this I’m not seeing?

Turn on the bat signal for you: @colcarroll

3 Likes

Hrm… I am not able to recreate the problem you are describing. I think you would have a problem only if one of your parameters was also named alpha or beta, in which case it would also be interpreted as an observed variable. Maybe you need to provide more of your example to recreate the problem?

image

Ah, apologies, I should’ve actually written an MWE. Then I would’ve seen I wasn’t passing named parameters, which is why it was failing, i.e. my actual code was with student(2, 4) as model:. Thanks!

1 Like

To be honest, it looked like it would fail to me. There’s an ugly try/except TypeError to allow that. I would probably use a special keyword if I did this again, so you could do something like

with student(2, 4, observations={'difficulty': 0.2}):
    ...

to pass observations. It makes things a little less magical and a little more obvious. Let me know if this seems like a good idea, and I can cut a new “major release”!

Was actually just about to respond that I was able to produce the error when passing in both parameters and observations. Interestingly the error is different based on using named parameters or not.

image

Ugh, yeah, right now you can make that first example work if you make the signature def student(alpha, beta, **kwargs):. The source is super terse, but it tried to just pass all the provided arguments to the function right now. That throws a TypeError, but then you get the less informative exception when it fails again.

The **kwargs works! The dict of observations you mentioned above would be cleaner but as long as there’s documentation for the current implementation it works well enough.

Hi,
I have the same issue and tried all versions of 1. changing var names, 2. explicitly passing the values and also adding **kwargs to the function but it fails in all cases.

My model looks like this currently but it is just a test version bc in the end I need to pass 9 values (which represent different conditions) that covary with the observed variable; so I first wanted to test it on an easy model which looks like this:

@sampled
def ff_from_f0_model(f0_observations, ff_observarions, **kwargs):
    intercept = pm.Uniform("intercept", lower=0, upper=20)
    slope = pm.Normal("slope", mu=0, sigma=5)
    sigma_sq = pm.TruncatedNormal('sigma_sq', mu=0, sigma=10, lower=0)
    
    y_pred = pm.Normal('y', mu=intercept + slope * f0_observation, sigma=sigma_sq, observed = ff_observarions)
with ff_from_f0_model(f0_observations=df['f0'], ff_observarions=df['ff]) as model:
    trace = pm.sample()

The error is the same

TypeError: ff_from_f0_model() missing 2 required positional arguments: 'f0_observations' and 'ff_observarions'

I would appreciate some help!