I wanted to do something similar to you, so I used your example (reduced to 2D), but I can’t get either your example or my reduced version to work. I’m using theano 1.0.5 & pymc 3.9.3 on Linux (conda-forge install).
import numpy as np
from numpy.linalg import inv
import matplotlib.pyplot as plt
import theano
import theano.tensor.nlinalg
import theano.tensor as tt
import pymc3 as pm
#Define Test Function
def true_funct(x,y):
val = np.cos(x) + np.cos(y) + 2*(x*x + y*y)
return val
# Create Observations
n_points = 40
noise_true = 0.001
data_x = np.random.uniform(-1,1,n_points)
data_y = np.random.uniform(-1,1,n_points)
X_train = np.concatenate((data_x[:,None],data_y[:,None]),axis=1)
Y_true = true_funct(data_x,data_y)[:,None]
Y_train = Y_true + np.random.normal(0,noise_true, Y_true.shape[0])[:,None]
sigma_noise = noise_true
with pm.Model() as model:
#List of Prior parameters
#-------------------------------
l_scale = pm.HalfCauchy('l_scale', 1, shape=2) #length scale parameter
sigma_f = pm.HalfCauchy('sigma_f', 1) #amplitude parameter
sigma_noise = pm.HalfCauchy('sigma_noise', .1)
# build the mean and cov matrix
cov_funct=pm.gp.cov.ExpQuad(2,l_scale)*sigma_f**2.
cov_funct=cov_funct(X_train)
K = tt.fill_diagonal(cov_funct, sigma_f**2. + sigma_noise**2.)
mean_func = pm.gp.mean.Zero()
obs = pm.MvNormal('obs', mean_func(X_train), K, observed=Y_train)
trace = pm.sample(1000,chains=2,cores=2, step=pm.NUTS())
pm.traceplot(trace, var_names=["sigma_f","l_scale"]);
This code basically stops with an error:
~/miniconda/envs/python3/lib/python3.7/site-packages/pymc3/step_methods/hmc/quadpotential.py in raise_ok()
262 ' is zero.'.format(*name_slc[ii]))
--> 263 raise ValueError('\n'.join(errmsg))
264
ValueError: Mass matrix contains zeros on the diagonal.
The derivative of RV `sigma_f_log__`.ravel()[0] is zero.
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
<ipython-input-2-44d3d3d36dd9> in <module>
41
42 obs = pm.MvNormal('obs', mean_func(X_train), K, observed=Y_train)
---> 43 trace = pm.sample(1000,chains=2,cores=2, step=pm.NUTS())
44
45 pm.traceplot(trace, var_names=["sigma_f","l_scale"]);
~/miniconda/envs/python3/lib/python3.7/site-packages/pymc3/sampling.py in sample(draws, step, init, n_init, start, trace, chain_idx, chains, cores, tune, progressbar, model, random_seed, discard_tuned_samples, compute_convergence_checks, callback, return_inferencedata, idata_kwargs, mp_ctx, pickle_backend, **kwargs)
543 _print_step_hierarchy(step)
544 try:
--> 545 trace = _mp_sample(**sample_args, **parallel_args)
546 except pickle.PickleError:
547 _log.warning("Could not pickle model, sampling singlethreaded.")
~/miniconda/envs/python3/lib/python3.7/site-packages/pymc3/sampling.py in _mp_sample(draws, tune, step, chains, cores, chain, random_seed, start, progressbar, trace, model, callback, discard_tuned_samples, mp_ctx, pickle_backend, **kwargs)
1484 try:
1485 with sampler:
-> 1486 for draw in sampler:
1487 trace = traces[draw.chain - chain]
1488 if trace.supports_sampler_stats and draw.stats is not None:
~/miniconda/envs/python3/lib/python3.7/site-packages/pymc3/parallel_sampling.py in __iter__(self)
490
491 while self._active:
--> 492 draw = ProcessAdapter.recv_draw(self._active)
493 proc, is_last, draw, tuning, stats, warns = draw
494 self._total_draws += 1
~/miniconda/envs/python3/lib/python3.7/site-packages/pymc3/parallel_sampling.py in recv_draw(processes, timeout)
363 else:
364 error = RuntimeError("Chain %s failed." % proc.chain)
--> 365 raise error from old_error
366 elif msg[0] == "writing_done":
367 proc._readable = True
RuntimeError: Chain 0 failed.