mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-06-02 14:45:15 +02:00
Merge branch 'devel' of github.com:SheffieldML/GPy into devel
This commit is contained in:
commit
958e9f7c7a
104 changed files with 5704 additions and 1159 deletions
|
|
@ -14,3 +14,5 @@ from warped_gp import WarpedGP
|
|||
from bayesian_gplvm import BayesianGPLVM
|
||||
from mrd import MRD
|
||||
from gradient_checker import GradientChecker
|
||||
from gp_multioutput_regression import GPMultioutputRegression
|
||||
from sparse_gp_multioutput_regression import SparseGPMultioutputRegression
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from .. import kern
|
|||
import itertools
|
||||
from matplotlib.colors import colorConverter
|
||||
from GPy.inference.optimization import SCG
|
||||
from GPy.util import plot_latent
|
||||
from GPy.util import plot_latent, linalg
|
||||
from GPy.models.gplvm import GPLVM
|
||||
from GPy.util.plot_latent import most_significant_input_dimensions
|
||||
from matplotlib import pyplot
|
||||
|
|
@ -66,8 +66,8 @@ class BayesianGPLVM(SparseGP, GPLVM):
|
|||
S_names = sum([['X_variance_%i_%i' % (n, q) for q in range(self.input_dim)] for n in range(self.num_data)], [])
|
||||
return (X_names + S_names + SparseGP._get_param_names(self))
|
||||
|
||||
def _get_print_names(self):
|
||||
return SparseGP._get_print_names(self)
|
||||
#def _get_print_names(self):
|
||||
# return SparseGP._get_print_names(self)
|
||||
|
||||
def _get_params(self):
|
||||
"""
|
||||
|
|
@ -140,12 +140,20 @@ class BayesianGPLVM(SparseGP, GPLVM):
|
|||
dpsi0 = -0.5 * self.input_dim * self.likelihood.precision
|
||||
dpsi2 = self.dL_dpsi2[0][None, :, :] # TODO: this may change if we ignore het. likelihoods
|
||||
V = self.likelihood.precision * Y
|
||||
|
||||
#compute CPsi1V
|
||||
if self.Cpsi1V is None:
|
||||
psi1V = np.dot(self.psi1.T, self.likelihood.V)
|
||||
tmp, _ = linalg.dtrtrs(self._Lm, np.asfortranarray(psi1V), lower=1, trans=0)
|
||||
tmp, _ = linalg.dpotrs(self.LB, tmp, lower=1)
|
||||
self.Cpsi1V, _ = linalg.dtrtrs(self._Lm, tmp, lower=1, trans=1)
|
||||
|
||||
dpsi1 = np.dot(self.Cpsi1V, V.T)
|
||||
|
||||
start = np.zeros(self.input_dim * 2)
|
||||
|
||||
for n, dpsi1_n in enumerate(dpsi1.T[:, :, None]):
|
||||
args = (self.kern, self.Z, dpsi0, dpsi1_n, dpsi2)
|
||||
args = (self.kern, self.Z, dpsi0, dpsi1_n.T, dpsi2)
|
||||
xopt, fopt, neval, status = SCG(f=latent_cost, gradf=latent_grad, x=start, optargs=args, display=False)
|
||||
|
||||
mu, log_S = xopt.reshape(2, 1, -1)
|
||||
|
|
@ -237,12 +245,13 @@ class BayesianGPLVM(SparseGP, GPLVM):
|
|||
"""
|
||||
Plot latent space X in 1D:
|
||||
|
||||
-if fig is given, create input_dim subplots in fig and plot in these
|
||||
-if ax is given plot input_dim 1D latent space plots of X into each `axis`
|
||||
-if neither fig nor ax is given create a figure with fignum and plot in there
|
||||
- if fig is given, create input_dim subplots in fig and plot in these
|
||||
- if ax is given plot input_dim 1D latent space plots of X into each `axis`
|
||||
- if neither fig nor ax is given create a figure with fignum and plot in there
|
||||
|
||||
colors:
|
||||
colors of different latent space dimensions input_dim
|
||||
|
||||
"""
|
||||
import pylab
|
||||
if ax is None:
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class BCGPLVM(GPLVM):
|
|||
GP._set_params(self, x[self.mapping.num_params:])
|
||||
|
||||
def _log_likelihood_gradients(self):
|
||||
dL_df = 2.*self.kern.dK_dX(self.dL_dK, self.X)
|
||||
dL_df = self.kern.dK_dX(self.dL_dK, self.X)
|
||||
dL_dtheta = self.mapping.df_dtheta(dL_df, self.likelihood.Y)
|
||||
return np.hstack((dL_dtheta.flatten(), GP._log_likelihood_gradients(self)))
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ class FITCClassification(FITC):
|
|||
kernel = kern.rbf(X.shape[1]) + kern.white(X.shape[1],1e-3)
|
||||
|
||||
if likelihood is None:
|
||||
distribution = likelihoods.likelihood_functions.Binomial()
|
||||
likelihood = likelihoods.EP(Y, distribution)
|
||||
noise_model = likelihoods.binomial()
|
||||
likelihood = likelihoods.EP(Y, noise_model)
|
||||
elif Y is not None:
|
||||
if not all(Y.flatten() == likelihood.data.flatten()):
|
||||
raise Warning, 'likelihood.data and Y are different.'
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class GPClassification(GP):
|
|||
This is a thin wrapper around the models.GP class, with a set of sensible defaults
|
||||
|
||||
:param X: input observations
|
||||
:param Y: observed values
|
||||
:param Y: observed values, can be None if likelihood is not None
|
||||
:param likelihood: a GPy likelihood, defaults to Binomial with probit link_function
|
||||
:param kernel: a GPy kernel, defaults to rbf
|
||||
:param normalize_X: whether to normalize the input data before computing (predictions will be in original scales)
|
||||
|
|
@ -31,8 +31,8 @@ class GPClassification(GP):
|
|||
kernel = kern.rbf(X.shape[1])
|
||||
|
||||
if likelihood is None:
|
||||
distribution = likelihoods.likelihood_functions.Binomial()
|
||||
likelihood = likelihoods.EP(Y, distribution)
|
||||
noise_model = likelihoods.binomial()
|
||||
likelihood = likelihoods.EP(Y, noise_model)
|
||||
elif Y is not None:
|
||||
if not all(Y.flatten() == likelihood.data.flatten()):
|
||||
raise Warning, 'likelihood.data and Y are different.'
|
||||
|
|
|
|||
58
GPy/models/gp_multioutput_regression.py
Normal file
58
GPy/models/gp_multioutput_regression.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# Copyright (c) 2013, Ricardo Andrade
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
|
||||
import numpy as np
|
||||
from ..core import GP
|
||||
from .. import likelihoods
|
||||
from .. import kern
|
||||
|
||||
class GPMultioutputRegression(GP):
|
||||
"""
|
||||
Multiple output Gaussian process with Gaussian noise
|
||||
|
||||
This is a wrapper around the models.GP class, with a set of sensible defaults
|
||||
|
||||
:param X_list: input observations
|
||||
:type X_list: list of numpy arrays (num_data_output_i x input_dim), one array per output
|
||||
:param Y_list: observed values
|
||||
:type Y_list: list of numpy arrays (num_data_output_i x 1), one array per output
|
||||
:param kernel_list: GPy kernels, defaults to rbf
|
||||
:type kernel_list: list of GPy kernels
|
||||
:param noise_variance_list: noise parameters per output, defaults to 1.0 for every output
|
||||
:type noise_variance_list: list of floats
|
||||
:param normalize_X: whether to normalize the input data before computing (predictions will be in original scales)
|
||||
:type normalize_X: False|True
|
||||
:param normalize_Y: whether to normalize the input data before computing (predictions will be in original scales)
|
||||
:type normalize_Y: False|True
|
||||
:param rank: number tuples of the corregionalization parameters 'coregion_W' (see coregionalize kernel documentation)
|
||||
:type rank: integer
|
||||
"""
|
||||
|
||||
def __init__(self,X_list,Y_list,kernel_list=None,noise_variance_list=None,normalize_X=False,normalize_Y=False,rank=1):
|
||||
|
||||
self.output_dim = len(Y_list)
|
||||
assert len(X_list) == self.output_dim, 'Number of outputs do not match length of inputs list.'
|
||||
|
||||
#Inputs indexing
|
||||
i = 0
|
||||
index = []
|
||||
for x,y in zip(X_list,Y_list):
|
||||
assert x.shape[0] == y.shape[0]
|
||||
index.append(np.repeat(i,x.size)[:,None])
|
||||
i += 1
|
||||
index = np.vstack(index)
|
||||
X = np.hstack([np.vstack(X_list),index])
|
||||
original_dim = X.shape[1] - 1
|
||||
|
||||
#Mixed noise likelihood definition
|
||||
likelihood = likelihoods.Gaussian_Mixed_Noise(Y_list,noise_params=noise_variance_list,normalize=normalize_Y)
|
||||
|
||||
#Coregionalization kernel definition
|
||||
if kernel_list is None:
|
||||
kernel_list = [kern.rbf(original_dim)]
|
||||
mkernel = kern.build_lcm(input_dim=original_dim, output_dim=self.output_dim, kernel_list = kernel_list, rank=rank)
|
||||
|
||||
self.multioutput = True
|
||||
GP.__init__(self, X, likelihood, mkernel, normalize_X=normalize_X)
|
||||
self.ensure_default_constraints()
|
||||
|
|
@ -61,7 +61,7 @@ class GPLVM(GP):
|
|||
GP._set_params(self, x[self.X.size:])
|
||||
|
||||
def _log_likelihood_gradients(self):
|
||||
dL_dX = 2.*self.kern.dK_dX(self.dL_dK, self.X)
|
||||
dL_dX = self.kern.dK_dX(self.dL_dK, self.X)
|
||||
|
||||
return np.hstack((dL_dX.flatten(), GP._log_likelihood_gradients(self)))
|
||||
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ class MRD(Model):
|
|||
:param input_dim: latent dimensionality
|
||||
:type input_dim: int
|
||||
:param initx: initialisation method for the latent space :
|
||||
|
||||
|
||||
* 'concat' - PCA on concatenation of all datasets
|
||||
* 'single' - Concatenation of PCA on datasets, respectively
|
||||
* 'random' - Random draw from a normal
|
||||
|
||||
|
||||
:type initx: ['concat'|'single'|'random']
|
||||
:param initz: initialisation method for inducing inputs
|
||||
:type initz: 'permute'|'random'
|
||||
|
|
@ -39,6 +39,7 @@ class MRD(Model):
|
|||
:param num_inducing: number of inducing inputs to use
|
||||
:param kernels: list of kernels or kernel shared for all BGPLVMS
|
||||
:type kernels: [GPy.kern.kern] | GPy.kern.kern | None (default)
|
||||
|
||||
"""
|
||||
def __init__(self, likelihood_or_Y_list, input_dim, num_inducing=10, names=None,
|
||||
kernels=None, initx='PCA',
|
||||
|
|
@ -163,28 +164,31 @@ class MRD(Model):
|
|||
self._init_X(initx, self.likelihood_list)
|
||||
self._init_Z(initz, self.X)
|
||||
|
||||
def _get_latent_param_names(self):
|
||||
#def _get_latent_param_names(self):
|
||||
def _get_param_names(self):
|
||||
n1 = self.gref._get_param_names()
|
||||
n1var = n1[:self.NQ * 2 + self.MQ]
|
||||
return n1var
|
||||
|
||||
|
||||
def _get_kernel_names(self):
|
||||
# return n1var
|
||||
#
|
||||
#def _get_kernel_names(self):
|
||||
map_names = lambda ns, name: map(lambda x: "{1}_{0}".format(*x),
|
||||
itertools.izip(ns,
|
||||
itertools.repeat(name)))
|
||||
kernel_names = (map_names(SparseGP._get_param_names(g)[self.MQ:], n) for g, n in zip(self.bgplvms, self.names))
|
||||
return kernel_names
|
||||
return list(itertools.chain(n1var, *(map_names(\
|
||||
SparseGP._get_param_names(g)[self.MQ:], n) \
|
||||
for g, n in zip(self.bgplvms, self.names))))
|
||||
# kernel_names = (map_names(SparseGP._get_param_names(g)[self.MQ:], n) for g, n in zip(self.bgplvms, self.names))
|
||||
# return kernel_names
|
||||
|
||||
def _get_param_names(self):
|
||||
#def _get_param_names(self):
|
||||
# X_names = sum([['X_%i_%i' % (n, q) for q in range(self.input_dim)] for n in range(self.num_data)], [])
|
||||
# S_names = sum([['X_variance_%i_%i' % (n, q) for q in range(self.input_dim)] for n in range(self.num_data)], [])
|
||||
n1var = self._get_latent_param_names()
|
||||
kernel_names = self._get_kernel_names()
|
||||
return list(itertools.chain(n1var, *kernel_names))
|
||||
# n1var = self._get_latent_param_names()
|
||||
# kernel_names = self._get_kernel_names()
|
||||
# return list(itertools.chain(n1var, *kernel_names))
|
||||
|
||||
def _get_print_names(self):
|
||||
return list(itertools.chain(*self._get_kernel_names()))
|
||||
#def _get_print_names(self):
|
||||
# return list(itertools.chain(*self._get_kernel_names()))
|
||||
|
||||
def _get_params(self):
|
||||
"""
|
||||
|
|
@ -335,8 +339,11 @@ class MRD(Model):
|
|||
|
||||
def plot_scales(self, fignum=None, ax=None, titles=None, sharex=False, sharey=True, *args, **kwargs):
|
||||
"""
|
||||
:param:`titles` :
|
||||
titles for axes of datasets
|
||||
|
||||
TODO: Explain other parameters
|
||||
|
||||
:param titles: titles for axes of datasets
|
||||
|
||||
"""
|
||||
if titles is None:
|
||||
titles = [r'${}$'.format(name) for name in self.names]
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ class SparseGPClassification(SparseGP):
|
|||
|
||||
def __init__(self, X, Y=None, likelihood=None, kernel=None, normalize_X=False, normalize_Y=False, Z=None, num_inducing=10):
|
||||
if kernel is None:
|
||||
kernel = kern.rbf(X.shape[1]) + kern.white(X.shape[1], 1e-3)
|
||||
kernel = kern.rbf(X.shape[1])# + kern.white(X.shape[1],1e-3)
|
||||
|
||||
if likelihood is None:
|
||||
distribution = likelihoods.likelihood_functions.Binomial()
|
||||
likelihood = likelihoods.EP(Y, distribution)
|
||||
noise_model = likelihoods.binomial()
|
||||
likelihood = likelihoods.EP(Y, noise_model)
|
||||
elif Y is not None:
|
||||
if not all(Y.flatten() == likelihood.data.flatten()):
|
||||
raise Warning, 'likelihood.data and Y are different.'
|
||||
|
|
|
|||
80
GPy/models/sparse_gp_multioutput_regression.py
Normal file
80
GPy/models/sparse_gp_multioutput_regression.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# Copyright (c) 2013, Ricardo Andrade
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
|
||||
import numpy as np
|
||||
from ..core import SparseGP
|
||||
from .. import likelihoods
|
||||
from .. import kern
|
||||
from ..util import multioutput
|
||||
|
||||
class SparseGPMultioutputRegression(SparseGP):
|
||||
"""
|
||||
Sparse multiple output Gaussian process with Gaussian noise
|
||||
|
||||
This is a wrapper around the models.SparseGP class, with a set of sensible defaults
|
||||
|
||||
:param X_list: input observations
|
||||
:type X_list: list of numpy arrays (num_data_output_i x input_dim), one array per output
|
||||
:param Y_list: observed values
|
||||
:type Y_list: list of numpy arrays (num_data_output_i x 1), one array per output
|
||||
:param kernel_list: GPy kernels, defaults to rbf
|
||||
:type kernel_list: list of GPy kernels
|
||||
:param noise_variance_list: noise parameters per output, defaults to 1.0 for every output
|
||||
:type noise_variance_list: list of floats
|
||||
:param normalize_X: whether to normalize the input data before computing (predictions will be in original scales)
|
||||
:type normalize_X: False|True
|
||||
:param normalize_Y: whether to normalize the input data before computing (predictions will be in original scales)
|
||||
:type normalize_Y: False|True
|
||||
:param Z_list: inducing inputs (optional)
|
||||
:type Z_list: list of numpy arrays (num_inducing_output_i x input_dim), one array per output | empty list
|
||||
:param num_inducing: number of inducing inputs per output, defaults to 10 (ignored if Z_list is not empty)
|
||||
:type num_inducing: integer
|
||||
:param rank: number tuples of the corregionalization parameters 'coregion_W' (see coregionalize kernel documentation)
|
||||
:type rank: integer
|
||||
"""
|
||||
#NOTE not tested with uncertain inputs
|
||||
def __init__(self,X_list,Y_list,kernel_list=None,noise_variance_list=None,normalize_X=False,normalize_Y=False,Z_list=[],num_inducing=10,rank=1):
|
||||
|
||||
self.output_dim = len(Y_list)
|
||||
assert len(X_list) == self.output_dim, 'Number of outputs do not match length of inputs list.'
|
||||
|
||||
#Inducing inputs list
|
||||
if len(Z_list):
|
||||
assert len(Z_list) == self.output_dim, 'Number of outputs do not match length of inducing inputs list.'
|
||||
else:
|
||||
if isinstance(num_inducing,np.int):
|
||||
num_inducing = [num_inducing] * self.output_dim
|
||||
num_inducing = np.asarray(num_inducing)
|
||||
assert num_inducing.size == self.output_dim, 'Number of outputs do not match length of inducing inputs list.'
|
||||
for ni,X in zip(num_inducing,X_list):
|
||||
i = np.random.permutation(X.shape[0])[:ni]
|
||||
Z_list.append(X[i].copy())
|
||||
|
||||
#Inputs and inducing inputs indexing
|
||||
i = 0
|
||||
index = []
|
||||
index_z = []
|
||||
for x,y,z in zip(X_list,Y_list,Z_list):
|
||||
assert x.shape[0] == y.shape[0]
|
||||
index.append(np.repeat(i,x.size)[:,None])
|
||||
index_z.append(np.repeat(i,z.size)[:,None])
|
||||
i += 1
|
||||
index = np.vstack(index)
|
||||
index_z = np.vstack(index_z)
|
||||
X = np.hstack([np.vstack(X_list),index])
|
||||
Z = np.hstack([np.vstack(Z_list),index_z])
|
||||
original_dim = X.shape[1] - 1
|
||||
|
||||
#Mixed noise likelihood definition
|
||||
likelihood = likelihoods.Gaussian_Mixed_Noise(Y_list,noise_params=noise_variance_list,normalize=normalize_Y)
|
||||
|
||||
#Coregionalization kernel definition
|
||||
if kernel_list is None:
|
||||
kernel_list = [kern.rbf(original_dim)]
|
||||
mkernel = kern.build_lcm(input_dim=original_dim, output_dim=self.output_dim, kernel_list = kernel_list, rank=rank)
|
||||
|
||||
self.multioutput = True
|
||||
SparseGP.__init__(self, X, likelihood, mkernel, Z=Z, normalize_X=normalize_X)
|
||||
self.constrain_fixed('.*iip_\d+_1')
|
||||
self.ensure_default_constraints()
|
||||
|
|
@ -20,7 +20,11 @@ class SparseGPRegression(SparseGP):
|
|||
:type normalize_X: False|True
|
||||
:param normalize_Y: whether to normalize the input data before computing (predictions will be in original scales)
|
||||
:type normalize_Y: False|True
|
||||
:param Z: inducing inputs (optional, see note)
|
||||
:type Z: np.ndarray (num_inducing x input_dim) | None
|
||||
:rtype: model object
|
||||
:param X_variance: The uncertainty in the measurements of X (Gaussian variance)
|
||||
:type X_variance: np.ndarray (num_data x input_dim) | None
|
||||
|
||||
.. Note:: Multiple independent outputs are allowed using columns of Y
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue