Skip to content

AttributeError: Can't pickle local object 'BoundedContinuous.default_transform.<locals>.transform_params' #4799

Closed
@mjhajharia

Description

@mjhajharia

Sampling time error:

AttributeError: Can't pickle local object 'BoundedContinuous.default_transform.<locals>.transform_params'

To reproduce:

%matplotlib inline
import aesara
import pymc3 as pm
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm
import pandas as pd
from pandas_datareader.data import DataReader
from pandas.plotting import register_matplotlib_converters
from aesara.graph.op import Op
plt.style.use('seaborn')
register_matplotlib_converters()
cpi = DataReader('CPIAUCNS', 'fred', start='1971-01', end='2018-12')
cpi.index = pd.DatetimeIndex(cpi.index, freq='MS')

# Define the inflation series that we'll use in analysis
inf = np.log(cpi).resample('QS').mean().diff()[1:] * 400
print(inf.head())
class Loglike(Op):

    itypes = [aesara.tensor.dvector] # expects a vector of parameter values when called
    otypes = [aesara.tensor.dscalar] # outputs a single scalar value (the log likelihood)

    def __init__(self, model):
        self.model = model
        self.score = Score(self.model)

    def perform(self, node, inputs, outputs):
        theta, = inputs  # contains the vector of parameters
        llf = self.model.loglike(theta)
        outputs[0][0] = np.array(llf) # output the log-likelihood

    def grad(self, inputs, g):
        # the method that calculates the gradients - it actually returns the
        # vector-Jacobian product - g[0] is a vector of parameter values
        theta, = inputs  # our parameters
        out = [g[0] * self.score(theta)]
        return out


class Score(Op):
    itypes = [aesara.tensor.dvector]
    otypes = [aesara.tensor.dvector]

    def __init__(self, model):
        self.model = model

    def perform(self, node, inputs, outputs):
        theta, = inputs
        outputs[0][0] = self.model.score(theta)
        
ndraws = 3000  
nburn = 600  

mod = sm.tsa.statespace.SARIMAX(inf, order=(1, 0, 1))

loglike = Loglike(mod)

with pm.Model():
    # Priors
    arL1 = pm.Uniform('ar.L1', -0.99, 0.99)
    maL1 = pm.Uniform('ma.L1', -0.99, 0.99)
    sigma2 = pm.InverseGamma('sigma2', 2, 4)

    # convert variables to aesara vectors
    theta = aesara.tensor.as_tensor_variable([arL1, maL1, sigma2])
    

    # use a DensityDist (use a lamdba function to "call" the Op)
    pm.Potential('likelihood',loglike(theta))

    # Draw samples
    trace = pm.sample(ndraws, tune=nburn, discard_tuned_samples=False,return_inferencedata=True,cores=4)

Versions:

Python implementation: CPython
Python version       : 3.9.5
IPython version      : 7.24.1

pymc3      : 4.0
json       : 2.0.9
pandas     : 1.2.4
matplotlib : 3.4.2
numpy      : 1.20.3
aesara     : 2.0.11
statsmodels: 0.12.2

Watermark: 2.2.0

More information: I don't know but maybe it's because of v4 or aesara or pickle backend. It works when cores=1 during sampling, so its only an error during multiprocessing. Also, a similar error happened a while back (I used pm.DensityDist insted of pm.Potential and got "runtime error: chain 0 failed" which was fixed with pickle backend = dill. Perhaps we need a better fix, any help is appreciated!!!!

CC: @brandonwillard

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions