Skip to content

AttributeError: scratchpad instance has no attribute 'test_value' #562

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
yangky11 opened this issue Jul 8, 2014 · 14 comments
Closed

AttributeError: scratchpad instance has no attribute 'test_value' #562

yangky11 opened this issue Jul 8, 2014 · 14 comments

Comments

@yangky11
Copy link

yangky11 commented Jul 8, 2014

Hi
When I run the example pymc/pymc/examples/latent_occupancy.py, the following exception occurs:

/home/yangky11/room502B/graphicalModel/example.py in <module>()
     52 
     53     # Latent variable for occupancy
---> 54     z = Bernoulli('z', p, y.shape)
     55 
     56     # Estimated mean count

/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/distributions/distribution.pyc in __new__(cls, name, *args, **kwargs)
     17             data = kwargs.pop('observed', None)
     18             dist = cls.dist(*args, **kwargs)
---> 19             return model.Var(name, dist, data)
     20         elif name is None:
     21             return object.__new__(cls) #for pickle

/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/model.pyc in Var(self, name, dist, data)
    142         """
    143         if data is None:
--> 144             var = FreeRV(name=name, distribution=dist, model=self)
    145             self.free_RVs.append(var)
    146         else:

/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/model.pyc in __init__(self, type, owner, index, name, distribution, model)
    320             self.distribution = distribution
    321             self.tag.test_value = np.ones(
--> 322                 distribution.shape, distribution.dtype) * distribution.default()
    323             self.logp_elemwiset = distribution.logp(self)
    324             self.model = model

/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/distributions/distribution.pyc in default(self)
     40 
     41     def default(self):
---> 42         return self.get_test_val(self.testval, self.defaults)
     43 
     44     def get_test_val(self, val, defaults):

/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/distributions/distribution.pyc in get_test_val(self, val, defaults)
     57 
     58         if isinstance(val, t.TensorVariable):
---> 59             return val.tag.test_value
     60 
     61         return val

AttributeError: scratchpad instance has no attribute 'test_value'

It seems that this happens whenever I create a free Bernoulli random variable

@jsalvatier
Copy link
Member

But doesn't happen with other distributions?

This is an odd error, I haven't see this before. What version of theano do
you have? Have you changed any theano config values?

On Tue, Jul 8, 2014 at 6:51 AM, Kaiyu Yang [email protected] wrote:

Hi
When I run the example pymc / pymc / examples / latent_occupancy.py, the
following exception occurs:

Traceback (most recent call last):
File "example.py", line 54, in
z = Bernoulli('z', p, y.shape)
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/distributions/distribution.py", line 19, in new
return model.Var(name, dist, data)
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/model.py", line 144, in Var
var = FreeRV(name=name, distribution=dist, model=self)
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/model.py", line 322, in init
distribution.shape, distribution.dtype) * distribution.default()
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/distributions/distribution.py", line 42, in default
return self.get_test_val(self.testval, self.defaults)
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/distributions/distribution.py", line 59, in get_test_val
return val.tag.test_value
AttributeError: scratchpad instance has no attribute 'test_value'

It seems that this happens whenever I create a free Bernoulli random
variable


Reply to this email directly or view it on GitHub
#562.

@twiecki
Copy link
Member

twiecki commented Aug 17, 2014

Closing because of no response.

@twiecki twiecki closed this as completed Aug 17, 2014
@michaelosthege
Copy link
Member

I am getting the same error. Consider this code:

import pymc3
from collections import OrderedDict
import traceback

distributions = OrderedDict([
    ("normal", pymc3.Normal.dist(mu=2, sd=1/3)),
    ("gamma", pymc3.Gamma.dist(alpha=2, beta=1/3)),
    ("beta", pymc3.Beta.dist(mu=2, sd=1)),
    ("constant", pymc3.Constant.dist(5.3))
])

for name,dist in distributions.items():
    try:
        with pymc3.Model() as pmodel:
            rv = pmodel.Var(name, dist)
            trace = pymc3.sample(200, n_init=200)
        print("\r\n\r\n>>>>>>>> {} succeeded\r\n\r\n".format(name))
    except Exception as ex:
        print("\r\n\r\n>>>>>>>> {} failed\r\n\r\n".format(name))
        traceback.print_exc()

The Normal and Constant distributions work fine, while the Gamma and Beta fail:

Auto-assigning NUTS sampler...
Initializing NUTS using jitter+adapt_diag...
 85%|###################################################################            | 594/700 [00:00<00:00, 939.53it/s]C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\step_methods\hmc\nuts.py:429: UserWarning: Chain 0 contains only 200 samples.
  % (self._chain_id, n))
100%|###############################################################################| 700/700 [00:00<00:00, 994.19it/s]


>>>>>>>> normal succeeded




>>>>>>>> gamma failed


Traceback (most recent call last):
  File "C:\Users\zufal\Source\Repos\pero\pero\tests\demo.py", line 15, in <module>
    rv = pmodel.Var(name, dist)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\model.py", line 759, in Var
    model=self)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\model.py", line 1386, in __init__
    transformed_name, transform.apply(distribution), total_size=total_size)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\transforms.py", line 37, in apply
    return TransformedDistribution.dist(dist, self)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\distribution.py", line 47, in dist
    dist.__init__(*args, **kwargs)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\transforms.py", line 62, in __init__
    testval = forward(dist.default())
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\distribution.py", line 62, in default
    return np.asarray(self.get_test_val(self.testval, self.defaults), self.dtype)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\distribution.py", line 67, in get_test_val
    if hasattr(self, v) and np.all(np.isfinite(self.getattr_value(v))):
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\distribution.py", line 83, in getattr_value
    return val.tag.test_value
AttributeError: 'scratchpad' object has no attribute 'test_value'


>>>>>>>> beta failed


Traceback (most recent call last):
  File "C:\Users\zufal\Source\Repos\pero\pero\tests\demo.py", line 15, in <module>
    rv = pmodel.Var(name, dist)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\model.py", line 759, in Var
    model=self)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\model.py", line 1386, in __init__
    transformed_name, transform.apply(distribution), total_size=total_size)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\transforms.py", line 37, in apply
    return TransformedDistribution.dist(dist, self)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\distribution.py", line 47, in dist
    dist.__init__(*args, **kwargs)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\transforms.py", line 62, in __init__
    testval = forward(dist.default())
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\distribution.py", line 62, in default
    return np.asarray(self.get_test_val(self.testval, self.defaults), self.dtype)
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\distribution.py", line 67, in get_test_val
    if hasattr(self, v) and np.all(np.isfinite(self.getattr_value(v))):
  File "C:\Users\zufal\Miniconda3\envs\venv35\lib\site-packages\pymc3\distributions\distribution.py", line 83, in getattr_value
    return val.tag.test_value
AttributeError: 'scratchpad' object has no attribute 'test_value'
Assigned Metropolis to constant
100%|##############################################################################| 700/700 [00:00<00:00, 4142.53it/s]


>>>>>>>> constant succeeded


Press any key to continue . . .

I have absolutely no idea what causes it, but it's a major roadblock for using Distribution.dist and pmodel.Var(name, dist)

@junpenglao
Copy link
Member

@michaelosthege The work around is to provide a testval:

    ("gamma", pymc3.Gamma.dist(alpha=2, beta=1/3, testval=.5)),
    ("beta", pymc3.Beta.dist(alpha=1, beta=1, testval=.5)),

@michaelosthege
Copy link
Member

@junpenglao There are even more ways how this error can occur:

This raises AttributeError: 'scratchpad' object has no attribute 'test_value' because of the Gamma variable:

u = pymc3.DiscreteUniform.dist(0, 4, testval=3)
g = pymc3.Gamma.dist(alpha=12, beta=2, testval=8.2)
with pymc3.Model(theano_config={'compute_test_value': 'off'}) as pmodel:
    pmodel.Var("u", u)
    pmodel.Var("g", g)

And this raises AttributeError: Elemwise{Cast{int32}}.0 has no test value because of the DiscreteUniform variable:

u = pymc3.DiscreteUniform.dist(0, 4, testval=3)
g = pymc3.Gamma.dist(alpha=12, beta=2, testval=8.2)
with pymc3.Model() as pmodel:
    pmodel.Var("u", u)
    pmodel.Var("g", g)

The way how pymc3/theano make use of testval/test_value and the theano_config is quite fragile.. :(

@twiecki
Copy link
Member

twiecki commented Sep 25, 2017

The second case is quite odd indeed. Any idea what's causing this?

@michaelosthege
Copy link
Member

michaelosthege commented Sep 25, 2017

My best guess so far (it's blocking me..) is that there are additional TensorConstants that are created when distributions/samplers/transforms are initialized. Those do not always get test-values and specifying testval=... on a Distribution does not help.
Setting compute_test_value to 'off' or 'warn' right after the import theano OR via pymc3.Model(...) can bypass that to not raise errors. (But does not address the actual issue.)

I have not yet found the cause of the first issue, but my gut feeling is that it's a pymc3 bug, because other distributions work.

@michaelosthege
Copy link
Member

When setting theano.config.compute_test_value = X upon import:

not set raise warn off
DiscreteUniform AttributeError OK OK AttributeError
Uniform [-20, 0] OK OK OK OK
Gamma OK OK OK OK

And via pymc.Model(theano_config=...):

not set raise warn off
DiscreteUniform AttributeError AttributeError OK OK
Uniform [-20, 0] OK OK OK scratchpad
Gamma OK OK OK scratchpad

@vanitoz
Copy link

vanitoz commented Oct 1, 2021

Have the same Issue with NegativeBinomial:

formula = 'TOTAL_CONV ~ ' + ' + '.join(['%s' % variable for variable in data.columns[:-1]])

priors

d_coef = {}
for val in data.columns[:-1]:
d_coef[val] = d_coef.get(val, pm.HalfNormal.dist())
d_intercept = {'Intercept': pm.Normal.dist()}
d_priors = {**d_intercept,**d_coef}

context for the model

with pm.Model() as model_glm_nb:

family = pm.glm.families.NegativeBinomial()
pm.GLM.from_formula(formula,
                    data = data, 
                    priors = d_priors, 
                    family= family)

trace_glm_nb = pm.sample(chains = 4, target_accept = 0.9)

AttributeError Traceback (most recent call last)
C:\Users\IZAKHA~1\AppData\Local\Temp/ipykernel_7752/2858010902.py in
3
4 family = pm.glm.families.NegativeBinomial()
----> 5 pm.GLM.from_formula(formula,
6 data = data,
7 priors = d_priors,

AttributeError: 'ValidatingScratchpad' object has no attribute 'test_value'

@michaelosthege
Copy link
Member

Hi @vanitoz,
with the upcoming pymc 4.0.0 release we are moving away from test_value alltogether, and are also removing the GLM submodule in favor of the bambi library.

Background is that test_value is a debugging feature of the Theano/Aesara backend framework that we've been misusing as a way to track initial values (starting points) for optimization and MCMC, or as means to learn about shapes.

So depending on the context of where you encountered this issue (e.g. which version you're on) you might want to consider moving to bambi already.

@NathanielF
Copy link
Contributor

NathanielF commented Jan 27, 2022

I'm also getting the same error with the SMC sampler when trying to replicate the Approximate Bayesian Computation referenced in https://bayesiancomputationbook.com/notebooks/chp_08.html

import pandas as pd
import numpy as np
from scipy import stats
from scipy import optimize
import sys
import pymc3 as pm
import sys

class g_and_k_quantile:
    def __init__(self):
        self.quantile_normal = stats.norm(0, 1).ppf
        self.pdf_normal = stats.norm(0, 1).pdf

    def ppf(self, x, a, b, g, k):
        z = self.quantile_normal(x)
        return a + b * (1 + 0.8 * np.tanh(g*z/2)) * ((1 + z**2)**k) * z

    
    def rvs(self, samples, a, b, g, k):
        x = np.random.uniform(0, 1, samples)
        return self.ppf(x, a, b, g, k)

    def cdf(self, x, a, b, g, k, zscale=False):   
        optimize.fminbound(f, -5, 5)

    def pdf(self, x, a, b, g, k):
        #z = cdf(x, a, b, g, k)
        z = x
        z_sq = z**2
        term1 = (1+z_sq)**k
        term2 = 1+0.8*np.tanh(g*x/2)
        term3 = (1+(2*k+1)*z_sq)/(1+z_sq)
        term4 = 0.8*g*z/(2*np.cosh(g*z/2)**2)

        deriv = b*term1*(term2*term3+term4)
        return self.pdf_normal(x) / deriv


def octo_summary(x):
    e1, e2, e3, e4, e5, e6, e7 = np.quantile(x, [0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875])
    sa = e4
    sb = e6 - e2
    sg = (e6 + e2 - 2*e4)/sb
    sk = (e7 - e5 + e3 - e1)/sb
    return np.array([sa, sb, sg, sk])

pollution_df = pd.read_csv('../input_data/pollution.csv')
bsas_co = pollution_df["co"].dropna().values

gk = g_and_k_quantile()
def gk_simulator(a, b, g, k):
    return gk.rvs(len(bsas_co), a, b, g, k)

bsas_co = np.array([0.5, 0.4, 0.3])



if __name__ == '__main__':

    with pm.Model() as gkm:
        a = pm.HalfNormal('a', sd=1)
        b = pm.HalfNormal('b', sd=1)
        g = pm.HalfNormal('g', sd=1)
        k = pm.HalfNormal('k', sd=1)

        s = pm.Simulator('s', gk_simulator, params=[a, b, g, k],
                         sum_stat=octo_summary,
                         epsilon=0.1,
                         observed=bsas_co)

        trace_gk, sim_data_gk = pm.sample_smc(kernel="ABC",
                                              parallel=True,
                                              save_sim_data=True
                                              )

image

Not sure how to fix this one?


UPDATE - The error disappears if i remove the parrallel=True, which is weird. So probably related to multithreading rather than the attribute error above

image

@ricardoV94
Copy link
Member

@NathanielF This should not be a problem in the new PyMC version (still in beta), if you can upgrade to it.

@michaelosthege
Copy link
Member

@NathanielF if you're working with a latest version (currently pymc3==3.11.4 or pymc==4.0.0b2) please open a new issue and let us know the versions. Otherwise please update to a latest release first.

@NathanielF
Copy link
Contributor

NathanielF commented Jan 27, 2022

Thanks Michael. i'm working with the environment recommended in the book, so yes 3.11.4.

image

Thanks @ricardoV94 and @michaelosthege, I'll open a new issue then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants