How to transform my code to v5

I‘m trying to transform my code from v3 to v5.But I got problems.In v3,I want to get all the samples after the sampling of pymc is completed,
Here are my codes

with pm.Model() as background_model:
    amp = pm.Uniform('amp',lower=15,upper=25)
    rate = pm.Uniform('rate', lower=8*1e2,upper= 1.2*1e3)
    E_start = pm.Uniform('E_start',lower=12.5*1e3,upper=13.0*1e3)    
    y_observed=pm.Normal(
        "y_observed",
        mu=amp*np.exp(-(E_mid_background-E_start)/rate),
        sigma=noise_total3,
        observed=background1,
        )
    output = pm.Deterministic('output',np.exp(-(E_mid_background-E_start)/rate))
    prior = pm.sample_prior_predictive()
    posterior3 = pm.sample(draws = Samples, target_accept = 0.9,chains=4,cores=1)
    posterior_only_background = pm.sample_posterior_predictive(posterior3)
    az.plot_trace(posterior3, var_names = ['amp','E_start','rate'])
    only_background=az.summary(posterior3, var_names = ['amp','E_start','rate'])
back=posterior3['amp'],posterior3['E_start'],posterior3['rate']
back1=back[0]
back2=back[1]
back3=back[2]
    

I used the following code to achieve this goal.

back=posterior3['amp'],posterior3['E_start'],posterior3['rate']
back1=back[0]
back2=back[1]
back3=back[2]

I hope to implement the same function in v5, what should I do?

All of the model code looks fine. You will just need to familiarize yourself with the new Arviz InferenceData object that is returned from sampling. See here for documentation about idata, or here for a discussion with a user who had a similar problem.

Amusingly (in the context of this thread), the Arviz idata docs reference PyMC3, but there will not be any differences with respect to working with idata.

1 Like

Thank you. Besides, in my code there are other parts which define a likelihood

def normal_logp(mu, sigma, obs):
    tau=1/sigma**2
    log_normal = np.log(np.sqrt(tau/(2*np.pi))*np.exp(-0.5*tau*(obs-mu)**2))
    log_normal = tt.switch(tau<=0,-np.inf,log_normal)
    return log_normal
class Normal_Progress(pm.Discrete):
    def __init__(self,mu,sigma,*args,**kwargs):
        super().__init__(*args, **kwargs)
        self.mu=mu
        self.sigma=sigma
        self.mode=mu    
    def logp(self,obs):
        mu=self.mu
        sigma=self.sigma
        return normal_logp(mu, sigma, obs)
    def random(self,point=None,size=None):
        mu,sigma =draw_values([self.mu,self.sigma],point=point,size=size)
        return generate_samples(st.norm.rvs,loc = mu,scale = sigma,size =size)
    

In v3,I follow the instructions in pm.CustomDist ,should I do the same as in v5?

The CustomDist API has been significantly changed between v3 and v5. For you this is good news, because it looks like your likelihood function is written entirely of pytensor ops whose logp graph can be automatically determined. See here for what appears to be a similar case

1 Like