Normal distribution throws errors when using shared variables


#1

I am having trouble implementing Normal distribution with mu that is a shared variable. See below example code:

product_mu_shared = shared(0.0)
product_sd = 0.1
total_quantity_shared = shared(np.array([0.0, 0.1, 0.2]))

with pm.Model() as quantity_model:    
    
    # Priors
    a = pm.Lognormal('a',mu=product_mu_shared, sd=product_sd)
    b = pm.Normal('b',mu=0.0, sd=product_sd)
    d = pm.Normal('d', mu=product_mu_shared, sd=product_sd)


    # Data likelihood
    vol = pm.Deterministic('vol', a+d, observed=total_quantity_shared)
        
    # Inference
    trace = pm.sample(10,tune=10)

Note: I’ve tried this on two versions of pymc3 (3.4.1 and 3.5) with same outcome
And I receive the following error message:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-6131815c61f7> in <module>()
      4     a = pm.Lognormal('a',mu=product_mu_shared, sd=product_sd)
      5     b = pm.Normal('b',mu=0.0, sd=product_sd)
----> 6     d = pm.Normal('d', mu=product_mu_shared, sd=product_sd)
      7 
      8 

C:\ProgramData\Anaconda3\lib\site-packages\pymc3\distributions\distribution.py in __new__(cls, name, *args, **kwargs)
     40             total_size = kwargs.pop('total_size', None)
     41             dist = cls.dist(*args, **kwargs)
---> 42             return model.Var(name, dist, data, total_size)
     43         else:
     44             raise TypeError("Name needs to be a string but got: {}".format(name))

C:\ProgramData\Anaconda3\lib\site-packages\pymc3\model.py in Var(self, name, dist, data, total_size)
    806                 with self:
    807                     var = FreeRV(name=name, distribution=dist,
--> 808                                  total_size=total_size, model=self)
    809                 self.free_RVs.append(var)
    810             else:

C:\ProgramData\Anaconda3\lib\site-packages\pymc3\model.py in __init__(self, type, owner, index, name, distribution, total_size, model)
   1205             self.distribution = distribution
   1206             self.tag.test_value = np.ones(
-> 1207                 distribution.shape, distribution.dtype) * distribution.default()
   1208             self.logp_elemwiset = distribution.logp(self)
   1209             # The logp might need scaling in minibatches.

C:\ProgramData\Anaconda3\lib\site-packages\pymc3\distributions\distribution.py in default(self)
     65 
     66     def default(self):
---> 67         return np.asarray(self.get_test_val(self.testval, self.defaults), self.dtype)
     68 
     69     def get_test_val(self, val, defaults):

C:\ProgramData\Anaconda3\lib\site-packages\pymc3\distributions\distribution.py in get_test_val(self, val, defaults)
     70         if val is None:
     71             for v in defaults:
---> 72                 if hasattr(self, v) and np.all(np.isfinite(self.getattr_value(v))):
     73                     return self.getattr_value(v)
     74         else:

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

#2

This is a bug, could you please raise an issue on github?


Changing prior during inference
#3

As a workaround for now, you can assign a test value to Normal:

    d = pm.Normal('d', mu=product_mu_shared, sd=product_sd, testval=0.)

FYI, you cannot put observed in a Deterministic node.


#4

Bug raise: