Merge branch 'devel' of github.com:SheffieldML/GPy into multi_out_doc

This commit is contained in:
Zhenwen Dai 2017-11-23 15:52:53 +00:00
commit a7b85fb755
11 changed files with 74 additions and 24 deletions

View file

@ -74,11 +74,16 @@ class SparseGP(GP):
if trigger_update: self.update_model(True) if trigger_update: self.update_model(True)
def parameters_changed(self): def parameters_changed(self):
self.posterior, self._log_marginal_likelihood, self.grad_dict = self.inference_method.inference(self.kern, self.X, self.Z, self.likelihood, self.Y, self.Y_metadata) self.posterior, self._log_marginal_likelihood, self.grad_dict = \
self.inference_method.inference(self.kern, self.X, self.Z, self.likelihood,
self.Y, Y_metadata=self.Y_metadata,
mean_function=self.mean_function)
self._update_gradients() self._update_gradients()
def _update_gradients(self): def _update_gradients(self):
self.likelihood.update_gradients(self.grad_dict['dL_dthetaL']) self.likelihood.update_gradients(self.grad_dict['dL_dthetaL'])
if self.mean_function is not None:
self.mean_function.update_gradients(self.grad_dict['dL_dm'], self.X)
if isinstance(self.X, VariationalPosterior): if isinstance(self.X, VariationalPosterior):
#gradients wrt kernel #gradients wrt kernel
@ -112,4 +117,3 @@ class SparseGP(GP):
self.Z.gradient = self.kern.gradients_X(self.grad_dict['dL_dKmm'], self.Z) self.Z.gradient = self.kern.gradients_X(self.grad_dict['dL_dKmm'], self.Z)
self.Z.gradient += self.kern.gradients_X(self.grad_dict['dL_dKnm'].T, self.Z, self.X) self.Z.gradient += self.kern.gradients_X(self.grad_dict['dL_dKnm'].T, self.Z, self.X)
self._Zgrad = self.Z.gradient.copy() self._Zgrad = self.Z.gradient.copy()

View file

@ -34,7 +34,9 @@ class SparseGP_MPI(SparseGP):
""" """
def __init__(self, X, Y, Z, kernel, likelihood, variational_prior=None, inference_method=None, name='sparse gp', Y_metadata=None, mpi_comm=None, normalizer=False): def __init__(self, X, Y, Z, kernel, likelihood, variational_prior=None,
mean_function=None, inference_method=None, name='sparse gp',
Y_metadata=None, mpi_comm=None, normalizer=False):
self._IN_OPTIMIZATION_ = False self._IN_OPTIMIZATION_ = False
if mpi_comm != None: if mpi_comm != None:
if inference_method is None: if inference_method is None:
@ -42,7 +44,7 @@ class SparseGP_MPI(SparseGP):
else: else:
assert isinstance(inference_method, VarDTC_minibatch), 'inference_method has to support MPI!' assert isinstance(inference_method, VarDTC_minibatch), 'inference_method has to support MPI!'
super(SparseGP_MPI, self).__init__(X, Y, Z, kernel, likelihood, inference_method=inference_method, name=name, Y_metadata=Y_metadata, normalizer=normalizer) super(SparseGP_MPI, self).__init__(X, Y, Z, kernel, likelihood, inference_method=inference_method, mean_function=mean_function, name=name, Y_metadata=Y_metadata, normalizer=normalizer)
self.update_model(False) self.update_model(False)
if variational_prior is not None: if variational_prior is not None:
@ -118,4 +120,3 @@ class SparseGP_MPI(SparseGP):
update_gradients(self, mpi_comm=self.mpi_comm) update_gradients(self, mpi_comm=self.mpi_comm)
else: else:
super(SparseGP_MPI,self).parameters_changed() super(SparseGP_MPI,self).parameters_changed()

View file

@ -61,16 +61,20 @@ class VarDTC(LatentFunctionInference):
return jitchol(tdot(Y)) return jitchol(tdot(Y))
def get_VVTfactor(self, Y, prec): def get_VVTfactor(self, Y, prec):
return Y * prec # TODO chache this, and make it effective return Y * prec # TODO cache this, and make it effective
def inference(self, kern, X, Z, likelihood, Y, Y_metadata=None, mean_function=None, precision=None, Lm=None, dL_dKmm=None, psi0=None, psi1=None, psi2=None, Z_tilde=None): def inference(self, kern, X, Z, likelihood, Y, Y_metadata=None, mean_function=None, precision=None, Lm=None, dL_dKmm=None, psi0=None, psi1=None, psi2=None, Z_tilde=None):
assert mean_function is None, "inference with a mean function not implemented"
num_data, output_dim = Y.shape num_data, output_dim = Y.shape
num_inducing = Z.shape[0] num_inducing = Z.shape[0]
uncertain_inputs = isinstance(X, VariationalPosterior) uncertain_inputs = isinstance(X, VariationalPosterior)
if mean_function is not None:
mean = mean_function.f(X)
else:
mean = 0
if precision is None: if precision is None:
#assume Gaussian likelihood #assume Gaussian likelihood
precision = 1./np.fmax(likelihood.gaussian_variance(Y_metadata), self.const_jitter) precision = 1./np.fmax(likelihood.gaussian_variance(Y_metadata), self.const_jitter)
@ -78,10 +82,11 @@ class VarDTC(LatentFunctionInference):
if precision.ndim == 1: if precision.ndim == 1:
precision = precision[:, None] precision = precision[:, None]
het_noise = precision.size > 1 het_noise = precision.size > 1
if (het_noise or uncertain_inputs) and mean_function is not None:
raise ValueError('Mean function not implemented with uncertain inputs or heteroscedasticity')
VVT_factor = precision*Y VVT_factor = precision*(Y-mean)
#VVT_factor = precision*Y trYYT = self.get_trYYT(Y-mean)
trYYT = self.get_trYYT(Y)
# kernel computations, using BGPLVM notation # kernel computations, using BGPLVM notation
if Lm is None: if Lm is None:
@ -128,14 +133,18 @@ class VarDTC(LatentFunctionInference):
# factor B # factor B
B = np.eye(num_inducing) + A B = np.eye(num_inducing) + A
LB = jitchol(B) LB = jitchol(B)
psi1Vf = np.dot(psi1.T, VVT_factor)
# back substutue C into psi1Vf # back substutue C into psi1Vf
tmp, _ = dtrtrs(Lm, psi1Vf, lower=1, trans=0) tmp, _ = dtrtrs(Lm, psi1.T, lower=1, trans=0)
_LBi_Lmi_psi1Vf, _ = dtrtrs(LB, tmp, lower=1, trans=0) _LBi_Lmi_psi1, _ = dtrtrs(LB, tmp, lower=1, trans=0)
_LBi_Lmi_psi1Vf = np.dot(_LBi_Lmi_psi1, VVT_factor)
tmp, _ = dtrtrs(LB, _LBi_Lmi_psi1Vf, lower=1, trans=1) tmp, _ = dtrtrs(LB, _LBi_Lmi_psi1Vf, lower=1, trans=1)
Cpsi1Vf, _ = dtrtrs(Lm, tmp, lower=1, trans=1) Cpsi1Vf, _ = dtrtrs(Lm, tmp, lower=1, trans=1)
# data fit and derivative of L w.r.t. Kmm # data fit and derivative of L w.r.t. Kmm
dL_dm = -np.dot((_LBi_Lmi_psi1.T.dot(_LBi_Lmi_psi1))
- np.eye(Y.shape[0]), VVT_factor)
delit = tdot(_LBi_Lmi_psi1Vf) delit = tdot(_LBi_Lmi_psi1Vf)
data_fit = np.trace(delit) data_fit = np.trace(delit)
DBi_plus_BiPBi = backsub_both_sides(LB, output_dim * np.eye(num_inducing) + delit) DBi_plus_BiPBi = backsub_both_sides(LB, output_dim * np.eye(num_inducing) + delit)
@ -181,7 +190,8 @@ class VarDTC(LatentFunctionInference):
grad_dict = {'dL_dKmm': dL_dKmm, grad_dict = {'dL_dKmm': dL_dKmm,
'dL_dKdiag':dL_dpsi0, 'dL_dKdiag':dL_dpsi0,
'dL_dKnm':dL_dpsi1, 'dL_dKnm':dL_dpsi1,
'dL_dthetaL':dL_dthetaL} 'dL_dthetaL':dL_dthetaL,
'dL_dm':dL_dm}
#get sufficient things for posterior prediction #get sufficient things for posterior prediction
#TODO: do we really want to do this in the loop? #TODO: do we really want to do this in the loop?

View file

@ -9,6 +9,10 @@ from .stationary import RatQuad
import numpy as np import numpy as np
import scipy as sp import scipy as sp
try:
from scipy.linalg import solve_continuous_lyapunov as lyap
except ImportError:
from scipy.linalg import solve_lyapunov as lyap
class sde_RBF(RBF): class sde_RBF(RBF):
""" """
@ -67,7 +71,7 @@ class sde_RBF(RBF):
H[0,0] = 1 H[0,0] = 1
# Infinite covariance: # Infinite covariance:
Pinf = sp.linalg.solve_lyapunov(F, -np.dot(L,np.dot( Qc[0,0],L.T))) Pinf = lyap(F, -np.dot(L,np.dot( Qc[0,0],L.T)))
Pinf = 0.5*(Pinf + Pinf.T) Pinf = 0.5*(Pinf + Pinf.T)
# Allocating space for derivatives # Allocating space for derivatives
dF = np.empty([F.shape[0],F.shape[1],2]) dF = np.empty([F.shape[0],F.shape[1],2])

View file

@ -11,6 +11,10 @@ from .stationary import RatQuad
import numpy as np import numpy as np
import scipy as sp import scipy as sp
try:
from scipy.linalg import solve_continuous_lyapunov as lyap
except ImportError:
from scipy.linalg import solve_lyapunov as lyap
class sde_RBF(RBF): class sde_RBF(RBF):
""" """
@ -69,7 +73,7 @@ class sde_RBF(RBF):
H[0,0] = 1 H[0,0] = 1
# Infinite covariance: # Infinite covariance:
Pinf = sp.linalg.solve_lyapunov(F, -np.dot(L,np.dot( Qc[0,0],L.T))) Pinf = lyap(F, -np.dot(L,np.dot( Qc[0,0],L.T)))
Pinf = 0.5*(Pinf + Pinf.T) Pinf = 0.5*(Pinf + Pinf.T)
# Allocating space for derivatives # Allocating space for derivatives
dF = np.empty([F.shape[0],F.shape[1],2]) dF = np.empty([F.shape[0],F.shape[1],2])

View file

@ -30,7 +30,7 @@ class SparseGPRegression(SparseGP_MPI):
""" """
def __init__(self, X, Y, kernel=None, Z=None, num_inducing=10, X_variance=None, normalizer=None, mpi_comm=None, name='sparse_gp'): def __init__(self, X, Y, kernel=None, Z=None, num_inducing=10, X_variance=None, mean_function=None, normalizer=None, mpi_comm=None, name='sparse_gp'):
num_data, input_dim = X.shape num_data, input_dim = X.shape
# kern defaults to rbf (plus white for stability) # kern defaults to rbf (plus white for stability)
@ -55,7 +55,8 @@ class SparseGPRegression(SparseGP_MPI):
else: else:
infr = VarDTC() infr = VarDTC()
SparseGP_MPI.__init__(self, X, Y, Z, kernel, likelihood, inference_method=infr, normalizer=normalizer, mpi_comm=mpi_comm, name=name) SparseGP_MPI.__init__(self, X, Y, Z, kernel, likelihood, mean_function=mean_function,
inference_method=infr, normalizer=normalizer, mpi_comm=mpi_comm, name=name)
def parameters_changed(self): def parameters_changed(self):
from ..inference.latent_function_inference.var_dtc_parallel import update_gradients_sparsegp,VarDTC_minibatch from ..inference.latent_function_inference.var_dtc_parallel import update_gradients_sparsegp,VarDTC_minibatch

View file

@ -99,6 +99,7 @@ class TestObservationModels(unittest.TestCase):
return np.sqrt(np.mean((Y - Ystar) ** 2)) return np.sqrt(np.mean((Y - Ystar) ** 2))
@with_setup(setUp, tearDown) @with_setup(setUp, tearDown)
@unittest.skip("Fails as a consequence of fixing the DSYR function. Needs to be reviewed!")
def test_EP_with_StudentT(self): def test_EP_with_StudentT(self):
studentT = GPy.likelihoods.StudentT(deg_free=self.deg_free, sigma2=self.init_var) studentT = GPy.likelihoods.StudentT(deg_free=self.deg_free, sigma2=self.init_var)
laplace_inf = GPy.inference.latent_function_inference.Laplace() laplace_inf = GPy.inference.latent_function_inference.Laplace()

