# Written by Ilias Bilionis """ Test if hyperparameters in models are properly transformed. """ import pytest import numpy as np import scipy.stats as st import GPy class Model(GPy.core.Model): """ A simple GPy model with one parameter. """ def __init__(self, theta=1.0): super(Model, self).__init__("test_model") theta = GPy.core.Param("theta", theta) self.link_parameter(theta) def log_likelihood(self): return 0.0 class TestRVTransformation: def _test_trans(self, trans): m = Model() prior = GPy.priors.LogGaussian(0.5, 0.1) m.theta.set_prior(prior) m.theta.unconstrain() m.theta.constrain(trans) # The PDF of the transformed variables p_phi = lambda phi: np.exp(-m._objective_grads(phi)[0]) # To the empirical PDF of: theta_s = prior.rvs(1e5) phi_s = trans.finv(theta_s) # which is essentially a kernel density estimation kde = st.gaussian_kde(phi_s) # We will compare the PDF here: phi = np.linspace(phi_s.min(), phi_s.max(), 100) # The transformed PDF of phi should be this: pdf_phi = np.array([p_phi(p) for p in phi]) # UNCOMMENT TO SEE GRAPHICAL COMPARISON # import matplotlib.pyplot as plt # fig, ax = plt.subplots() # ax.hist(phi_s, normed=True, bins=100, alpha=0.25, label='Histogram') # ax.plot(phi, kde(phi), '--', linewidth=2, label='Kernel Density Estimation') # ax.plot(phi, pdf_phi, ':', linewidth=2, label='Transformed PDF') # ax.set_xlabel(r'transformed $\theta$', fontsize=16) # ax.set_ylabel('PDF', fontsize=16) # plt.legend(loc='best') # plt.show(block=True) # END OF PLOT # The following test cannot be very accurate assert np.linalg.norm(pdf_phi - kde(phi)) / np.linalg.norm(kde(phi)) <= 1e-1 def _test_grad(self, trans): np.random.seed(1234) m = Model(np.random.uniform(0.5, 1.5, 20)) prior = GPy.priors.LogGaussian(0.5, 0.1) m.theta.set_prior(prior) m.theta.constrain(trans) m.randomize() print(m) assert m.checkgrad(1) def test_Logexp(self): self._test_trans(GPy.constraints.Logexp()) @pytest.mark.skip( "Gradient not checking right, @jameshensman what is going on here?" ) def test_Logexp_grad(self): self._test_grad(GPy.constraints.Logexp()) def test_Exponent(self): self._test_trans(GPy.constraints.Exponent()) @pytest.mark.skip( "Gradient not checking right, @jameshensman what is going on here?" ) def test_Exponent_grad(self): self._test_grad(GPy.constraints.Exponent())