mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-06-02 14:45:15 +02:00
Corrected Multivariate Gaussian prior (#775)
* Corrected MultivariateGaussian prior Some corrections including adapting to current version of pdinv, correcting the expressions of constant, pdf and its gradient, and adding the printing function. After some tests, seems to run as expected, similarly to the Gaussian prior which was already working. * Added test of MultivariateGaussian prior Simple unit test for creating a kernel with Multivariate Gaussian prior over the lengthscales, then performing GP regression. * Took care of case where x of shape (n, 1) for multivariate Gaussian prior * Got rid of unnecessary asserts in Multivariate Gaussian prior since loss of time Co-authored-by: and <buisson-fenet@is.mpg.de>
This commit is contained in:
parent
46ce7c1680
commit
ff82f12c3d
2 changed files with 56 additions and 14 deletions
|
|
@ -200,37 +200,50 @@ class MultivariateGaussian(Prior):
|
||||||
|
|
||||||
def __new__(cls, mu=0, var=1): # Singleton:
|
def __new__(cls, mu=0, var=1): # Singleton:
|
||||||
if cls._instances:
|
if cls._instances:
|
||||||
cls._instances[:] = [instance for instance in cls._instances if instance()]
|
cls._instances[:] = [instance for instance in cls._instances if
|
||||||
|
instance()]
|
||||||
for instance in cls._instances:
|
for instance in cls._instances:
|
||||||
if np.all(instance().mu == mu) and np.all(instance().var == var):
|
if np.all(instance().mu == mu) and np.all(
|
||||||
|
instance().var == var):
|
||||||
return instance()
|
return instance()
|
||||||
o = super(Prior, cls).__new__(cls, mu, var)
|
newfunc = super(Prior, cls).__new__
|
||||||
|
if newfunc is object.__new__:
|
||||||
|
o = newfunc(cls)
|
||||||
|
else:
|
||||||
|
o = newfunc(cls, mu, var)
|
||||||
cls._instances.append(weakref.ref(o))
|
cls._instances.append(weakref.ref(o))
|
||||||
return cls._instances[-1]()
|
return cls._instances[-1]()
|
||||||
|
|
||||||
def __init__(self, mu, var):
|
def __init__(self, mu, var):
|
||||||
self.mu = np.array(mu).flatten()
|
self.mu = np.array(mu).flatten()
|
||||||
self.var = np.array(var)
|
self.var = np.array(var)
|
||||||
assert len(self.var.shape) == 2
|
assert len(self.var.shape) == 2, 'Covariance must be a matrix'
|
||||||
assert self.var.shape[0] == self.var.shape[1]
|
assert self.var.shape[0] == self.var.shape[1], \
|
||||||
|
'Covariance must be a square matrix'
|
||||||
assert self.var.shape[0] == self.mu.size
|
assert self.var.shape[0] == self.mu.size
|
||||||
self.input_dim = self.mu.size
|
self.input_dim = self.mu.size
|
||||||
self.inv, self.hld = pdinv(self.var)
|
self.inv, _, self.hld, _ = pdinv(self.var)
|
||||||
self.constant = -0.5 * self.input_dim * np.log(2 * np.pi) - self.hld
|
self.constant = -0.5 * (self.input_dim * np.log(2 * np.pi) + self.hld)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return 'MultiN(' + str(self.mu) + ', ' + str(np.diag(self.var)) + ')'
|
||||||
|
|
||||||
def summary(self):
|
def summary(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def pdf(self, x):
|
def pdf(self, x):
|
||||||
|
x = np.array(x).flatten()
|
||||||
return np.exp(self.lnpdf(x))
|
return np.exp(self.lnpdf(x))
|
||||||
|
|
||||||
def lnpdf(self, x):
|
def lnpdf(self, x):
|
||||||
|
x = np.array(x).flatten()
|
||||||
d = x - self.mu
|
d = x - self.mu
|
||||||
return self.constant - 0.5 * np.sum(d * np.dot(d, self.inv), 1)
|
return self.constant - 0.5 * np.dot(d.T, np.dot(self.inv, d))
|
||||||
|
|
||||||
def lnpdf_grad(self, x):
|
def lnpdf_grad(self, x):
|
||||||
|
x = np.array(x).flatten()
|
||||||
d = x - self.mu
|
d = x - self.mu
|
||||||
return -np.dot(self.inv, d)
|
return - np.dot(self.inv, d)
|
||||||
|
|
||||||
def rvs(self, n):
|
def rvs(self, n):
|
||||||
return np.random.multivariate_normal(self.mu, self.var, n)
|
return np.random.multivariate_normal(self.mu, self.var, n)
|
||||||
|
|
@ -247,14 +260,15 @@ class MultivariateGaussian(Prior):
|
||||||
return self.mu, self.var
|
return self.mu, self.var
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
self.mu = state[0]
|
self.mu = np.array(state[0]).flatten()
|
||||||
self.var = state[1]
|
self.var = state[1]
|
||||||
assert len(self.var.shape) == 2
|
assert len(self.var.shape) == 2, 'Covariance must be a matrix'
|
||||||
assert self.var.shape[0] == self.var.shape[1]
|
assert self.var.shape[0] == self.var.shape[1], \
|
||||||
|
'Covariance must be a square matrix'
|
||||||
assert self.var.shape[0] == self.mu.size
|
assert self.var.shape[0] == self.mu.size
|
||||||
self.input_dim = self.mu.size
|
self.input_dim = self.mu.size
|
||||||
self.inv, self.hld = pdinv(self.var)
|
self.inv, _, self.hld, _ = pdinv(self.var)
|
||||||
self.constant = -0.5 * self.input_dim * np.log(2 * np.pi) - self.hld
|
self.constant = -0.5 * (self.input_dim * np.log(2 * np.pi) + self.hld)
|
||||||
|
|
||||||
def gamma_from_EV(E, V):
|
def gamma_from_EV(E, V):
|
||||||
warnings.warn("use Gamma.from_EV to create Gamma Prior", FutureWarning)
|
warnings.warn("use Gamma.from_EV to create Gamma Prior", FutureWarning)
|
||||||
|
|
|
||||||
|
|
@ -936,6 +936,34 @@ class GradientTests(np.testing.TestCase):
|
||||||
#import ipdb;ipdb.set_trace()
|
#import ipdb;ipdb.set_trace()
|
||||||
#m.constrain_fixed('.*rbf_var', 1.)
|
#m.constrain_fixed('.*rbf_var', 1.)
|
||||||
self.assertTrue(m.checkgrad())
|
self.assertTrue(m.checkgrad())
|
||||||
|
|
||||||
|
def test_simple_MultivariateGaussian_prior(self):
|
||||||
|
X = np.random.multivariate_normal(
|
||||||
|
[1, 5], np.diag([0.5, 0.3]), (100, 1)).reshape(100, 2)
|
||||||
|
Y = X + np.random.randn(100, 2) * 0.05
|
||||||
|
kernel = GPy.kern.RBF(input_dim=2, variance=1,lengthscale=1, ARD=True)
|
||||||
|
kernel.unconstrain()
|
||||||
|
kernel.variance.set_prior(GPy.priors.Gaussian(150, 5))
|
||||||
|
kernel.lengthscale.set_prior(GPy.priors.MultivariateGaussian(
|
||||||
|
np.array([20, 20]), np.diag([5, 5])))
|
||||||
|
m = GPy.models.GPRegression(X, Y, kernel=kernel)
|
||||||
|
m.optimize()
|
||||||
|
print(m.kern.variance)
|
||||||
|
print(m.kern.lengthscale)
|
||||||
|
|
||||||
|
def test_simple_MultivariateGaussian_prior_matrixmean(self):
|
||||||
|
X = np.random.multivariate_normal(
|
||||||
|
[1, 5], np.diag([0.5, 0.3]), (100, 1)).reshape(100, 2)
|
||||||
|
Y = X + np.random.randn(100, 2) * 0.05
|
||||||
|
kernel = GPy.kern.RBF(input_dim=2, variance=1,lengthscale=1, ARD=True)
|
||||||
|
kernel.unconstrain()
|
||||||
|
kernel.variance.set_prior(GPy.priors.Gaussian(150, 5))
|
||||||
|
kernel.lengthscale.set_prior(GPy.priors.MultivariateGaussian(
|
||||||
|
np.array([[20, 20]]), np.diag([5, 5])))
|
||||||
|
m = GPy.models.GPRegression(X, Y, kernel=kernel)
|
||||||
|
m.optimize()
|
||||||
|
print(m.kern.variance)
|
||||||
|
print(m.kern.lengthscale)
|
||||||
|
|
||||||
def test_multioutput_sparse_regression_1D(self):
|
def test_multioutput_sparse_regression_1D(self):
|
||||||
X1 = np.random.rand(500, 1) * 8
|
X1 = np.random.rand(500, 1) * 8
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue