Pymc3: sample_smc fails for models with transformed variables

Created on 4 Dec 2017  路  6Comments  路  Source: pymc-devs/pymc3

Consider this minimal example:

y = np.array([1, 2, 3])

with pm.Model() as model:
    sigma = pm.Uniform('sigma', 0, 10)
    yl = pm.Normal('likelihood', mu=y.mean(), sd=sigma, observed=y)
    trace = smc.sample_smc(n_steps=20, n_chains=1000, homepath='/tmp') 

This works fine with NUTS but fails with SMC. The error:

~/miniconda3/envs/base/lib/python3.6/site-packages/pymc3/step_methods/smc.py in <dictcomp>(.0)
    185         self.array_population = np.zeros(n_chains)
    186         for _ in range(self.n_chains):
--> 187             self.population.append(pm.Point({v.name: v.random() for v in vars}, model=model))
    188 
    189         self.chain_previous_lpoint = copy.deepcopy(self.population)

TypeError: 'NoneType' object is not callable

It works fine if the Uniform prior is replaced with a Normal--or for that matter, with any other non-bounded distribution. The problem seems to be that the loop over vars includes the transformed variables (in this case, sigma_interval__), so the random() call fails.

All 6 comments

Hi @tyarkoni thanks for the report your diagnostic is right, this is a know limitation of the current implementation of SMC (and something that needs to be fixed!)

In the mean time you can do:

sigma = pm.Uniform('sigma', 0, 10, transform=None)

Hi @aloctavodia, is this the same reason why I am seeing errors running smc.sample_smc with a HalfStudentT prior on my standard deviation for a Normal distribution? I'm new to pymc3 but it looks like HalfStudentT is using a log transformation.

Hi @markberger, I guess you could have the same problem, if that's the case using transform=None should make your model run. Every distribution with a boundary it is automatically transformed by PyMC3. Tomorrow I will send a PR to allow SMC to work with transfomed variables.

It still fails for some model:

import numpy as np
import pymc3 as pm
import theano.tensor as tt
from tempfile import mkdtemp
from pymc3.step_methods import smc

M = 6
N = 10
X = np.random.randn(100, M)
L = np.random.randn(100, N)
w0 = np.random.randn(M, 1)
z0 = np.random.randn(N, 1)
y = np.dot(X, w0) + np.dot(L, z0) + np.random.rand(100,)

test_folder = mkdtemp(prefix='ATMIP_TEST')

n_chains = 500
n_steps = 100
tune_interval = 25
n_jobs = 1

with pm.Model() as mixedEffect2:
    ### hyperpriors
    # transform need to be None for SMC to work (transformed doesnt have random method)
    h2 = pm.Uniform('h2')
    sigma2 = pm.HalfCauchy('sigma2', 5)
    # beta_0 = pm.Uniform('beta_0', lower=-1000, upper=1000)   # a replacement for improper prior
    w = pm.Normal('w', mu=0, sd=100, shape=M)
    z = pm.Normal('z', mu=0, sd=(h2 * sigma2) ** 0.5, shape=N)
    g = tt.dot(L, z)
    y = pm.Normal('y', mu=g + tt.dot(X, w),
                  sd=((1 - h2) * sigma2) ** 0.5, observed=y)
    mtrace = smc.sample_smc(
                            n_steps=n_steps,
                            n_chains=n_chains,
                            tune_interval=tune_interval,
                            n_jobs=n_jobs,
                            progressbar=False,
                            stage=0,
                            homepath=test_folder
                            )

OK, I will check this!

It seems that sampling from the prior is not as straightforward as I previously thought, I will try an alternative and send a PR tomorrow :-)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

springcoil picture springcoil  路  23Comments

twiecki picture twiecki  路  23Comments

kayhan-batmanghelich picture kayhan-batmanghelich  路  46Comments

marciomacielbastos picture marciomacielbastos  路  28Comments

fonnesbeck picture fonnesbeck  路  49Comments