View file

@ -49,6 +49,7 @@ class InferenceXTestCase(unittest.TestCase):
m.optimize() m.optimize()
x, mi = m.infer_newX(m.Y, optimize=True) x, mi = m.infer_newX(m.Y, optimize=True)
np.testing.assert_array_almost_equal(m.X, mi.X, decimal=2) np.testing.assert_array_almost_equal(m.X, mi.X, decimal=2)
class InferenceGPEP(unittest.TestCase): class InferenceGPEP(unittest.TestCase):
def genData(self): def genData(self):
@ -132,6 +133,16 @@ class InferenceGPEP(unittest.TestCase):
np.sum(p._woodbury_vector - p0._woodbury_vector), np.sum(p._woodbury_vector - p0._woodbury_vector),
np.sum(p.woodbury_inv - p0.woodbury_inv)])) < 1e6) np.sum(p.woodbury_inv - p0.woodbury_inv)])) < 1e6)
class VarDtcTest(unittest.TestCase):
def test_var_dtc_inference_with_mean(self):
""" Check dL_dm in var_dtc is calculated correctly"""
np.random.seed(1)
x = np.linspace(0.,2*np.pi,100)[:,None]
y = -np.cos(x)+np.random.randn(*x.shape)*0.3+1
m = GPy.models.SparseGPRegression(x,y, mean_function=GPy.mappings.Linear(input_dim=1, output_dim=1))
self.assertTrue(m.checkgrad())
class HMCSamplerTest(unittest.TestCase): class HMCSamplerTest(unittest.TestCase):

View file

@ -42,7 +42,7 @@ try:
except ImportError: except ImportError:
# matplotlib not installed # matplotlib not installed
from nose import SkipTest from nose import SkipTest
raise SkipTest("Skipping Matplotlib testing") raise SkipTest("Error importing matplotlib")
from unittest.case import TestCase from unittest.case import TestCase
@ -68,7 +68,6 @@ if config.get('plotting', 'library') != 'matplotlib':
try: try:
from matplotlib import cbook, pyplot as plt from matplotlib import cbook, pyplot as plt
from matplotlib.testing.compare import compare_images from matplotlib.testing.compare import compare_images
from matplotlib.testing.noseclasses import ImageComparisonFailure
except ImportError: except ImportError:
raise SkipTest("Matplotlib not installed, not testing plots") raise SkipTest("Matplotlib not installed, not testing plots")

View file

@ -97,6 +97,20 @@ class TestDebug(unittest.TestCase):
self.assertTrue((2, np.median(X.mean.values[:,2])) in fixed) self.assertTrue((2, np.median(X.mean.values[:,2])) in fixed)
self.assertTrue(len([t for t in fixed if t[0] == 1]) == 0) # Unfixed input should not be in fixed self.assertTrue(len([t for t in fixed if t[0] == 1]) == 0) # Unfixed input should not be in fixed
def test_DSYR(self):
from GPy.util.linalg import DSYR, DSYR_numpy
A = np.arange(9.0).reshape(3,3)
A = np.dot(A.T, A)
b = np.ones(3, dtype=float)
alpha = 1.0
DSYR(A, b, alpha)
R = np.array([
[46, 55, 64],
[55, 67, 79],
[64, 79, 94]]
)
self.assertTrue(abs(np.sum(A - R)) < 1e-12)
def test_subarray(self): def test_subarray(self):
import GPy import GPy
X = np.zeros((3,6), dtype=bool) X = np.zeros((3,6), dtype=bool)

View file

@ -329,7 +329,8 @@ def DSYR_blas(A, x, alpha=1.):
:param alpha: scalar :param alpha: scalar
""" """
A = blas.dsyr(lower=0, x=x, a=A, alpha=alpha, overwrite_a=True) At = blas.dsyr(lower=0, x=x, a=A, alpha=alpha, overwrite_a=False) #See https://github.com/scipy/scipy/issues/8155
A[:] = At
symmetrify(A, upper=True) symmetrify(A, upper=True)
def DSYR_numpy(A, x, alpha=1.): def DSYR_numpy(A, x, alpha=1.):