SMC sampling appears to not allow supplying a starting trace


#1

Hello, firstly I really want to thank the developers (especially @aloctavodia) for the recent refactoring of the SMC methods. Without knowing a great deal things here appear much more user friendly and PyMC3-y!

I cloned the current master from github and got some errors when trying to use a starting trace, this was because my model may have some issues with _initial_population(). 2nd code block below is reproducing the error during the call to _initial_population() in smc.py. Anyway, as I was looking into this I found that _initial_population() is called for all cases in sample_smc().

Perhaps I am wrong but this function doesn’t need to be called if a starting trace is supplied (i.e. start=prev_trace). In lines 463 to 493 of smc.py, _initial_population is called on line 493 looks like it overwrites any step.population object that may have existed. Am I missing something?

I made _initial_population run only conditionally if start=None and my code appears to run as expected with start=prev_trace as 1st code block below. Please let me know if this is a bug or if I’m misunderstanding how the step.population gets set from a start trace. If it is a bug I would happily open an issue, discuss how to fix it, then make a PR. Thanks!

with update_model:
    trace_updated = pm.sample(
        200,
        start=prev_trace,
        chains=200,
        cores=1,
        step=pm.SMC(),
    )
with update_model:
    step=pm.SMC()
    print(step.vars)
    v = step.vars[0]
    start = update_model.test_point
    print(pm.util.is_transformed_name(v.name))
    trans = v.distribution.transform_used.forward_val
    print(trans(step.vars[0].distribution.dist.random(size=chains, point=start)))

output of above:

Using present model likelihood!
[sigma0_interval__, mu2_interval__, mu1_interval__, mu0_interval__, theta_5_interval__, theta_4_interval__, theta_3_interval__, theta_2_interval__, theta_1_interval__]
True
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-44-5d9c3d05854d> in <module>()
      6     print(pm.util.is_transformed_name(v.name))
      7     trans = v.distribution.transform_used.forward_val
----> 8     print(trans(step.vars[0].distribution.dist.random(size=chains, point=start)))

TypeError: random() got an unexpected keyword argument 'point'

#2

Good catch! I think you are right and this is a bug. A Pull Request will be more than welcome.


#3

Cool, it’s my first time contributing here but I’ll take a stab! I opened an issue for this, and I’ll put out a PR after running the pytests:

 pytest --cov=pymc3 pymc3/tests/test_smc.py

#4

Here’s a simple little Pull Request. Tried to follow the guidelines as closely as possible. Please let me know there if you would like some improvements/changes to it.