mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-05-21 14:05:14 +02:00
Merge branch 'devel' of github.com:SheffieldML/GPy into devel
This commit is contained in:
commit
2e99fa1502
115 changed files with 7495 additions and 2930 deletions
|
|
@ -126,7 +126,7 @@ class FITC(SparseGP):
|
||||||
self._dpsi1_dX += self.kern.dK_dX(_dpsi1.T,self.Z,self.X[i:i+1,:])
|
self._dpsi1_dX += self.kern.dK_dX(_dpsi1.T,self.Z,self.X[i:i+1,:])
|
||||||
|
|
||||||
# the partial derivative vector for the likelihood
|
# the partial derivative vector for the likelihood
|
||||||
if self.likelihood.Nparams == 0:
|
if self.likelihood.num_params == 0:
|
||||||
# save computation here.
|
# save computation here.
|
||||||
self.partial_for_likelihood = None
|
self.partial_for_likelihood = None
|
||||||
elif self.likelihood.is_heteroscedastic:
|
elif self.likelihood.is_heteroscedastic:
|
||||||
|
|
@ -159,7 +159,7 @@ class FITC(SparseGP):
|
||||||
A = -0.5 * self.num_data * self.output_dim * np.log(2.*np.pi) + 0.5 * np.sum(np.log(self.beta_star)) - 0.5 * np.sum(self.V_star * self.likelihood.Y)
|
A = -0.5 * self.num_data * self.output_dim * np.log(2.*np.pi) + 0.5 * np.sum(np.log(self.beta_star)) - 0.5 * np.sum(self.V_star * self.likelihood.Y)
|
||||||
C = -self.output_dim * (np.sum(np.log(np.diag(self.LB))))
|
C = -self.output_dim * (np.sum(np.log(np.diag(self.LB))))
|
||||||
D = 0.5 * np.sum(np.square(self._LBi_Lmi_psi1V))
|
D = 0.5 * np.sum(np.square(self._LBi_Lmi_psi1V))
|
||||||
return A + C + D
|
return A + C + D + self.likelihood.Z
|
||||||
|
|
||||||
def _log_likelihood_gradients(self):
|
def _log_likelihood_gradients(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import numpy as np
|
||||||
import pylab as pb
|
import pylab as pb
|
||||||
from .. import kern
|
from .. import kern
|
||||||
from ..util.linalg import pdinv, mdot, tdot, dpotrs, dtrtrs
|
from ..util.linalg import pdinv, mdot, tdot, dpotrs, dtrtrs
|
||||||
from ..likelihoods import EP
|
from ..likelihoods import EP, Laplace
|
||||||
from gp_base import GPBase
|
from gp_base import GPBase
|
||||||
|
|
||||||
class GP(GPBase):
|
class GP(GPBase):
|
||||||
|
|
@ -25,20 +25,23 @@ class GP(GPBase):
|
||||||
"""
|
"""
|
||||||
def __init__(self, X, likelihood, kernel, normalize_X=False):
|
def __init__(self, X, likelihood, kernel, normalize_X=False):
|
||||||
GPBase.__init__(self, X, likelihood, kernel, normalize_X=normalize_X)
|
GPBase.__init__(self, X, likelihood, kernel, normalize_X=normalize_X)
|
||||||
self._set_params(self._get_params())
|
self.update_likelihood_approximation()
|
||||||
|
|
||||||
def getstate(self):
|
|
||||||
return GPBase.getstate(self)
|
|
||||||
|
|
||||||
def setstate(self, state):
|
|
||||||
GPBase.setstate(self, state)
|
|
||||||
self._set_params(self._get_params())
|
|
||||||
|
|
||||||
def _set_params(self, p):
|
def _set_params(self, p):
|
||||||
self.kern._set_params_transformed(p[:self.kern.num_params_transformed()])
|
new_kern_params = p[:self.kern.num_params_transformed()]
|
||||||
self.likelihood._set_params(p[self.kern.num_params_transformed():])
|
new_likelihood_params = p[self.kern.num_params_transformed():]
|
||||||
|
old_likelihood_params = self.likelihood._get_params()
|
||||||
|
|
||||||
|
self.kern._set_params_transformed(new_kern_params)
|
||||||
|
self.likelihood._set_params_transformed(new_likelihood_params)
|
||||||
|
|
||||||
self.K = self.kern.K(self.X)
|
self.K = self.kern.K(self.X)
|
||||||
|
|
||||||
|
#Re fit likelihood approximation (if it is an approx), as parameters have changed
|
||||||
|
if isinstance(self.likelihood, Laplace):
|
||||||
|
self.likelihood.fit_full(self.K)
|
||||||
|
|
||||||
self.K += self.likelihood.covariance_matrix
|
self.K += self.likelihood.covariance_matrix
|
||||||
|
|
||||||
self.Ki, self.L, self.Li, self.K_logdet = pdinv(self.K)
|
self.Ki, self.L, self.Li, self.K_logdet = pdinv(self.K)
|
||||||
|
|
@ -55,6 +58,10 @@ class GP(GPBase):
|
||||||
tmp, _ = dpotrs(self.L, np.asfortranarray(tmp.T), lower=1)
|
tmp, _ = dpotrs(self.L, np.asfortranarray(tmp.T), lower=1)
|
||||||
self.dL_dK = 0.5 * (tmp - self.output_dim * self.Ki)
|
self.dL_dK = 0.5 * (tmp - self.output_dim * self.Ki)
|
||||||
|
|
||||||
|
#Adding dZ_dK (0 for a non-approximate likelihood, compensates for
|
||||||
|
#additional gradients of K when log-likelihood has non-zero Z term)
|
||||||
|
self.dL_dK += self.likelihood.dZ_dK
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return np.hstack((self.kern._get_params_transformed(), self.likelihood._get_params()))
|
return np.hstack((self.kern._get_params_transformed(), self.likelihood._get_params()))
|
||||||
|
|
||||||
|
|
@ -94,19 +101,13 @@ class GP(GPBase):
|
||||||
return (-0.5 * self.num_data * self.output_dim * np.log(2.*np.pi) -
|
return (-0.5 * self.num_data * self.output_dim * np.log(2.*np.pi) -
|
||||||
0.5 * self.output_dim * self.K_logdet + self._model_fit_term() + self.likelihood.Z)
|
0.5 * self.output_dim * self.K_logdet + self._model_fit_term() + self.likelihood.Z)
|
||||||
|
|
||||||
|
|
||||||
def _log_likelihood_gradients(self):
|
def _log_likelihood_gradients(self):
|
||||||
"""
|
"""
|
||||||
The gradient of all parameters.
|
The gradient of all parameters.
|
||||||
|
|
||||||
Note, we use the chain rule: dL_dtheta = dL_dK * d_K_dtheta
|
Note, we use the chain rule: dL_dtheta = dL_dK * d_K_dtheta
|
||||||
"""
|
"""
|
||||||
#return np.hstack((self.kern.dK_dtheta(dL_dK=self.dL_dK, X=self.X), self.likelihood._gradients(partial=np.diag(self.dL_dK))))
|
return np.hstack((self.kern.dK_dtheta(dL_dK=self.dL_dK, X=self.X), self.likelihood._gradients(partial=np.diag(self.dL_dK))))
|
||||||
if not isinstance(self.likelihood,EP):
|
|
||||||
tmp = np.hstack((self.kern.dK_dtheta(dL_dK=self.dL_dK, X=self.X), self.likelihood._gradients(partial=np.diag(self.dL_dK))))
|
|
||||||
else:
|
|
||||||
tmp = np.hstack((self.kern.dK_dtheta(dL_dK=self.dL_dK, X=self.X), self.likelihood._gradients(partial=np.diag(self.dL_dK))))
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
def _raw_predict(self, _Xnew, which_parts='all', full_cov=False, stop=False):
|
def _raw_predict(self, _Xnew, which_parts='all', full_cov=False, stop=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -193,3 +194,11 @@ class GP(GPBase):
|
||||||
"""
|
"""
|
||||||
Xnew = self._add_output_index(Xnew, output)
|
Xnew = self._add_output_index(Xnew, output)
|
||||||
return self.predict(Xnew, which_parts=which_parts, full_cov=full_cov, likelihood_args=likelihood_args)
|
return self.predict(Xnew, which_parts=which_parts, full_cov=full_cov, likelihood_args=likelihood_args)
|
||||||
|
|
||||||
|
def getstate(self):
|
||||||
|
return GPBase.getstate(self)
|
||||||
|
|
||||||
|
def setstate(self, state):
|
||||||
|
GPBase.setstate(self, state)
|
||||||
|
self._set_params(self._get_params())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,16 @@ from ..likelihoods import Gaussian, Gaussian_Mixed_Noise
|
||||||
class GPBase(Model):
|
class GPBase(Model):
|
||||||
"""
|
"""
|
||||||
Gaussian process base model for holding shared behaviour between
|
Gaussian process base model for holding shared behaviour between
|
||||||
sparse_GP and GP models.
|
sparse_GP and GP models, and potentially other models in the future.
|
||||||
|
|
||||||
|
Here we define some functions that are use
|
||||||
"""
|
"""
|
||||||
def __init__(self, X, likelihood, kernel, normalize_X=False):
|
def __init__(self, X, likelihood, kernel, normalize_X=False):
|
||||||
|
if len(X.shape)==1:
|
||||||
|
X = X.reshape(-1,1)
|
||||||
|
warnings.warn("One dimension output (N,) being reshaped to (N,1)")
|
||||||
self.X = X
|
self.X = X
|
||||||
assert len(self.X.shape) == 2
|
assert len(self.X.shape) == 2, "too many dimensions for X input"
|
||||||
self.num_data, self.input_dim = self.X.shape
|
self.num_data, self.input_dim = self.X.shape
|
||||||
assert isinstance(kernel, kern.kern)
|
assert isinstance(kernel, kern.kern)
|
||||||
self.kern = kernel
|
self.kern = kernel
|
||||||
|
|
@ -34,31 +39,8 @@ class GPBase(Model):
|
||||||
# All leaf nodes should call self._set_params(self._get_params()) at
|
# All leaf nodes should call self._set_params(self._get_params()) at
|
||||||
# the end
|
# the end
|
||||||
|
|
||||||
def getstate(self):
|
|
||||||
"""
|
|
||||||
Get the current state of the class, here we return everything that is needed to recompute the model.
|
|
||||||
"""
|
|
||||||
return Model.getstate(self) + [self.X,
|
|
||||||
self.num_data,
|
|
||||||
self.input_dim,
|
|
||||||
self.kern,
|
|
||||||
self.likelihood,
|
|
||||||
self.output_dim,
|
|
||||||
self._Xoffset,
|
|
||||||
self._Xscale]
|
|
||||||
|
|
||||||
def setstate(self, state):
|
def posterior_samples_f(self,X,size=10,which_parts='all'):
|
||||||
self._Xscale = state.pop()
|
|
||||||
self._Xoffset = state.pop()
|
|
||||||
self.output_dim = state.pop()
|
|
||||||
self.likelihood = state.pop()
|
|
||||||
self.kern = state.pop()
|
|
||||||
self.input_dim = state.pop()
|
|
||||||
self.num_data = state.pop()
|
|
||||||
self.X = state.pop()
|
|
||||||
Model.setstate(self, state)
|
|
||||||
|
|
||||||
def posterior_samples_f(self,X,size=10,which_parts='all',full_cov=True):
|
|
||||||
"""
|
"""
|
||||||
Samples the posterior GP at the points X.
|
Samples the posterior GP at the points X.
|
||||||
|
|
||||||
|
|
@ -72,16 +54,13 @@ class GPBase(Model):
|
||||||
:type full_cov: bool.
|
:type full_cov: bool.
|
||||||
:returns: Ysim: set of simulations, a Numpy array (N x samples).
|
:returns: Ysim: set of simulations, a Numpy array (N x samples).
|
||||||
"""
|
"""
|
||||||
m, v = self._raw_predict(X, which_parts=which_parts, full_cov=full_cov)
|
m, v = self._raw_predict(X, which_parts=which_parts, full_cov=True)
|
||||||
v = v.reshape(m.size,-1) if len(v.shape)==3 else v
|
v = v.reshape(m.size,-1) if len(v.shape)==3 else v
|
||||||
if not full_cov:
|
|
||||||
Ysim = np.random.multivariate_normal(m.flatten(), np.diag(v.flatten()), size).T
|
|
||||||
else:
|
|
||||||
Ysim = np.random.multivariate_normal(m.flatten(), v, size).T
|
Ysim = np.random.multivariate_normal(m.flatten(), v, size).T
|
||||||
|
|
||||||
return Ysim
|
return Ysim
|
||||||
|
|
||||||
def posterior_samples(self,X,size=10,which_parts='all',full_cov=True,noise_model=None):
|
def posterior_samples(self,X,size=10,which_parts='all',noise_model=None):
|
||||||
"""
|
"""
|
||||||
Samples the posterior GP at the points X.
|
Samples the posterior GP at the points X.
|
||||||
|
|
||||||
|
|
@ -97,7 +76,7 @@ class GPBase(Model):
|
||||||
:type noise_model: integer.
|
:type noise_model: integer.
|
||||||
:returns: Ysim: set of simulations, a Numpy array (N x samples).
|
:returns: Ysim: set of simulations, a Numpy array (N x samples).
|
||||||
"""
|
"""
|
||||||
Ysim = self.posterior_samples_f(X, size, which_parts=which_parts, full_cov=full_cov)
|
Ysim = self.posterior_samples_f(X, size, which_parts=which_parts)
|
||||||
if isinstance(self.likelihood,Gaussian):
|
if isinstance(self.likelihood,Gaussian):
|
||||||
noise_std = np.sqrt(self.likelihood._get_params())
|
noise_std = np.sqrt(self.likelihood._get_params())
|
||||||
Ysim += np.random.normal(0,noise_std,Ysim.shape)
|
Ysim += np.random.normal(0,noise_std,Ysim.shape)
|
||||||
|
|
@ -110,90 +89,43 @@ class GPBase(Model):
|
||||||
|
|
||||||
return Ysim
|
return Ysim
|
||||||
|
|
||||||
def plot_f(self, samples=0, plot_limits=None, which_data='all', which_parts='all', resolution=None, full_cov=False, fignum=None, ax=None):
|
def plot_f(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Plot the GP's view of the world, where the data is normalized and the
|
Plot the GP's view of the world, where the data is normalized and before applying a likelihood.
|
||||||
- In one dimension, the function is plotted with a shaded region identifying two standard deviations.
|
|
||||||
- In two dimsensions, a contour-plot shows the mean predicted function
|
|
||||||
- Not implemented in higher dimensions
|
|
||||||
|
|
||||||
:param samples: the number of a posteriori samples to plot
|
This is a convenience function: we simply call self.plot with the
|
||||||
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
|
argument use_raw_predict set True. All args and kwargs are passed on to
|
||||||
:param which_data: which if the training data to plot (default all)
|
plot.
|
||||||
:type which_data: 'all' or a slice object to slice self.X, self.Y
|
|
||||||
:param which_parts: which of the kernel functions to plot (additively)
|
|
||||||
:type which_parts: 'all', or list of bools
|
|
||||||
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
|
|
||||||
:type resolution: int
|
|
||||||
:param full_cov:
|
|
||||||
:type full_cov: bool
|
|
||||||
:param fignum: figure to plot on.
|
|
||||||
:type fignum: figure number
|
|
||||||
:param ax: axes to plot on.
|
|
||||||
:type ax: axes handle
|
|
||||||
|
|
||||||
:param output: which output to plot (for multiple output models only)
|
see also: gp_base.plot
|
||||||
:type output: integer (first output is 0)
|
|
||||||
"""
|
"""
|
||||||
if which_data == 'all':
|
kwargs['plot_raw'] = True
|
||||||
which_data = slice(None)
|
self.plot(*args, **kwargs)
|
||||||
|
|
||||||
if ax is None:
|
def plot(self, plot_limits=None, which_data_rows='all',
|
||||||
fig = pb.figure(num=fignum)
|
which_data_ycols='all', which_parts='all', fixed_inputs=[],
|
||||||
ax = fig.add_subplot(111)
|
levels=20, samples=0, fignum=None, ax=None, resolution=None,
|
||||||
|
plot_raw=False,
|
||||||
if self.X.shape[1] == 1:
|
linecol=Tango.colorsHex['darkBlue'],fillcol=Tango.colorsHex['lightBlue']):
|
||||||
resolution = resolution or 200
|
|
||||||
Xnew, xmin, xmax = x_frame1D(self.X, plot_limits=plot_limits)
|
|
||||||
|
|
||||||
m, v = self._raw_predict(Xnew, which_parts=which_parts)
|
|
||||||
if samples:
|
|
||||||
Ysim = self.posterior_samples_f(Xnew, samples, which_parts=which_parts, full_cov=True)
|
|
||||||
for yi in Ysim.T:
|
|
||||||
ax.plot(Xnew, yi[:,None], Tango.colorsHex['darkBlue'], linewidth=0.25)
|
|
||||||
gpplot(Xnew, m, m - 2 * np.sqrt(v), m + 2 * np.sqrt(v), axes=ax)
|
|
||||||
|
|
||||||
ax.plot(self.X[which_data], self.likelihood.Y[which_data], 'kx', mew=1.5)
|
|
||||||
ax.set_xlim(xmin, xmax)
|
|
||||||
ymin, ymax = min(np.append(self.likelihood.Y, m - 2 * np.sqrt(np.diag(v)[:, None]))), max(np.append(self.likelihood.Y, m + 2 * np.sqrt(np.diag(v)[:, None])))
|
|
||||||
ymin, ymax = ymin - 0.1 * (ymax - ymin), ymax + 0.1 * (ymax - ymin)
|
|
||||||
ax.set_ylim(ymin, ymax)
|
|
||||||
|
|
||||||
elif self.X.shape[1] == 2:
|
|
||||||
|
|
||||||
resolution = resolution or 50
|
|
||||||
Xnew, xmin, xmax, xx, yy = x_frame2D(self.X, plot_limits, resolution)
|
|
||||||
m, v = self._raw_predict(Xnew, which_parts=which_parts)
|
|
||||||
m = m.reshape(resolution, resolution).T
|
|
||||||
ax.contour(xx, yy, m, vmin=m.min(), vmax=m.max(), cmap=pb.cm.jet) # @UndefinedVariable
|
|
||||||
ax.scatter(self.X[:, 0], self.X[:, 1], 40, self.likelihood.Y, linewidth=0, cmap=pb.cm.jet, vmin=m.min(), vmax=m.max()) # @UndefinedVariable
|
|
||||||
ax.set_xlim(xmin[0], xmax[0])
|
|
||||||
ax.set_ylim(xmin[1], xmax[1])
|
|
||||||
|
|
||||||
if samples:
|
|
||||||
warnings.warn("Samples only implemented for 1 dimensional inputs.")
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
|
||||||
|
|
||||||
def plot(self, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, samples=0, fignum=None, ax=None, fixed_inputs=[], linecol=Tango.colorsHex['darkBlue'],fillcol=Tango.colorsHex['lightBlue']):
|
|
||||||
"""
|
"""
|
||||||
Plot the GP with noise where the likelihood is Gaussian.
|
|
||||||
|
|
||||||
Plot the posterior of the GP.
|
Plot the posterior of the GP.
|
||||||
- In one dimension, the function is plotted with a shaded region identifying two standard deviations.
|
- In one dimension, the function is plotted with a shaded region identifying two standard deviations.
|
||||||
- In two dimsensions, a contour-plot shows the mean predicted function
|
- In two dimsensions, a contour-plot shows the mean predicted function
|
||||||
- Not implemented in higher dimensions
|
- In higher dimensions, use fixed_inputs to plot the GP with some of the inputs fixed.
|
||||||
|
|
||||||
Can plot only part of the data and part of the posterior functions
|
Can plot only part of the data and part of the posterior functions
|
||||||
using which_data and which_functions
|
using which_data_rowsm which_data_ycols and which_parts
|
||||||
|
|
||||||
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
|
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
|
||||||
:type plot_limits: np.array
|
:type plot_limits: np.array
|
||||||
:param which_data: which if the training data to plot (default all)
|
:param which_data_rows: which of the training data to plot (default all)
|
||||||
:type which_data: 'all' or a slice object to slice self.X, self.Y
|
:type which_data_rows: 'all' or a slice object to slice self.X, self.Y
|
||||||
|
:param which_data_ycols: when the data has several columns (independant outputs), only plot these
|
||||||
|
:type which_data_rows: 'all' or a list of integers
|
||||||
:param which_parts: which of the kernel functions to plot (additively)
|
:param which_parts: which of the kernel functions to plot (additively)
|
||||||
:type which_parts: 'all', or list of bools
|
:type which_parts: 'all', or list of bools
|
||||||
|
:param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
|
||||||
|
:type fixed_inputs: a list of tuples
|
||||||
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
|
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
|
||||||
:type resolution: int
|
:type resolution: int
|
||||||
:param levels: number of levels to plot in a contour plot.
|
:param levels: number of levels to plot in a contour plot.
|
||||||
|
|
@ -205,216 +137,139 @@ class GPBase(Model):
|
||||||
:param ax: axes to plot on.
|
:param ax: axes to plot on.
|
||||||
:type ax: axes handle
|
:type ax: axes handle
|
||||||
:type output: integer (first output is 0)
|
:type output: integer (first output is 0)
|
||||||
:param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
|
|
||||||
:type fixed_inputs: a list of tuples
|
|
||||||
:param linecol: color of line to plot.
|
:param linecol: color of line to plot.
|
||||||
:type linecol:
|
:type linecol:
|
||||||
:param fillcol: color of fill
|
:param fillcol: color of fill
|
||||||
:param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure
|
:param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure
|
||||||
"""
|
"""
|
||||||
if which_data == 'all':
|
#deal with optional arguments
|
||||||
which_data = slice(None)
|
if which_data_rows == 'all':
|
||||||
|
which_data_rows = slice(None)
|
||||||
|
if which_data_ycols == 'all':
|
||||||
|
which_data_ycols = np.arange(self.output_dim)
|
||||||
|
if len(which_data_ycols)==0:
|
||||||
|
raise ValueError('No data selected for plotting')
|
||||||
if ax is None:
|
if ax is None:
|
||||||
fig = pb.figure(num=fignum)
|
fig = pb.figure(num=fignum)
|
||||||
ax = fig.add_subplot(111)
|
ax = fig.add_subplot(111)
|
||||||
|
|
||||||
plotdims = self.input_dim - len(fixed_inputs)
|
#work out what the inputs are for plotting (1D or 2D)
|
||||||
if plotdims == 1:
|
|
||||||
resolution = resolution or 200
|
|
||||||
|
|
||||||
Xu = self.X * self._Xscale + self._Xoffset #NOTE self.X are the normalized values now
|
|
||||||
|
|
||||||
fixed_dims = np.array([i for i,v in fixed_inputs])
|
fixed_dims = np.array([i for i,v in fixed_inputs])
|
||||||
freedim = np.setdiff1d(np.arange(self.input_dim),fixed_dims)
|
free_dims = np.setdiff1d(np.arange(self.input_dim),fixed_dims)
|
||||||
|
|
||||||
Xnew, xmin, xmax = x_frame1D(Xu[:,freedim], plot_limits=plot_limits)
|
#one dimensional plotting
|
||||||
|
if len(free_dims) == 1:
|
||||||
|
|
||||||
|
#define the frame on which to plot
|
||||||
|
resolution = resolution or 200
|
||||||
|
Xu = self.X * self._Xscale + self._Xoffset #NOTE self.X are the normalized values now
|
||||||
|
Xnew, xmin, xmax = x_frame1D(Xu[:,free_dims], plot_limits=plot_limits)
|
||||||
Xgrid = np.empty((Xnew.shape[0],self.input_dim))
|
Xgrid = np.empty((Xnew.shape[0],self.input_dim))
|
||||||
Xgrid[:,freedim] = Xnew
|
Xgrid[:,free_dims] = Xnew
|
||||||
for i,v in fixed_inputs:
|
for i,v in fixed_inputs:
|
||||||
Xgrid[:,i] = v
|
Xgrid[:,i] = v
|
||||||
|
|
||||||
m, v, lower, upper = self.predict(Xgrid, which_parts=which_parts)
|
#make a prediction on the frame and plot it
|
||||||
|
if plot_raw:
|
||||||
|
m, v = self._raw_predict(Xgrid, which_parts=which_parts)
|
||||||
|
lower = m - 2*np.sqrt(v)
|
||||||
|
upper = m + 2*np.sqrt(v)
|
||||||
|
Y = self.likelihood.Y
|
||||||
|
else:
|
||||||
|
m, v, lower, upper = self.predict(Xgrid, which_parts=which_parts, sampling=False) #Compute the exact mean
|
||||||
|
m_, v_, lower, upper = self.predict(Xgrid, which_parts=which_parts, sampling=True, num_samples=15000) #Apporximate the percentiles
|
||||||
|
Y = self.likelihood.data
|
||||||
|
for d in which_data_ycols:
|
||||||
|
gpplot(Xnew, m[:, d], lower[:, d], upper[:, d], axes=ax, edgecol=linecol, fillcol=fillcol)
|
||||||
|
ax.plot(Xu[which_data_rows,free_dims], Y[which_data_rows, d], 'kx', mew=1.5)
|
||||||
|
|
||||||
|
#optionally plot some samples
|
||||||
if samples: #NOTE not tested with fixed_inputs
|
if samples: #NOTE not tested with fixed_inputs
|
||||||
Ysim = self.posterior_samples(Xgrid, samples, which_parts=which_parts, full_cov=True)
|
Ysim = self.posterior_samples(Xgrid, samples, which_parts=which_parts)
|
||||||
for yi in Ysim.T:
|
for yi in Ysim.T:
|
||||||
ax.plot(Xnew, yi[:,None], Tango.colorsHex['darkBlue'], linewidth=0.25)
|
ax.plot(Xnew, yi[:,None], Tango.colorsHex['darkBlue'], linewidth=0.25)
|
||||||
#ax.plot(Xnew, yi[:,None], marker='x', linestyle='--',color=Tango.colorsHex['darkBlue']) #TODO apply this line for discrete outputs.
|
#ax.plot(Xnew, yi[:,None], marker='x', linestyle='--',color=Tango.colorsHex['darkBlue']) #TODO apply this line for discrete outputs.
|
||||||
|
|
||||||
for d in range(m.shape[1]):
|
#set the limits of the plot to some sensible values
|
||||||
gpplot(Xnew, m[:, d], lower[:, d], upper[:, d], axes=ax, edgecol=linecol, fillcol=fillcol)
|
ymin, ymax = min(np.append(Y[which_data_rows, which_data_ycols].flatten(), lower)), max(np.append(Y[which_data_rows, which_data_ycols].flatten(), upper))
|
||||||
ax.plot(Xu[which_data,freedim], self.likelihood.data[which_data, d], 'kx', mew=1.5)
|
|
||||||
ymin, ymax = min(np.append(self.likelihood.data, lower)), max(np.append(self.likelihood.data, upper))
|
|
||||||
ymin, ymax = ymin - 0.1 * (ymax - ymin), ymax + 0.1 * (ymax - ymin)
|
ymin, ymax = ymin - 0.1 * (ymax - ymin), ymax + 0.1 * (ymax - ymin)
|
||||||
ax.set_xlim(xmin, xmax)
|
ax.set_xlim(xmin, xmax)
|
||||||
ax.set_ylim(ymin, ymax)
|
ax.set_ylim(ymin, ymax)
|
||||||
|
|
||||||
elif self.X.shape[1] == 2:
|
#2D plotting
|
||||||
|
elif len(free_dims) == 2:
|
||||||
|
|
||||||
|
#define the frame for plotting on
|
||||||
resolution = resolution or 50
|
resolution = resolution or 50
|
||||||
Xnew, _, _, xmin, xmax = x_frame2D(self.X, plot_limits, resolution)
|
Xu = self.X * self._Xscale + self._Xoffset #NOTE self.X are the normalized values now
|
||||||
|
Xnew, _, _, xmin, xmax = x_frame2D(Xu[:,free_dims], plot_limits, resolution)
|
||||||
|
Xgrid = np.empty((Xnew.shape[0],self.input_dim))
|
||||||
|
Xgrid[:,free_dims] = Xnew
|
||||||
|
for i,v in fixed_inputs:
|
||||||
|
Xgrid[:,i] = v
|
||||||
x, y = np.linspace(xmin[0], xmax[0], resolution), np.linspace(xmin[1], xmax[1], resolution)
|
x, y = np.linspace(xmin[0], xmax[0], resolution), np.linspace(xmin[1], xmax[1], resolution)
|
||||||
m, _, lower, upper = self.predict(Xnew, which_parts=which_parts)
|
|
||||||
m = m.reshape(resolution, resolution).T
|
#predict on the frame and plot
|
||||||
ax.contour(x, y, m, levels, vmin=m.min(), vmax=m.max(), cmap=pb.cm.jet) # @UndefinedVariable
|
if plot_raw:
|
||||||
Yf = self.likelihood.Y.flatten()
|
m, _ = self._raw_predict(Xgrid, which_parts=which_parts)
|
||||||
ax.scatter(self.X[:, 0], self.X[:, 1], 40, Yf, cmap=pb.cm.jet, vmin=m.min(), vmax=m.max(), linewidth=0.) # @UndefinedVariable
|
Y = self.likelihood.Y
|
||||||
|
else:
|
||||||
|
m, _, _, _ = self.predict(Xgrid, which_parts=which_parts,sampling=False)
|
||||||
|
Y = self.likelihood.data
|
||||||
|
for d in which_data_ycols:
|
||||||
|
m_d = m[:,d].reshape(resolution, resolution).T
|
||||||
|
ax.contour(x, y, m_d, levels, vmin=m.min(), vmax=m.max(), cmap=pb.cm.jet)
|
||||||
|
ax.scatter(self.X[which_data_rows, free_dims[0]], self.X[which_data_rows, free_dims[1]], 40, Y[which_data_rows, d], cmap=pb.cm.jet, vmin=m.min(), vmax=m.max(), linewidth=0.)
|
||||||
|
|
||||||
|
#set the limits of the plot to some sensible values
|
||||||
ax.set_xlim(xmin[0], xmax[0])
|
ax.set_xlim(xmin[0], xmax[0])
|
||||||
ax.set_ylim(xmin[1], xmax[1])
|
ax.set_ylim(xmin[1], xmax[1])
|
||||||
|
|
||||||
if samples:
|
if samples:
|
||||||
warnings.warn("Samples only implemented for 1 dimensional inputs.")
|
warnings.warn("Samples are rather difficult to plot for 2D inputs...")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
||||||
|
|
||||||
def plot_single_output_f(self, output=None, samples=0, plot_limits=None, which_data='all', which_parts='all', resolution=None, full_cov=False, fignum=None, ax=None):
|
def getstate(self):
|
||||||
"""
|
"""
|
||||||
For a specific output, in a multioutput model, this function works just as plot_f on single output models.
|
Get the curent state of the class. This is only used to efficiently
|
||||||
|
pickle the model. See also self.setstate
|
||||||
:param output: which output to plot (for multiple output models only)
|
|
||||||
:type output: integer (first output is 0)
|
|
||||||
:param samples: the number of a posteriori samples to plot
|
|
||||||
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
|
|
||||||
:param which_data: which if the training data to plot (default all)
|
|
||||||
:type which_data: 'all' or a slice object to slice self.X, self.Y
|
|
||||||
:param which_parts: which of the kernel functions to plot (additively)
|
|
||||||
:type which_parts: 'all', or list of bools
|
|
||||||
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
|
|
||||||
:type resolution: int
|
|
||||||
:param full_cov:
|
|
||||||
:type full_cov: bool
|
|
||||||
:param fignum: figure to plot on.
|
|
||||||
:type fignum: figure number
|
|
||||||
:param ax: axes to plot on.
|
|
||||||
:type ax: axes handle
|
|
||||||
"""
|
"""
|
||||||
assert output is not None, "An output must be specified."
|
return Model.getstate(self) + [self.X,
|
||||||
assert len(self.likelihood.noise_model_list) > output, "The model has only %s outputs." %(self.output_dim + 1)
|
self.num_data,
|
||||||
|
self.input_dim,
|
||||||
|
self.kern,
|
||||||
|
self.likelihood,
|
||||||
|
self.output_dim,
|
||||||
|
self._Xoffset,
|
||||||
|
self._Xscale]
|
||||||
|
|
||||||
if which_data == 'all':
|
def setstate(self, state):
|
||||||
which_data = slice(None)
|
|
||||||
|
|
||||||
if ax is None:
|
|
||||||
fig = pb.figure(num=fignum)
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
|
|
||||||
if self.X.shape[1] == 2:
|
|
||||||
Xu = self.X[self.X[:,-1]==output ,0:1]
|
|
||||||
Xnew, xmin, xmax = x_frame1D(Xu, plot_limits=plot_limits)
|
|
||||||
Xnew_indexed = self._add_output_index(Xnew,output)
|
|
||||||
|
|
||||||
m, v = self._raw_predict(Xnew_indexed, which_parts=which_parts)
|
|
||||||
|
|
||||||
if samples:
|
|
||||||
Ysim = self.posterior_samples_f(Xnew_indexed, samples, which_parts=which_parts, full_cov=True)
|
|
||||||
for yi in Ysim.T:
|
|
||||||
ax.plot(Xnew, yi[:,None], Tango.colorsHex['darkBlue'], linewidth=0.25)
|
|
||||||
|
|
||||||
gpplot(Xnew, m, m - 2 * np.sqrt(v), m + 2 * np.sqrt(v), axes=ax)
|
|
||||||
ax.plot(Xu[which_data], self.likelihood.Y[self.likelihood.index==output][:,None], 'kx', mew=1.5)
|
|
||||||
ax.set_xlim(xmin, xmax)
|
|
||||||
ymin, ymax = min(np.append(self.likelihood.Y, m - 2 * np.sqrt(np.diag(v)[:, None]))), max(np.append(self.likelihood.Y, m + 2 * np.sqrt(np.diag(v)[:, None])))
|
|
||||||
ymin, ymax = ymin - 0.1 * (ymax - ymin), ymax + 0.1 * (ymax - ymin)
|
|
||||||
ax.set_ylim(ymin, ymax)
|
|
||||||
|
|
||||||
elif self.X.shape[1] == 3:
|
|
||||||
raise NotImplementedError, "Plots not implemented for multioutput models with 2D inputs...yet"
|
|
||||||
#if samples:
|
|
||||||
# warnings.warn("Samples only implemented for 1 dimensional inputs.")
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
|
||||||
|
|
||||||
|
|
||||||
def plot_single_output(self, output=None, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, samples=0, fignum=None, ax=None, fixed_inputs=[], linecol=Tango.colorsHex['darkBlue'],fillcol=Tango.colorsHex['lightBlue']):
|
|
||||||
"""
|
"""
|
||||||
For a specific output, in a multioutput model, this function works just as plot_f on single output models.
|
Set the state of the model. Used for efficient pickling
|
||||||
|
|
||||||
:param output: which output to plot (for multiple output models only)
|
|
||||||
:type output: integer (first output is 0)
|
|
||||||
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
|
|
||||||
:type plot_limits: np.array
|
|
||||||
:param which_data: which if the training data to plot (default all)
|
|
||||||
:type which_data: 'all' or a slice object to slice self.X, self.Y
|
|
||||||
:param which_parts: which of the kernel functions to plot (additively)
|
|
||||||
:type which_parts: 'all', or list of bools
|
|
||||||
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
|
|
||||||
:type resolution: int
|
|
||||||
:param levels: number of levels to plot in a contour plot.
|
|
||||||
:type levels: int
|
|
||||||
:param samples: the number of a posteriori samples to plot
|
|
||||||
:type samples: int
|
|
||||||
:param fignum: figure to plot on.
|
|
||||||
:type fignum: figure number
|
|
||||||
:param ax: axes to plot on.
|
|
||||||
:type ax: axes handle
|
|
||||||
:type output: integer (first output is 0)
|
|
||||||
:param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
|
|
||||||
:type fixed_inputs: a list of tuples
|
|
||||||
:param linecol: color of line to plot.
|
|
||||||
:type linecol:
|
|
||||||
:param fillcol: color of fill
|
|
||||||
:param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure
|
|
||||||
"""
|
"""
|
||||||
assert output is not None, "An output must be specified."
|
self._Xscale = state.pop()
|
||||||
assert len(self.likelihood.noise_model_list) > output, "The model has only %s outputs." %(self.output_dim + 1)
|
self._Xoffset = state.pop()
|
||||||
if which_data == 'all':
|
self.output_dim = state.pop()
|
||||||
which_data = slice(None)
|
self.likelihood = state.pop()
|
||||||
|
self.kern = state.pop()
|
||||||
|
self.input_dim = state.pop()
|
||||||
|
self.num_data = state.pop()
|
||||||
|
self.X = state.pop()
|
||||||
|
Model.setstate(self, state)
|
||||||
|
|
||||||
if ax is None:
|
def log_predictive_density(self, x_test, y_test):
|
||||||
fig = pb.figure(num=fignum)
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
|
|
||||||
if self.X.shape[1] == 2:
|
|
||||||
resolution = resolution or 200
|
|
||||||
|
|
||||||
Xu = self.X[self.X[:,-1]==output,:] #keep the output of interest
|
|
||||||
Xu = self.X * self._Xscale + self._Xoffset
|
|
||||||
Xu = self.X[self.X[:,-1]==output ,0:1] #get rid of the index column
|
|
||||||
|
|
||||||
Xnew, xmin, xmax = x_frame1D(Xu, plot_limits=plot_limits)
|
|
||||||
Xnew_indexed = self._add_output_index(Xnew,output)
|
|
||||||
|
|
||||||
|
|
||||||
m, v, lower, upper = self.predict(Xnew_indexed, which_parts=which_parts,noise_model=output)
|
|
||||||
|
|
||||||
if samples: #NOTE not tested with fixed_inputs
|
|
||||||
Ysim = self.posterior_samples(Xnew_indexed, samples, which_parts=which_parts, full_cov=True,noise_model=output)
|
|
||||||
for yi in Ysim.T:
|
|
||||||
ax.plot(Xnew, yi[:,None], Tango.colorsHex['darkBlue'], linewidth=0.25)
|
|
||||||
|
|
||||||
for d in range(m.shape[1]):
|
|
||||||
gpplot(Xnew, m[:, d], lower[:, d], upper[:, d], axes=ax, edgecol=linecol, fillcol=fillcol)
|
|
||||||
ax.plot(Xu[which_data], self.likelihood.noise_model_list[output].data, 'kx', mew=1.5)
|
|
||||||
ymin, ymax = min(np.append(self.likelihood.data, lower)), max(np.append(self.likelihood.data, upper))
|
|
||||||
ymin, ymax = ymin - 0.1 * (ymax - ymin), ymax + 0.1 * (ymax - ymin)
|
|
||||||
ax.set_xlim(xmin, xmax)
|
|
||||||
ax.set_ylim(ymin, ymax)
|
|
||||||
|
|
||||||
elif self.X.shape[1] == 3:
|
|
||||||
raise NotImplementedError, "Plots not implemented for multioutput models with 2D inputs...yet"
|
|
||||||
#if samples:
|
|
||||||
# warnings.warn("Samples only implemented for 1 dimensional inputs.")
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
|
||||||
|
|
||||||
|
|
||||||
def _add_output_index(self,X,output):
|
|
||||||
"""
|
"""
|
||||||
In a multioutput model, appends an index column to X to specify the output it is related to.
|
Calculation of the log predictive density
|
||||||
|
|
||||||
:param X: Input data
|
.. math:
|
||||||
:type X: np.ndarray, N x self.input_dim
|
p(y_{*}|D) = p(y_{*}|f_{*})p(f_{*}|\mu_{*}\\sigma^{2}_{*})
|
||||||
:param output: output X is related to
|
|
||||||
:type output: integer in {0,..., output_dim-1}
|
|
||||||
|
|
||||||
.. Note:: For multiple non-independent outputs models only.
|
:param x_test: test observations (x_{*})
|
||||||
|
:type x_test: (Nx1) array
|
||||||
|
:param y_test: test observations (y_{*})
|
||||||
|
:type y_test: (Nx1) array
|
||||||
"""
|
"""
|
||||||
|
mu_star, var_star = self._raw_predict(x_test)
|
||||||
assert hasattr(self,'multioutput'), 'This function is for multiple output models only.'
|
return self.likelihood.log_predictive_density(y_test, mu_star, var_star)
|
||||||
|
|
||||||
index = np.ones((X.shape[0],1))*output
|
|
||||||
return np.hstack((X,index))
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ class Mapping(Parameterized):
|
||||||
|
|
||||||
def df_dtheta(self, dL_df, X):
|
def df_dtheta(self, dL_df, X):
|
||||||
"""The gradient of the outputs of the multi-layer perceptron with respect to each of the parameters.
|
"""The gradient of the outputs of the multi-layer perceptron with respect to each of the parameters.
|
||||||
|
|
||||||
:param dL_df: gradient of the objective with respect to the function.
|
:param dL_df: gradient of the objective with respect to the function.
|
||||||
:type dL_df: ndarray (num_data x output_dim)
|
:type dL_df: ndarray (num_data x output_dim)
|
||||||
:param X: input locations where the function is evaluated.
|
:param X: input locations where the function is evaluated.
|
||||||
|
|
@ -44,7 +43,6 @@ class Mapping(Parameterized):
|
||||||
:returns: Matrix containing gradients with respect to parameters of each output for each input data.
|
:returns: Matrix containing gradients with respect to parameters of each output for each input data.
|
||||||
:rtype: ndarray (num_params length)
|
:rtype: ndarray (num_params length)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def plot(self, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, samples=0, fignum=None, ax=None, fixed_inputs=[], linecol=Tango.colorsHex['darkBlue']):
|
def plot(self, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, samples=0, fignum=None, ax=None, fixed_inputs=[], linecol=Tango.colorsHex['darkBlue']):
|
||||||
|
|
@ -126,7 +124,11 @@ class Mapping(Parameterized):
|
||||||
from GPy.core.model import Model
|
from GPy.core.model import Model
|
||||||
|
|
||||||
class Mapping_check_model(Model):
|
class Mapping_check_model(Model):
|
||||||
"""This is a dummy model class used as a base class for checking that the gradients of a given mapping are implemented correctly. It enables checkgradient() to be called independently on each mapping."""
|
"""
|
||||||
|
This is a dummy model class used as a base class for checking that the
|
||||||
|
gradients of a given mapping are implemented correctly. It enables
|
||||||
|
checkgradient() to be called independently on each mapping.
|
||||||
|
"""
|
||||||
def __init__(self, mapping=None, dL_df=None, X=None):
|
def __init__(self, mapping=None, dL_df=None, X=None):
|
||||||
num_samples = 20
|
num_samples = 20
|
||||||
if mapping==None:
|
if mapping==None:
|
||||||
|
|
|
||||||
|
|
@ -259,7 +259,7 @@ class Model(Parameterized):
|
||||||
these terms are present in the name the parameter is
|
these terms are present in the name the parameter is
|
||||||
constrained positive.
|
constrained positive.
|
||||||
"""
|
"""
|
||||||
positive_strings = ['variance', 'lengthscale', 'precision', 'kappa']
|
positive_strings = ['variance', 'lengthscale', 'precision', 'decay', 'kappa']
|
||||||
# param_names = self._get_param_names()
|
# param_names = self._get_param_names()
|
||||||
currently_constrained = self.all_constrained_indices()
|
currently_constrained = self.all_constrained_indices()
|
||||||
to_make_positive = []
|
to_make_positive = []
|
||||||
|
|
@ -453,6 +453,11 @@ class Model(Parameterized):
|
||||||
|
|
||||||
if not verbose:
|
if not verbose:
|
||||||
# just check the global ratio
|
# just check the global ratio
|
||||||
|
|
||||||
|
#choose a random direction to find the linear approximation in
|
||||||
|
if x.size==2:
|
||||||
|
dx = step * np.ones(2) # random direction for 2 parameters can fail dure to symmetry
|
||||||
|
else:
|
||||||
dx = step * np.sign(np.random.uniform(-1, 1, x.size))
|
dx = step * np.sign(np.random.uniform(-1, 1, x.size))
|
||||||
|
|
||||||
# evaulate around the point x
|
# evaulate around the point x
|
||||||
|
|
@ -549,7 +554,7 @@ class Model(Parameterized):
|
||||||
|
|
||||||
.. Note: kwargs are passed to update_likelihood and optimize functions.
|
.. Note: kwargs are passed to update_likelihood and optimize functions.
|
||||||
"""
|
"""
|
||||||
assert isinstance(self.likelihood, likelihoods.EP) or isinstance(self.likelihood, likelihoods.EP_Mixed_Noise), "pseudo_EM is only available for EP likelihoods"
|
assert isinstance(self.likelihood, (likelihoods.EP, likelihoods.EP_Mixed_Noise, likelihoods.Laplace)), "pseudo_EM is only available for approximate likelihoods"
|
||||||
ll_change = stop_crit + 1.
|
ll_change = stop_crit + 1.
|
||||||
iteration = 0
|
iteration = 0
|
||||||
last_ll = -np.inf
|
last_ll = -np.inf
|
||||||
|
|
|
||||||
|
|
@ -52,23 +52,6 @@ class SparseGP(GPBase):
|
||||||
|
|
||||||
self._const_jitter = None
|
self._const_jitter = None
|
||||||
|
|
||||||
def getstate(self):
|
|
||||||
"""
|
|
||||||
Get the current state of the class,
|
|
||||||
here just all the indices, rest can get recomputed
|
|
||||||
"""
|
|
||||||
return GPBase.getstate(self) + [self.Z,
|
|
||||||
self.num_inducing,
|
|
||||||
self.has_uncertain_inputs,
|
|
||||||
self.X_variance]
|
|
||||||
|
|
||||||
def setstate(self, state):
|
|
||||||
self.X_variance = state.pop()
|
|
||||||
self.has_uncertain_inputs = state.pop()
|
|
||||||
self.num_inducing = state.pop()
|
|
||||||
self.Z = state.pop()
|
|
||||||
GPBase.setstate(self, state)
|
|
||||||
|
|
||||||
def _compute_kernel_matrices(self):
|
def _compute_kernel_matrices(self):
|
||||||
# kernel computations, using BGPLVM notation
|
# kernel computations, using BGPLVM notation
|
||||||
self.Kmm = self.kern.K(self.Z)
|
self.Kmm = self.kern.K(self.Z)
|
||||||
|
|
@ -87,7 +70,6 @@ class SparseGP(GPBase):
|
||||||
|
|
||||||
# factor Kmm
|
# factor Kmm
|
||||||
self._Lm = jitchol(self.Kmm + self._const_jitter)
|
self._Lm = jitchol(self.Kmm + self._const_jitter)
|
||||||
# TODO: no white kernel needed anymore, all noise in likelihood --------
|
|
||||||
|
|
||||||
# The rather complex computations of self._A
|
# The rather complex computations of self._A
|
||||||
if self.has_uncertain_inputs:
|
if self.has_uncertain_inputs:
|
||||||
|
|
@ -156,7 +138,7 @@ class SparseGP(GPBase):
|
||||||
|
|
||||||
|
|
||||||
# the partial derivative vector for the likelihood
|
# the partial derivative vector for the likelihood
|
||||||
if self.likelihood.Nparams == 0:
|
if self.likelihood.num_params == 0:
|
||||||
# save computation here.
|
# save computation here.
|
||||||
self.partial_for_likelihood = None
|
self.partial_for_likelihood = None
|
||||||
elif self.likelihood.is_heteroscedastic:
|
elif self.likelihood.is_heteroscedastic:
|
||||||
|
|
@ -341,7 +323,10 @@ class SparseGP(GPBase):
|
||||||
return mean, var, _025pm, _975pm
|
return mean, var, _025pm, _975pm
|
||||||
|
|
||||||
|
|
||||||
def plot_f(self, samples=0, plot_limits=None, which_data='all', which_parts='all', resolution=None, full_cov=False, fignum=None, ax=None):
|
def plot_f(self, samples=0, plot_limits=None, which_data_rows='all',
|
||||||
|
which_data_ycols='all', which_parts='all', resolution=None,
|
||||||
|
full_cov=False, fignum=None, ax=None):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Plot the GP's view of the world, where the data is normalized and the
|
Plot the GP's view of the world, where the data is normalized and the
|
||||||
- In one dimension, the function is plotted with a shaded region identifying two standard deviations.
|
- In one dimension, the function is plotted with a shaded region identifying two standard deviations.
|
||||||
|
|
@ -350,8 +335,8 @@ class SparseGP(GPBase):
|
||||||
|
|
||||||
:param samples: the number of a posteriori samples to plot
|
:param samples: the number of a posteriori samples to plot
|
||||||
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
|
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
|
||||||
:param which_data: which if the training data to plot (default all)
|
:param which_data_rows: which if the training data to plot (default all)
|
||||||
:type which_data: 'all' or a slice object to slice self.X, self.Y
|
:type which_data_rows: 'all' or a slice object to slice self.X, self.Y
|
||||||
:param which_parts: which of the kernel functions to plot (additively)
|
:param which_parts: which of the kernel functions to plot (additively)
|
||||||
:type which_parts: 'all', or list of bools
|
:type which_parts: 'all', or list of bools
|
||||||
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
|
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
|
||||||
|
|
@ -371,10 +356,10 @@ class SparseGP(GPBase):
|
||||||
ax = fig.add_subplot(111)
|
ax = fig.add_subplot(111)
|
||||||
if fignum is None and ax is None:
|
if fignum is None and ax is None:
|
||||||
fignum = fig.num
|
fignum = fig.num
|
||||||
if which_data is 'all':
|
if which_data_rows is 'all':
|
||||||
which_data = slice(None)
|
which_data_rows = slice(None)
|
||||||
|
|
||||||
GPBase.plot_f(self, samples=samples, plot_limits=plot_limits, which_data='all', which_parts='all', resolution=resolution, full_cov=full_cov, fignum=fignum, ax=ax)
|
GPBase.plot_f(self, samples=samples, plot_limits=plot_limits, which_data_rows=which_data_rows, which_data_ycols=which_data_ycols, which_parts=which_parts, resolution=resolution, fignum=fignum, ax=ax)
|
||||||
|
|
||||||
if self.X.shape[1] == 1:
|
if self.X.shape[1] == 1:
|
||||||
if self.has_uncertain_inputs:
|
if self.has_uncertain_inputs:
|
||||||
|
|
@ -389,177 +374,98 @@ class SparseGP(GPBase):
|
||||||
Zu = self.Z * self._Xscale + self._Xoffset
|
Zu = self.Z * self._Xscale + self._Xoffset
|
||||||
ax.plot(Zu[:, 0], Zu[:, 1], 'wo')
|
ax.plot(Zu[:, 0], Zu[:, 1], 'wo')
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
||||||
|
|
||||||
def plot(self, samples=0, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, fignum=None, ax=None):
|
def plot(self, plot_limits=None, which_data_rows='all',
|
||||||
|
which_data_ycols='all', which_parts='all', fixed_inputs=[],
|
||||||
|
plot_raw=False,
|
||||||
|
levels=20, samples=0, fignum=None, ax=None, resolution=None):
|
||||||
|
"""
|
||||||
|
Plot the posterior of the sparse GP.
|
||||||
|
- In one dimension, the function is plotted with a shaded region identifying two standard deviations.
|
||||||
|
- In two dimsensions, a contour-plot shows the mean predicted function
|
||||||
|
- In higher dimensions, use fixed_inputs to plot the GP with some of the inputs fixed.
|
||||||
|
|
||||||
|
Can plot only part of the data and part of the posterior functions
|
||||||
|
using which_data_rowsm which_data_ycols and which_parts
|
||||||
|
|
||||||
|
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
|
||||||
|
:type plot_limits: np.array
|
||||||
|
:param which_data_rows: which of the training data to plot (default all)
|
||||||
|
:type which_data_rows: 'all' or a slice object to slice self.X, self.Y
|
||||||
|
:param which_data_ycols: when the data has several columns (independant outputs), only plot these
|
||||||
|
:type which_data_rows: 'all' or a list of integers
|
||||||
|
:param which_parts: which of the kernel functions to plot (additively)
|
||||||
|
:type which_parts: 'all', or list of bools
|
||||||
|
:param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
|
||||||
|
:type fixed_inputs: a list of tuples
|
||||||
|
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
|
||||||
|
:type resolution: int
|
||||||
|
:param levels: number of levels to plot in a contour plot.
|
||||||
|
:type levels: int
|
||||||
|
:param samples: the number of a posteriori samples to plot
|
||||||
|
:type samples: int
|
||||||
|
:param fignum: figure to plot on.
|
||||||
|
:type fignum: figure number
|
||||||
|
:param ax: axes to plot on.
|
||||||
|
:type ax: axes handle
|
||||||
|
:type output: integer (first output is 0)
|
||||||
|
:param linecol: color of line to plot.
|
||||||
|
:type linecol:
|
||||||
|
:param fillcol: color of fill
|
||||||
|
:param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure
|
||||||
|
"""
|
||||||
|
#deal work out which ax to plot on
|
||||||
if ax is None:
|
if ax is None:
|
||||||
fig = pb.figure(num=fignum)
|
fig = pb.figure(num=fignum)
|
||||||
ax = fig.add_subplot(111)
|
ax = fig.add_subplot(111)
|
||||||
if fignum is None and ax is None:
|
|
||||||
fignum = fig.num
|
|
||||||
if which_data is 'all':
|
|
||||||
which_data = slice(None)
|
|
||||||
|
|
||||||
GPBase.plot(self, samples=samples, plot_limits=plot_limits, which_data='all', which_parts='all', resolution=resolution, levels=20, fignum=fignum, ax=ax)
|
#work out what the inputs are for plotting (1D or 2D)
|
||||||
|
fixed_dims = np.array([i for i,v in fixed_inputs])
|
||||||
|
free_dims = np.setdiff1d(np.arange(self.input_dim),fixed_dims)
|
||||||
|
|
||||||
if self.X.shape[1] == 1:
|
#call the base plotting
|
||||||
|
GPBase.plot(self, samples=samples, plot_limits=plot_limits,
|
||||||
|
which_data_rows=which_data_rows,
|
||||||
|
which_data_ycols=which_data_ycols, fixed_inputs=fixed_inputs,
|
||||||
|
which_parts=which_parts, resolution=resolution, levels=20,
|
||||||
|
fignum=fignum, ax=ax)
|
||||||
|
|
||||||
|
if len(free_dims) == 1:
|
||||||
|
#plot errorbars for the uncertain inputs
|
||||||
if self.has_uncertain_inputs:
|
if self.has_uncertain_inputs:
|
||||||
Xu = self.X * self._Xscale + self._Xoffset # NOTE self.X are the normalized values now
|
Xu = self.X * self._Xscale + self._Xoffset # NOTE self.X are the normalized values now
|
||||||
ax.errorbar(Xu[which_data, 0], self.likelihood.data[which_data, 0],
|
ax.errorbar(Xu[which_data_rows, 0], self.likelihood.data[which_data_rows, 0],
|
||||||
xerr=2 * np.sqrt(self.X_variance[which_data, 0]),
|
xerr=2 * np.sqrt(self.X_variance[which_data_rows, 0]),
|
||||||
ecolor='k', fmt=None, elinewidth=.5, alpha=.5)
|
ecolor='k', fmt=None, elinewidth=.5, alpha=.5)
|
||||||
|
|
||||||
|
#plot the inducing inputs
|
||||||
Zu = self.Z * self._Xscale + self._Xoffset
|
Zu = self.Z * self._Xscale + self._Xoffset
|
||||||
ax.plot(Zu, np.zeros_like(Zu) + ax.get_ylim()[0], 'r|', mew=1.5, markersize=12)
|
ax.plot(Zu, np.zeros_like(Zu) + ax.get_ylim()[0], 'r|', mew=1.5, markersize=12)
|
||||||
|
|
||||||
elif self.X.shape[1] == 2:
|
elif len(free_dims) == 2:
|
||||||
Zu = self.Z * self._Xscale + self._Xoffset
|
Zu = self.Z * self._Xscale + self._Xoffset
|
||||||
ax.plot(Zu[:, 0], Zu[:, 1], 'wo')
|
ax.plot(Zu[:, 0], Zu[:, 1], 'wo')
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
||||||
|
|
||||||
def predict_single_output(self, Xnew, output=0, which_parts='all', full_cov=False):
|
def getstate(self):
|
||||||
"""
|
"""
|
||||||
For a specific output, predict the function at the new point(s) Xnew.
|
Get the current state of the class,
|
||||||
|
here just all the indices, rest can get recomputed
|
||||||
:param Xnew: The points at which to make a prediction
|
|
||||||
:type Xnew: np.ndarray, Nnew x self.input_dim
|
|
||||||
:param output: output to predict
|
|
||||||
:type output: integer in {0,..., num_outputs-1}
|
|
||||||
:param which_parts: specifies which outputs kernel(s) to use in prediction
|
|
||||||
:type which_parts: ('all', list of bools)
|
|
||||||
:param full_cov: whether to return the full covariance matrix, or just the diagonal
|
|
||||||
:type full_cov: bool
|
|
||||||
:rtype: posterior mean, a Numpy array, Nnew x self.input_dim
|
|
||||||
:rtype: posterior variance, a Numpy array, Nnew x 1 if full_cov=False, Nnew x Nnew otherwise
|
|
||||||
:rtype: lower and upper boundaries of the 95% confidence intervals, Numpy arrays, Nnew x self.input_dim
|
|
||||||
|
|
||||||
.. Note:: For multiple output models only
|
|
||||||
"""
|
"""
|
||||||
|
return GPBase.getstate(self) + [self.Z,
|
||||||
|
self.num_inducing,
|
||||||
|
self.has_uncertain_inputs,
|
||||||
|
self.X_variance]
|
||||||
|
|
||||||
assert hasattr(self,'multioutput')
|
def setstate(self, state):
|
||||||
index = np.ones_like(Xnew)*output
|
self.X_variance = state.pop()
|
||||||
Xnew = np.hstack((Xnew,index))
|
self.has_uncertain_inputs = state.pop()
|
||||||
|
self.num_inducing = state.pop()
|
||||||
# normalize X values
|
self.Z = state.pop()
|
||||||
Xnew = (Xnew.copy() - self._Xoffset) / self._Xscale
|
GPBase.setstate(self, state)
|
||||||
mu, var = self._raw_predict(Xnew, full_cov=full_cov, which_parts=which_parts)
|
|
||||||
|
|
||||||
# now push through likelihood
|
|
||||||
mean, var, _025pm, _975pm = self.likelihood.predictive_values(mu, var, full_cov, noise_model = output)
|
|
||||||
return mean, var, _025pm, _975pm
|
|
||||||
|
|
||||||
def _raw_predict_single_output(self, _Xnew, output=0, X_variance_new=None, which_parts='all', full_cov=False,stop=False):
|
|
||||||
"""
|
|
||||||
Internal helper function for making predictions for a specific output,
|
|
||||||
does not account for normalization or likelihood
|
|
||||||
---------
|
|
||||||
|
|
||||||
:param Xnew: The points at which to make a prediction
|
|
||||||
:type Xnew: np.ndarray, Nnew x self.input_dim
|
|
||||||
:param output: output to predict
|
|
||||||
:type output: integer in {0,..., num_outputs-1}
|
|
||||||
:param which_parts: specifies which outputs kernel(s) to use in prediction
|
|
||||||
:type which_parts: ('all', list of bools)
|
|
||||||
:param full_cov: whether to return the full covariance matrix, or just the diagonal
|
|
||||||
|
|
||||||
.. Note:: For multiple output models only
|
|
||||||
"""
|
|
||||||
Bi, _ = dpotri(self.LB, lower=0) # WTH? this lower switch should be 1, but that doesn't work!
|
|
||||||
symmetrify(Bi)
|
|
||||||
Kmmi_LmiBLmi = backsub_both_sides(self._Lm, np.eye(self.num_inducing) - Bi)
|
|
||||||
|
|
||||||
if self.Cpsi1V is None:
|
|
||||||
psi1V = np.dot(self.psi1.T,self.likelihood.V)
|
|
||||||
tmp, _ = dtrtrs(self._Lm, np.asfortranarray(psi1V), lower=1, trans=0)
|
|
||||||
tmp, _ = dpotrs(self.LB, tmp, lower=1)
|
|
||||||
self.Cpsi1V, _ = dtrtrs(self._Lm, tmp, lower=1, trans=1)
|
|
||||||
|
|
||||||
assert hasattr(self,'multioutput')
|
|
||||||
index = np.ones_like(_Xnew)*output
|
|
||||||
_Xnew = np.hstack((_Xnew,index))
|
|
||||||
|
|
||||||
if X_variance_new is None:
|
|
||||||
Kx = self.kern.K(self.Z, _Xnew, which_parts=which_parts)
|
|
||||||
mu = np.dot(Kx.T, self.Cpsi1V)
|
|
||||||
if full_cov:
|
|
||||||
Kxx = self.kern.K(_Xnew, which_parts=which_parts)
|
|
||||||
var = Kxx - mdot(Kx.T, Kmmi_LmiBLmi, Kx) # NOTE this won't work for plotting
|
|
||||||
else:
|
|
||||||
Kxx = self.kern.Kdiag(_Xnew, which_parts=which_parts)
|
|
||||||
var = Kxx - np.sum(Kx * np.dot(Kmmi_LmiBLmi, Kx), 0)
|
|
||||||
else:
|
|
||||||
Kx = self.kern.psi1(self.Z, _Xnew, X_variance_new)
|
|
||||||
mu = np.dot(Kx, self.Cpsi1V)
|
|
||||||
if full_cov:
|
|
||||||
raise NotImplementedError, "TODO"
|
|
||||||
else:
|
|
||||||
Kxx = self.kern.psi0(self.Z, _Xnew, X_variance_new)
|
|
||||||
psi2 = self.kern.psi2(self.Z, _Xnew, X_variance_new)
|
|
||||||
var = Kxx - np.sum(np.sum(psi2 * Kmmi_LmiBLmi[None, :, :], 1), 1)
|
|
||||||
|
|
||||||
return mu, var[:, None]
|
|
||||||
|
|
||||||
|
|
||||||
def plot_single_output_f(self, output=None, samples=0, plot_limits=None, which_data='all', which_parts='all', resolution=None, full_cov=False, fignum=None, ax=None):
|
|
||||||
|
|
||||||
if ax is None:
|
|
||||||
fig = pb.figure(num=fignum)
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
if fignum is None and ax is None:
|
|
||||||
fignum = fig.num
|
|
||||||
if which_data is 'all':
|
|
||||||
which_data = slice(None)
|
|
||||||
|
|
||||||
GPBase.plot_single_output_f(self, output=output, samples=samples, plot_limits=plot_limits, which_data='all', which_parts='all', resolution=resolution, full_cov=full_cov, fignum=fignum, ax=ax)
|
|
||||||
|
|
||||||
if self.X.shape[1] == 2:
|
|
||||||
if self.has_uncertain_inputs:
|
|
||||||
Xu = self.X * self._Xscale + self._Xoffset # NOTE self.X are the normalized values now
|
|
||||||
ax.errorbar(Xu[which_data, 0], self.likelihood.data[which_data, 0],
|
|
||||||
xerr=2 * np.sqrt(self.X_variance[which_data, 0]),
|
|
||||||
ecolor='k', fmt=None, elinewidth=.5, alpha=.5)
|
|
||||||
Zu = self.Z * self._Xscale + self._Xoffset
|
|
||||||
Zu = Zu[Zu[:,1]==output,0:1]
|
|
||||||
ax.plot(Zu[:,0], np.zeros_like(Zu[:,0]) + ax.get_ylim()[0], 'r|', mew=1.5, markersize=12)
|
|
||||||
|
|
||||||
elif self.X.shape[1] == 2:
|
|
||||||
Zu = self.Z * self._Xscale + self._Xoffset
|
|
||||||
Zu = Zu[Zu[:,1]==output,0:2]
|
|
||||||
ax.plot(Zu[:, 0], Zu[:, 1], 'wo')
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
|
||||||
|
|
||||||
def plot_single_output(self, output=None, samples=0, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, fignum=None, ax=None):
|
|
||||||
if ax is None:
|
|
||||||
fig = pb.figure(num=fignum)
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
if fignum is None and ax is None:
|
|
||||||
fignum = fig.num
|
|
||||||
if which_data is 'all':
|
|
||||||
which_data = slice(None)
|
|
||||||
|
|
||||||
GPBase.plot_single_output(self, samples=samples, plot_limits=plot_limits, which_data='all', which_parts='all', resolution=resolution, levels=20, fignum=fignum, ax=ax, output=output)
|
|
||||||
|
|
||||||
if self.X.shape[1] == 2:
|
|
||||||
if self.has_uncertain_inputs:
|
|
||||||
Xu = self.X * self._Xscale + self._Xoffset # NOTE self.X are the normalized values now
|
|
||||||
ax.errorbar(Xu[which_data, 0], self.likelihood.data[which_data, 0],
|
|
||||||
xerr=2 * np.sqrt(self.X_variance[which_data, 0]),
|
|
||||||
ecolor='k', fmt=None, elinewidth=.5, alpha=.5)
|
|
||||||
Zu = self.Z * self._Xscale + self._Xoffset
|
|
||||||
Zu = Zu[Zu[:,1]==output,0:1]
|
|
||||||
ax.plot(Zu, np.zeros_like(Zu) + ax.get_ylim()[0], 'r|', mew=1.5, markersize=12)
|
|
||||||
|
|
||||||
elif self.X.shape[1] == 3:
|
|
||||||
Zu = self.Z * self._Xscale + self._Xoffset
|
|
||||||
Zu = Zu[Zu[:,1]==output,0:1]
|
|
||||||
ax.plot(Zu[:, 0], Zu[:, 1], 'wo')
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
|
|
||||||
|
|
|
||||||
|
|
@ -18,34 +18,19 @@ class SVIGP(GPBase):
|
||||||
Stochastic Variational inference in a Gaussian Process
|
Stochastic Variational inference in a Gaussian Process
|
||||||
|
|
||||||
:param X: inputs
|
:param X: inputs
|
||||||
:type X: np.ndarray (N x Q)
|
:type X: np.ndarray (num_data x num_inputs)
|
||||||
:param Y: observed data
|
:param Y: observed data
|
||||||
:type Y: np.ndarray of observations (N x D)
|
:type Y: np.ndarray of observations (num_data x output_dim)
|
||||||
:param batchsize: the size of a h
|
:param batchsize: the size of a minibatch
|
||||||
|
|
||||||
Additional kwargs are used as for a sparse GP. They include:
|
|
||||||
|
|
||||||
:param q_u: canonical parameters of the distribution squasehd into a 1D array
|
:param q_u: canonical parameters of the distribution squasehd into a 1D array
|
||||||
:type q_u: np.ndarray
|
:type q_u: np.ndarray
|
||||||
:param M: Number of inducing points (optional, default 10. Ignored if Z is not None)
|
|
||||||
:type M: int
|
|
||||||
:param kernel: the kernel/covariance function. See link kernels
|
:param kernel: the kernel/covariance function. See link kernels
|
||||||
:type kernel: a GPy kernel
|
:type kernel: a GPy kernel
|
||||||
:param Z: inducing inputs (optional, see note)
|
:param Z: inducing inputs
|
||||||
:type Z: np.ndarray (M x Q) | None
|
:type Z: np.ndarray (num_inducing x num_inputs)
|
||||||
:param X_uncertainty: The uncertainty in the measurements of X (Gaussian variance)
|
|
||||||
:type X_uncertainty: np.ndarray (N x Q) | None
|
|
||||||
:param Zslices: slices for the inducing inputs (see slicing TODO: link)
|
|
||||||
:param M: Number of inducing points (optional, default 10. Ignored if Z is not None)
|
|
||||||
:type M: int
|
|
||||||
:param beta: noise precision. TODO: ignore beta if doing EP
|
|
||||||
:type beta: float
|
|
||||||
:param normalize_(X|Y): whether to normalize the data before computing (predictions will be in original scales)
|
|
||||||
:type normalize_(X|Y): bool
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, X, likelihood, kernel, Z, q_u=None, batchsize=10, X_variance=None):
|
def __init__(self, X, likelihood, kernel, Z, q_u=None, batchsize=10, X_variance=None):
|
||||||
GPBase.__init__(self, X, likelihood, kernel, normalize_X=False)
|
GPBase.__init__(self, X, likelihood, kernel, normalize_X=False)
|
||||||
self.batchsize=batchsize
|
self.batchsize=batchsize
|
||||||
|
|
@ -452,7 +437,7 @@ class SVIGP(GPBase):
|
||||||
else:
|
else:
|
||||||
return mu, diag_var[:,None]
|
return mu, diag_var[:,None]
|
||||||
|
|
||||||
def predict(self, Xnew, X_variance_new=None, which_parts='all', full_cov=False):
|
def predict(self, Xnew, X_variance_new=None, which_parts='all', full_cov=False, sampling=False, num_samples=15000):
|
||||||
# normalize X values
|
# normalize X values
|
||||||
Xnew = (Xnew.copy() - self._Xoffset) / self._Xscale
|
Xnew = (Xnew.copy() - self._Xoffset) / self._Xscale
|
||||||
if X_variance_new is not None:
|
if X_variance_new is not None:
|
||||||
|
|
@ -462,7 +447,7 @@ class SVIGP(GPBase):
|
||||||
mu, var = self._raw_predict(Xnew, X_variance_new, full_cov=full_cov, which_parts=which_parts)
|
mu, var = self._raw_predict(Xnew, X_variance_new, full_cov=full_cov, which_parts=which_parts)
|
||||||
|
|
||||||
# now push through likelihood
|
# now push through likelihood
|
||||||
mean, var, _025pm, _975pm = self.likelihood.predictive_values(mu, var, full_cov)
|
mean, var, _025pm, _975pm = self.likelihood.predictive_values(mu, var, full_cov, sampling=sampling, num_samples=num_samples)
|
||||||
|
|
||||||
return mean, var, _025pm, _975pm
|
return mean, var, _025pm, _975pm
|
||||||
|
|
||||||
|
|
|
||||||
19
GPy/core/variational.py
Normal file
19
GPy/core/variational.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
'''
|
||||||
|
Created on 6 Nov 2013
|
||||||
|
|
||||||
|
@author: maxz
|
||||||
|
'''
|
||||||
|
from parameterized import Parameterized
|
||||||
|
from parameter import Param
|
||||||
|
|
||||||
|
class Normal(Parameterized):
|
||||||
|
'''
|
||||||
|
Normal distribution for variational approximations.
|
||||||
|
|
||||||
|
holds the means and variances for a factorizing multivariate normal distribution
|
||||||
|
'''
|
||||||
|
def __init__(self, name, means, variances):
|
||||||
|
Parameterized.__init__(self, name=name)
|
||||||
|
self.means = Param("mean", means)
|
||||||
|
self.variances = Param('variance', variances)
|
||||||
|
self.add_parameters(self.means, self.variances)
|
||||||
|
|
@ -6,12 +6,11 @@
|
||||||
Gaussian Processes classification
|
Gaussian Processes classification
|
||||||
"""
|
"""
|
||||||
import pylab as pb
|
import pylab as pb
|
||||||
import numpy as np
|
|
||||||
import GPy
|
import GPy
|
||||||
|
|
||||||
default_seed = 10000
|
default_seed = 10000
|
||||||
|
|
||||||
def oil(num_inducing=50, max_iters=100, kernel=None):
|
def oil(num_inducing=50, max_iters=100, kernel=None, optimize=True, plot=True):
|
||||||
"""
|
"""
|
||||||
Run a Gaussian process classification on the three phase oil data. The demonstration calls the basic GP classification model and uses EP to approximate the likelihood.
|
Run a Gaussian process classification on the three phase oil data. The demonstration calls the basic GP classification model and uses EP to approximate the likelihood.
|
||||||
|
|
||||||
|
|
@ -33,6 +32,7 @@ def oil(num_inducing=50, max_iters=100, kernel=None):
|
||||||
m.update_likelihood_approximation()
|
m.update_likelihood_approximation()
|
||||||
|
|
||||||
# Optimize
|
# Optimize
|
||||||
|
if optimize:
|
||||||
m.optimize(max_iters=max_iters)
|
m.optimize(max_iters=max_iters)
|
||||||
print(m)
|
print(m)
|
||||||
|
|
||||||
|
|
@ -41,9 +41,9 @@ def oil(num_inducing=50, max_iters=100, kernel=None):
|
||||||
GPy.util.classification.conf_matrix(probs, Ytest)
|
GPy.util.classification.conf_matrix(probs, Ytest)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def toy_linear_1d_classification(seed=default_seed):
|
def toy_linear_1d_classification(seed=default_seed, optimize=True, plot=True):
|
||||||
"""
|
"""
|
||||||
Simple 1D classification example
|
Simple 1D classification example using EP approximation
|
||||||
|
|
||||||
:param seed: seed value for data generation (default is 4).
|
:param seed: seed value for data generation (default is 4).
|
||||||
:type seed: int
|
:type seed: int
|
||||||
|
|
@ -58,20 +58,59 @@ def toy_linear_1d_classification(seed=default_seed):
|
||||||
m = GPy.models.GPClassification(data['X'], Y)
|
m = GPy.models.GPClassification(data['X'], Y)
|
||||||
|
|
||||||
# Optimize
|
# Optimize
|
||||||
|
if optimize:
|
||||||
#m.update_likelihood_approximation()
|
#m.update_likelihood_approximation()
|
||||||
# Parameters optimization:
|
# Parameters optimization:
|
||||||
#m.optimize()
|
#m.optimize()
|
||||||
|
#m.update_likelihood_approximation()
|
||||||
m.pseudo_EM()
|
m.pseudo_EM()
|
||||||
|
|
||||||
# Plot
|
# Plot
|
||||||
|
if plot:
|
||||||
fig, axes = pb.subplots(2, 1)
|
fig, axes = pb.subplots(2, 1)
|
||||||
m.plot_f(ax=axes[0])
|
m.plot_f(ax=axes[0])
|
||||||
m.plot(ax=axes[1])
|
m.plot(ax=axes[1])
|
||||||
print(m)
|
|
||||||
|
|
||||||
|
print m
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def sparse_toy_linear_1d_classification(num_inducing=10,seed=default_seed):
|
def toy_linear_1d_classification_laplace(seed=default_seed, optimize=True, plot=True):
|
||||||
|
"""
|
||||||
|
Simple 1D classification example using Laplace approximation
|
||||||
|
|
||||||
|
:param seed: seed value for data generation (default is 4).
|
||||||
|
:type seed: int
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = GPy.util.datasets.toy_linear_1d_classification(seed=seed)
|
||||||
|
Y = data['Y'][:, 0:1]
|
||||||
|
Y[Y.flatten() == -1] = 0
|
||||||
|
|
||||||
|
bern_noise_model = GPy.likelihoods.bernoulli()
|
||||||
|
laplace_likelihood = GPy.likelihoods.Laplace(Y.copy(), bern_noise_model)
|
||||||
|
|
||||||
|
# Model definition
|
||||||
|
m = GPy.models.GPClassification(data['X'], Y, likelihood=laplace_likelihood)
|
||||||
|
print m
|
||||||
|
|
||||||
|
# Optimize
|
||||||
|
if optimize:
|
||||||
|
#m.update_likelihood_approximation()
|
||||||
|
# Parameters optimization:
|
||||||
|
m.optimize('bfgs', messages=1)
|
||||||
|
#m.pseudo_EM()
|
||||||
|
|
||||||
|
# Plot
|
||||||
|
if plot:
|
||||||
|
fig, axes = pb.subplots(2, 1)
|
||||||
|
m.plot_f(ax=axes[0])
|
||||||
|
m.plot(ax=axes[1])
|
||||||
|
|
||||||
|
print m
|
||||||
|
return m
|
||||||
|
|
||||||
|
def sparse_toy_linear_1d_classification(num_inducing=10, seed=default_seed, optimize=True, plot=True):
|
||||||
"""
|
"""
|
||||||
Sparse 1D classification example
|
Sparse 1D classification example
|
||||||
|
|
||||||
|
|
@ -89,20 +128,22 @@ def sparse_toy_linear_1d_classification(num_inducing=10,seed=default_seed):
|
||||||
m['.*len'] = 4.
|
m['.*len'] = 4.
|
||||||
|
|
||||||
# Optimize
|
# Optimize
|
||||||
|
if optimize:
|
||||||
#m.update_likelihood_approximation()
|
#m.update_likelihood_approximation()
|
||||||
# Parameters optimization:
|
# Parameters optimization:
|
||||||
#m.optimize()
|
#m.optimize()
|
||||||
m.pseudo_EM()
|
m.pseudo_EM()
|
||||||
|
|
||||||
# Plot
|
# Plot
|
||||||
|
if plot:
|
||||||
fig, axes = pb.subplots(2, 1)
|
fig, axes = pb.subplots(2, 1)
|
||||||
m.plot_f(ax=axes[0])
|
m.plot_f(ax=axes[0])
|
||||||
m.plot(ax=axes[1])
|
m.plot(ax=axes[1])
|
||||||
print(m)
|
|
||||||
|
|
||||||
|
print m
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def toy_heaviside(seed=default_seed):
|
def toy_heaviside(seed=default_seed, optimize=True, plot=True):
|
||||||
"""
|
"""
|
||||||
Simple 1D classification example using a heavy side gp transformation
|
Simple 1D classification example using a heavy side gp transformation
|
||||||
|
|
||||||
|
|
@ -116,25 +157,27 @@ def toy_heaviside(seed=default_seed):
|
||||||
Y[Y.flatten() == -1] = 0
|
Y[Y.flatten() == -1] = 0
|
||||||
|
|
||||||
# Model definition
|
# Model definition
|
||||||
noise_model = GPy.likelihoods.binomial(GPy.likelihoods.noise_models.gp_transformations.Heaviside())
|
noise_model = GPy.likelihoods.bernoulli(GPy.likelihoods.noise_models.gp_transformations.Heaviside())
|
||||||
likelihood = GPy.likelihoods.EP(Y, noise_model)
|
likelihood = GPy.likelihoods.EP(Y, noise_model)
|
||||||
m = GPy.models.GPClassification(data['X'], likelihood=likelihood)
|
m = GPy.models.GPClassification(data['X'], likelihood=likelihood)
|
||||||
|
|
||||||
# Optimize
|
# Optimize
|
||||||
|
if optimize:
|
||||||
m.update_likelihood_approximation()
|
m.update_likelihood_approximation()
|
||||||
# Parameters optimization:
|
# Parameters optimization:
|
||||||
m.optimize()
|
m.optimize()
|
||||||
#m.pseudo_EM()
|
#m.pseudo_EM()
|
||||||
|
|
||||||
# Plot
|
# Plot
|
||||||
|
if plot:
|
||||||
fig, axes = pb.subplots(2, 1)
|
fig, axes = pb.subplots(2, 1)
|
||||||
m.plot_f(ax=axes[0])
|
m.plot_f(ax=axes[0])
|
||||||
m.plot(ax=axes[1])
|
m.plot(ax=axes[1])
|
||||||
print(m)
|
|
||||||
|
|
||||||
|
print m
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def crescent_data(model_type='Full', num_inducing=10, seed=default_seed, kernel=None):
|
def crescent_data(model_type='Full', num_inducing=10, seed=default_seed, kernel=None, optimize=True, plot=True):
|
||||||
"""
|
"""
|
||||||
Run a Gaussian process classification on the crescent data. The demonstration calls the basic GP classification model and uses EP to approximate the likelihood.
|
Run a Gaussian process classification on the crescent data. The demonstration calls the basic GP classification model and uses EP to approximate the likelihood.
|
||||||
|
|
||||||
|
|
@ -161,8 +204,11 @@ def crescent_data(model_type='Full', num_inducing=10, seed=default_seed, kernel=
|
||||||
m = GPy.models.FITCClassification(data['X'], Y, kernel=kernel, num_inducing=num_inducing)
|
m = GPy.models.FITCClassification(data['X'], Y, kernel=kernel, num_inducing=num_inducing)
|
||||||
m['.*len'] = 3.
|
m['.*len'] = 3.
|
||||||
|
|
||||||
|
if optimize:
|
||||||
m.pseudo_EM()
|
m.pseudo_EM()
|
||||||
print(m)
|
|
||||||
|
if plot:
|
||||||
m.plot()
|
m.plot()
|
||||||
|
|
||||||
|
print m
|
||||||
return m
|
return m
|
||||||
|
|
|
||||||
|
|
@ -1,96 +1,93 @@
|
||||||
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
import numpy as _np
|
||||||
|
default_seed = _np.random.seed(123344)
|
||||||
|
|
||||||
import numpy as np
|
def bgplvm_test_model(seed=default_seed, optimize=False, verbose=1, plot=False):
|
||||||
from matplotlib import pyplot as plt, cm
|
"""
|
||||||
|
model for testing purposes. Samples from a GP with rbf kernel and learns
|
||||||
import GPy
|
the samples with a new kernel. Normally not for optimization, just model cheking
|
||||||
from GPy.core.transformations import logexp
|
"""
|
||||||
from GPy.models.bayesian_gplvm import BayesianGPLVM
|
|
||||||
from GPy.likelihoods.gaussian import Gaussian
|
from GPy.likelihoods.gaussian import Gaussian
|
||||||
|
import GPy
|
||||||
|
|
||||||
default_seed = np.random.seed(123344)
|
num_inputs = 13
|
||||||
|
num_inducing = 5
|
||||||
|
if plot:
|
||||||
|
output_dim = 1
|
||||||
|
input_dim = 2
|
||||||
|
else:
|
||||||
|
input_dim = 2
|
||||||
|
output_dim = 25
|
||||||
|
|
||||||
def BGPLVM(seed=default_seed):
|
|
||||||
N = 5
|
|
||||||
num_inducing = 4
|
|
||||||
Q = 3
|
|
||||||
D = 2
|
|
||||||
# generate GPLVM-like data
|
# generate GPLVM-like data
|
||||||
X = np.random.rand(N, Q)
|
X = _np.random.rand(num_inputs, input_dim)
|
||||||
lengthscales = np.random.rand(Q)
|
lengthscales = _np.random.rand(input_dim)
|
||||||
k = (GPy.kern.rbf(Q, .5, lengthscales, ARD=True)
|
k = (GPy.kern.rbf(input_dim, .5, lengthscales, ARD=True)
|
||||||
+ GPy.kern.white(Q, 0.01))
|
+ GPy.kern.white(input_dim, 0.01))
|
||||||
K = k.K(X)
|
K = k.K(X)
|
||||||
Y = np.random.multivariate_normal(np.zeros(N), K, D).T
|
Y = _np.random.multivariate_normal(_np.zeros(num_inputs), K, output_dim).T
|
||||||
lik = Gaussian(Y, normalize=True)
|
lik = Gaussian(Y, normalize=True)
|
||||||
|
|
||||||
k = GPy.kern.rbf_inv(Q, .5, np.ones(Q) * 2., ARD=True) + GPy.kern.bias(Q) + GPy.kern.white(Q)
|
k = GPy.kern.rbf_inv(input_dim, .5, _np.ones(input_dim) * 2., ARD=True) + GPy.kern.bias(input_dim) + GPy.kern.white(input_dim)
|
||||||
# k = GPy.kern.rbf(Q) + GPy.kern.bias(Q) + GPy.kern.white(Q, 0.00001)
|
# k = GPy.kern.linear(input_dim) + GPy.kern.bias(input_dim) + GPy.kern.white(input_dim, 0.00001)
|
||||||
# k = GPy.kern.rbf(Q, ARD = False) + GPy.kern.white(Q, 0.00001)
|
# k = GPy.kern.rbf(input_dim, ARD = False) + GPy.kern.white(input_dim, 0.00001)
|
||||||
|
# k = GPy.kern.rbf(input_dim, .5, _np.ones(input_dim) * 2., ARD=True) + GPy.kern.rbf(input_dim, .3, _np.ones(input_dim) * .2, ARD=True)
|
||||||
|
# k = GPy.kern.rbf(input_dim, .5, 2., ARD=0) + GPy.kern.rbf(input_dim, .3, .2, ARD=0)
|
||||||
|
# k = GPy.kern.rbf(input_dim, .5, _np.ones(input_dim) * 2., ARD=True) + GPy.kern.linear(input_dim, _np.ones(input_dim) * .2, ARD=True)
|
||||||
|
|
||||||
m = GPy.models.BayesianGPLVM(lik, Q, kernel=k, num_inducing=num_inducing)
|
m = GPy.models.BayesianGPLVM(lik, input_dim, kernel=k, num_inducing=num_inducing)
|
||||||
m.lengthscales = lengthscales
|
m.lengthscales = lengthscales
|
||||||
# m.constrain_positive('(rbf|bias|noise|white|S)')
|
|
||||||
# m.constrain_fixed('S', 1)
|
|
||||||
|
|
||||||
# pb.figure()
|
if plot:
|
||||||
# m.plot()
|
import matplotlib.pyplot as pb
|
||||||
# pb.title('PCA initialisation')
|
m.plot()
|
||||||
# pb.figure()
|
pb.title('PCA initialisation')
|
||||||
# m.optimize(messages = 1)
|
|
||||||
# m.plot()
|
if optimize:
|
||||||
# pb.title('After optimisation')
|
m.optimize('scg', messages=verbose)
|
||||||
# m.randomize()
|
if plot:
|
||||||
# m.checkgrad(verbose=1)
|
m.plot()
|
||||||
|
pb.title('After optimisation')
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def GPLVM_oil_100(optimize=True):
|
def gplvm_oil_100(optimize=True, verbose=1, plot=True):
|
||||||
|
import GPy
|
||||||
data = GPy.util.datasets.oil_100()
|
data = GPy.util.datasets.oil_100()
|
||||||
Y = data['X']
|
Y = data['X']
|
||||||
|
|
||||||
# create simple GP model
|
# create simple GP model
|
||||||
kernel = GPy.kern.rbf(6, ARD=True) + GPy.kern.bias(6)
|
kernel = GPy.kern.rbf(6, ARD=True) + GPy.kern.bias(6)
|
||||||
m = GPy.models.GPLVM(Y, 6, kernel=kernel)
|
m = GPy.models.GPLVM(Y, 6, kernel=kernel)
|
||||||
m.data_labels = data['Y'].argmax(axis=1)
|
m.data_labels = data['Y'].argmax(axis=1)
|
||||||
|
if optimize: m.optimize('scg', messages=verbose)
|
||||||
# optimize
|
if plot: m.plot_latent(labels=m.data_labels)
|
||||||
if optimize:
|
|
||||||
m.optimize('scg', messages=1)
|
|
||||||
|
|
||||||
# plot
|
|
||||||
print(m)
|
|
||||||
m.plot_latent(labels=m.data_labels)
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def sparseGPLVM_oil(optimize=True, N=100, Q=6, num_inducing=15, max_iters=50):
|
def sparse_gplvm_oil(optimize=True, verbose=0, plot=True, N=100, Q=6, num_inducing=15, max_iters=50):
|
||||||
np.random.seed(0)
|
import GPy
|
||||||
|
_np.random.seed(0)
|
||||||
data = GPy.util.datasets.oil()
|
data = GPy.util.datasets.oil()
|
||||||
|
|
||||||
Y = data['X'][:N]
|
Y = data['X'][:N]
|
||||||
Y = Y - Y.mean(0)
|
Y = Y - Y.mean(0)
|
||||||
Y /= Y.std(0)
|
Y /= Y.std(0)
|
||||||
|
# Create the model
|
||||||
# create simple GP model
|
|
||||||
kernel = GPy.kern.rbf(Q, ARD=True) + GPy.kern.bias(Q)
|
kernel = GPy.kern.rbf(Q, ARD=True) + GPy.kern.bias(Q)
|
||||||
m = GPy.models.SparseGPLVM(Y, Q, kernel=kernel, num_inducing=num_inducing)
|
m = GPy.models.SparseGPLVM(Y, Q, kernel=kernel, num_inducing=num_inducing)
|
||||||
m.data_labels = data['Y'].argmax(axis=1)
|
m.data_labels = data['Y'][:N].argmax(axis=1)
|
||||||
|
|
||||||
# optimize
|
if optimize: m.optimize('scg', messages=verbose, max_iters=max_iters)
|
||||||
if optimize:
|
if plot:
|
||||||
m.optimize('scg', messages=1, max_iters=max_iters)
|
m.plot_latent(labels=m.data_labels)
|
||||||
|
m.kern.plot_ARD()
|
||||||
# plot
|
|
||||||
print(m)
|
|
||||||
# m.plot_latent(labels=m.data_labels)
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def swiss_roll(optimize=True, N=1000, num_inducing=15, Q=4, sigma=.2, plot=False):
|
def swiss_roll(optimize=True, verbose=1, plot=True, N=1000, num_inducing=15, Q=4, sigma=.2):
|
||||||
|
import GPy
|
||||||
from GPy.util.datasets import swiss_roll_generated
|
from GPy.util.datasets import swiss_roll_generated
|
||||||
from GPy.core.transformations import logexp_clipped
|
from GPy.models import BayesianGPLVM
|
||||||
|
|
||||||
data = swiss_roll_generated(N=N, sigma=sigma)
|
data = swiss_roll_generated(num_samples=N, sigma=sigma)
|
||||||
Y = data['Y']
|
Y = data['Y']
|
||||||
Y -= Y.mean()
|
Y -= Y.mean()
|
||||||
Y /= Y.std()
|
Y /= Y.std()
|
||||||
|
|
@ -103,119 +100,98 @@ def swiss_roll(optimize=True, N=1000, num_inducing=15, Q=4, sigma=.2, plot=False
|
||||||
iso = Isomap().fit(Y)
|
iso = Isomap().fit(Y)
|
||||||
X = iso.embedding_
|
X = iso.embedding_
|
||||||
if Q > 2:
|
if Q > 2:
|
||||||
X = np.hstack((X, np.random.randn(N, Q - 2)))
|
X = _np.hstack((X, _np.random.randn(N, Q - 2)))
|
||||||
except ImportError:
|
except ImportError:
|
||||||
X = np.random.randn(N, Q)
|
X = _np.random.randn(N, Q)
|
||||||
|
|
||||||
if plot:
|
if plot:
|
||||||
from mpl_toolkits import mplot3d
|
import matplotlib.pyplot as plt
|
||||||
import pylab
|
from mpl_toolkits.mplot3d import Axes3D # @UnusedImport
|
||||||
fig = pylab.figure("Swiss Roll Data")
|
fig = plt.figure("Swiss Roll Data")
|
||||||
ax = fig.add_subplot(121, projection='3d')
|
ax = fig.add_subplot(121, projection='3d')
|
||||||
ax.scatter(*Y.T, c=c)
|
ax.scatter(*Y.T, c=c)
|
||||||
ax.set_title("Swiss Roll")
|
ax.set_title("Swiss Roll")
|
||||||
|
|
||||||
ax = fig.add_subplot(122)
|
ax = fig.add_subplot(122)
|
||||||
ax.scatter(*X.T[:2], c=c)
|
ax.scatter(*X.T[:2], c=c)
|
||||||
ax.set_title("Initialization")
|
ax.set_title("BGPLVM init")
|
||||||
|
|
||||||
|
|
||||||
var = .5
|
var = .5
|
||||||
S = (var * np.ones_like(X) + np.clip(np.random.randn(N, Q) * var ** 2,
|
S = (var * _np.ones_like(X) + _np.clip(_np.random.randn(N, Q) * var ** 2,
|
||||||
- (1 - var),
|
- (1 - var),
|
||||||
(1 - var))) + .001
|
(1 - var))) + .001
|
||||||
Z = np.random.permutation(X)[:num_inducing]
|
Z = _np.random.permutation(X)[:num_inducing]
|
||||||
|
|
||||||
kernel = GPy.kern.rbf(Q, ARD=True) + GPy.kern.bias(Q, np.exp(-2)) + GPy.kern.white(Q, np.exp(-2))
|
kernel = GPy.kern.rbf(Q, ARD=True) + GPy.kern.bias(Q, _np.exp(-2)) + GPy.kern.white(Q, _np.exp(-2))
|
||||||
|
|
||||||
m = BayesianGPLVM(Y, Q, X=X, X_variance=S, num_inducing=num_inducing, Z=Z, kernel=kernel)
|
m = BayesianGPLVM(Y, Q, X=X, X_variance=S, num_inducing=num_inducing, Z=Z, kernel=kernel)
|
||||||
m.data_colors = c
|
m.data_colors = c
|
||||||
m.data_t = t
|
m.data_t = t
|
||||||
|
|
||||||
m['rbf_lengthscale'] = 1. # X.var(0).max() / X.var(0)
|
|
||||||
m['noise_variance'] = Y.var() / 100.
|
m['noise_variance'] = Y.var() / 100.
|
||||||
m['bias_variance'] = 0.05
|
|
||||||
|
|
||||||
if optimize:
|
if optimize:
|
||||||
m.optimize('scg', messages=1)
|
m.optimize('scg', messages=verbose, max_iters=2e3)
|
||||||
|
|
||||||
|
if plot:
|
||||||
|
fig = plt.figure('fitted')
|
||||||
|
ax = fig.add_subplot(111)
|
||||||
|
s = m.input_sensitivity().argsort()[::-1][:2]
|
||||||
|
ax.scatter(*m.X.T[s], c=c)
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def BGPLVM_oil(optimize=True, N=200, Q=7, num_inducing=40, max_iters=1000, plot=False, **k):
|
def bgplvm_oil(optimize=True, verbose=1, plot=True, N=200, Q=7, num_inducing=40, max_iters=1000, **k):
|
||||||
np.random.seed(0)
|
import GPy
|
||||||
|
from GPy.likelihoods import Gaussian
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
|
||||||
|
_np.random.seed(0)
|
||||||
data = GPy.util.datasets.oil()
|
data = GPy.util.datasets.oil()
|
||||||
|
|
||||||
# create simple GP model
|
kernel = GPy.kern.rbf_inv(Q, 1., [.1] * Q, ARD=True) + GPy.kern.bias(Q, _np.exp(-2))
|
||||||
kernel = GPy.kern.rbf_inv(Q, 1., [.1] * Q, ARD=True) + GPy.kern.bias(Q, np.exp(-2))
|
|
||||||
|
|
||||||
Y = data['X'][:N]
|
Y = data['X'][:N]
|
||||||
Yn = Gaussian(Y, normalize=True)
|
Yn = Gaussian(Y, normalize=True)
|
||||||
# Yn = Y - Y.mean(0)
|
|
||||||
# Yn /= Yn.std(0)
|
|
||||||
|
|
||||||
m = GPy.models.BayesianGPLVM(Yn, Q, kernel=kernel, num_inducing=num_inducing, **k)
|
m = GPy.models.BayesianGPLVM(Yn, Q, kernel=kernel, num_inducing=num_inducing, **k)
|
||||||
m.data_labels = data['Y'][:N].argmax(axis=1)
|
m.data_labels = data['Y'][:N].argmax(axis=1)
|
||||||
|
|
||||||
# m.constrain('variance|leng', logexp_clipped())
|
|
||||||
# m['.*lengt'] = m.X.var(0).max() / m.X.var(0)
|
|
||||||
m['noise'] = Yn.Y.var() / 100.
|
m['noise'] = Yn.Y.var() / 100.
|
||||||
|
|
||||||
|
|
||||||
# optimize
|
|
||||||
if optimize:
|
if optimize:
|
||||||
m.constrain_fixed('noise')
|
m.optimize('scg', messages=verbose, max_iters=max_iters, gtol=.05)
|
||||||
m.optimize('scg', messages=1, max_iters=200, gtol=.05)
|
|
||||||
m.constrain_positive('noise')
|
|
||||||
m.constrain_bounded('white', 1e-7, 1)
|
|
||||||
m.optimize('scg', messages=1, max_iters=max_iters, gtol=.05)
|
|
||||||
|
|
||||||
if plot:
|
if plot:
|
||||||
y = m.likelihood.Y[0, :]
|
y = m.likelihood.Y[0, :]
|
||||||
fig, (latent_axes, sense_axes) = plt.subplots(1, 2)
|
fig, (latent_axes, sense_axes) = plt.subplots(1, 2)
|
||||||
plt.sca(latent_axes)
|
m.plot_latent(ax=latent_axes)
|
||||||
m.plot_latent()
|
|
||||||
data_show = GPy.util.visualize.vector_show(y)
|
data_show = GPy.util.visualize.vector_show(y)
|
||||||
lvm_visualizer = GPy.util.visualize.lvm_dimselect(m.X[0, :], m, data_show, latent_axes=latent_axes) # , sense_axes=sense_axes)
|
lvm_visualizer = GPy.util.visualize.lvm_dimselect(m.X[0, :], # @UnusedVariable
|
||||||
|
m, data_show, latent_axes=latent_axes, sense_axes=sense_axes)
|
||||||
raw_input('Press enter to finish')
|
raw_input('Press enter to finish')
|
||||||
plt.close(fig)
|
plt.close(fig)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def oil_100():
|
|
||||||
data = GPy.util.datasets.oil_100()
|
|
||||||
m = GPy.models.GPLVM(data['X'], 2)
|
|
||||||
|
|
||||||
# optimize
|
|
||||||
m.optimize(messages=1, max_iters=2)
|
|
||||||
|
|
||||||
# plot
|
|
||||||
print(m)
|
|
||||||
# m.plot_latent(labels=data['Y'].argmax(axis=1))
|
|
||||||
return m
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _simulate_sincos(D1, D2, D3, N, num_inducing, Q, plot_sim=False):
|
def _simulate_sincos(D1, D2, D3, N, num_inducing, Q, plot_sim=False):
|
||||||
x = np.linspace(0, 4 * np.pi, N)[:, None]
|
x = _np.linspace(0, 4 * _np.pi, N)[:, None]
|
||||||
s1 = np.vectorize(lambda x: np.sin(x))
|
s1 = _np.vectorize(lambda x: _np.sin(x))
|
||||||
s2 = np.vectorize(lambda x: np.cos(x))
|
s2 = _np.vectorize(lambda x: _np.cos(x))
|
||||||
s3 = np.vectorize(lambda x:-np.exp(-np.cos(2 * x)))
|
s3 = _np.vectorize(lambda x:-_np.exp(-_np.cos(2 * x)))
|
||||||
sS = np.vectorize(lambda x: np.sin(2 * x))
|
sS = _np.vectorize(lambda x: _np.sin(2 * x))
|
||||||
|
|
||||||
s1 = s1(x)
|
s1 = s1(x)
|
||||||
s2 = s2(x)
|
s2 = s2(x)
|
||||||
s3 = s3(x)
|
s3 = s3(x)
|
||||||
sS = sS(x)
|
sS = sS(x)
|
||||||
|
|
||||||
S1 = np.hstack([s1, sS])
|
S1 = _np.hstack([s1, sS])
|
||||||
S2 = np.hstack([s2, s3, sS])
|
S2 = _np.hstack([s2, s3, sS])
|
||||||
S3 = np.hstack([s3, sS])
|
S3 = _np.hstack([s3, sS])
|
||||||
|
|
||||||
Y1 = S1.dot(np.random.randn(S1.shape[1], D1))
|
Y1 = S1.dot(_np.random.randn(S1.shape[1], D1))
|
||||||
Y2 = S2.dot(np.random.randn(S2.shape[1], D2))
|
Y2 = S2.dot(_np.random.randn(S2.shape[1], D2))
|
||||||
Y3 = S3.dot(np.random.randn(S3.shape[1], D3))
|
Y3 = S3.dot(_np.random.randn(S3.shape[1], D3))
|
||||||
|
|
||||||
Y1 += .3 * np.random.randn(*Y1.shape)
|
Y1 += .3 * _np.random.randn(*Y1.shape)
|
||||||
Y2 += .2 * np.random.randn(*Y2.shape)
|
Y2 += .2 * _np.random.randn(*Y2.shape)
|
||||||
Y3 += .25 * np.random.randn(*Y3.shape)
|
Y3 += .25 * _np.random.randn(*Y3.shape)
|
||||||
|
|
||||||
Y1 -= Y1.mean(0)
|
Y1 -= Y1.mean(0)
|
||||||
Y2 -= Y2.mean(0)
|
Y2 -= Y2.mean(0)
|
||||||
|
|
@ -230,6 +206,7 @@ def _simulate_sincos(D1, D2, D3, N, num_inducing, Q, plot_sim=False):
|
||||||
|
|
||||||
if plot_sim:
|
if plot_sim:
|
||||||
import pylab
|
import pylab
|
||||||
|
import matplotlib.cm as cm
|
||||||
import itertools
|
import itertools
|
||||||
fig = pylab.figure("MRD Simulation Data", figsize=(8, 6))
|
fig = pylab.figure("MRD Simulation Data", figsize=(8, 6))
|
||||||
fig.clf()
|
fig.clf()
|
||||||
|
|
@ -240,220 +217,247 @@ def _simulate_sincos(D1, D2, D3, N, num_inducing, Q, plot_sim=False):
|
||||||
ax.legend()
|
ax.legend()
|
||||||
for i, Y in enumerate(Ylist):
|
for i, Y in enumerate(Ylist):
|
||||||
ax = fig.add_subplot(2, len(Ylist), len(Ylist) + 1 + i)
|
ax = fig.add_subplot(2, len(Ylist), len(Ylist) + 1 + i)
|
||||||
ax.imshow(Y, aspect='auto', cmap=cm.gray) # @UndefinedVariable
|
ax.imshow(Y, aspect='auto', cmap=cm.gray)
|
||||||
ax.set_title("Y{}".format(i + 1))
|
ax.set_title("Y{}".format(i + 1))
|
||||||
pylab.draw()
|
pylab.draw()
|
||||||
pylab.tight_layout()
|
pylab.tight_layout()
|
||||||
|
|
||||||
return slist, [S1, S2, S3], Ylist
|
return slist, [S1, S2, S3], Ylist
|
||||||
|
|
||||||
def bgplvm_simulation_matlab_compare():
|
# def bgplvm_simulation_matlab_compare():
|
||||||
from GPy.util.datasets import simulation_BGPLVM
|
# from GPy.util.datasets import simulation_BGPLVM
|
||||||
sim_data = simulation_BGPLVM()
|
# from GPy import kern
|
||||||
Y = sim_data['Y']
|
# from GPy.models import BayesianGPLVM
|
||||||
S = sim_data['S']
|
#
|
||||||
mu = sim_data['mu']
|
# sim_data = simulation_BGPLVM()
|
||||||
num_inducing, [_, Q] = 3, mu.shape
|
# Y = sim_data['Y']
|
||||||
|
# mu = sim_data['mu']
|
||||||
|
# num_inducing, [_, Q] = 3, mu.shape
|
||||||
|
#
|
||||||
|
# k = kern.linear(Q, ARD=True) + kern.bias(Q, _np.exp(-2)) + kern.white(Q, _np.exp(-2))
|
||||||
|
# m = BayesianGPLVM(Y, Q, init="PCA", num_inducing=num_inducing, kernel=k,
|
||||||
|
# _debug=False)
|
||||||
|
# m.auto_scale_factor = True
|
||||||
|
# m['noise'] = Y.var() / 100.
|
||||||
|
# m['linear_variance'] = .01
|
||||||
|
# return m
|
||||||
|
|
||||||
from GPy.models import mrd
|
def bgplvm_simulation(optimize=True, verbose=1,
|
||||||
from GPy import kern
|
plot=True, plot_sim=False,
|
||||||
reload(mrd); reload(kern)
|
|
||||||
k = kern.linear(Q, ARD=True) + kern.bias(Q, np.exp(-2)) + kern.white(Q, np.exp(-2))
|
|
||||||
m = BayesianGPLVM(Y, Q, init="PCA", num_inducing=num_inducing, kernel=k,
|
|
||||||
# X=mu,
|
|
||||||
# X_variance=S,
|
|
||||||
_debug=False)
|
|
||||||
m.auto_scale_factor = True
|
|
||||||
m['noise'] = Y.var() / 100.
|
|
||||||
m['linear_variance'] = .01
|
|
||||||
return m
|
|
||||||
|
|
||||||
def bgplvm_simulation(optimize='scg',
|
|
||||||
plot=True,
|
|
||||||
max_iters=2e4,
|
max_iters=2e4,
|
||||||
plot_sim=False):
|
):
|
||||||
# from GPy.core.transformations import logexp_clipped
|
|
||||||
D1, D2, D3, N, num_inducing, Q = 15, 5, 8, 30, 3, 10
|
|
||||||
slist, Slist, Ylist = _simulate_sincos(D1, D2, D3, N, num_inducing, Q, plot_sim)
|
|
||||||
|
|
||||||
from GPy.models import mrd
|
|
||||||
from GPy import kern
|
from GPy import kern
|
||||||
reload(mrd); reload(kern)
|
from GPy.models import BayesianGPLVM
|
||||||
|
|
||||||
|
D1, D2, D3, N, num_inducing, Q = 15, 5, 8, 30, 3, 10
|
||||||
|
_, _, Ylist = _simulate_sincos(D1, D2, D3, N, num_inducing, Q, plot_sim)
|
||||||
Y = Ylist[0]
|
Y = Ylist[0]
|
||||||
|
k = kern.linear(Q, ARD=True) + kern.bias(Q, _np.exp(-2)) + kern.white(Q, _np.exp(-2)) # + kern.bias(Q)
|
||||||
k = kern.linear(Q, ARD=True) + kern.bias(Q, np.exp(-2)) + kern.white(Q, np.exp(-2)) # + kern.bias(Q)
|
|
||||||
m = BayesianGPLVM(Y, Q, init="PCA", num_inducing=num_inducing, kernel=k)
|
m = BayesianGPLVM(Y, Q, init="PCA", num_inducing=num_inducing, kernel=k)
|
||||||
|
|
||||||
# m.constrain('variance|noise', logexp_clipped())
|
|
||||||
m['noise'] = Y.var() / 100.
|
m['noise'] = Y.var() / 100.
|
||||||
|
|
||||||
if optimize:
|
if optimize:
|
||||||
print "Optimizing model:"
|
print "Optimizing model:"
|
||||||
m.optimize(optimize, max_iters=max_iters,
|
m.optimize('scg', messages=verbose, max_iters=max_iters,
|
||||||
messages=True, gtol=.05)
|
gtol=.05)
|
||||||
if plot:
|
if plot:
|
||||||
m.plot_X_1d("BGPLVM Latent Space 1D")
|
m.plot_X_1d("BGPLVM Latent Space 1D")
|
||||||
m.kern.plot_ARD('BGPLVM Simulation ARD Parameters')
|
m.kern.plot_ARD('BGPLVM Simulation ARD Parameters')
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def mrd_simulation(optimize=True, plot=True, plot_sim=True, **kw):
|
def mrd_simulation(optimize=True, verbose=True, plot=True, plot_sim=True, **kw):
|
||||||
D1, D2, D3, N, num_inducing, Q = 60, 20, 36, 60, 6, 5
|
from GPy import kern
|
||||||
slist, Slist, Ylist = _simulate_sincos(D1, D2, D3, N, num_inducing, Q, plot_sim)
|
from GPy.models import MRD
|
||||||
|
from GPy.likelihoods import Gaussian
|
||||||
|
|
||||||
|
D1, D2, D3, N, num_inducing, Q = 60, 20, 36, 60, 6, 5
|
||||||
|
_, _, Ylist = _simulate_sincos(D1, D2, D3, N, num_inducing, Q, plot_sim)
|
||||||
likelihood_list = [Gaussian(x, normalize=True) for x in Ylist]
|
likelihood_list = [Gaussian(x, normalize=True) for x in Ylist]
|
||||||
|
|
||||||
from GPy.models import mrd
|
k = kern.linear(Q, ARD=True) + kern.bias(Q, _np.exp(-2)) + kern.white(Q, _np.exp(-2))
|
||||||
from GPy import kern
|
m = MRD(likelihood_list, input_dim=Q, num_inducing=num_inducing, kernels=k, initx="", initz='permute', **kw)
|
||||||
|
|
||||||
reload(mrd); reload(kern)
|
|
||||||
|
|
||||||
k = kern.linear(Q, ARD=True) + kern.bias(Q, np.exp(-2)) + kern.white(Q, np.exp(-2))
|
|
||||||
m = mrd.MRD(likelihood_list, input_dim=Q, num_inducing=num_inducing, kernels=k, initx="", initz='permute', **kw)
|
|
||||||
m.ensure_default_constraints()
|
m.ensure_default_constraints()
|
||||||
|
|
||||||
for i, bgplvm in enumerate(m.bgplvms):
|
for i, bgplvm in enumerate(m.bgplvms):
|
||||||
m['{}_noise'.format(i)] = bgplvm.likelihood.Y.var() / 500.
|
m['{}_noise'.format(i)] = bgplvm.likelihood.Y.var() / 500.
|
||||||
|
|
||||||
|
|
||||||
# DEBUG
|
|
||||||
# np.seterr("raise")
|
|
||||||
|
|
||||||
if optimize:
|
if optimize:
|
||||||
print "Optimizing Model:"
|
print "Optimizing Model:"
|
||||||
m.optimize(messages=1, max_iters=8e3, gtol=.1)
|
m.optimize(messages=verbose, max_iters=8e3, gtol=.1)
|
||||||
if plot:
|
if plot:
|
||||||
m.plot_X_1d("MRD Latent Space 1D")
|
m.plot_X_1d("MRD Latent Space 1D")
|
||||||
m.plot_scales("MRD Scales")
|
m.plot_scales("MRD Scales")
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def brendan_faces():
|
def brendan_faces(optimize=True, verbose=True, plot=True):
|
||||||
from GPy import kern
|
import GPy
|
||||||
|
|
||||||
data = GPy.util.datasets.brendan_faces()
|
data = GPy.util.datasets.brendan_faces()
|
||||||
Q = 2
|
Q = 2
|
||||||
Y = data['Y'][0:-1:10, :]
|
Y = data['Y']
|
||||||
# Y = data['Y']
|
|
||||||
Yn = Y - Y.mean()
|
Yn = Y - Y.mean()
|
||||||
Yn /= Yn.std()
|
Yn /= Yn.std()
|
||||||
|
|
||||||
m = GPy.models.GPLVM(Yn, Q)
|
m = GPy.models.GPLVM(Yn, Q)
|
||||||
# m = GPy.models.BayesianGPLVM(Yn, Q, num_inducing=100)
|
|
||||||
|
|
||||||
# optimize
|
# optimize
|
||||||
m.constrain('rbf|noise|white', GPy.core.transformations.logexp_clipped())
|
m.constrain('rbf|noise|white', GPy.core.transformations.logexp_clipped())
|
||||||
|
|
||||||
m.optimize('scg', messages=1, max_f_eval=10000)
|
if optimize: m.optimize('scg', messages=verbose, max_iters=1000)
|
||||||
|
|
||||||
|
if plot:
|
||||||
ax = m.plot_latent(which_indices=(0, 1))
|
ax = m.plot_latent(which_indices=(0, 1))
|
||||||
y = m.likelihood.Y[0, :]
|
y = m.likelihood.Y[0, :]
|
||||||
data_show = GPy.util.visualize.image_show(y[None, :], dimensions=(20, 28), transpose=True, invert=False, scale=False)
|
data_show = GPy.util.visualize.image_show(y[None, :], dimensions=(20, 28), transpose=True, order='F', invert=False, scale=False)
|
||||||
lvm_visualizer = GPy.util.visualize.lvm(m.X[0, :].copy(), m, data_show, ax)
|
GPy.util.visualize.lvm(m.X[0, :].copy(), m, data_show, ax)
|
||||||
raw_input('Press enter to finish')
|
raw_input('Press enter to finish')
|
||||||
|
|
||||||
return m
|
return m
|
||||||
def stick_play(range=None, frame_rate=15):
|
|
||||||
|
def olivetti_faces(optimize=True, verbose=True, plot=True):
|
||||||
|
import GPy
|
||||||
|
|
||||||
|
data = GPy.util.datasets.olivetti_faces()
|
||||||
|
Q = 2
|
||||||
|
Y = data['Y']
|
||||||
|
Yn = Y - Y.mean()
|
||||||
|
Yn /= Yn.std()
|
||||||
|
|
||||||
|
m = GPy.models.GPLVM(Yn, Q)
|
||||||
|
if optimize: m.optimize('scg', messages=verbose, max_iters=1000)
|
||||||
|
if plot:
|
||||||
|
ax = m.plot_latent(which_indices=(0, 1))
|
||||||
|
y = m.likelihood.Y[0, :]
|
||||||
|
data_show = GPy.util.visualize.image_show(y[None, :], dimensions=(112, 92), transpose=False, invert=False, scale=False)
|
||||||
|
GPy.util.visualize.lvm(m.X[0, :].copy(), m, data_show, ax)
|
||||||
|
raw_input('Press enter to finish')
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
||||||
|
def stick_play(range=None, frame_rate=15, optimize=False, verbose=True, plot=True):
|
||||||
|
import GPy
|
||||||
data = GPy.util.datasets.osu_run1()
|
data = GPy.util.datasets.osu_run1()
|
||||||
# optimize
|
# optimize
|
||||||
if range == None:
|
if range == None:
|
||||||
Y = data['Y'].copy()
|
Y = data['Y'].copy()
|
||||||
else:
|
else:
|
||||||
Y = data['Y'][range[0]:range[1], :].copy()
|
Y = data['Y'][range[0]:range[1], :].copy()
|
||||||
|
if plot:
|
||||||
y = Y[0, :]
|
y = Y[0, :]
|
||||||
data_show = GPy.util.visualize.stick_show(y[None, :], connect=data['connect'])
|
data_show = GPy.util.visualize.stick_show(y[None, :], connect=data['connect'])
|
||||||
GPy.util.visualize.data_play(Y, data_show, frame_rate)
|
GPy.util.visualize.data_play(Y, data_show, frame_rate)
|
||||||
return Y
|
return Y
|
||||||
|
|
||||||
def stick(kernel=None):
|
def stick(kernel=None, optimize=True, verbose=True, plot=True):
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
import GPy
|
||||||
|
|
||||||
data = GPy.util.datasets.osu_run1()
|
data = GPy.util.datasets.osu_run1()
|
||||||
# optimize
|
# optimize
|
||||||
m = GPy.models.GPLVM(data['Y'], 2, kernel=kernel)
|
m = GPy.models.GPLVM(data['Y'], 2, kernel=kernel)
|
||||||
m.optimize(messages=1, max_f_eval=10000)
|
if optimize: m.optimize(messages=verbose, max_f_eval=10000)
|
||||||
if GPy.util.visualize.visual_available:
|
if plot and GPy.util.visualize.visual_available:
|
||||||
plt.clf
|
plt.clf
|
||||||
ax = m.plot_latent()
|
ax = m.plot_latent()
|
||||||
y = m.likelihood.Y[0, :]
|
y = m.likelihood.Y[0, :]
|
||||||
data_show = GPy.util.visualize.stick_show(y[None, :], connect=data['connect'])
|
data_show = GPy.util.visualize.stick_show(y[None, :], connect=data['connect'])
|
||||||
lvm_visualizer = GPy.util.visualize.lvm(m.X[0, :].copy(), m, data_show, ax)
|
GPy.util.visualize.lvm(m.X[0, :].copy(), m, data_show, ax)
|
||||||
raw_input('Press enter to finish')
|
raw_input('Press enter to finish')
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def bcgplvm_linear_stick(kernel=None):
|
def bcgplvm_linear_stick(kernel=None, optimize=True, verbose=True, plot=True):
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
import GPy
|
||||||
|
|
||||||
data = GPy.util.datasets.osu_run1()
|
data = GPy.util.datasets.osu_run1()
|
||||||
# optimize
|
# optimize
|
||||||
mapping = GPy.mappings.Linear(data['Y'].shape[1], 2)
|
mapping = GPy.mappings.Linear(data['Y'].shape[1], 2)
|
||||||
m = GPy.models.BCGPLVM(data['Y'], 2, kernel=kernel, mapping=mapping)
|
m = GPy.models.BCGPLVM(data['Y'], 2, kernel=kernel, mapping=mapping)
|
||||||
m.optimize(messages=1, max_f_eval=10000)
|
if optimize: m.optimize(messages=verbose, max_f_eval=10000)
|
||||||
if GPy.util.visualize.visual_available:
|
if plot and GPy.util.visualize.visual_available:
|
||||||
plt.clf
|
plt.clf
|
||||||
ax = m.plot_latent()
|
ax = m.plot_latent()
|
||||||
y = m.likelihood.Y[0, :]
|
y = m.likelihood.Y[0, :]
|
||||||
data_show = GPy.util.visualize.stick_show(y[None, :], connect=data['connect'])
|
data_show = GPy.util.visualize.stick_show(y[None, :], connect=data['connect'])
|
||||||
lvm_visualizer = GPy.util.visualize.lvm(m.X[0, :].copy(), m, data_show, ax)
|
GPy.util.visualize.lvm(m.X[0, :].copy(), m, data_show, ax)
|
||||||
raw_input('Press enter to finish')
|
raw_input('Press enter to finish')
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def bcgplvm_stick(kernel=None):
|
def bcgplvm_stick(kernel=None, optimize=True, verbose=True, plot=True):
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
import GPy
|
||||||
|
|
||||||
data = GPy.util.datasets.osu_run1()
|
data = GPy.util.datasets.osu_run1()
|
||||||
# optimize
|
# optimize
|
||||||
back_kernel=GPy.kern.rbf(data['Y'].shape[1], lengthscale=5.)
|
back_kernel=GPy.kern.rbf(data['Y'].shape[1], lengthscale=5.)
|
||||||
mapping = GPy.mappings.Kernel(X=data['Y'], output_dim=2, kernel=back_kernel)
|
mapping = GPy.mappings.Kernel(X=data['Y'], output_dim=2, kernel=back_kernel)
|
||||||
m = GPy.models.BCGPLVM(data['Y'], 2, kernel=kernel, mapping=mapping)
|
m = GPy.models.BCGPLVM(data['Y'], 2, kernel=kernel, mapping=mapping)
|
||||||
m.optimize(messages=1, max_f_eval=10000)
|
if optimize: m.optimize(messages=verbose, max_f_eval=10000)
|
||||||
if GPy.util.visualize.visual_available:
|
if plot and GPy.util.visualize.visual_available:
|
||||||
plt.clf
|
plt.clf
|
||||||
ax = m.plot_latent()
|
ax = m.plot_latent()
|
||||||
y = m.likelihood.Y[0, :]
|
y = m.likelihood.Y[0, :]
|
||||||
data_show = GPy.util.visualize.stick_show(y[None, :], connect=data['connect'])
|
data_show = GPy.util.visualize.stick_show(y[None, :], connect=data['connect'])
|
||||||
lvm_visualizer = GPy.util.visualize.lvm(m.X[0, :].copy(), m, data_show, ax)
|
GPy.util.visualize.lvm(m.X[0, :].copy(), m, data_show, ax)
|
||||||
raw_input('Press enter to finish')
|
raw_input('Press enter to finish')
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def robot_wireless():
|
def robot_wireless(optimize=True, verbose=True, plot=True):
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
import GPy
|
||||||
|
|
||||||
data = GPy.util.datasets.robot_wireless()
|
data = GPy.util.datasets.robot_wireless()
|
||||||
# optimize
|
# optimize
|
||||||
m = GPy.models.GPLVM(data['Y'], 2)
|
m = GPy.models.GPLVM(data['Y'], 2)
|
||||||
m.optimize(messages=1, max_f_eval=10000)
|
if optimize: m.optimize(messages=verbose, max_f_eval=10000)
|
||||||
m._set_params(m._get_params())
|
m._set_params(m._get_params())
|
||||||
plt.clf
|
if plot:
|
||||||
ax = m.plot_latent()
|
m.plot_latent()
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def stick_bgplvm(model=None):
|
def stick_bgplvm(model=None, optimize=True, verbose=True, plot=True):
|
||||||
|
from GPy.models import BayesianGPLVM
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
import GPy
|
||||||
|
|
||||||
data = GPy.util.datasets.osu_run1()
|
data = GPy.util.datasets.osu_run1()
|
||||||
Q = 6
|
Q = 6
|
||||||
kernel = GPy.kern.rbf(Q, ARD=True) + GPy.kern.bias(Q, np.exp(-2)) + GPy.kern.white(Q, np.exp(-2))
|
kernel = GPy.kern.rbf(Q, ARD=True) + GPy.kern.bias(Q, _np.exp(-2)) + GPy.kern.white(Q, _np.exp(-2))
|
||||||
m = BayesianGPLVM(data['Y'], Q, init="PCA", num_inducing=20, kernel=kernel)
|
m = BayesianGPLVM(data['Y'], Q, init="PCA", num_inducing=20, kernel=kernel)
|
||||||
# optimize
|
# optimize
|
||||||
m.ensure_default_constraints()
|
m.ensure_default_constraints()
|
||||||
m.optimize('scg', messages=1, max_iters=200, xtol=1e-300, ftol=1e-300)
|
if optimize: m.optimize('scg', messages=verbose, max_iters=200, xtol=1e-300, ftol=1e-300)
|
||||||
m._set_params(m._get_params())
|
m._set_params(m._get_params())
|
||||||
|
if plot:
|
||||||
plt.clf, (latent_axes, sense_axes) = plt.subplots(1, 2)
|
plt.clf, (latent_axes, sense_axes) = plt.subplots(1, 2)
|
||||||
plt.sca(latent_axes)
|
plt.sca(latent_axes)
|
||||||
m.plot_latent()
|
m.plot_latent()
|
||||||
y = m.likelihood.Y[0, :].copy()
|
y = m.likelihood.Y[0, :].copy()
|
||||||
data_show = GPy.util.visualize.stick_show(y[None, :], connect=data['connect'])
|
data_show = GPy.util.visualize.stick_show(y[None, :], connect=data['connect'])
|
||||||
lvm_visualizer = GPy.util.visualize.lvm_dimselect(m.X[0, :].copy(), m, data_show, latent_axes=latent_axes, sense_axes=sense_axes)
|
GPy.util.visualize.lvm_dimselect(m.X[0, :].copy(), m, data_show, latent_axes=latent_axes, sense_axes=sense_axes)
|
||||||
raw_input('Press enter to finish')
|
raw_input('Press enter to finish')
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
def cmu_mocap(subject='35', motion=['01'], in_place=True):
|
def cmu_mocap(subject='35', motion=['01'], in_place=True, optimize=True, verbose=True, plot=True):
|
||||||
|
import GPy
|
||||||
|
|
||||||
data = GPy.util.datasets.cmu_mocap(subject, motion)
|
data = GPy.util.datasets.cmu_mocap(subject, motion)
|
||||||
Y = data['Y']
|
|
||||||
if in_place:
|
if in_place:
|
||||||
# Make figure move in place.
|
# Make figure move in place.
|
||||||
data['Y'][:, 0:3] = 0.0
|
data['Y'][:, 0:3] = 0.0
|
||||||
|
|
||||||
m = GPy.models.GPLVM(data['Y'], 2, normalize_Y=True)
|
m = GPy.models.GPLVM(data['Y'], 2, normalize_Y=True)
|
||||||
|
|
||||||
# optimize
|
if optimize:
|
||||||
m.optimize(messages=1, max_f_eval=10000)
|
m.optimize(messages=verbose, max_f_eval=10000)
|
||||||
|
|
||||||
|
if plot:
|
||||||
ax = m.plot_latent()
|
ax = m.plot_latent()
|
||||||
y = m.likelihood.Y[0, :]
|
y = m.likelihood.Y[0, :]
|
||||||
data_show = GPy.util.visualize.skeleton_show(y[None, :], data['skel'])
|
data_show = GPy.util.visualize.skeleton_show(y[None, :], data['skel'])
|
||||||
|
|
@ -462,31 +466,3 @@ def cmu_mocap(subject='35', motion=['01'], in_place=True):
|
||||||
lvm_visualizer.close()
|
lvm_visualizer.close()
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
# def BGPLVM_oil():
|
|
||||||
# data = GPy.util.datasets.oil()
|
|
||||||
# Y, X = data['Y'], data['X']
|
|
||||||
# X -= X.mean(axis=0)
|
|
||||||
# X /= X.std(axis=0)
|
|
||||||
#
|
|
||||||
# Q = 10
|
|
||||||
# num_inducing = 30
|
|
||||||
#
|
|
||||||
# kernel = GPy.kern.rbf(Q, ARD=True) + GPy.kern.bias(Q) + GPy.kern.white(Q)
|
|
||||||
# m = GPy.models.BayesianGPLVM(X, Q, kernel=kernel, num_inducing=num_inducing)
|
|
||||||
# # m.scale_factor = 100.0
|
|
||||||
# m.constrain_positive('(white|noise|bias|X_variance|rbf_variance|rbf_length)')
|
|
||||||
# from sklearn import cluster
|
|
||||||
# km = cluster.KMeans(num_inducing, verbose=10)
|
|
||||||
# Z = km.fit(m.X).cluster_centers_
|
|
||||||
# # Z = GPy.util.misc.kmm_init(m.X, num_inducing)
|
|
||||||
# m.set('iip', Z)
|
|
||||||
# m.set('bias', 1e-4)
|
|
||||||
# # optimize
|
|
||||||
#
|
|
||||||
# import pdb; pdb.set_trace()
|
|
||||||
# m.optimize('tnc', messages=1)
|
|
||||||
# print m
|
|
||||||
# m.plot_latent(labels=data['Y'].argmax(axis=1))
|
|
||||||
# return m
|
|
||||||
|
|
||||||
|
|
|
||||||
286
GPy/examples/non_gaussian.py
Normal file
286
GPy/examples/non_gaussian.py
Normal file
|
|
@ -0,0 +1,286 @@
|
||||||
|
import GPy
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from GPy.util import datasets
|
||||||
|
|
||||||
|
def student_t_approx(optimize=True, plot=True):
|
||||||
|
"""
|
||||||
|
Example of regressing with a student t likelihood using Laplace
|
||||||
|
"""
|
||||||
|
real_std = 0.1
|
||||||
|
#Start a function, any function
|
||||||
|
X = np.linspace(0.0, np.pi*2, 100)[:, None]
|
||||||
|
Y = np.sin(X) + np.random.randn(*X.shape)*real_std
|
||||||
|
Y = Y/Y.max()
|
||||||
|
Yc = Y.copy()
|
||||||
|
|
||||||
|
X_full = np.linspace(0.0, np.pi*2, 500)[:, None]
|
||||||
|
Y_full = np.sin(X_full)
|
||||||
|
Y_full = Y_full/Y_full.max()
|
||||||
|
|
||||||
|
#Slightly noisy data
|
||||||
|
Yc[75:80] += 1
|
||||||
|
|
||||||
|
#Very noisy data
|
||||||
|
#Yc[10] += 100
|
||||||
|
#Yc[25] += 10
|
||||||
|
#Yc[23] += 10
|
||||||
|
#Yc[26] += 1000
|
||||||
|
#Yc[24] += 10
|
||||||
|
#Yc = Yc/Yc.max()
|
||||||
|
|
||||||
|
#Add student t random noise to datapoints
|
||||||
|
deg_free = 5
|
||||||
|
print "Real noise: ", real_std
|
||||||
|
initial_var_guess = 0.5
|
||||||
|
edited_real_sd = initial_var_guess
|
||||||
|
|
||||||
|
# Kernel object
|
||||||
|
kernel1 = GPy.kern.rbf(X.shape[1]) + GPy.kern.white(X.shape[1])
|
||||||
|
kernel2 = kernel1.copy()
|
||||||
|
kernel3 = kernel1.copy()
|
||||||
|
kernel4 = kernel1.copy()
|
||||||
|
|
||||||
|
#Gaussian GP model on clean data
|
||||||
|
m1 = GPy.models.GPRegression(X, Y.copy(), kernel=kernel1)
|
||||||
|
# optimize
|
||||||
|
m1.ensure_default_constraints()
|
||||||
|
m1.constrain_fixed('white', 1e-5)
|
||||||
|
m1.randomize()
|
||||||
|
|
||||||
|
#Gaussian GP model on corrupt data
|
||||||
|
m2 = GPy.models.GPRegression(X, Yc.copy(), kernel=kernel2)
|
||||||
|
m2.ensure_default_constraints()
|
||||||
|
m2.constrain_fixed('white', 1e-5)
|
||||||
|
m2.randomize()
|
||||||
|
|
||||||
|
#Student t GP model on clean data
|
||||||
|
t_distribution = GPy.likelihoods.noise_model_constructors.student_t(deg_free=deg_free, sigma2=edited_real_sd)
|
||||||
|
stu_t_likelihood = GPy.likelihoods.Laplace(Y.copy(), t_distribution)
|
||||||
|
m3 = GPy.models.GPRegression(X, Y.copy(), kernel3, likelihood=stu_t_likelihood)
|
||||||
|
m3.ensure_default_constraints()
|
||||||
|
m3.constrain_bounded('t_noise', 1e-6, 10.)
|
||||||
|
m3.constrain_fixed('white', 1e-5)
|
||||||
|
m3.randomize()
|
||||||
|
|
||||||
|
#Student t GP model on corrupt data
|
||||||
|
t_distribution = GPy.likelihoods.noise_model_constructors.student_t(deg_free=deg_free, sigma2=edited_real_sd)
|
||||||
|
corrupt_stu_t_likelihood = GPy.likelihoods.Laplace(Yc.copy(), t_distribution)
|
||||||
|
m4 = GPy.models.GPRegression(X, Yc.copy(), kernel4, likelihood=corrupt_stu_t_likelihood)
|
||||||
|
m4.ensure_default_constraints()
|
||||||
|
m4.constrain_bounded('t_noise', 1e-6, 10.)
|
||||||
|
m4.constrain_fixed('white', 1e-5)
|
||||||
|
m4.randomize()
|
||||||
|
|
||||||
|
if optimize:
|
||||||
|
optimizer='scg'
|
||||||
|
print "Clean Gaussian"
|
||||||
|
m1.optimize(optimizer, messages=1)
|
||||||
|
print "Corrupt Gaussian"
|
||||||
|
m2.optimize(optimizer, messages=1)
|
||||||
|
print "Clean student t"
|
||||||
|
m3.optimize(optimizer, messages=1)
|
||||||
|
print "Corrupt student t"
|
||||||
|
m4.optimize(optimizer, messages=1)
|
||||||
|
|
||||||
|
if plot:
|
||||||
|
plt.figure(1)
|
||||||
|
plt.suptitle('Gaussian likelihood')
|
||||||
|
ax = plt.subplot(211)
|
||||||
|
m1.plot(ax=ax)
|
||||||
|
plt.plot(X_full, Y_full)
|
||||||
|
plt.ylim(-1.5, 1.5)
|
||||||
|
plt.title('Gaussian clean')
|
||||||
|
|
||||||
|
ax = plt.subplot(212)
|
||||||
|
m2.plot(ax=ax)
|
||||||
|
plt.plot(X_full, Y_full)
|
||||||
|
plt.ylim(-1.5, 1.5)
|
||||||
|
plt.title('Gaussian corrupt')
|
||||||
|
|
||||||
|
plt.figure(2)
|
||||||
|
plt.suptitle('Student-t likelihood')
|
||||||
|
ax = plt.subplot(211)
|
||||||
|
m3.plot(ax=ax)
|
||||||
|
plt.plot(X_full, Y_full)
|
||||||
|
plt.ylim(-1.5, 1.5)
|
||||||
|
plt.title('Student-t rasm clean')
|
||||||
|
|
||||||
|
ax = plt.subplot(212)
|
||||||
|
m4.plot(ax=ax)
|
||||||
|
plt.plot(X_full, Y_full)
|
||||||
|
plt.ylim(-1.5, 1.5)
|
||||||
|
plt.title('Student-t rasm corrupt')
|
||||||
|
|
||||||
|
return m1, m2, m3, m4
|
||||||
|
|
||||||
|
def boston_example(optimize=True, plot=True):
|
||||||
|
import sklearn
|
||||||
|
from sklearn.cross_validation import KFold
|
||||||
|
optimizer='bfgs'
|
||||||
|
messages=0
|
||||||
|
data = datasets.boston_housing()
|
||||||
|
degrees_freedoms = [3, 5, 8, 10]
|
||||||
|
X = data['X'].copy()
|
||||||
|
Y = data['Y'].copy()
|
||||||
|
X = X-X.mean(axis=0)
|
||||||
|
X = X/X.std(axis=0)
|
||||||
|
Y = Y-Y.mean()
|
||||||
|
Y = Y/Y.std()
|
||||||
|
num_folds = 10
|
||||||
|
kf = KFold(len(Y), n_folds=num_folds, indices=True)
|
||||||
|
num_models = len(degrees_freedoms) + 3 #3 for baseline, gaussian, gaussian laplace approx
|
||||||
|
score_folds = np.zeros((num_models, num_folds))
|
||||||
|
pred_density = score_folds.copy()
|
||||||
|
|
||||||
|
def rmse(Y, Ystar):
|
||||||
|
return np.sqrt(np.mean((Y-Ystar)**2))
|
||||||
|
|
||||||
|
for n, (train, test) in enumerate(kf):
|
||||||
|
X_train, X_test, Y_train, Y_test = X[train], X[test], Y[train], Y[test]
|
||||||
|
print "Fold {}".format(n)
|
||||||
|
|
||||||
|
noise = 1e-1 #np.exp(-2)
|
||||||
|
rbf_len = 0.5
|
||||||
|
data_axis_plot = 4
|
||||||
|
kernelstu = GPy.kern.rbf(X.shape[1]) + GPy.kern.white(X.shape[1]) + GPy.kern.bias(X.shape[1])
|
||||||
|
kernelgp = GPy.kern.rbf(X.shape[1]) + GPy.kern.white(X.shape[1]) + GPy.kern.bias(X.shape[1])
|
||||||
|
|
||||||
|
#Baseline
|
||||||
|
score_folds[0, n] = rmse(Y_test, np.mean(Y_train))
|
||||||
|
|
||||||
|
#Gaussian GP
|
||||||
|
print "Gauss GP"
|
||||||
|
mgp = GPy.models.GPRegression(X_train.copy(), Y_train.copy(), kernel=kernelgp.copy())
|
||||||
|
mgp.ensure_default_constraints()
|
||||||
|
mgp.constrain_fixed('white', 1e-5)
|
||||||
|
mgp['rbf_len'] = rbf_len
|
||||||
|
mgp['noise'] = noise
|
||||||
|
print mgp
|
||||||
|
if optimize:
|
||||||
|
mgp.optimize(optimizer=optimizer, messages=messages)
|
||||||
|
Y_test_pred = mgp.predict(X_test)
|
||||||
|
score_folds[1, n] = rmse(Y_test, Y_test_pred[0])
|
||||||
|
pred_density[1, n] = np.mean(mgp.log_predictive_density(X_test, Y_test))
|
||||||
|
print mgp
|
||||||
|
print pred_density
|
||||||
|
|
||||||
|
print "Gaussian Laplace GP"
|
||||||
|
N, D = Y_train.shape
|
||||||
|
g_distribution = GPy.likelihoods.noise_model_constructors.gaussian(variance=noise, N=N, D=D)
|
||||||
|
g_likelihood = GPy.likelihoods.Laplace(Y_train.copy(), g_distribution)
|
||||||
|
mg = GPy.models.GPRegression(X_train.copy(), Y_train.copy(), kernel=kernelstu.copy(), likelihood=g_likelihood)
|
||||||
|
mg.ensure_default_constraints()
|
||||||
|
mg.constrain_positive('noise_variance')
|
||||||
|
mg.constrain_fixed('white', 1e-5)
|
||||||
|
mg['rbf_len'] = rbf_len
|
||||||
|
mg['noise'] = noise
|
||||||
|
print mg
|
||||||
|
if optimize:
|
||||||
|
mg.optimize(optimizer=optimizer, messages=messages)
|
||||||
|
Y_test_pred = mg.predict(X_test)
|
||||||
|
score_folds[2, n] = rmse(Y_test, Y_test_pred[0])
|
||||||
|
pred_density[2, n] = np.mean(mg.log_predictive_density(X_test, Y_test))
|
||||||
|
print pred_density
|
||||||
|
print mg
|
||||||
|
|
||||||
|
for stu_num, df in enumerate(degrees_freedoms):
|
||||||
|
#Student T
|
||||||
|
print "Student-T GP {}df".format(df)
|
||||||
|
t_distribution = GPy.likelihoods.noise_model_constructors.student_t(deg_free=df, sigma2=noise)
|
||||||
|
stu_t_likelihood = GPy.likelihoods.Laplace(Y_train.copy(), t_distribution)
|
||||||
|
mstu_t = GPy.models.GPRegression(X_train.copy(), Y_train.copy(), kernel=kernelstu.copy(), likelihood=stu_t_likelihood)
|
||||||
|
mstu_t.ensure_default_constraints()
|
||||||
|
mstu_t.constrain_fixed('white', 1e-5)
|
||||||
|
mstu_t.constrain_bounded('t_noise', 0.0001, 1000)
|
||||||
|
mstu_t['rbf_len'] = rbf_len
|
||||||
|
mstu_t['t_noise'] = noise
|
||||||
|
print mstu_t
|
||||||
|
if optimize:
|
||||||
|
mstu_t.optimize(optimizer=optimizer, messages=messages)
|
||||||
|
Y_test_pred = mstu_t.predict(X_test)
|
||||||
|
score_folds[3+stu_num, n] = rmse(Y_test, Y_test_pred[0])
|
||||||
|
pred_density[3+stu_num, n] = np.mean(mstu_t.log_predictive_density(X_test, Y_test))
|
||||||
|
print pred_density
|
||||||
|
print mstu_t
|
||||||
|
|
||||||
|
if plot:
|
||||||
|
plt.figure()
|
||||||
|
plt.scatter(X_test[:, data_axis_plot], Y_test_pred[0])
|
||||||
|
plt.scatter(X_test[:, data_axis_plot], Y_test, c='r', marker='x')
|
||||||
|
plt.title('GP gauss')
|
||||||
|
|
||||||
|
plt.figure()
|
||||||
|
plt.scatter(X_test[:, data_axis_plot], Y_test_pred[0])
|
||||||
|
plt.scatter(X_test[:, data_axis_plot], Y_test, c='r', marker='x')
|
||||||
|
plt.title('Lap gauss')
|
||||||
|
|
||||||
|
plt.figure()
|
||||||
|
plt.scatter(X_test[:, data_axis_plot], Y_test_pred[0])
|
||||||
|
plt.scatter(X_test[:, data_axis_plot], Y_test, c='r', marker='x')
|
||||||
|
plt.title('Stu t {}df'.format(df))
|
||||||
|
|
||||||
|
print "Average scores: {}".format(np.mean(score_folds, 1))
|
||||||
|
print "Average pred density: {}".format(np.mean(pred_density, 1))
|
||||||
|
|
||||||
|
if plot:
|
||||||
|
#Plotting
|
||||||
|
stu_t_legends = ['Student T, df={}'.format(df) for df in degrees_freedoms]
|
||||||
|
legends = ['Baseline', 'Gaussian', 'Laplace Approx Gaussian'] + stu_t_legends
|
||||||
|
|
||||||
|
#Plot boxplots for RMSE density
|
||||||
|
fig = plt.figure()
|
||||||
|
ax=fig.add_subplot(111)
|
||||||
|
plt.title('RMSE')
|
||||||
|
bp = ax.boxplot(score_folds.T, notch=0, sym='+', vert=1, whis=1.5)
|
||||||
|
plt.setp(bp['boxes'], color='black')
|
||||||
|
plt.setp(bp['whiskers'], color='black')
|
||||||
|
plt.setp(bp['fliers'], color='red', marker='+')
|
||||||
|
xtickNames = plt.setp(ax, xticklabels=legends)
|
||||||
|
plt.setp(xtickNames, rotation=45, fontsize=8)
|
||||||
|
ax.set_ylabel('RMSE')
|
||||||
|
ax.set_xlabel('Distribution')
|
||||||
|
#Make grid and put it below boxes
|
||||||
|
ax.yaxis.grid(True, linestyle='-', which='major', color='lightgrey',
|
||||||
|
alpha=0.5)
|
||||||
|
ax.set_axisbelow(True)
|
||||||
|
|
||||||
|
#Plot boxplots for predictive density
|
||||||
|
fig = plt.figure()
|
||||||
|
ax=fig.add_subplot(111)
|
||||||
|
plt.title('Predictive density')
|
||||||
|
bp = ax.boxplot(pred_density[1:,:].T, notch=0, sym='+', vert=1, whis=1.5)
|
||||||
|
plt.setp(bp['boxes'], color='black')
|
||||||
|
plt.setp(bp['whiskers'], color='black')
|
||||||
|
plt.setp(bp['fliers'], color='red', marker='+')
|
||||||
|
xtickNames = plt.setp(ax, xticklabels=legends[1:])
|
||||||
|
plt.setp(xtickNames, rotation=45, fontsize=8)
|
||||||
|
ax.set_ylabel('Mean Log probability P(Y*|Y)')
|
||||||
|
ax.set_xlabel('Distribution')
|
||||||
|
#Make grid and put it below boxes
|
||||||
|
ax.yaxis.grid(True, linestyle='-', which='major', color='lightgrey',
|
||||||
|
alpha=0.5)
|
||||||
|
ax.set_axisbelow(True)
|
||||||
|
return mstu_t
|
||||||
|
|
||||||
|
#def precipitation_example():
|
||||||
|
#import sklearn
|
||||||
|
#from sklearn.cross_validation import KFold
|
||||||
|
#data = datasets.boston_housing()
|
||||||
|
#X = data['X'].copy()
|
||||||
|
#Y = data['Y'].copy()
|
||||||
|
#X = X-X.mean(axis=0)
|
||||||
|
#X = X/X.std(axis=0)
|
||||||
|
#Y = Y-Y.mean()
|
||||||
|
#Y = Y/Y.std()
|
||||||
|
#import ipdb; ipdb.set_trace() # XXX BREAKPOINT
|
||||||
|
#num_folds = 10
|
||||||
|
#kf = KFold(len(Y), n_folds=num_folds, indices=True)
|
||||||
|
#score_folds = np.zeros((4, num_folds))
|
||||||
|
#def rmse(Y, Ystar):
|
||||||
|
#return np.sqrt(np.mean((Y-Ystar)**2))
|
||||||
|
##for train, test in kf:
|
||||||
|
#for n, (train, test) in enumerate(kf):
|
||||||
|
#X_train, X_test, Y_train, Y_test = X[train], X[test], Y[train], Y[test]
|
||||||
|
#print "Fold {}".format(n)
|
||||||
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Gaussian Processes regression examples
|
Gaussian Processes regression examples
|
||||||
"""
|
"""
|
||||||
|
|
@ -9,88 +8,105 @@ import pylab as pb
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import GPy
|
import GPy
|
||||||
|
|
||||||
def coregionalization_toy2(max_iters=100):
|
def olympic_marathon_men(optimize=True, plot=True):
|
||||||
|
"""Run a standard Gaussian process regression on the Olympic marathon data."""
|
||||||
|
data = GPy.util.datasets.olympic_marathon_men()
|
||||||
|
|
||||||
|
# create simple GP Model
|
||||||
|
m = GPy.models.GPRegression(data['X'], data['Y'])
|
||||||
|
|
||||||
|
# set the lengthscale to be something sensible (defaults to 1)
|
||||||
|
m['rbf_lengthscale'] = 10
|
||||||
|
|
||||||
|
if optimize:
|
||||||
|
m.optimize('bfgs', max_iters=200)
|
||||||
|
if plot:
|
||||||
|
m.plot(plot_limits=(1850, 2050))
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
||||||
|
def coregionalization_toy2(optimize=True, plot=True):
|
||||||
"""
|
"""
|
||||||
A simple demonstration of coregionalization on two sinusoidal functions.
|
A simple demonstration of coregionalization on two sinusoidal functions.
|
||||||
"""
|
"""
|
||||||
|
#build a design matrix with a column of integers indicating the output
|
||||||
X1 = np.random.rand(50, 1) * 8
|
X1 = np.random.rand(50, 1) * 8
|
||||||
X2 = np.random.rand(30, 1) * 5
|
X2 = np.random.rand(30, 1) * 5
|
||||||
index = np.vstack((np.zeros_like(X1), np.ones_like(X2)))
|
index = np.vstack((np.zeros_like(X1), np.ones_like(X2)))
|
||||||
X = np.hstack((np.vstack((X1, X2)), index))
|
X = np.hstack((np.vstack((X1, X2)), index))
|
||||||
|
|
||||||
|
#build a suitable set of observed variables
|
||||||
Y1 = np.sin(X1) + np.random.randn(*X1.shape) * 0.05
|
Y1 = np.sin(X1) + np.random.randn(*X1.shape) * 0.05
|
||||||
Y2 = np.sin(X2) + np.random.randn(*X2.shape) * 0.05 + 2.
|
Y2 = np.sin(X2) + np.random.randn(*X2.shape) * 0.05 + 2.
|
||||||
Y = np.vstack((Y1, Y2))
|
Y = np.vstack((Y1, Y2))
|
||||||
|
|
||||||
|
#build the kernel
|
||||||
k1 = GPy.kern.rbf(1) + GPy.kern.bias(1)
|
k1 = GPy.kern.rbf(1) + GPy.kern.bias(1)
|
||||||
k2 = GPy.kern.coregionalize(2,1)
|
k2 = GPy.kern.coregionalize(2,1)
|
||||||
k = k1**k2 #k = k1.prod(k2,tensor=True)
|
k = k1**k2
|
||||||
m = GPy.models.GPRegression(X, Y, kernel=k)
|
m = GPy.models.GPRegression(X, Y, kernel=k)
|
||||||
m.constrain_fixed('.*rbf_var', 1.)
|
m.constrain_fixed('.*rbf_var', 1.)
|
||||||
# m.constrain_positive('.*kappa')
|
|
||||||
m.optimize('sim', messages=1, max_iters=max_iters)
|
|
||||||
|
|
||||||
pb.figure()
|
if optimize:
|
||||||
Xtest1 = np.hstack((np.linspace(0, 9, 100)[:, None], np.zeros((100, 1))))
|
m.optimize('bfgs', max_iters=100)
|
||||||
Xtest2 = np.hstack((np.linspace(0, 9, 100)[:, None], np.ones((100, 1))))
|
|
||||||
mean, var, low, up = m.predict(Xtest1)
|
if plot:
|
||||||
GPy.util.plot.gpplot(Xtest1[:, 0], mean, low, up)
|
m.plot(fixed_inputs=[(1,0)])
|
||||||
mean, var, low, up = m.predict(Xtest2)
|
m.plot(fixed_inputs=[(1,1)], ax=pb.gca())
|
||||||
GPy.util.plot.gpplot(Xtest2[:, 0], mean, low, up)
|
|
||||||
pb.plot(X1[:, 0], Y1[:, 0], 'rx', mew=2)
|
|
||||||
pb.plot(X2[:, 0], Y2[:, 0], 'gx', mew=2)
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def coregionalization_toy(max_iters=100):
|
#FIXME: Needs recovering once likelihoods are consolidated
|
||||||
"""
|
#def coregionalization_toy(optimize=True, plot=True):
|
||||||
A simple demonstration of coregionalization on two sinusoidal functions.
|
# """
|
||||||
"""
|
# A simple demonstration of coregionalization on two sinusoidal functions.
|
||||||
X1 = np.random.rand(50, 1) * 8
|
# """
|
||||||
X2 = np.random.rand(30, 1) * 5
|
# X1 = np.random.rand(50, 1) * 8
|
||||||
X = np.vstack((X1, X2))
|
# X2 = np.random.rand(30, 1) * 5
|
||||||
Y1 = np.sin(X1) + np.random.randn(*X1.shape) * 0.05
|
# X = np.vstack((X1, X2))
|
||||||
Y2 = -np.sin(X2) + np.random.randn(*X2.shape) * 0.05
|
# Y1 = np.sin(X1) + np.random.randn(*X1.shape) * 0.05
|
||||||
Y = np.vstack((Y1, Y2))
|
# Y2 = -np.sin(X2) + np.random.randn(*X2.shape) * 0.05
|
||||||
|
# Y = np.vstack((Y1, Y2))
|
||||||
|
#
|
||||||
|
# k1 = GPy.kern.rbf(1)
|
||||||
|
# m = GPy.models.GPMultioutputRegression(X_list=[X1,X2],Y_list=[Y1,Y2],kernel_list=[k1])
|
||||||
|
# m.constrain_fixed('.*rbf_var', 1.)
|
||||||
|
# m.optimize(max_iters=100)
|
||||||
|
#
|
||||||
|
# fig, axes = pb.subplots(2,1)
|
||||||
|
# m.plot(fixed_inputs=[(1,0)],ax=axes[0])
|
||||||
|
# m.plot(fixed_inputs=[(1,1)],ax=axes[1])
|
||||||
|
# axes[0].set_title('Output 0')
|
||||||
|
# axes[1].set_title('Output 1')
|
||||||
|
# return m
|
||||||
|
|
||||||
k1 = GPy.kern.rbf(1)
|
def coregionalization_sparse(optimize=True, plot=True):
|
||||||
m = GPy.models.GPMultioutputRegression(X_list=[X1,X2],Y_list=[Y1,Y2],kernel_list=[k1])
|
|
||||||
m.constrain_fixed('.*rbf_var', 1.)
|
|
||||||
m.optimize(max_iters=max_iters)
|
|
||||||
|
|
||||||
fig, axes = pb.subplots(2,1)
|
|
||||||
m.plot_single_output(output=0,ax=axes[0])
|
|
||||||
m.plot_single_output(output=1,ax=axes[1])
|
|
||||||
axes[0].set_title('Output 0')
|
|
||||||
axes[1].set_title('Output 1')
|
|
||||||
return m
|
|
||||||
|
|
||||||
def coregionalization_sparse(max_iters=100):
|
|
||||||
"""
|
"""
|
||||||
A simple demonstration of coregionalization on two sinusoidal functions using sparse approximations.
|
A simple demonstration of coregionalization on two sinusoidal functions using sparse approximations.
|
||||||
"""
|
"""
|
||||||
X1 = np.random.rand(500, 1) * 8
|
#fetch the data from the non sparse examples
|
||||||
X2 = np.random.rand(300, 1) * 5
|
m = coregionalization_toy2(optimize=False, plot=False)
|
||||||
index = np.vstack((np.zeros_like(X1), np.ones_like(X2)))
|
X, Y = m.X, m.likelihood.Y
|
||||||
X = np.hstack((np.vstack((X1, X2)), index))
|
|
||||||
Y1 = np.sin(X1) + np.random.randn(*X1.shape) * 0.05
|
|
||||||
Y2 = -np.sin(X2) + np.random.randn(*X2.shape) * 0.05
|
|
||||||
Y = np.vstack((Y1, Y2))
|
|
||||||
|
|
||||||
k1 = GPy.kern.rbf(1)
|
#construct a model
|
||||||
|
m = GPy.models.SparseGPRegression(X,Y)
|
||||||
|
m.constrain_fixed('iip_\d+_1') # don't optimize the inducing input indexes
|
||||||
|
|
||||||
m = GPy.models.SparseGPMultioutputRegression(X_list=[X1,X2],Y_list=[Y1,Y2],kernel_list=[k1],num_inducing=5)
|
if optimize:
|
||||||
m.constrain_fixed('.*rbf_var',1.)
|
m.optimize('bfgs', max_iters=100, messages=1)
|
||||||
#m.optimize(messages=1)
|
|
||||||
m.optimize_restarts(5, robust=True, messages=1, max_iters=max_iters, optimizer='bfgs')
|
if plot:
|
||||||
|
m.plot(fixed_inputs=[(1,0)])
|
||||||
|
m.plot(fixed_inputs=[(1,1)], ax=pb.gca())
|
||||||
|
|
||||||
fig, axes = pb.subplots(2,1)
|
|
||||||
m.plot_single_output(output=0,ax=axes[0],plot_limits=(-1,9))
|
|
||||||
m.plot_single_output(output=1,ax=axes[1],plot_limits=(-1,9))
|
|
||||||
axes[0].set_title('Output 0')
|
|
||||||
axes[1].set_title('Output 1')
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def epomeo_gpx(max_iters=100):
|
def epomeo_gpx(max_iters=200, optimize=True, plot=True):
|
||||||
"""Perform Gaussian process regression on the latitude and longitude data from the Mount Epomeo runs. Requires gpxpy to be installed on your system to load in the data."""
|
"""
|
||||||
|
Perform Gaussian process regression on the latitude and longitude data
|
||||||
|
from the Mount Epomeo runs. Requires gpxpy to be installed on your system
|
||||||
|
to load in the data.
|
||||||
|
"""
|
||||||
data = GPy.util.datasets.epomeo_gpx()
|
data = GPy.util.datasets.epomeo_gpx()
|
||||||
num_data_list = []
|
num_data_list = []
|
||||||
for Xpart in data['X']:
|
for Xpart in data['X']:
|
||||||
|
|
@ -119,14 +135,16 @@ def epomeo_gpx(max_iters=100):
|
||||||
m.constrain_fixed('.*rbf_var', 1.)
|
m.constrain_fixed('.*rbf_var', 1.)
|
||||||
m.constrain_fixed('iip')
|
m.constrain_fixed('iip')
|
||||||
m.constrain_bounded('noise_variance', 1e-3, 1e-1)
|
m.constrain_bounded('noise_variance', 1e-3, 1e-1)
|
||||||
# m.optimize_restarts(5, robust=True, messages=1, max_iters=max_iters, optimizer='bfgs')
|
|
||||||
m.optimize(max_iters=max_iters,messages=True)
|
m.optimize(max_iters=max_iters,messages=True)
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
def multiple_optima(gene_number=937, resolution=80, model_restarts=10, seed=10000, max_iters=300, optimize=True, plot=True):
|
||||||
def multiple_optima(gene_number=937, resolution=80, model_restarts=10, seed=10000, max_iters=300):
|
"""
|
||||||
"""Show an example of a multimodal error surface for Gaussian process regression. Gene 939 has bimodal behaviour where the noisy mode is higher."""
|
Show an example of a multimodal error surface for Gaussian process
|
||||||
|
regression. Gene 939 has bimodal behaviour where the noisy mode is
|
||||||
|
higher.
|
||||||
|
"""
|
||||||
|
|
||||||
# Contour over a range of length scales and signal/noise ratios.
|
# Contour over a range of length scales and signal/noise ratios.
|
||||||
length_scales = np.linspace(0.1, 60., resolution)
|
length_scales = np.linspace(0.1, 60., resolution)
|
||||||
|
|
@ -139,6 +157,7 @@ def multiple_optima(gene_number=937, resolution=80, model_restarts=10, seed=1000
|
||||||
data['Y'] = data['Y'] - np.mean(data['Y'])
|
data['Y'] = data['Y'] - np.mean(data['Y'])
|
||||||
|
|
||||||
lls = GPy.examples.regression._contour_data(data, length_scales, log_SNRs, GPy.kern.rbf)
|
lls = GPy.examples.regression._contour_data(data, length_scales, log_SNRs, GPy.kern.rbf)
|
||||||
|
if plot:
|
||||||
pb.contour(length_scales, log_SNRs, np.exp(lls), 20, cmap=pb.cm.jet)
|
pb.contour(length_scales, log_SNRs, np.exp(lls), 20, cmap=pb.cm.jet)
|
||||||
ax = pb.gca()
|
ax = pb.gca()
|
||||||
pb.xlabel('length scale')
|
pb.xlabel('length scale')
|
||||||
|
|
@ -162,25 +181,31 @@ def multiple_optima(gene_number=937, resolution=80, model_restarts=10, seed=1000
|
||||||
optim_point_y[0] = np.log10(m['rbf_variance']) - np.log10(m['noise_variance']);
|
optim_point_y[0] = np.log10(m['rbf_variance']) - np.log10(m['noise_variance']);
|
||||||
|
|
||||||
# optimize
|
# optimize
|
||||||
|
if optimize:
|
||||||
m.optimize('scg', xtol=1e-6, ftol=1e-6, max_iters=max_iters)
|
m.optimize('scg', xtol=1e-6, ftol=1e-6, max_iters=max_iters)
|
||||||
|
|
||||||
optim_point_x[1] = m['rbf_lengthscale']
|
optim_point_x[1] = m['rbf_lengthscale']
|
||||||
optim_point_y[1] = np.log10(m['rbf_variance']) - np.log10(m['noise_variance']);
|
optim_point_y[1] = np.log10(m['rbf_variance']) - np.log10(m['noise_variance']);
|
||||||
|
|
||||||
|
if plot:
|
||||||
pb.arrow(optim_point_x[0], optim_point_y[0], optim_point_x[1] - optim_point_x[0], optim_point_y[1] - optim_point_y[0], label=str(i), head_length=1, head_width=0.5, fc='k', ec='k')
|
pb.arrow(optim_point_x[0], optim_point_y[0], optim_point_x[1] - optim_point_x[0], optim_point_y[1] - optim_point_y[0], label=str(i), head_length=1, head_width=0.5, fc='k', ec='k')
|
||||||
models.append(m)
|
models.append(m)
|
||||||
|
|
||||||
|
if plot:
|
||||||
ax.set_xlim(xlim)
|
ax.set_xlim(xlim)
|
||||||
ax.set_ylim(ylim)
|
ax.set_ylim(ylim)
|
||||||
return m # (models, lls)
|
return m # (models, lls)
|
||||||
|
|
||||||
def _contour_data(data, length_scales, log_SNRs, kernel_call=GPy.kern.rbf):
|
def _contour_data(data, length_scales, log_SNRs, kernel_call=GPy.kern.rbf):
|
||||||
"""Evaluate the GP objective function for a given data set for a range of signal to noise ratios and a range of lengthscales.
|
"""
|
||||||
|
Evaluate the GP objective function for a given data set for a range of
|
||||||
|
signal to noise ratios and a range of lengthscales.
|
||||||
|
|
||||||
:data_set: A data set from the utils.datasets director.
|
:data_set: A data set from the utils.datasets director.
|
||||||
:length_scales: a list of length scales to explore for the contour plot.
|
:length_scales: a list of length scales to explore for the contour plot.
|
||||||
:log_SNRs: a list of base 10 logarithm signal to noise ratios to explore for the contour plot.
|
:log_SNRs: a list of base 10 logarithm signal to noise ratios to explore for the contour plot.
|
||||||
:kernel: a kernel to use for the 'signal' portion of the data."""
|
:kernel: a kernel to use for the 'signal' portion of the data.
|
||||||
|
"""
|
||||||
|
|
||||||
lls = []
|
lls = []
|
||||||
total_var = np.var(data['Y'])
|
total_var = np.var(data['Y'])
|
||||||
|
|
@ -203,74 +228,96 @@ def _contour_data(data, length_scales, log_SNRs, kernel_call=GPy.kern.rbf):
|
||||||
return np.array(lls)
|
return np.array(lls)
|
||||||
|
|
||||||
|
|
||||||
def olympic_100m_men(max_iters=100, kernel=None):
|
def olympic_100m_men(optimize=True, plot=True):
|
||||||
"""Run a standard Gaussian process regression on the Rogers and Girolami olympics data."""
|
"""Run a standard Gaussian process regression on the Rogers and Girolami olympics data."""
|
||||||
data = GPy.util.datasets.olympic_100m_men()
|
data = GPy.util.datasets.olympic_100m_men()
|
||||||
|
|
||||||
# create simple GP Model
|
# create simple GP Model
|
||||||
m = GPy.models.GPRegression(data['X'], data['Y'], kernel)
|
m = GPy.models.GPRegression(data['X'], data['Y'])
|
||||||
|
|
||||||
# set the lengthscale to be something sensible (defaults to 1)
|
# set the lengthscale to be something sensible (defaults to 1)
|
||||||
if kernel==None:
|
|
||||||
m['rbf_lengthscale'] = 10
|
m['rbf_lengthscale'] = 10
|
||||||
|
|
||||||
# optimize
|
if optimize:
|
||||||
m.optimize(max_iters=max_iters)
|
m.optimize('bfgs', max_iters=200)
|
||||||
|
|
||||||
# plot
|
if plot:
|
||||||
m.plot(plot_limits=(1850, 2050))
|
m.plot(plot_limits=(1850, 2050))
|
||||||
print(m)
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def olympic_marathon_men(max_iters=100, kernel=None):
|
def toy_rbf_1d(optimize=True, plot=True):
|
||||||
"""Run a standard Gaussian process regression on the Olympic marathon data."""
|
|
||||||
data = GPy.util.datasets.olympic_marathon_men()
|
|
||||||
|
|
||||||
# create simple GP Model
|
|
||||||
m = GPy.models.GPRegression(data['X'], data['Y'], kernel)
|
|
||||||
|
|
||||||
# set the lengthscale to be something sensible (defaults to 1)
|
|
||||||
if kernel==None:
|
|
||||||
m['rbf_lengthscale'] = 10
|
|
||||||
|
|
||||||
# optimize
|
|
||||||
m.optimize(max_iters=max_iters)
|
|
||||||
|
|
||||||
# plot
|
|
||||||
m.plot(plot_limits=(1850, 2050))
|
|
||||||
print(m)
|
|
||||||
return m
|
|
||||||
|
|
||||||
def toy_rbf_1d(optimizer='tnc', max_nb_eval_optim=100):
|
|
||||||
"""Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance."""
|
"""Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance."""
|
||||||
data = GPy.util.datasets.toy_rbf_1d()
|
data = GPy.util.datasets.toy_rbf_1d()
|
||||||
|
|
||||||
# create simple GP Model
|
# create simple GP Model
|
||||||
m = GPy.models.GPRegression(data['X'], data['Y'])
|
m = GPy.models.GPRegression(data['X'], data['Y'])
|
||||||
|
|
||||||
# optimize
|
if optimize:
|
||||||
m.optimize(optimizer, max_f_eval=max_nb_eval_optim)
|
m.optimize('bfgs')
|
||||||
# plot
|
if plot:
|
||||||
m.plot()
|
m.plot()
|
||||||
print(m)
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def toy_rbf_1d_50(max_iters=100):
|
def toy_rbf_1d_50(optimize=True, plot=True):
|
||||||
"""Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance."""
|
"""Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance."""
|
||||||
data = GPy.util.datasets.toy_rbf_1d_50()
|
data = GPy.util.datasets.toy_rbf_1d_50()
|
||||||
|
|
||||||
# create simple GP Model
|
# create simple GP Model
|
||||||
m = GPy.models.GPRegression(data['X'], data['Y'])
|
m = GPy.models.GPRegression(data['X'], data['Y'])
|
||||||
|
|
||||||
# optimize
|
if optimize:
|
||||||
m.optimize(max_iters=max_iters)
|
m.optimize('bfgs')
|
||||||
|
if plot:
|
||||||
# plot
|
|
||||||
m.plot()
|
m.plot()
|
||||||
print(m)
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def toy_ARD(max_iters=1000, kernel_type='linear', num_samples=300, D=4):
|
|
||||||
|
def toy_poisson_rbf_1d(optimize=True, plot=True):
|
||||||
|
"""Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance."""
|
||||||
|
x_len = 400
|
||||||
|
X = np.linspace(0, 10, x_len)[:, None]
|
||||||
|
f_true = np.random.multivariate_normal(np.zeros(x_len), GPy.kern.rbf(1).K(X))
|
||||||
|
Y = np.array([np.random.poisson(np.exp(f)) for f in f_true]).reshape(x_len,1)
|
||||||
|
|
||||||
|
noise_model = GPy.likelihoods.poisson()
|
||||||
|
likelihood = GPy.likelihoods.EP(Y,noise_model)
|
||||||
|
|
||||||
|
# create simple GP Model
|
||||||
|
m = GPy.models.GPRegression(X, Y, likelihood=likelihood)
|
||||||
|
|
||||||
|
if optimize:
|
||||||
|
m.optimize('bfgs')
|
||||||
|
if plot:
|
||||||
|
m.plot()
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
||||||
|
def toy_poisson_rbf_1d_laplace(optimize=True, plot=True):
|
||||||
|
"""Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance."""
|
||||||
|
optimizer='scg'
|
||||||
|
x_len = 30
|
||||||
|
X = np.linspace(0, 10, x_len)[:, None]
|
||||||
|
f_true = np.random.multivariate_normal(np.zeros(x_len), GPy.kern.rbf(1).K(X))
|
||||||
|
Y = np.array([np.random.poisson(np.exp(f)) for f in f_true])[:,None]
|
||||||
|
|
||||||
|
noise_model = GPy.likelihoods.poisson()
|
||||||
|
likelihood = GPy.likelihoods.Laplace(Y,noise_model)
|
||||||
|
|
||||||
|
# create simple GP Model
|
||||||
|
m = GPy.models.GPRegression(X, Y, likelihood=likelihood)
|
||||||
|
|
||||||
|
if optimize:
|
||||||
|
m.optimize(optimizer)
|
||||||
|
if plot:
|
||||||
|
m.plot()
|
||||||
|
# plot the real underlying rate function
|
||||||
|
pb.plot(X, np.exp(f_true), '--k', linewidth=2)
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
||||||
|
def toy_ARD(max_iters=1000, kernel_type='linear', num_samples=300, D=4, optimize=True, plot=True):
|
||||||
# Create an artificial dataset where the values in the targets (Y)
|
# Create an artificial dataset where the values in the targets (Y)
|
||||||
# only depend in dimensions 1 and 3 of the inputs (X). Run ARD to
|
# only depend in dimensions 1 and 3 of the inputs (X). Run ARD to
|
||||||
# see if this dependency can be recovered
|
# see if this dependency can be recovered
|
||||||
|
|
@ -300,13 +347,16 @@ def toy_ARD(max_iters=1000, kernel_type='linear', num_samples=300, D=4):
|
||||||
# len_prior = GPy.priors.inverse_gamma(1,18) # 1, 25
|
# len_prior = GPy.priors.inverse_gamma(1,18) # 1, 25
|
||||||
# m.set_prior('.*lengthscale',len_prior)
|
# m.set_prior('.*lengthscale',len_prior)
|
||||||
|
|
||||||
|
if optimize:
|
||||||
m.optimize(optimizer='scg', max_iters=max_iters, messages=1)
|
m.optimize(optimizer='scg', max_iters=max_iters, messages=1)
|
||||||
|
|
||||||
|
if plot:
|
||||||
m.kern.plot_ARD()
|
m.kern.plot_ARD()
|
||||||
print(m)
|
|
||||||
|
print m
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def toy_ARD_sparse(max_iters=1000, kernel_type='linear', num_samples=300, D=4):
|
def toy_ARD_sparse(max_iters=1000, kernel_type='linear', num_samples=300, D=4, optimize=True, plot=True):
|
||||||
# Create an artificial dataset where the values in the targets (Y)
|
# Create an artificial dataset where the values in the targets (Y)
|
||||||
# only depend in dimensions 1 and 3 of the inputs (X). Run ARD to
|
# only depend in dimensions 1 and 3 of the inputs (X). Run ARD to
|
||||||
# see if this dependency can be recovered
|
# see if this dependency can be recovered
|
||||||
|
|
@ -337,13 +387,16 @@ def toy_ARD_sparse(max_iters=1000, kernel_type='linear', num_samples=300, D=4):
|
||||||
# len_prior = GPy.priors.inverse_gamma(1,18) # 1, 25
|
# len_prior = GPy.priors.inverse_gamma(1,18) # 1, 25
|
||||||
# m.set_prior('.*lengthscale',len_prior)
|
# m.set_prior('.*lengthscale',len_prior)
|
||||||
|
|
||||||
|
if optimize:
|
||||||
m.optimize(optimizer='scg', max_iters=max_iters, messages=1)
|
m.optimize(optimizer='scg', max_iters=max_iters, messages=1)
|
||||||
|
|
||||||
|
if plot:
|
||||||
m.kern.plot_ARD()
|
m.kern.plot_ARD()
|
||||||
print(m)
|
|
||||||
|
print m
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def robot_wireless(max_iters=100, kernel=None):
|
def robot_wireless(max_iters=100, kernel=None, optimize=True, plot=True):
|
||||||
"""Predict the location of a robot given wirelss signal strength readings."""
|
"""Predict the location of a robot given wirelss signal strength readings."""
|
||||||
data = GPy.util.datasets.robot_wireless()
|
data = GPy.util.datasets.robot_wireless()
|
||||||
|
|
||||||
|
|
@ -351,8 +404,11 @@ def robot_wireless(max_iters=100, kernel=None):
|
||||||
m = GPy.models.GPRegression(data['Y'], data['X'], kernel=kernel)
|
m = GPy.models.GPRegression(data['Y'], data['X'], kernel=kernel)
|
||||||
|
|
||||||
# optimize
|
# optimize
|
||||||
|
if optimize:
|
||||||
m.optimize(messages=True, max_iters=max_iters)
|
m.optimize(messages=True, max_iters=max_iters)
|
||||||
|
|
||||||
Xpredict = m.predict(data['Ytest'])[0]
|
Xpredict = m.predict(data['Ytest'])[0]
|
||||||
|
if plot:
|
||||||
pb.plot(data['Xtest'][:, 0], data['Xtest'][:, 1], 'r-')
|
pb.plot(data['Xtest'][:, 0], data['Xtest'][:, 1], 'r-')
|
||||||
pb.plot(Xpredict[:, 0], Xpredict[:, 1], 'b-')
|
pb.plot(Xpredict[:, 0], Xpredict[:, 1], 'b-')
|
||||||
pb.axis('equal')
|
pb.axis('equal')
|
||||||
|
|
@ -360,11 +416,12 @@ def robot_wireless(max_iters=100, kernel=None):
|
||||||
pb.legend(('True Location', 'Predicted Location'))
|
pb.legend(('True Location', 'Predicted Location'))
|
||||||
|
|
||||||
sse = ((data['Xtest'] - Xpredict)**2).sum()
|
sse = ((data['Xtest'] - Xpredict)**2).sum()
|
||||||
print(m)
|
|
||||||
|
print m
|
||||||
print('Sum of squares error on test data: ' + str(sse))
|
print('Sum of squares error on test data: ' + str(sse))
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def silhouette(max_iters=100):
|
def silhouette(max_iters=100, optimize=True, plot=True):
|
||||||
"""Predict the pose of a figure given a silhouette. This is a task from Agarwal and Triggs 2004 ICML paper."""
|
"""Predict the pose of a figure given a silhouette. This is a task from Agarwal and Triggs 2004 ICML paper."""
|
||||||
data = GPy.util.datasets.silhouette()
|
data = GPy.util.datasets.silhouette()
|
||||||
|
|
||||||
|
|
@ -372,12 +429,13 @@ def silhouette(max_iters=100):
|
||||||
m = GPy.models.GPRegression(data['X'], data['Y'])
|
m = GPy.models.GPRegression(data['X'], data['Y'])
|
||||||
|
|
||||||
# optimize
|
# optimize
|
||||||
|
if optimize:
|
||||||
m.optimize(messages=True, max_iters=max_iters)
|
m.optimize(messages=True, max_iters=max_iters)
|
||||||
|
|
||||||
print(m)
|
print m
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def sparse_GP_regression_1D(num_samples=400, num_inducing=5, max_iters=100):
|
def sparse_GP_regression_1D(num_samples=400, num_inducing=5, max_iters=100, optimize=True, plot=True):
|
||||||
"""Run a 1D example of a sparse GP regression."""
|
"""Run a 1D example of a sparse GP regression."""
|
||||||
# sample inputs and outputs
|
# sample inputs and outputs
|
||||||
X = np.random.uniform(-3., 3., (num_samples, 1))
|
X = np.random.uniform(-3., 3., (num_samples, 1))
|
||||||
|
|
@ -386,14 +444,17 @@ def sparse_GP_regression_1D(num_samples=400, num_inducing=5, max_iters=100):
|
||||||
rbf = GPy.kern.rbf(1)
|
rbf = GPy.kern.rbf(1)
|
||||||
# create simple GP Model
|
# create simple GP Model
|
||||||
m = GPy.models.SparseGPRegression(X, Y, kernel=rbf, num_inducing=num_inducing)
|
m = GPy.models.SparseGPRegression(X, Y, kernel=rbf, num_inducing=num_inducing)
|
||||||
|
|
||||||
|
|
||||||
m.checkgrad(verbose=1)
|
m.checkgrad(verbose=1)
|
||||||
|
|
||||||
|
if optimize:
|
||||||
m.optimize('tnc', messages=1, max_iters=max_iters)
|
m.optimize('tnc', messages=1, max_iters=max_iters)
|
||||||
|
|
||||||
|
if plot:
|
||||||
m.plot()
|
m.plot()
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def sparse_GP_regression_2D(num_samples=400, num_inducing=50, max_iters=100):
|
def sparse_GP_regression_2D(num_samples=400, num_inducing=50, max_iters=100, optimize=True, plot=True):
|
||||||
"""Run a 2D example of a sparse GP regression."""
|
"""Run a 2D example of a sparse GP regression."""
|
||||||
X = np.random.uniform(-3., 3., (num_samples, 2))
|
X = np.random.uniform(-3., 3., (num_samples, 2))
|
||||||
Y = np.sin(X[:, 0:1]) * np.sin(X[:, 1:2]) + np.random.randn(num_samples, 1) * 0.05
|
Y = np.sin(X[:, 0:1]) * np.sin(X[:, 1:2]) + np.random.randn(num_samples, 1) * 0.05
|
||||||
|
|
@ -409,13 +470,18 @@ def sparse_GP_regression_2D(num_samples=400, num_inducing=50, max_iters=100):
|
||||||
|
|
||||||
m.checkgrad()
|
m.checkgrad()
|
||||||
|
|
||||||
# optimize and plot
|
# optimize
|
||||||
|
if optimize:
|
||||||
m.optimize('tnc', messages=1, max_iters=max_iters)
|
m.optimize('tnc', messages=1, max_iters=max_iters)
|
||||||
|
|
||||||
|
# plot
|
||||||
|
if plot:
|
||||||
m.plot()
|
m.plot()
|
||||||
print(m)
|
|
||||||
|
print m
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def uncertain_inputs_sparse_regression(max_iters=100):
|
def uncertain_inputs_sparse_regression(max_iters=200, optimize=True, plot=True):
|
||||||
"""Run a 1D example of a sparse GP regression with uncertain inputs."""
|
"""Run a 1D example of a sparse GP regression with uncertain inputs."""
|
||||||
fig, axes = pb.subplots(1, 2, figsize=(12, 5))
|
fig, axes = pb.subplots(1, 2, figsize=(12, 5))
|
||||||
|
|
||||||
|
|
@ -430,18 +496,23 @@ def uncertain_inputs_sparse_regression(max_iters=100):
|
||||||
|
|
||||||
# create simple GP Model - no input uncertainty on this one
|
# create simple GP Model - no input uncertainty on this one
|
||||||
m = GPy.models.SparseGPRegression(X, Y, kernel=k, Z=Z)
|
m = GPy.models.SparseGPRegression(X, Y, kernel=k, Z=Z)
|
||||||
|
|
||||||
|
if optimize:
|
||||||
m.optimize('scg', messages=1, max_iters=max_iters)
|
m.optimize('scg', messages=1, max_iters=max_iters)
|
||||||
|
|
||||||
|
if plot:
|
||||||
m.plot(ax=axes[0])
|
m.plot(ax=axes[0])
|
||||||
axes[0].set_title('no input uncertainty')
|
axes[0].set_title('no input uncertainty')
|
||||||
|
print m
|
||||||
|
|
||||||
# the same Model with uncertainty
|
# the same Model with uncertainty
|
||||||
m = GPy.models.SparseGPRegression(X, Y, kernel=k, Z=Z, X_variance=S)
|
m = GPy.models.SparseGPRegression(X, Y, kernel=k, Z=Z, X_variance=S)
|
||||||
|
if optimize:
|
||||||
m.optimize('scg', messages=1, max_iters=max_iters)
|
m.optimize('scg', messages=1, max_iters=max_iters)
|
||||||
|
if plot:
|
||||||
m.plot(ax=axes[1])
|
m.plot(ax=axes[1])
|
||||||
axes[1].set_title('with input uncertainty')
|
axes[1].set_title('with input uncertainty')
|
||||||
print(m)
|
|
||||||
|
|
||||||
fig.canvas.draw()
|
fig.canvas.draw()
|
||||||
|
|
||||||
|
print m
|
||||||
return m
|
return m
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import pylab as pb
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import GPy
|
import GPy
|
||||||
|
|
||||||
def toy_1d():
|
def toy_1d(optimize=True, plot=True):
|
||||||
N = 2000
|
N = 2000
|
||||||
M = 20
|
M = 20
|
||||||
|
|
||||||
|
|
@ -20,22 +20,18 @@ def toy_1d():
|
||||||
|
|
||||||
m.param_steplength = 1e-4
|
m.param_steplength = 1e-4
|
||||||
|
|
||||||
|
if plot:
|
||||||
fig = pb.figure()
|
fig = pb.figure()
|
||||||
ax = fig.add_subplot(111)
|
ax = fig.add_subplot(111)
|
||||||
def cb():
|
def cb(foo):
|
||||||
ax.cla()
|
ax.cla()
|
||||||
m.plot(ax=ax,Z_height=-3)
|
m.plot(ax=ax,Z_height=-3)
|
||||||
ax.set_ylim(-3,3)
|
ax.set_ylim(-3,3)
|
||||||
fig.canvas.draw()
|
fig.canvas.draw()
|
||||||
|
|
||||||
|
if optimize:
|
||||||
m.optimize(500, callback=cb, callback_interval=1)
|
m.optimize(500, callback=cb, callback_interval=1)
|
||||||
|
|
||||||
|
if plot:
|
||||||
m.plot_traces()
|
m.plot_traces()
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pb.ion()
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import GPy
|
import GPy
|
||||||
|
|
||||||
def tuto_GP_regression():
|
def tuto_GP_regression(optimize=True, plot=True):
|
||||||
"""The detailed explanations of the commands used in this file can be found in the tutorial section"""
|
"""The detailed explanations of the commands used in this file can be found in the tutorial section"""
|
||||||
|
|
||||||
X = np.random.uniform(-3.,3.,(20,1))
|
X = np.random.uniform(-3.,3.,(20,1))
|
||||||
|
|
@ -22,6 +22,7 @@ def tuto_GP_regression():
|
||||||
m = GPy.models.GPRegression(X, Y, kernel)
|
m = GPy.models.GPRegression(X, Y, kernel)
|
||||||
|
|
||||||
print m
|
print m
|
||||||
|
if plot:
|
||||||
m.plot()
|
m.plot()
|
||||||
|
|
||||||
m.constrain_positive('')
|
m.constrain_positive('')
|
||||||
|
|
@ -31,8 +32,8 @@ def tuto_GP_regression():
|
||||||
m.constrain_bounded('.*lengthscale',1.,10. )
|
m.constrain_bounded('.*lengthscale',1.,10. )
|
||||||
m.constrain_fixed('.*noise',0.0025)
|
m.constrain_fixed('.*noise',0.0025)
|
||||||
|
|
||||||
|
if optimize:
|
||||||
m.optimize()
|
m.optimize()
|
||||||
|
|
||||||
m.optimize_restarts(num_restarts = 10)
|
m.optimize_restarts(num_restarts = 10)
|
||||||
|
|
||||||
#######################################################
|
#######################################################
|
||||||
|
|
@ -51,12 +52,15 @@ def tuto_GP_regression():
|
||||||
m.constrain_positive('')
|
m.constrain_positive('')
|
||||||
|
|
||||||
# optimize and plot
|
# optimize and plot
|
||||||
|
if optimize:
|
||||||
m.optimize('tnc', max_f_eval = 1000)
|
m.optimize('tnc', max_f_eval = 1000)
|
||||||
|
if plot:
|
||||||
m.plot()
|
m.plot()
|
||||||
print(m)
|
|
||||||
|
print m
|
||||||
return(m)
|
return(m)
|
||||||
|
|
||||||
def tuto_kernel_overview():
|
def tuto_kernel_overview(optimize=True, plot=True):
|
||||||
"""The detailed explanations of the commands used in this file can be found in the tutorial section"""
|
"""The detailed explanations of the commands used in this file can be found in the tutorial section"""
|
||||||
ker1 = GPy.kern.rbf(1) # Equivalent to ker1 = GPy.kern.rbf(input_dim=1, variance=1., lengthscale=1.)
|
ker1 = GPy.kern.rbf(1) # Equivalent to ker1 = GPy.kern.rbf(input_dim=1, variance=1., lengthscale=1.)
|
||||||
ker2 = GPy.kern.rbf(input_dim=1, variance = .75, lengthscale=2.)
|
ker2 = GPy.kern.rbf(input_dim=1, variance = .75, lengthscale=2.)
|
||||||
|
|
@ -64,6 +68,7 @@ def tuto_kernel_overview():
|
||||||
|
|
||||||
print ker2
|
print ker2
|
||||||
|
|
||||||
|
if plot:
|
||||||
ker1.plot()
|
ker1.plot()
|
||||||
ker2.plot()
|
ker2.plot()
|
||||||
ker3.plot()
|
ker3.plot()
|
||||||
|
|
@ -114,6 +119,8 @@ def tuto_kernel_overview():
|
||||||
|
|
||||||
# Create GP regression model
|
# Create GP regression model
|
||||||
m = GPy.models.GPRegression(X, Y, Kanova)
|
m = GPy.models.GPRegression(X, Y, Kanova)
|
||||||
|
|
||||||
|
if plot:
|
||||||
fig = pb.figure(figsize=(5,5))
|
fig = pb.figure(figsize=(5,5))
|
||||||
ax = fig.add_subplot(111)
|
ax = fig.add_subplot(111)
|
||||||
m.plot(ax=ax)
|
m.plot(ax=ax)
|
||||||
|
|
@ -137,7 +144,7 @@ def tuto_kernel_overview():
|
||||||
return(m)
|
return(m)
|
||||||
|
|
||||||
|
|
||||||
def model_interaction():
|
def model_interaction(optimize=True, plot=True):
|
||||||
X = np.random.randn(20,1)
|
X = np.random.randn(20,1)
|
||||||
Y = np.sin(X) + np.random.randn(*X.shape)*0.01 + 5.
|
Y = np.sin(X) + np.random.randn(*X.shape)*0.01 + 5.
|
||||||
k = GPy.kern.rbf(1) + GPy.kern.bias(1)
|
k = GPy.kern.rbf(1) + GPy.kern.bias(1)
|
||||||
|
|
|
||||||
7
GPy/gpy_config.cfg
Normal file
7
GPy/gpy_config.cfg
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# This is the configuration file for GPy
|
||||||
|
|
||||||
|
[parallel]
|
||||||
|
# Enable openmp support. This speeds up some computations, depending on the number
|
||||||
|
# of cores available. Setting up a compiler with openmp support can be difficult on
|
||||||
|
# some platforms, hence this option.
|
||||||
|
openmp=False
|
||||||
|
|
@ -5,6 +5,7 @@ import numpy as np
|
||||||
from kern import kern
|
from kern import kern
|
||||||
import parts
|
import parts
|
||||||
|
|
||||||
|
|
||||||
def rbf_inv(input_dim,variance=1., inv_lengthscale=None,ARD=False):
|
def rbf_inv(input_dim,variance=1., inv_lengthscale=None,ARD=False):
|
||||||
"""
|
"""
|
||||||
Construct an RBF kernel
|
Construct an RBF kernel
|
||||||
|
|
@ -149,33 +150,6 @@ def white(input_dim,variance=1.):
|
||||||
part = parts.white.White(input_dim,variance)
|
part = parts.white.White(input_dim,variance)
|
||||||
return kern(input_dim, [part])
|
return kern(input_dim, [part])
|
||||||
|
|
||||||
def eq_ode1(output_dim, W=None, rank=1, kappa=None, length_scale=1., decay=None, delay=None):
|
|
||||||
"""Covariance function for first order differential equation driven by an exponentiated quadratic covariance.
|
|
||||||
|
|
||||||
This outputs of this kernel have the form
|
|
||||||
.. math::
|
|
||||||
\frac{\text{d}y_j}{\text{d}t} = \sum_{i=1}^R w_{j,i} f_i(t-\delta_j) +\sqrt{\kappa_j}g_j(t) - d_jy_j(t)
|
|
||||||
|
|
||||||
where :math:`R` is the rank of the system, :math:`w_{j,i}` is the sensitivity of the :math:`j`th output to the :math:`i`th latent function, :math:`d_j` is the decay rate of the :math:`j`th output and :math:`f_i(t)` and :math:`g_i(t)` are independent latent Gaussian processes goverened by an exponentiated quadratic covariance.
|
|
||||||
|
|
||||||
:param output_dim: number of outputs driven by latent function.
|
|
||||||
:type output_dim: int
|
|
||||||
:param W: sensitivities of each output to the latent driving function.
|
|
||||||
:type W: ndarray (output_dim x rank).
|
|
||||||
:param rank: If rank is greater than 1 then there are assumed to be a total of rank latent forces independently driving the system, each with identical covariance.
|
|
||||||
:type rank: int
|
|
||||||
:param decay: decay rates for the first order system.
|
|
||||||
:type decay: array of length output_dim.
|
|
||||||
:param delay: delay between latent force and output response.
|
|
||||||
:type delay: array of length output_dim.
|
|
||||||
:param kappa: diagonal term that allows each latent output to have an independent component to the response.
|
|
||||||
:type kappa: array of length output_dim.
|
|
||||||
|
|
||||||
.. Note: see first order differential equation examples in GPy.examples.regression for some usage.
|
|
||||||
"""
|
|
||||||
part = parts.eq_ode1.Eq_ode1(output_dim, W, rank, kappa, length_scale, decay, delay)
|
|
||||||
return kern(2, [part])
|
|
||||||
|
|
||||||
|
|
||||||
def exponential(input_dim,variance=1., lengthscale=None, ARD=False):
|
def exponential(input_dim,variance=1., lengthscale=None, ARD=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -292,7 +266,7 @@ except ImportError:
|
||||||
if sympy_available:
|
if sympy_available:
|
||||||
from parts.sympykern import spkern
|
from parts.sympykern import spkern
|
||||||
from sympy.parsing.sympy_parser import parse_expr
|
from sympy.parsing.sympy_parser import parse_expr
|
||||||
from GPy.util.symbolic import sinc
|
from GPy.util import symbolic
|
||||||
|
|
||||||
def rbf_sympy(input_dim, ARD=False, variance=1., lengthscale=1.):
|
def rbf_sympy(input_dim, ARD=False, variance=1., lengthscale=1.):
|
||||||
"""
|
"""
|
||||||
|
|
@ -302,8 +276,8 @@ if sympy_available:
|
||||||
Z = sp.symbols('z_:' + str(input_dim))
|
Z = sp.symbols('z_:' + str(input_dim))
|
||||||
variance = sp.var('variance',positive=True)
|
variance = sp.var('variance',positive=True)
|
||||||
if ARD:
|
if ARD:
|
||||||
lengthscales = [sp.var('lengthscale_%i' % i, positive=True) for i in range(input_dim)]
|
lengthscales = sp.symbols('lengthscale_:' + str(input_dim))
|
||||||
dist_string = ' + '.join(['(x_%i-z_%i)**2/lengthscale_%i**2' % (i, i, i) for i in range(input_dim)])
|
dist_string = ' + '.join(['(x_%i-z_%i)**2/lengthscale%i**2' % (i, i, i) for i in range(input_dim)])
|
||||||
dist = parse_expr(dist_string)
|
dist = parse_expr(dist_string)
|
||||||
f = variance*sp.exp(-dist/2.)
|
f = variance*sp.exp(-dist/2.)
|
||||||
else:
|
else:
|
||||||
|
|
@ -313,26 +287,59 @@ if sympy_available:
|
||||||
f = variance*sp.exp(-dist/(2*lengthscale**2))
|
f = variance*sp.exp(-dist/(2*lengthscale**2))
|
||||||
return kern(input_dim, [spkern(input_dim, f, name='rbf_sympy')])
|
return kern(input_dim, [spkern(input_dim, f, name='rbf_sympy')])
|
||||||
|
|
||||||
def sinc(input_dim, ARD=False, variance=1., lengthscale=1.):
|
def eq_sympy(input_dim, output_dim, ARD=False):
|
||||||
"""
|
"""
|
||||||
TODO: Not clear why this isn't working, suggests argument of sinc is not a number.
|
Latent force model covariance, exponentiated quadratic with multiple outputs. Derived from a diffusion equation with the initial spatial condition layed down by a Gaussian process with lengthscale given by shared_lengthscale.
|
||||||
sinc covariance funciton
|
|
||||||
"""
|
|
||||||
X = sp.symbols('x_:' + str(input_dim))
|
|
||||||
Z = sp.symbols('z_:' + str(input_dim))
|
|
||||||
variance = sp.var('variance',positive=True)
|
|
||||||
if ARD:
|
|
||||||
lengthscales = [sp.var('lengthscale_%i' % i, positive=True) for i in range(input_dim)]
|
|
||||||
dist_string = ' + '.join(['(x_%i-z_%i)**2/lengthscale_%i**2' % (i, i, i) for i in range(input_dim)])
|
|
||||||
dist = parse_expr(dist_string)
|
|
||||||
f = variance*sinc(sp.pi*sp.sqrt(dist))
|
|
||||||
else:
|
|
||||||
lengthscale = sp.var('lengthscale',positive=True)
|
|
||||||
dist_string = ' + '.join(['(x_%i-z_%i)**2' % (i, i) for i in range(input_dim)])
|
|
||||||
dist = parse_expr(dist_string)
|
|
||||||
f = variance*sinc(sp.pi*sp.sqrt(dist)/lengthscale)
|
|
||||||
|
|
||||||
return kern(input_dim, [spkern(input_dim, f, name='sinc')])
|
See IEEE Trans Pattern Anal Mach Intell. 2013 Nov;35(11):2693-705. doi: 10.1109/TPAMI.2013.86. Linear latent force models using Gaussian processes. Alvarez MA, Luengo D, Lawrence ND.
|
||||||
|
|
||||||
|
:param input_dim: Dimensionality of the kernel
|
||||||
|
:type input_dim: int
|
||||||
|
:param output_dim: number of outputs in the covariance function.
|
||||||
|
:type output_dim: int
|
||||||
|
:param ARD: whether or not to user ARD (default False).
|
||||||
|
:type ARD: bool
|
||||||
|
|
||||||
|
"""
|
||||||
|
real_input_dim = input_dim
|
||||||
|
if output_dim>1:
|
||||||
|
real_input_dim -= 1
|
||||||
|
X = sp.symbols('x_:' + str(real_input_dim))
|
||||||
|
Z = sp.symbols('z_:' + str(real_input_dim))
|
||||||
|
scale = sp.var('scale_i scale_j',positive=True)
|
||||||
|
if ARD:
|
||||||
|
lengthscales = [sp.var('lengthscale%i_i lengthscale%i_j' % i, positive=True) for i in range(real_input_dim)]
|
||||||
|
shared_lengthscales = [sp.var('shared_lengthscale%i' % i, positive=True) for i in range(real_input_dim)]
|
||||||
|
dist_string = ' + '.join(['(x_%i-z_%i)**2/(shared_lengthscale%i**2 + lengthscale%i_i**2 + lengthscale%i_j**2)' % (i, i, i) for i in range(real_input_dim)])
|
||||||
|
dist = parse_expr(dist_string)
|
||||||
|
f = variance*sp.exp(-dist/2.)
|
||||||
|
else:
|
||||||
|
lengthscales = sp.var('lengthscale_i lengthscale_j',positive=True)
|
||||||
|
shared_lengthscale = sp.var('shared_lengthscale',positive=True)
|
||||||
|
dist_string = ' + '.join(['(x_%i-z_%i)**2' % (i, i) for i in range(real_input_dim)])
|
||||||
|
dist = parse_expr(dist_string)
|
||||||
|
f = scale_i*scale_j*sp.exp(-dist/(2*(lengthscale_i**2 + lengthscale_j**2 + shared_lengthscale**2)))
|
||||||
|
return kern(input_dim, [spkern(input_dim, f, output_dim=output_dim, name='eq_sympy')])
|
||||||
|
|
||||||
|
def ode1_eq(output_dim=1):
|
||||||
|
"""
|
||||||
|
Latent force model covariance, first order differential
|
||||||
|
equation driven by exponentiated quadratic.
|
||||||
|
|
||||||
|
See N. D. Lawrence, G. Sanguinetti and M. Rattray. (2007)
|
||||||
|
'Modelling transcriptional regulation using Gaussian
|
||||||
|
processes' in B. Schoelkopf, J. C. Platt and T. Hofmann (eds)
|
||||||
|
Advances in Neural Information Processing Systems, MIT Press,
|
||||||
|
Cambridge, MA, pp 785--792.
|
||||||
|
|
||||||
|
:param output_dim: number of outputs in the covariance function.
|
||||||
|
:type output_dim: int
|
||||||
|
"""
|
||||||
|
input_dim = 2
|
||||||
|
x_0, z_0, decay_i, decay_j, scale_i, scale_j, lengthscale = sp.symbols('x_0, z_0, decay_i, decay_j, scale_i, scale_j, lengthscale')
|
||||||
|
f = scale_i*scale_j*(symbolic.h(x_0, z_0, decay_i, decay_j, lengthscale)
|
||||||
|
+ symbolic.h(z_0, x_0, decay_j, decay_i, lengthscale))
|
||||||
|
return kern(input_dim, [spkern(input_dim, f, output_dim=output_dim, name='ode1_eq')])
|
||||||
|
|
||||||
def sympykern(input_dim, k=None, output_dim=1, name=None, param=None):
|
def sympykern(input_dim, k=None, output_dim=1, name=None, param=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -426,9 +433,21 @@ def prod(k1,k2,tensor=False):
|
||||||
def symmetric(k):
|
def symmetric(k):
|
||||||
"""
|
"""
|
||||||
Construct a symmetric kernel from an existing kernel
|
Construct a symmetric kernel from an existing kernel
|
||||||
|
|
||||||
|
The symmetric kernel works by adding two GP functions together, and computing the overall covariance.
|
||||||
|
|
||||||
|
Let f ~ GP(x | 0, k(x, x')). Now let g = f(x) + f(-x).
|
||||||
|
|
||||||
|
It's easy to see that g is a symmetric function: g(x) = g(-x).
|
||||||
|
|
||||||
|
by construction, g, is a gaussian Process with mean 0 and covariance
|
||||||
|
|
||||||
|
k(x, x') + k(-x, x') + k(x, -x') + k(-x, -x')
|
||||||
|
|
||||||
|
This constructor builds a covariance function of this form from the initial kernel
|
||||||
"""
|
"""
|
||||||
k_ = k.copy()
|
k_ = k.copy()
|
||||||
k_.parts = [symmetric.Symmetric(p) for p in k.parts]
|
k_.parts = [parts.symmetric.Symmetric(p) for p in k.parts]
|
||||||
return k_
|
return k_
|
||||||
|
|
||||||
def coregionalize(output_dim,rank=1, W=None, kappa=None):
|
def coregionalize(output_dim,rank=1, W=None, kappa=None):
|
||||||
|
|
@ -564,3 +583,20 @@ def ODE_1(input_dim=1, varianceU=1., varianceY=1., lengthscaleU=None, lengthsc
|
||||||
"""
|
"""
|
||||||
part = parts.ODE_1.ODE_1(input_dim, varianceU, varianceY, lengthscaleU, lengthscaleY)
|
part = parts.ODE_1.ODE_1(input_dim, varianceU, varianceY, lengthscaleU, lengthscaleY)
|
||||||
return kern(input_dim, [part])
|
return kern(input_dim, [part])
|
||||||
|
|
||||||
|
def ODE_UY(input_dim=2, varianceU=1., varianceY=1., lengthscaleU=None, lengthscaleY=None):
|
||||||
|
"""
|
||||||
|
kernel resultiong from a first order ODE with OU driving GP
|
||||||
|
:param input_dim: the number of input dimension, has to be equal to one
|
||||||
|
:type input_dim: int
|
||||||
|
:param input_lengthU: the number of input U length
|
||||||
|
:param varianceU: variance of the driving GP
|
||||||
|
:type varianceU: float
|
||||||
|
:param varianceY: 'variance' of the transfer function
|
||||||
|
:type varianceY: float
|
||||||
|
:param lengthscaleY: 'lengthscale' of the transfer function
|
||||||
|
:type lengthscaleY: float
|
||||||
|
:rtype: kernel object
|
||||||
|
"""
|
||||||
|
part = parts.ODE_UY.ODE_UY(input_dim, varianceU, varianceY, lengthscaleU, lengthscaleY)
|
||||||
|
return kern(input_dim, [part])
|
||||||
|
|
|
||||||
320
GPy/kern/kern.py
320
GPy/kern/kern.py
|
|
@ -31,7 +31,7 @@ class kern(Parameterized):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.parts = parts
|
self.parts = parts
|
||||||
self.Nparts = len(parts)
|
self.num_parts = len(parts)
|
||||||
self.num_params = sum([p.num_params for p in self.parts])
|
self.num_params = sum([p.num_params for p in self.parts])
|
||||||
|
|
||||||
self.input_dim = input_dim
|
self.input_dim = input_dim
|
||||||
|
|
@ -61,7 +61,7 @@ class kern(Parameterized):
|
||||||
here just all the indices, rest can get recomputed
|
here just all the indices, rest can get recomputed
|
||||||
"""
|
"""
|
||||||
return Parameterized.getstate(self) + [self.parts,
|
return Parameterized.getstate(self) + [self.parts,
|
||||||
self.Nparts,
|
self.num_parts,
|
||||||
self.num_params,
|
self.num_params,
|
||||||
self.input_dim,
|
self.input_dim,
|
||||||
self.input_slices,
|
self.input_slices,
|
||||||
|
|
@ -73,13 +73,13 @@ class kern(Parameterized):
|
||||||
self.input_slices = state.pop()
|
self.input_slices = state.pop()
|
||||||
self.input_dim = state.pop()
|
self.input_dim = state.pop()
|
||||||
self.num_params = state.pop()
|
self.num_params = state.pop()
|
||||||
self.Nparts = state.pop()
|
self.num_parts = state.pop()
|
||||||
self.parts = state.pop()
|
self.parts = state.pop()
|
||||||
Parameterized.setstate(self, state)
|
Parameterized.setstate(self, state)
|
||||||
|
|
||||||
|
|
||||||
def plot_ARD(self, fignum=None, ax=None, title='', legend=False):
|
def plot_ARD(self, fignum=None, ax=None, title='', legend=False):
|
||||||
"""If an ARD kernel is present, it bar-plots the ARD parameters.
|
"""If an ARD kernel is present, plot a bar representation using matplotlib
|
||||||
|
|
||||||
:param fignum: figure number of the plot
|
:param fignum: figure number of the plot
|
||||||
:param ax: matplotlib axis to plot on
|
:param ax: matplotlib axis to plot on
|
||||||
|
|
@ -87,7 +87,6 @@ class kern(Parameterized):
|
||||||
title of the plot,
|
title of the plot,
|
||||||
pass '' to not print a title
|
pass '' to not print a title
|
||||||
pass None for a generic title
|
pass None for a generic title
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if ax is None:
|
if ax is None:
|
||||||
fig = pb.figure(fignum)
|
fig = pb.figure(fignum)
|
||||||
|
|
@ -152,6 +151,13 @@ class kern(Parameterized):
|
||||||
return ax
|
return ax
|
||||||
|
|
||||||
def _transform_gradients(self, g):
|
def _transform_gradients(self, g):
|
||||||
|
"""
|
||||||
|
Apply the transformations of the kernel so that the returned vector
|
||||||
|
represents the gradient in the transformed space (i.e. that given by
|
||||||
|
get_params_transformed())
|
||||||
|
|
||||||
|
:param g: the gradient vector for the current model, usually created by dK_dtheta
|
||||||
|
"""
|
||||||
x = self._get_params()
|
x = self._get_params()
|
||||||
[np.put(x, i, x * t.gradfactor(x[i])) for i, t in zip(self.constrained_indices, self.constraints)]
|
[np.put(x, i, x * t.gradfactor(x[i])) for i, t in zip(self.constrained_indices, self.constraints)]
|
||||||
[np.put(g, i, v) for i, v in [(t[0], np.sum(g[t])) for t in self.tied_indices]]
|
[np.put(g, i, v) for i, v in [(t[0], np.sum(g[t])) for t in self.tied_indices]]
|
||||||
|
|
@ -162,7 +168,9 @@ class kern(Parameterized):
|
||||||
return g
|
return g
|
||||||
|
|
||||||
def compute_param_slices(self):
|
def compute_param_slices(self):
|
||||||
"""create a set of slices that can index the parameters of each part."""
|
"""
|
||||||
|
Create a set of slices that can index the parameters of each part.
|
||||||
|
"""
|
||||||
self.param_slices = []
|
self.param_slices = []
|
||||||
count = 0
|
count = 0
|
||||||
for p in self.parts:
|
for p in self.parts:
|
||||||
|
|
@ -170,14 +178,19 @@ class kern(Parameterized):
|
||||||
count += p.num_params
|
count += p.num_params
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
"""
|
""" Overloading of the '+' operator. for more control, see self.add """
|
||||||
Shortcut for `add`.
|
|
||||||
"""
|
|
||||||
return self.add(other)
|
return self.add(other)
|
||||||
|
|
||||||
def add(self, other, tensor=False):
|
def add(self, other, tensor=False):
|
||||||
"""
|
"""
|
||||||
Add another kernel to this one. Both kernels are defined on the same _space_
|
Add another kernel to this one.
|
||||||
|
|
||||||
|
If Tensor is False, both kernels are defined on the same _space_. then
|
||||||
|
the created kernel will have the same number of inputs as self and
|
||||||
|
other (which must be the same).
|
||||||
|
|
||||||
|
If Tensor is True, then the dimensions are stacked 'horizontally', so
|
||||||
|
that the resulting kernel has self.input_dim + other.input_dim
|
||||||
|
|
||||||
:param other: the other kernel to be added
|
:param other: the other kernel to be added
|
||||||
:type other: GPy.kern
|
:type other: GPy.kern
|
||||||
|
|
@ -210,9 +223,7 @@ class kern(Parameterized):
|
||||||
return newkern
|
return newkern
|
||||||
|
|
||||||
def __mul__(self, other):
|
def __mul__(self, other):
|
||||||
"""
|
""" Here we overload the '*' operator. See self.prod for more information"""
|
||||||
Shortcut for `prod`.
|
|
||||||
"""
|
|
||||||
return self.prod(other)
|
return self.prod(other)
|
||||||
|
|
||||||
def __pow__(self, other, tensor=False):
|
def __pow__(self, other, tensor=False):
|
||||||
|
|
@ -307,8 +318,19 @@ class kern(Parameterized):
|
||||||
return sum([[name + '_' + n for n in k._get_param_names()] for name, k in zip(names, self.parts)], [])
|
return sum([[name + '_' + n for n in k._get_param_names()] for name, k in zip(names, self.parts)], [])
|
||||||
|
|
||||||
def K(self, X, X2=None, which_parts='all'):
|
def K(self, X, X2=None, which_parts='all'):
|
||||||
|
"""
|
||||||
|
Compute the kernel function.
|
||||||
|
|
||||||
|
:param X: the first set of inputs to the kernel
|
||||||
|
:param X2: (optional) the second set of arguments to the kernel. If X2
|
||||||
|
is None, this is passed throgh to the 'part' object, which
|
||||||
|
handles this as X2 == X.
|
||||||
|
:param which_parts: a list of booleans detailing whether to include
|
||||||
|
each of the part functions. By default, 'all'
|
||||||
|
indicates [True]*self.num_parts
|
||||||
|
"""
|
||||||
if which_parts == 'all':
|
if which_parts == 'all':
|
||||||
which_parts = [True] * self.Nparts
|
which_parts = [True] * self.num_parts
|
||||||
assert X.shape[1] == self.input_dim
|
assert X.shape[1] == self.input_dim
|
||||||
if X2 is None:
|
if X2 is None:
|
||||||
target = np.zeros((X.shape[0], X.shape[0]))
|
target = np.zeros((X.shape[0], X.shape[0]))
|
||||||
|
|
@ -329,6 +351,7 @@ class kern(Parameterized):
|
||||||
:param X2: Observed data inputs (optional, defaults to X)
|
:param X2: Observed data inputs (optional, defaults to X)
|
||||||
:type X2: np.ndarray (num_inducing x input_dim)
|
:type X2: np.ndarray (num_inducing x input_dim)
|
||||||
|
|
||||||
|
returns: dL_dtheta
|
||||||
"""
|
"""
|
||||||
assert X.shape[1] == self.input_dim
|
assert X.shape[1] == self.input_dim
|
||||||
target = np.zeros(self.num_params)
|
target = np.zeros(self.num_params)
|
||||||
|
|
@ -340,7 +363,7 @@ class kern(Parameterized):
|
||||||
return self._transform_gradients(target)
|
return self._transform_gradients(target)
|
||||||
|
|
||||||
def dK_dX(self, dL_dK, X, X2=None):
|
def dK_dX(self, dL_dK, X, X2=None):
|
||||||
"""Compute the gradient of the covariance function with respect to X.
|
"""Compute the gradient of the objective function with respect to X.
|
||||||
|
|
||||||
:param dL_dK: An array of gradients of the objective function with respect to the covariance function.
|
:param dL_dK: An array of gradients of the objective function with respect to the covariance function.
|
||||||
:type dL_dK: np.ndarray (num_samples x num_inducing)
|
:type dL_dK: np.ndarray (num_samples x num_inducing)
|
||||||
|
|
@ -359,7 +382,7 @@ class kern(Parameterized):
|
||||||
def Kdiag(self, X, which_parts='all'):
|
def Kdiag(self, X, which_parts='all'):
|
||||||
"""Compute the diagonal of the covariance function for inputs X."""
|
"""Compute the diagonal of the covariance function for inputs X."""
|
||||||
if which_parts == 'all':
|
if which_parts == 'all':
|
||||||
which_parts = [True] * self.Nparts
|
which_parts = [True] * self.num_parts
|
||||||
assert X.shape[1] == self.input_dim
|
assert X.shape[1] == self.input_dim
|
||||||
target = np.zeros(X.shape[0])
|
target = np.zeros(X.shape[0])
|
||||||
[p.Kdiag(X[:, i_s], target=target) for p, i_s, part_on in zip(self.parts, self.input_slices, which_parts) if part_on]
|
[p.Kdiag(X[:, i_s], target=target) for p, i_s, part_on in zip(self.parts, self.input_slices, which_parts) if part_on]
|
||||||
|
|
@ -389,6 +412,9 @@ class kern(Parameterized):
|
||||||
[p.dpsi0_dtheta(dL_dpsi0, Z[:, i_s], mu[:, i_s], S[:, i_s], target[ps]) for p, ps, i_s in zip(self.parts, self.param_slices, self.input_slices)]
|
[p.dpsi0_dtheta(dL_dpsi0, Z[:, i_s], mu[:, i_s], S[:, i_s], target[ps]) for p, ps, i_s in zip(self.parts, self.param_slices, self.input_slices)]
|
||||||
return self._transform_gradients(target)
|
return self._transform_gradients(target)
|
||||||
|
|
||||||
|
def dpsi0_dZ(self, dL_dpsi0, Z, mu, S):
|
||||||
|
return np.zeros_like(Z)
|
||||||
|
|
||||||
def dpsi0_dmuS(self, dL_dpsi0, Z, mu, S):
|
def dpsi0_dmuS(self, dL_dpsi0, Z, mu, S):
|
||||||
target_mu, target_S = np.zeros_like(mu), np.zeros_like(S)
|
target_mu, target_S = np.zeros_like(mu), np.zeros_like(S)
|
||||||
[p.dpsi0_dmuS(dL_dpsi0, Z[:, i_s], mu[:, i_s], S[:, i_s], target_mu[:, i_s], target_S[:, i_s]) for p, i_s in zip(self.parts, self.input_slices)]
|
[p.dpsi0_dmuS(dL_dpsi0, Z[:, i_s], mu[:, i_s], S[:, i_s], target_mu[:, i_s], target_S[:, i_s]) for p, i_s in zip(self.parts, self.input_slices)]
|
||||||
|
|
@ -417,87 +443,246 @@ class kern(Parameterized):
|
||||||
|
|
||||||
def psi2(self, Z, mu, S):
|
def psi2(self, Z, mu, S):
|
||||||
"""
|
"""
|
||||||
Computer the psi2 statistics for the covariance function.
|
:param Z: np.ndarray of inducing inputs (M x Q)
|
||||||
|
:param mu, S: np.ndarrays of means and variances (each N x Q)
|
||||||
:param Z: np.ndarray of inducing inputs (num_inducing x input_dim)
|
:returns psi2: np.ndarray (N,M,M)
|
||||||
:param mu, S: np.ndarrays of means and variances (each num_samples x input_dim)
|
|
||||||
:returns psi2: np.ndarray (num_samples,num_inducing,num_inducing)
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
target = np.zeros((mu.shape[0], Z.shape[0], Z.shape[0]))
|
target = np.zeros((mu.shape[0], Z.shape[0], Z.shape[0]))
|
||||||
[p.psi2(Z[:, i_s], mu[:, i_s], S[:, i_s], target) for p, i_s in zip(self.parts, self.input_slices)]
|
[p.psi2(Z[:, i_s], mu[:, i_s], S[:, i_s], target) for p, i_s in zip(self.parts, self.input_slices)]
|
||||||
|
|
||||||
# compute the "cross" terms
|
# compute the "cross" terms
|
||||||
# TODO: input_slices needed
|
# TODO: input_slices needed
|
||||||
crossterms = 0
|
from parts.white import White
|
||||||
|
from parts.rbf import RBF
|
||||||
|
from parts.rbf_inv import RBFInv
|
||||||
|
from parts.bias import Bias
|
||||||
|
from parts.linear import Linear
|
||||||
|
from parts.fixed import Fixed
|
||||||
|
|
||||||
for [p1, i_s1], [p2, i_s2] in itertools.combinations(zip(self.parts, self.input_slices), 2):
|
for (p1, i1), (p2, i2) in itertools.combinations(itertools.izip(self.parts, self.input_slices), 2):
|
||||||
if i_s1 == i_s2:
|
# white doesn;t combine with anything
|
||||||
# TODO psi1 this must be faster/better/precached/more nice
|
if isinstance(p1, White) or isinstance(p2, White):
|
||||||
tmp1 = np.zeros((mu.shape[0], Z.shape[0]))
|
pass
|
||||||
p1.psi1(Z[:, i_s1], mu[:, i_s1], S[:, i_s1], tmp1)
|
# rbf X bias
|
||||||
tmp2 = np.zeros((mu.shape[0], Z.shape[0]))
|
elif isinstance(p1, (Bias, Fixed)) and isinstance(p2, (RBF, RBFInv)):
|
||||||
p2.psi1(Z[:, i_s2], mu[:, i_s2], S[:, i_s2], tmp2)
|
target += p1.variance * (p2._psi1[:, :, None] + p2._psi1[:, None, :])
|
||||||
|
elif isinstance(p2, (Bias, Fixed)) and isinstance(p1, (RBF, RBFInv)):
|
||||||
|
target += p2.variance * (p1._psi1[:, :, None] + p1._psi1[:, None, :])
|
||||||
|
# linear X bias
|
||||||
|
elif isinstance(p1, (Bias, Fixed)) and isinstance(p2, (Linear, RBF, RBFInv)):
|
||||||
|
tmp = np.zeros((mu.shape[0], Z.shape[0]))
|
||||||
|
p2.psi1(Z, mu, S, tmp)
|
||||||
|
target += p1.variance * (tmp[:, :, None] + tmp[:, None, :])
|
||||||
|
elif isinstance(p2, (Bias, Fixed)) and isinstance(p1, (Linear, RBF, RBFInv)):
|
||||||
|
tmp = np.zeros((mu.shape[0], Z.shape[0]))
|
||||||
|
p1.psi1(Z, mu, S, tmp)
|
||||||
|
target += p2.variance * (tmp[:, :, None] + tmp[:, None, :])
|
||||||
|
# rbf X any
|
||||||
|
elif False:#isinstance(p1, (RBF, RBFInv)) or isinstance(p2, (RBF, RBFInv)):
|
||||||
|
if isinstance(p2, (RBF, RBFInv)) and not isinstance(p1, (RBF, RBFInv)):
|
||||||
|
p1t = p1; p1 = p2; p2 = p1t; del p1t
|
||||||
|
N, M = mu.shape[0], Z.shape[0]; NM=N*M
|
||||||
|
psi11 = np.zeros((N, M))
|
||||||
|
psi12 = np.zeros((NM, M))
|
||||||
|
p1.psi1(Z, mu, S, psi11)
|
||||||
|
Mu, Sigma = p1._crossterm_mu_S(Z, mu, S)
|
||||||
|
Mu, Sigma = Mu.reshape(NM,self.input_dim), Sigma.reshape(NM,self.input_dim)
|
||||||
|
|
||||||
prod = np.multiply(tmp1, tmp2)
|
p2.psi1(Z, Mu, Sigma, psi12)
|
||||||
crossterms += prod[:, :, None] + prod[:, None, :]
|
eK2 = psi12.reshape(N, M, M)
|
||||||
|
crossterms = eK2 * (psi11[:, :, None] + psi11[:, None, :])
|
||||||
# target += crossterms
|
target += crossterms
|
||||||
return target + crossterms
|
else:
|
||||||
|
raise NotImplementedError, "psi2 cannot be computed for this kernel"
|
||||||
|
return target
|
||||||
|
|
||||||
def dpsi2_dtheta(self, dL_dpsi2, Z, mu, S):
|
def dpsi2_dtheta(self, dL_dpsi2, Z, mu, S):
|
||||||
"""Gradient of the psi2 statistics with respect to the parameters."""
|
|
||||||
target = np.zeros(self.num_params)
|
target = np.zeros(self.num_params)
|
||||||
[p.dpsi2_dtheta(dL_dpsi2, Z[:, i_s], mu[:, i_s], S[:, i_s], target[ps]) for p, i_s, ps in zip(self.parts, self.input_slices, self.param_slices)]
|
[p.dpsi2_dtheta(dL_dpsi2, Z[:, i_s], mu[:, i_s], S[:, i_s], target[ps]) for p, i_s, ps in zip(self.parts, self.input_slices, self.param_slices)]
|
||||||
|
|
||||||
|
from parts.white import White
|
||||||
|
from parts.rbf import RBF
|
||||||
|
from parts.rbf_inv import RBFInv
|
||||||
|
from parts.bias import Bias
|
||||||
|
from parts.linear import Linear
|
||||||
|
from parts.fixed import Fixed
|
||||||
|
|
||||||
# compute the "cross" terms
|
# compute the "cross" terms
|
||||||
# TODO: better looping, input_slices
|
# TODO: better looping, input_slices
|
||||||
for i1, i2 in itertools.permutations(range(len(self.parts)), 2):
|
for i1, i2 in itertools.combinations(range(len(self.parts)), 2):
|
||||||
p1, p2 = self.parts[i1], self.parts[i2]
|
p1, p2 = self.parts[i1], self.parts[i2]
|
||||||
#ipsl1, ipsl2 = self.input_slices[i1], self.input_slices[i2]
|
#ipsl1, ipsl2 = self.input_slices[i1], self.input_slices[i2]
|
||||||
ps1, ps2 = self.param_slices[i1], self.param_slices[i2]
|
ps1, ps2 = self.param_slices[i1], self.param_slices[i2]
|
||||||
|
if isinstance(p1, White) or isinstance(p2, White):
|
||||||
|
pass
|
||||||
|
# rbf X bias
|
||||||
|
elif isinstance(p1, (Bias, Fixed)) and isinstance(p2, (RBF, RBFInv)):
|
||||||
|
p2.dpsi1_dtheta(dL_dpsi2.sum(1) * p1.variance * 2., Z, mu, S, target[ps2])
|
||||||
|
p1.dpsi1_dtheta(dL_dpsi2.sum(1) * p2._psi1 * 2., Z, mu, S, target[ps1])
|
||||||
|
elif isinstance(p2, (Bias, Fixed)) and isinstance(p1, (RBF, RBFInv)):
|
||||||
|
p1.dpsi1_dtheta(dL_dpsi2.sum(1) * p2.variance * 2., Z, mu, S, target[ps1])
|
||||||
|
p2.dpsi1_dtheta(dL_dpsi2.sum(1) * p1._psi1 * 2., Z, mu, S, target[ps2])
|
||||||
|
# linear X bias
|
||||||
|
elif isinstance(p1, (Bias, Fixed)) and isinstance(p2, Linear):
|
||||||
|
p2.dpsi1_dtheta(dL_dpsi2.sum(1) * p1.variance * 2., Z, mu, S, target[ps2]) # [ps1])
|
||||||
|
psi1 = np.zeros((mu.shape[0], Z.shape[0]))
|
||||||
|
p2.psi1(Z, mu, S, psi1)
|
||||||
|
p1.dpsi1_dtheta(dL_dpsi2.sum(1) * psi1 * 2., Z, mu, S, target[ps1])
|
||||||
|
elif isinstance(p2, (Bias, Fixed)) and isinstance(p1, Linear):
|
||||||
|
p1.dpsi1_dtheta(dL_dpsi2.sum(1) * p2.variance * 2., Z, mu, S, target[ps1])
|
||||||
|
psi1 = np.zeros((mu.shape[0], Z.shape[0]))
|
||||||
|
p1.psi1(Z, mu, S, psi1)
|
||||||
|
p2.dpsi1_dtheta(dL_dpsi2.sum(1) * psi1 * 2., Z, mu, S, target[ps2])
|
||||||
|
# rbf X any
|
||||||
|
elif False:#isinstance(p1, (RBF, RBFInv)) or isinstance(p2, (RBF, RBFInv)):
|
||||||
|
if isinstance(p2, (RBF, RBFInv)) and not isinstance(p1, (RBF, RBFInv)):
|
||||||
|
# turn around to have rbf in front
|
||||||
|
p1, p2 = self.parts[i2], self.parts[i1]
|
||||||
|
ps1, ps2 = self.param_slices[i2], self.param_slices[i1]
|
||||||
|
|
||||||
tmp = np.zeros((mu.shape[0], Z.shape[0]))
|
N, M = mu.shape[0], Z.shape[0]; NM=N*M
|
||||||
p1.psi1(Z, mu, S, tmp)
|
|
||||||
p2.dpsi1_dtheta((tmp[:, None, :] * dL_dpsi2).sum(1) * 2., Z, mu, S, target[ps2])
|
psi11 = np.zeros((N, M))
|
||||||
|
p1.psi1(Z, mu, S, psi11)
|
||||||
|
|
||||||
|
Mu, Sigma = p1._crossterm_mu_S(Z, mu, S)
|
||||||
|
Mu, Sigma = Mu.reshape(NM,self.input_dim), Sigma.reshape(NM,self.input_dim)
|
||||||
|
|
||||||
|
tmp1 = np.zeros_like(target[ps1])
|
||||||
|
tmp2 = np.zeros_like(target[ps2])
|
||||||
|
# for n in range(N):
|
||||||
|
# for m in range(M):
|
||||||
|
# for m_prime in range(M):
|
||||||
|
# p1.dpsi1_dtheta((dL_dpsi2[n:n+1,m:m+1,m_prime:m_prime+1]*psi12_t.reshape(N,M,M)[n:n+1,m:m+1,m_prime:m_prime+1])[0], Z[m:m+1], mu[n:n+1], S[n:n+1], tmp2)#Z[m_prime:m_prime+1], mu[n:n+1], S[n:n+1], tmp2)
|
||||||
|
# p1.dpsi1_dtheta((dL_dpsi2[n:n+1,m:m+1,m_prime:m_prime+1]*psi12_t.reshape(N,M,M)[n:n+1,m_prime:m_prime+1,m:m+1])[0], Z[m_prime:m_prime+1], mu[n:n+1], S[n:n+1], tmp2)
|
||||||
|
# Mu, Sigma= Mu.reshape(N,M,self.input_dim), Sigma.reshape(N,M,self.input_dim)
|
||||||
|
# p2.dpsi1_dtheta((dL_dpsi2[n:n+1,m:m+1,m_prime:m_prime+1]*(psi11[n:n+1,m_prime:m_prime+1]))[0], Z[m:m+1], Mu[n:n+1,m], Sigma[n:n+1,m], target[ps2])
|
||||||
|
# p2.dpsi1_dtheta((dL_dpsi2[n:n+1,m:m+1,m_prime:m_prime+1]*(psi11[n:n+1,m:m+1]))[0], Z[m_prime:m_prime+1], Mu[n:n+1, m_prime], Sigma[n:n+1, m_prime], target[ps2])#Z[m_prime:m_prime+1], Mu[n+m:(n+m)+1], Sigma[n+m:(n+m)+1], target[ps2])
|
||||||
|
|
||||||
|
if isinstance(p1, RBF) and isinstance(p2, RBF):
|
||||||
|
psi12 = np.zeros((N, M))
|
||||||
|
p2.psi1(Z, mu, S, psi12)
|
||||||
|
Mu2, Sigma2 = p2._crossterm_mu_S(Z, mu, S)
|
||||||
|
Mu2, Sigma2 = Mu2.reshape(NM,self.input_dim), Sigma2.reshape(NM,self.input_dim)
|
||||||
|
p1.dpsi1_dtheta((dL_dpsi2*(psi12[:,:,None] + psi12[:,None,:])).reshape(NM,M), Z, Mu2, Sigma2, tmp1)
|
||||||
|
pass
|
||||||
|
|
||||||
|
if isinstance(p1, RBF) and isinstance(p2, Linear):
|
||||||
|
#import ipdb;ipdb.set_trace()
|
||||||
|
pass
|
||||||
|
|
||||||
|
p2.dpsi1_dtheta((dL_dpsi2*(psi11[:,:,None] + psi11[:,None,:])).reshape(NM,M), Z, Mu, Sigma, tmp2)
|
||||||
|
|
||||||
|
target[ps1] += tmp1
|
||||||
|
target[ps2] += tmp2
|
||||||
|
else:
|
||||||
|
raise NotImplementedError, "psi2 cannot be computed for this kernel"
|
||||||
|
|
||||||
return self._transform_gradients(target)
|
return self._transform_gradients(target)
|
||||||
|
|
||||||
def dpsi2_dZ(self, dL_dpsi2, Z, mu, S):
|
def dpsi2_dZ(self, dL_dpsi2, Z, mu, S):
|
||||||
target = np.zeros_like(Z)
|
target = np.zeros_like(Z)
|
||||||
[p.dpsi2_dZ(dL_dpsi2, Z[:, i_s], mu[:, i_s], S[:, i_s], target[:, i_s]) for p, i_s in zip(self.parts, self.input_slices)]
|
[p.dpsi2_dZ(dL_dpsi2, Z[:, i_s], mu[:, i_s], S[:, i_s], target[:, i_s]) for p, i_s in zip(self.parts, self.input_slices)]
|
||||||
# target *= 2
|
|
||||||
|
from parts.white import White
|
||||||
|
from parts.rbf import RBF
|
||||||
|
from parts.rbf_inv import RBFInv
|
||||||
|
from parts.bias import Bias
|
||||||
|
from parts.linear import Linear
|
||||||
|
from parts.fixed import Fixed
|
||||||
|
|
||||||
# compute the "cross" terms
|
# compute the "cross" terms
|
||||||
# TODO: we need input_slices here.
|
# TODO: better looping, input_slices
|
||||||
for p1, p2 in itertools.permutations(self.parts, 2):
|
for p1, p2 in itertools.combinations(self.parts, 2):
|
||||||
if p1.name == 'linear' and p2.name == 'linear':
|
if isinstance(p1, White) or isinstance(p2, White):
|
||||||
raise NotImplementedError("We don't handle linear/linear cross-terms")
|
pass
|
||||||
tmp = np.zeros((mu.shape[0], Z.shape[0]))
|
# rbf X bias
|
||||||
p1.psi1(Z, mu, S, tmp)
|
elif isinstance(p1, (Bias, Fixed)) and isinstance(p2, (RBF, RBFInv)):
|
||||||
p2.dpsi1_dZ((tmp[:, None, :] * dL_dpsi2).sum(1), Z, mu, S, target)
|
p2.dpsi1_dZ(dL_dpsi2.sum(1) * p1.variance, Z, mu, S, target)
|
||||||
|
elif isinstance(p2, (Bias, Fixed)) and isinstance(p1, (RBF, RBFInv)):
|
||||||
|
p1.dpsi1_dZ(dL_dpsi2.sum(1) * p2.variance, Z, mu, S, target)
|
||||||
|
# linear X bias
|
||||||
|
elif isinstance(p1, (Bias, Fixed)) and isinstance(p2, Linear):
|
||||||
|
p2.dpsi1_dZ(dL_dpsi2.sum(1) * p1.variance, Z, mu, S, target)
|
||||||
|
elif isinstance(p2, (Bias, Fixed)) and isinstance(p1, Linear):
|
||||||
|
p1.dpsi1_dZ(dL_dpsi2.sum(1) * p2.variance, Z, mu, S, target)
|
||||||
|
# rbf X any
|
||||||
|
elif False:#isinstance(p1, (RBF, RBFInv)) or isinstance(p2, (RBF, RBFInv)):
|
||||||
|
if isinstance(p2, (RBF, RBFInv)) and not isinstance(p1, (RBF, RBFInv)):
|
||||||
|
p1t = p1; p1 = p2; p2 = p1t; del p1t
|
||||||
|
N, M = mu.shape[0], Z.shape[0]; NM=N*M
|
||||||
|
psi11 = np.zeros((N, M))
|
||||||
|
psi12 = np.zeros((NM, M))
|
||||||
|
#psi12_t = np.zeros((N,M))
|
||||||
|
|
||||||
|
p1.psi1(Z, mu, S, psi11)
|
||||||
|
Mu, Sigma = p1._crossterm_mu_S(Z, mu, S)
|
||||||
|
Mu, Sigma = Mu.reshape(NM,self.input_dim), Sigma.reshape(NM,self.input_dim)
|
||||||
|
|
||||||
|
p2.psi1(Z, Mu, Sigma, psi12)
|
||||||
|
tmp1 = np.zeros_like(target)
|
||||||
|
p1.dpsi1_dZ((dL_dpsi2*psi12.reshape(N,M,M)).sum(1), Z, mu, S, tmp1)
|
||||||
|
p1.dpsi1_dZ((dL_dpsi2*psi12.reshape(N,M,M)).sum(2), Z, mu, S, tmp1)
|
||||||
|
target += tmp1
|
||||||
|
|
||||||
|
#p2.dpsi1_dtheta((dL_dpsi2*(psi11[:,:,None] + psi11[:,None,:])).reshape(NM,M), Z, Mu, Sigma, target)
|
||||||
|
p2.dpsi1_dZ((dL_dpsi2*(psi11[:,:,None] + psi11[:,None,:])).reshape(NM,M), Z, Mu, Sigma, target)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError, "psi2 cannot be computed for this kernel"
|
||||||
return target * 2
|
return target * 2
|
||||||
|
|
||||||
def dpsi2_dmuS(self, dL_dpsi2, Z, mu, S):
|
def dpsi2_dmuS(self, dL_dpsi2, Z, mu, S):
|
||||||
target_mu, target_S = np.zeros((2, mu.shape[0], mu.shape[1]))
|
target_mu, target_S = np.zeros((2, mu.shape[0], mu.shape[1]))
|
||||||
[p.dpsi2_dmuS(dL_dpsi2, Z[:, i_s], mu[:, i_s], S[:, i_s], target_mu[:, i_s], target_S[:, i_s]) for p, i_s in zip(self.parts, self.input_slices)]
|
[p.dpsi2_dmuS(dL_dpsi2, Z[:, i_s], mu[:, i_s], S[:, i_s], target_mu[:, i_s], target_S[:, i_s]) for p, i_s in zip(self.parts, self.input_slices)]
|
||||||
|
|
||||||
|
from parts.white import White
|
||||||
|
from parts.rbf import RBF
|
||||||
|
from parts.rbf_inv import RBFInv
|
||||||
|
from parts.bias import Bias
|
||||||
|
from parts.linear import Linear
|
||||||
|
from parts.fixed import Fixed
|
||||||
|
|
||||||
# compute the "cross" terms
|
# compute the "cross" terms
|
||||||
# TODO: we need input_slices here.
|
# TODO: better looping, input_slices
|
||||||
for p1, p2 in itertools.permutations(self.parts, 2):
|
for p1, p2 in itertools.combinations(self.parts, 2):
|
||||||
if p1.name == 'linear' and p2.name == 'linear':
|
if isinstance(p1, White) or isinstance(p2, White):
|
||||||
raise NotImplementedError("We don't handle linear/linear cross-terms")
|
pass
|
||||||
|
# rbf X bias
|
||||||
|
elif isinstance(p1, (Bias, Fixed)) and isinstance(p2, (RBF, RBFInv)):
|
||||||
|
p2.dpsi1_dmuS(dL_dpsi2.sum(1) * p1.variance * 2., Z, mu, S, target_mu, target_S)
|
||||||
|
elif isinstance(p2, (Bias, Fixed)) and isinstance(p1, (RBF, RBFInv)):
|
||||||
|
p1.dpsi1_dmuS(dL_dpsi2.sum(1) * p2.variance * 2., Z, mu, S, target_mu, target_S)
|
||||||
|
# linear X bias
|
||||||
|
elif isinstance(p1, (Bias, Fixed)) and isinstance(p2, Linear):
|
||||||
|
p2.dpsi1_dmuS(dL_dpsi2.sum(1) * p1.variance * 2., Z, mu, S, target_mu, target_S)
|
||||||
|
elif isinstance(p2, (Bias, Fixed)) and isinstance(p1, Linear):
|
||||||
|
p1.dpsi1_dmuS(dL_dpsi2.sum(1) * p2.variance * 2., Z, mu, S, target_mu, target_S)
|
||||||
|
# rbf X any
|
||||||
|
elif False:#isinstance(p1, (RBF, RBFInv)) or isinstance(p2, (RBF, RBFInv)):
|
||||||
|
if isinstance(p2, (RBF, RBFInv)) and not isinstance(p1, (RBF, RBFInv)):
|
||||||
|
p1t = p1; p1 = p2; p2 = p1t; del p1t
|
||||||
|
N, M = mu.shape[0], Z.shape[0]; NM=N*M
|
||||||
|
psi11 = np.zeros((N, M))
|
||||||
|
psi12 = np.zeros((NM, M))
|
||||||
|
#psi12_t = np.zeros((N,M))
|
||||||
|
|
||||||
tmp = np.zeros((mu.shape[0], Z.shape[0]))
|
p1.psi1(Z, mu, S, psi11)
|
||||||
p1.psi1(Z, mu, S, tmp)
|
Mu, Sigma = p1._crossterm_mu_S(Z, mu, S)
|
||||||
p2.dpsi1_dmuS((tmp[:, None, :] * dL_dpsi2).sum(1) * 2., Z, mu, S, target_mu, target_S)
|
Mu, Sigma = Mu.reshape(NM,self.input_dim), Sigma.reshape(NM,self.input_dim)
|
||||||
|
|
||||||
|
p2.psi1(Z, Mu, Sigma, psi12)
|
||||||
|
p1.dpsi1_dmuS((dL_dpsi2*psi12.reshape(N,M,M)).sum(1), Z, mu, S, target_mu, target_S)
|
||||||
|
p1.dpsi1_dmuS((dL_dpsi2*psi12.reshape(N,M,M)).sum(2), Z, mu, S, target_mu, target_S)
|
||||||
|
|
||||||
|
#p2.dpsi1_dtheta((dL_dpsi2*(psi11[:,:,None] + psi11[:,None,:])).reshape(NM,M), Z, Mu, Sigma, target)
|
||||||
|
p2.dpsi1_dmuS((dL_dpsi2*(psi11[:,:,None])).sum(1)*2, Z, Mu.reshape(N,M,self.input_dim).sum(1), Sigma.reshape(N,M,self.input_dim).sum(1), target_mu, target_S)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError, "psi2 cannot be computed for this kernel"
|
||||||
return target_mu, target_S
|
return target_mu, target_S
|
||||||
|
|
||||||
def plot(self, x=None, plot_limits=None, which_parts='all', resolution=None, *args, **kwargs):
|
def plot(self, x=None, plot_limits=None, which_parts='all', resolution=None, *args, **kwargs):
|
||||||
if which_parts == 'all':
|
if which_parts == 'all':
|
||||||
which_parts = [True] * self.Nparts
|
which_parts = [True] * self.num_parts
|
||||||
if self.input_dim == 1:
|
if self.input_dim == 1:
|
||||||
if x is None:
|
if x is None:
|
||||||
x = np.zeros((1, 1))
|
x = np.zeros((1, 1))
|
||||||
|
|
@ -551,17 +736,18 @@ class kern(Parameterized):
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError, "Cannot plot a kernel with more than two input dimensions"
|
raise NotImplementedError, "Cannot plot a kernel with more than two input dimensions"
|
||||||
|
|
||||||
from GPy.core.model import Model
|
from ..core.model import Model
|
||||||
|
|
||||||
class Kern_check_model(Model):
|
class Kern_check_model(Model):
|
||||||
"""This is a dummy model class used as a base class for checking that the gradients of a given kernel are implemented correctly. It enables checkgradient() to be called independently on a kernel."""
|
"""This is a dummy model class used as a base class for checking that the gradients of a given kernel are implemented correctly. It enables checkgradient() to be called independently on a kernel."""
|
||||||
def __init__(self, kernel=None, dL_dK=None, X=None, X2=None):
|
def __init__(self, kernel=None, dL_dK=None, X=None, X2=None):
|
||||||
num_samples = 20
|
num_samples = 20
|
||||||
num_samples2 = 10
|
num_samples2 = 10
|
||||||
if kernel==None:
|
if kernel==None:
|
||||||
|
import GPy
|
||||||
kernel = GPy.kern.rbf(1)
|
kernel = GPy.kern.rbf(1)
|
||||||
|
del GPy
|
||||||
if X==None:
|
if X==None:
|
||||||
X = np.random.randn(num_samples, kernel.input_dim)
|
X = np.random.normal(size=(num_samples, kernel.input_dim))
|
||||||
if dL_dK==None:
|
if dL_dK==None:
|
||||||
if X2==None:
|
if X2==None:
|
||||||
dL_dK = np.ones((X.shape[0], X.shape[0]))
|
dL_dK = np.ones((X.shape[0], X.shape[0]))
|
||||||
|
|
@ -574,7 +760,7 @@ class Kern_check_model(Model):
|
||||||
self.dL_dK = dL_dK
|
self.dL_dK = dL_dK
|
||||||
#self.constrained_indices=[]
|
#self.constrained_indices=[]
|
||||||
#self.constraints=[]
|
#self.constraints=[]
|
||||||
Model.__init__(self)
|
super(Kern_check_model, self).__init__()
|
||||||
|
|
||||||
def is_positive_definite(self):
|
def is_positive_definite(self):
|
||||||
v = np.linalg.eig(self.kernel.K(self.X))[0]
|
v = np.linalg.eig(self.kernel.K(self.X))[0]
|
||||||
|
|
@ -658,7 +844,7 @@ class Kern_check_dKdiag_dX(Kern_check_model):
|
||||||
def _set_params(self, x):
|
def _set_params(self, x):
|
||||||
self.X=x.reshape(self.X.shape)
|
self.X=x.reshape(self.X.shape)
|
||||||
|
|
||||||
def kern_test(kern, X=None, X2=None, verbose=False):
|
def kern_test(kern, X=None, X2=None, output_ind=None, verbose=False, X_positive=False):
|
||||||
"""This function runs on kernels to check the correctness of their implementation. It checks that the covariance function is positive definite for a randomly generated data set.
|
"""This function runs on kernels to check the correctness of their implementation. It checks that the covariance function is positive definite for a randomly generated data set.
|
||||||
|
|
||||||
:param kern: the kernel to be tested.
|
:param kern: the kernel to be tested.
|
||||||
|
|
@ -672,8 +858,19 @@ def kern_test(kern, X=None, X2=None, verbose=False):
|
||||||
pass_checks = True
|
pass_checks = True
|
||||||
if X==None:
|
if X==None:
|
||||||
X = np.random.randn(10, kern.input_dim)
|
X = np.random.randn(10, kern.input_dim)
|
||||||
|
if X_positive:
|
||||||
|
X = abs(X)
|
||||||
|
if output_ind is not None:
|
||||||
|
assert(output_ind<kern.input_dim)
|
||||||
|
X[:, output_ind] = np.random.randint(low=0,high=kern.parts[0].output_dim, size=X.shape[0])
|
||||||
if X2==None:
|
if X2==None:
|
||||||
X2 = np.random.randn(20, kern.input_dim)
|
X2 = np.random.randn(20, kern.input_dim)
|
||||||
|
if X_positive:
|
||||||
|
X2 = abs(X2)
|
||||||
|
if output_ind is not None:
|
||||||
|
assert(output_ind<kern.input_dim)
|
||||||
|
X2[:, output_ind] = np.random.randint(low=0, high=kern.parts[0].output_dim, size=X2.shape[0])
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print("Checking covariance function is positive definite.")
|
print("Checking covariance function is positive definite.")
|
||||||
result = Kern_check_model(kern, X=X).is_positive_definite()
|
result = Kern_check_model(kern, X=X).is_positive_definite()
|
||||||
|
|
@ -766,3 +963,4 @@ def kern_test(kern, X=None, X2=None, verbose=False):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return pass_checks
|
return pass_checks
|
||||||
|
del Model
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,10 @@ class ODE_1(Kernpart):
|
||||||
k3 = np.exp(-lu*dist) * ( (1+lu*dist)/(lu+ly) + (lu)/(lu+ly)**2 )
|
k3 = np.exp(-lu*dist) * ( (1+lu*dist)/(lu+ly) + (lu)/(lu+ly)**2 )
|
||||||
dkdvar = k1+k2+k3
|
dkdvar = k1+k2+k3
|
||||||
|
|
||||||
|
#target[0] dk dvarU
|
||||||
|
#target[1] dk dvarY
|
||||||
|
#target[2] dk d theta1
|
||||||
|
#target[3] dk d theta2
|
||||||
target[0] += np.sum(self.varianceY*dkdvar * dL_dK)
|
target[0] += np.sum(self.varianceY*dkdvar * dL_dK)
|
||||||
target[1] += np.sum(self.varianceU*dkdvar * dL_dK)
|
target[1] += np.sum(self.varianceU*dkdvar * dL_dK)
|
||||||
target[2] += np.sum(dktheta1*(-np.sqrt(3)*self.lengthscaleU**(-2)) * dL_dK)
|
target[2] += np.sum(dktheta1*(-np.sqrt(3)*self.lengthscaleU**(-2)) * dL_dK)
|
||||||
|
|
|
||||||
281
GPy/kern/parts/ODE_UY.py
Normal file
281
GPy/kern/parts/ODE_UY.py
Normal file
|
|
@ -0,0 +1,281 @@
|
||||||
|
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||||
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
|
||||||
|
|
||||||
|
from kernpart import Kernpart
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def index_to_slices(index):
|
||||||
|
"""
|
||||||
|
take a numpy array of integers (index) and return a nested list of slices such that the slices describe the start, stop points for each integer in the index.
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
>>> index = np.asarray([0,0,0,1,1,1,2,2,2])
|
||||||
|
returns
|
||||||
|
>>> [[slice(0,3,None)],[slice(3,6,None)],[slice(6,9,None)]]
|
||||||
|
|
||||||
|
or, a more complicated example
|
||||||
|
>>> index = np.asarray([0,0,1,1,0,2,2,2,1,1])
|
||||||
|
returns
|
||||||
|
>>> [[slice(0,2,None),slice(4,5,None)],[slice(2,4,None),slice(8,10,None)],[slice(5,8,None)]]
|
||||||
|
"""
|
||||||
|
|
||||||
|
#contruct the return structure
|
||||||
|
ind = np.asarray(index,dtype=np.int64)
|
||||||
|
ret = [[] for i in range(ind.max()+1)]
|
||||||
|
|
||||||
|
#find the switchpoints
|
||||||
|
ind_ = np.hstack((ind,ind[0]+ind[-1]+1))
|
||||||
|
switchpoints = np.nonzero(ind_ - np.roll(ind_,+1))[0]
|
||||||
|
|
||||||
|
[ret[ind_i].append(slice(*indexes_i)) for ind_i,indexes_i in zip(ind[switchpoints[:-1]],zip(switchpoints,switchpoints[1:]))]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
class ODE_UY(Kernpart):
|
||||||
|
"""
|
||||||
|
kernel resultiong from a first order ODE with OU driving GP
|
||||||
|
|
||||||
|
:param input_dim: the number of input dimension, has to be equal to one
|
||||||
|
:type input_dim: int
|
||||||
|
:param input_lengthU: the number of input U length
|
||||||
|
:type input_dim: int
|
||||||
|
:param varianceU: variance of the driving GP
|
||||||
|
:type varianceU: float
|
||||||
|
:param lengthscaleU: lengthscale of the driving GP (sqrt(3)/lengthscaleU)
|
||||||
|
:type lengthscaleU: float
|
||||||
|
:param varianceY: 'variance' of the transfer function
|
||||||
|
:type varianceY: float
|
||||||
|
:param lengthscaleY: 'lengthscale' of the transfer function (1/lengthscaleY)
|
||||||
|
:type lengthscaleY: float
|
||||||
|
:rtype: kernel object
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, input_dim=2,varianceU=1., varianceY=1., lengthscaleU=None, lengthscaleY=None):
|
||||||
|
assert input_dim==2, "Only defined for input_dim = 1"
|
||||||
|
self.input_dim = input_dim
|
||||||
|
self.num_params = 4
|
||||||
|
self.name = 'ODE_UY'
|
||||||
|
|
||||||
|
|
||||||
|
if lengthscaleU is not None:
|
||||||
|
lengthscaleU = np.asarray(lengthscaleU)
|
||||||
|
assert lengthscaleU.size == 1, "lengthscaleU should be one dimensional"
|
||||||
|
else:
|
||||||
|
lengthscaleU = np.ones(1)
|
||||||
|
if lengthscaleY is not None:
|
||||||
|
lengthscaleY = np.asarray(lengthscaleY)
|
||||||
|
assert lengthscaleY.size == 1, "lengthscaleY should be one dimensional"
|
||||||
|
else:
|
||||||
|
lengthscaleY = np.ones(1)
|
||||||
|
#lengthscaleY = 0.5
|
||||||
|
self._set_params(np.hstack((varianceU, varianceY, lengthscaleU,lengthscaleY)))
|
||||||
|
|
||||||
|
def _get_params(self):
|
||||||
|
"""return the value of the parameters."""
|
||||||
|
return np.hstack((self.varianceU,self.varianceY, self.lengthscaleU,self.lengthscaleY))
|
||||||
|
|
||||||
|
def _set_params(self, x):
|
||||||
|
"""set the value of the parameters."""
|
||||||
|
assert x.size == self.num_params
|
||||||
|
|
||||||
|
self.varianceU = x[0]
|
||||||
|
self.varianceY = x[1]
|
||||||
|
self.lengthscaleU = x[2]
|
||||||
|
self.lengthscaleY = x[3]
|
||||||
|
|
||||||
|
|
||||||
|
def _get_param_names(self):
|
||||||
|
"""return parameter names."""
|
||||||
|
return ['varianceU','varianceY', 'lengthscaleU', 'lengthscaleY']
|
||||||
|
|
||||||
|
|
||||||
|
def K(self, X, X2, target):
|
||||||
|
"""Compute the covariance matrix between X and X2."""
|
||||||
|
# model : a * dy/dt + b * y = U
|
||||||
|
#lu=sqrt(3)/theta1 ly=1/theta2 theta2= a/b :thetay sigma2=1/(2ab) :sigmay
|
||||||
|
|
||||||
|
X,slices = X[:,:-1],index_to_slices(X[:,-1])
|
||||||
|
if X2 is None:
|
||||||
|
X2,slices2 = X,slices
|
||||||
|
else:
|
||||||
|
X2,slices2 = X2[:,:-1],index_to_slices(X2[:,-1])
|
||||||
|
|
||||||
|
|
||||||
|
#rdist = X[:,0][:,None] - X2[:,0][:,None].T
|
||||||
|
rdist = X - X2.T
|
||||||
|
ly=1/self.lengthscaleY
|
||||||
|
lu=np.sqrt(3)/self.lengthscaleU
|
||||||
|
#iu=self.input_lengthU #dimention of U
|
||||||
|
|
||||||
|
Vu=self.varianceU
|
||||||
|
Vy=self.varianceY
|
||||||
|
|
||||||
|
kuu = lambda dist:Vu * (1 + lu* np.abs(dist)) * np.exp(-lu * np.abs(dist))
|
||||||
|
|
||||||
|
k1 = lambda dist:np.exp(-ly*np.abs(dist))*(2*lu+ly)/(lu+ly)**2
|
||||||
|
k2 = lambda dist:(np.exp(-lu*dist)*(ly-2*lu+lu*ly*dist-lu**2*dist) + np.exp(-ly*dist)*(2*lu-ly) ) / (ly-lu)**2
|
||||||
|
k3 = lambda dist:np.exp(-lu*dist) * ( (1+lu*dist)/(lu+ly) + (lu)/(lu+ly)**2 )
|
||||||
|
kyy = lambda dist:Vu*Vy*(k1(dist) + k2(dist) + k3(dist))
|
||||||
|
|
||||||
|
kyu3 = lambda dist:np.exp(-lu*dist)/(lu+ly)*(1+lu*(dist+1/(lu+ly)))
|
||||||
|
kyup = lambda dist:Vu*Vy*(k1(dist)+k2(dist)) #t>0 kyu
|
||||||
|
kyun = lambda dist:Vu*Vy*(kyu3(dist)) #t<0 kyu
|
||||||
|
|
||||||
|
kuyp = lambda dist:Vu*Vy*(kyu3(dist)) #t>0 kuy
|
||||||
|
kuyn = lambda dist:Vu*Vy*(k1(dist)+k2(dist)) #t<0 kuy
|
||||||
|
|
||||||
|
for i, s1 in enumerate(slices):
|
||||||
|
for j, s2 in enumerate(slices2):
|
||||||
|
for ss1 in s1:
|
||||||
|
for ss2 in s2:
|
||||||
|
if i==0 and j==0:
|
||||||
|
target[ss1,ss2] = kuu(np.abs(rdist[ss1,ss2]))
|
||||||
|
elif i==0 and j==1:
|
||||||
|
target[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kuyp(np.abs(rdist[ss1,ss2])), kuyn(np.abs(rdist[s1[0],s2[0]]) ) )
|
||||||
|
elif i==1 and j==1:
|
||||||
|
target[ss1,ss2] = kyy(np.abs(rdist[ss1,ss2]))
|
||||||
|
else:
|
||||||
|
target[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kyup(np.abs(rdist[ss1,ss2])), kyun(np.abs(rdist[s1[0],s2[0]]) ) )
|
||||||
|
|
||||||
|
|
||||||
|
#KUU = kuu(np.abs(rdist[:iu,:iu]))
|
||||||
|
|
||||||
|
#KYY = kyy(np.abs(rdist[iu:,iu:]))
|
||||||
|
|
||||||
|
#KYU = np.where(rdist[iu:,:iu]>0,kyup(np.abs(rdist[iu:,:iu])),kyun(np.abs(rdist[iu:,:iu]) ))
|
||||||
|
|
||||||
|
#KUY = np.where(rdist[:iu,iu:]>0,kuyp(np.abs(rdist[:iu,iu:])),kuyn(np.abs(rdist[:iu,iu:]) ))
|
||||||
|
|
||||||
|
#ker=np.vstack((np.hstack([KUU,KUY]),np.hstack([KYU,KYY])))
|
||||||
|
|
||||||
|
#np.add(ker, target, target)
|
||||||
|
|
||||||
|
def Kdiag(self, X, target):
|
||||||
|
"""Compute the diagonal of the covariance matrix associated to X."""
|
||||||
|
ly=1/self.lengthscaleY
|
||||||
|
lu=np.sqrt(3)/self.lengthscaleU
|
||||||
|
#ly=self.lengthscaleY
|
||||||
|
#lu=self.lengthscaleU
|
||||||
|
|
||||||
|
k1 = (2*lu+ly)/(lu+ly)**2
|
||||||
|
k2 = (ly-2*lu + 2*lu-ly ) / (ly-lu)**2
|
||||||
|
k3 = 1/(lu+ly) + (lu)/(lu+ly)**2
|
||||||
|
|
||||||
|
slices = index_to_slices(X[:,-1])
|
||||||
|
|
||||||
|
for i, ss1 in enumerate(slices):
|
||||||
|
for s1 in ss1:
|
||||||
|
if i==0:
|
||||||
|
target[s1]+= self.varianceU
|
||||||
|
elif i==1:
|
||||||
|
target[s1]+= self.varianceU*self.varianceY*(k1+k2+k3)
|
||||||
|
else:
|
||||||
|
raise ValueError, "invalid input/output index"
|
||||||
|
|
||||||
|
#target[slices[0][0]]+= self.varianceU #matern32 diag
|
||||||
|
#target[slices[1][0]]+= self.varianceU*self.varianceY*(k1+k2+k3) # diag
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def dK_dtheta(self, dL_dK, X, X2, target):
|
||||||
|
"""derivative of the covariance matrix with respect to the parameters."""
|
||||||
|
if X2 is None: X2 = X
|
||||||
|
dist = np.abs(X - X2.T)
|
||||||
|
|
||||||
|
X,slices = X[:,:-1],index_to_slices(X[:,-1])
|
||||||
|
if X2 is None:
|
||||||
|
X2,slices2 = X,slices
|
||||||
|
else:
|
||||||
|
X2,slices2 = X2[:,:-1],index_to_slices(X2[:,-1])
|
||||||
|
|
||||||
|
|
||||||
|
ly=1/self.lengthscaleY
|
||||||
|
lu=np.sqrt(3)/self.lengthscaleU
|
||||||
|
#ly=self.lengthscaleY
|
||||||
|
#lu=self.lengthscaleU
|
||||||
|
|
||||||
|
dk1theta1 = lambda dist: np.exp(-ly*dist)*2*(-lu)/(lu+ly)**3
|
||||||
|
#c=np.sqrt(3)
|
||||||
|
#t1=c/lu
|
||||||
|
#t2=1/ly
|
||||||
|
#dk1theta1=np.exp(-dist*ly)*t2*( (2*c*t2+2*t1)/(c*t2+t1)**2 -2*(2*c*t2*t1+t1**2)/(c*t2+t1)**3 )
|
||||||
|
|
||||||
|
dk2theta1 = lambda dist: 1*(
|
||||||
|
np.exp(-lu*dist)*dist*(-ly+2*lu-lu*ly*dist+dist*lu**2)*(ly-lu)**(-2) + np.exp(-lu*dist)*(-2+ly*dist-2*dist*lu)*(ly-lu)**(-2)
|
||||||
|
+np.exp(-dist*lu)*(ly-2*lu+ly*lu*dist-dist*lu**2)*2*(ly-lu)**(-3)
|
||||||
|
+np.exp(-dist*ly)*2*(ly-lu)**(-2)
|
||||||
|
+np.exp(-dist*ly)*2*(2*lu-ly)*(ly-lu)**(-3)
|
||||||
|
)
|
||||||
|
|
||||||
|
dk3theta1 = lambda dist: np.exp(-dist*lu)*(lu+ly)**(-2)*((2*lu+ly+dist*lu**2+lu*ly*dist)*(-dist-2/(lu+ly))+2+2*lu*dist+ly*dist)
|
||||||
|
|
||||||
|
dktheta1 = lambda dist: self.varianceU*self.varianceY*(dk1theta1+dk2theta1+dk3theta1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dk1theta2 = lambda dist: np.exp(-ly*dist) * ((lu+ly)**(-2)) * ( (-dist)*(2*lu+ly) + 1 + (-2)*(2*lu+ly)/(lu+ly) )
|
||||||
|
|
||||||
|
dk2theta2 =lambda dist: 1*(
|
||||||
|
np.exp(-dist*lu)*(ly-lu)**(-2) * ( 1+lu*dist+(-2)*(ly-2*lu+lu*ly*dist-dist*lu**2)*(ly-lu)**(-1) )
|
||||||
|
+np.exp(-dist*ly)*(ly-lu)**(-2) * ( (-dist)*(2*lu-ly) -1+(2*lu-ly)*(-2)*(ly-lu)**(-1) )
|
||||||
|
)
|
||||||
|
|
||||||
|
dk3theta2 = lambda dist: np.exp(-dist*lu) * (-3*lu-ly-dist*lu**2-lu*ly*dist)/(lu+ly)**3
|
||||||
|
|
||||||
|
dktheta2 = lambda dist: self.varianceU*self.varianceY*(dk1theta2 + dk2theta2 +dk3theta2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
k1 = lambda dist: np.exp(-ly*dist)*(2*lu+ly)/(lu+ly)**2
|
||||||
|
k2 = lambda dist: (np.exp(-lu*dist)*(ly-2*lu+lu*ly*dist-lu**2*dist) + np.exp(-ly*dist)*(2*lu-ly) ) / (ly-lu)**2
|
||||||
|
k3 = lambda dist: np.exp(-lu*dist) * ( (1+lu*dist)/(lu+ly) + (lu)/(lu+ly)**2 )
|
||||||
|
dkdvar = k1+k2+k3
|
||||||
|
|
||||||
|
|
||||||
|
for i, s1 in enumerate(slices):
|
||||||
|
for j, s2 in enumerate(slices2):
|
||||||
|
for ss1 in s1:
|
||||||
|
for ss2 in s2:
|
||||||
|
if i==0 and j==0:
|
||||||
|
#target[ss1,ss2] = kuu(np.abs(rdist[ss1,ss2]))
|
||||||
|
elif i==0 and j==1:
|
||||||
|
#target[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kuyp(np.abs(rdist[ss1,ss2])), kuyn(np.abs(rdist[s1[0],s2[0]]) ) )
|
||||||
|
elif i==1 and j==1:
|
||||||
|
#target[ss1,ss2] = kyy(np.abs(rdist[ss1,ss2]))
|
||||||
|
else:
|
||||||
|
#target[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kyup(np.abs(rdist[ss1,ss2])), kyun(np.abs(rdist[s1[0],s2[0]]) ) )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
target[0] += np.sum(self.varianceY*dkdvar * dL_dK)
|
||||||
|
target[1] += np.sum(self.varianceU*dkdvar * dL_dK)
|
||||||
|
target[2] += np.sum(dktheta1*(-np.sqrt(3)*self.lengthscaleU**(-2)) * dL_dK)
|
||||||
|
target[3] += np.sum(dktheta2*(-self.lengthscaleY**(-2)) * dL_dK)
|
||||||
|
|
||||||
|
|
||||||
|
# def dKdiag_dtheta(self, dL_dKdiag, X, target):
|
||||||
|
# """derivative of the diagonal of the covariance matrix with respect to the parameters."""
|
||||||
|
# # NB: derivative of diagonal elements wrt lengthscale is 0
|
||||||
|
# target[0] += np.sum(dL_dKdiag)
|
||||||
|
|
||||||
|
# def dK_dX(self, dL_dK, X, X2, target):
|
||||||
|
# """derivative of the covariance matrix with respect to X."""
|
||||||
|
# if X2 is None: X2 = X
|
||||||
|
# dist = np.sqrt(np.sum(np.square((X[:, None, :] - X2[None, :, :]) / self.lengthscale), -1))[:, :, None]
|
||||||
|
# ddist_dX = (X[:, None, :] - X2[None, :, :]) / self.lengthscale ** 2 / np.where(dist != 0., dist, np.inf)
|
||||||
|
# dK_dX = -np.transpose(self.variance * np.exp(-dist) * ddist_dX, (1, 0, 2))
|
||||||
|
# target += np.sum(dK_dX * dL_dK.T[:, :, None], 0)
|
||||||
|
|
||||||
|
# def dKdiag_dX(self, dL_dKdiag, X, target):
|
||||||
|
# pass
|
||||||
|
|
@ -14,6 +14,7 @@ import Matern32
|
||||||
import Matern52
|
import Matern52
|
||||||
import mlp
|
import mlp
|
||||||
import ODE_1
|
import ODE_1
|
||||||
|
import ODE_UY
|
||||||
import periodic_exponential
|
import periodic_exponential
|
||||||
import periodic_Matern32
|
import periodic_Matern32
|
||||||
import periodic_Matern52
|
import periodic_Matern52
|
||||||
|
|
@ -26,4 +27,5 @@ import rbf
|
||||||
import rbf_inv
|
import rbf_inv
|
||||||
import spline
|
import spline
|
||||||
import symmetric
|
import symmetric
|
||||||
|
import sympy_helpers
|
||||||
import white
|
import white
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
# Copyright (c) 2013, GPy authors (see AUTHORS.txt).
|
# Copyright (c) 2013, GPy authors (see AUTHORS.txt).
|
||||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
|
||||||
from IPython.core.debugger import Tracer; debug_here=Tracer()
|
|
||||||
from kernpart import Kernpart
|
from kernpart import Kernpart
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from ...util.linalg import tdot
|
from ...util.linalg import tdot
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from independent_outputs import index_to_slices
|
||||||
|
|
||||||
class Hierarchical(Kernpart):
|
class Hierarchical(Kernpart):
|
||||||
"""
|
"""
|
||||||
A kernel part which can reopresent a hierarchy of indepencnce: a gerenalisation of independent_outputs
|
A kernel part which can reopresent a hierarchy of indepencnce: a generalisation of independent_outputs
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self,parts):
|
def __init__(self,parts):
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,18 @@
|
||||||
class Kernpart(object):
|
class Kernpart(object):
|
||||||
def __init__(self,input_dim):
|
def __init__(self,input_dim):
|
||||||
"""
|
"""
|
||||||
The base class for a kernpart: a positive definite function which forms part of a kernel
|
The base class for a kernpart: a positive definite function which forms part of a covariance function (kernel).
|
||||||
|
|
||||||
:param input_dim: the number of input dimensions to the function
|
:param input_dim: the number of input dimensions to the function
|
||||||
:type input_dim: int
|
:type input_dim: int
|
||||||
|
|
||||||
Do not instantiate.
|
Do not instantiate.
|
||||||
"""
|
"""
|
||||||
|
# the input dimensionality for the covariance
|
||||||
self.input_dim = input_dim
|
self.input_dim = input_dim
|
||||||
|
# the number of optimisable parameters
|
||||||
self.num_params = 1
|
self.num_params = 1
|
||||||
|
# the name of the covariance function.
|
||||||
self.name = 'unnamed'
|
self.name = 'unnamed'
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import numpy as np
|
||||||
from ...util.linalg import tdot
|
from ...util.linalg import tdot
|
||||||
from ...util.misc import fast_array_equal
|
from ...util.misc import fast_array_equal
|
||||||
from scipy import weave
|
from scipy import weave
|
||||||
|
from ...util.config import *
|
||||||
|
|
||||||
class Linear(Kernpart):
|
class Linear(Kernpart):
|
||||||
"""
|
"""
|
||||||
|
|
@ -51,6 +52,26 @@ class Linear(Kernpart):
|
||||||
self._Z, self._mu, self._S = np.empty(shape=(3, 1))
|
self._Z, self._mu, self._S = np.empty(shape=(3, 1))
|
||||||
self._X, self._X2, self._params = np.empty(shape=(3, 1))
|
self._X, self._X2, self._params = np.empty(shape=(3, 1))
|
||||||
|
|
||||||
|
# a set of optional args to pass to weave
|
||||||
|
weave_options_openmp = {'headers' : ['<omp.h>'],
|
||||||
|
'extra_compile_args': ['-fopenmp -O3'],
|
||||||
|
'extra_link_args' : ['-lgomp'],
|
||||||
|
'libraries': ['gomp']}
|
||||||
|
weave_options_noopenmp = {'extra_compile_args': ['-O3']}
|
||||||
|
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
self.weave_options = weave_options_openmp
|
||||||
|
self.weave_support_code = """
|
||||||
|
#include <omp.h>
|
||||||
|
#include <math.h>
|
||||||
|
"""
|
||||||
|
else:
|
||||||
|
self.weave_options = weave_options_noopenmp
|
||||||
|
self.weave_support_code = """
|
||||||
|
#include <math.h>
|
||||||
|
"""
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return self.variances
|
return self.variances
|
||||||
|
|
||||||
|
|
@ -190,11 +211,17 @@ class Linear(Kernpart):
|
||||||
#target_mu_dummy += (dL_dpsi2[:, :, :, None] * muAZZA).sum(1).sum(1)
|
#target_mu_dummy += (dL_dpsi2[:, :, :, None] * muAZZA).sum(1).sum(1)
|
||||||
#target_S_dummy += (dL_dpsi2[:, :, :, None] * self.ZA[None, :, None, :] * self.ZA[None, None, :, :]).sum(1).sum(1)
|
#target_S_dummy += (dL_dpsi2[:, :, :, None] * self.ZA[None, :, None, :] * self.ZA[None, None, :, :]).sum(1).sum(1)
|
||||||
|
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
pragma_string = "#pragma omp parallel for private(m,mm,q,qq,factor,tmp)"
|
||||||
|
else:
|
||||||
|
pragma_string = ''
|
||||||
|
|
||||||
#Using weave, we can exploiut the symmetry of this problem:
|
#Using weave, we can exploiut the symmetry of this problem:
|
||||||
code = """
|
code = """
|
||||||
int n, m, mm,q,qq;
|
int n, m, mm,q,qq;
|
||||||
double factor,tmp;
|
double factor,tmp;
|
||||||
#pragma omp parallel for private(m,mm,q,qq,factor,tmp)
|
%s
|
||||||
for(n=0;n<N;n++){
|
for(n=0;n<N;n++){
|
||||||
for(m=0;m<num_inducing;m++){
|
for(m=0;m<num_inducing;m++){
|
||||||
for(mm=0;mm<=m;mm++){
|
for(mm=0;mm<=m;mm++){
|
||||||
|
|
@ -218,19 +245,13 @@ class Linear(Kernpart):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""" % pragma_string
|
||||||
support_code = """
|
|
||||||
#include <omp.h>
|
|
||||||
#include <math.h>
|
|
||||||
"""
|
|
||||||
weave_options = {'headers' : ['<omp.h>'],
|
|
||||||
'extra_compile_args': ['-fopenmp -O3'], #-march=native'],
|
|
||||||
'extra_link_args' : ['-lgomp']}
|
|
||||||
|
|
||||||
N,num_inducing,input_dim = mu.shape[0],Z.shape[0],mu.shape[1]
|
|
||||||
weave.inline(code, support_code=support_code, libraries=['gomp'],
|
N,num_inducing,input_dim = int(mu.shape[0]),int(Z.shape[0]),int(mu.shape[1])
|
||||||
|
weave.inline(code, support_code=self.weave_support_code,
|
||||||
arg_names=['N','num_inducing','input_dim','mu','AZZA','AZZA_2','target_mu','target_S','dL_dpsi2'],
|
arg_names=['N','num_inducing','input_dim','mu','AZZA','AZZA_2','target_mu','target_S','dL_dpsi2'],
|
||||||
type_converters=weave.converters.blitz,**weave_options)
|
type_converters=weave.converters.blitz,**self.weave_options)
|
||||||
|
|
||||||
|
|
||||||
def dpsi2_dZ(self, dL_dpsi2, Z, mu, S, target):
|
def dpsi2_dZ(self, dL_dpsi2, Z, mu, S, target):
|
||||||
|
|
@ -240,9 +261,15 @@ class Linear(Kernpart):
|
||||||
#dummy_target += psi2_dZ.sum(0).sum(0)
|
#dummy_target += psi2_dZ.sum(0).sum(0)
|
||||||
|
|
||||||
AZA = self.variances*self.ZAinner
|
AZA = self.variances*self.ZAinner
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
pragma_string = '#pragma omp parallel for private(n,mm,q)'
|
||||||
|
else:
|
||||||
|
pragma_string = ''
|
||||||
|
|
||||||
code="""
|
code="""
|
||||||
int n,m,mm,q;
|
int n,m,mm,q;
|
||||||
#pragma omp parallel for private(n,mm,q)
|
%s
|
||||||
for(m=0;m<num_inducing;m++){
|
for(m=0;m<num_inducing;m++){
|
||||||
for(q=0;q<input_dim;q++){
|
for(q=0;q<input_dim;q++){
|
||||||
for(mm=0;mm<num_inducing;mm++){
|
for(mm=0;mm<num_inducing;mm++){
|
||||||
|
|
@ -252,22 +279,13 @@ class Linear(Kernpart):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""" % pragma_string
|
||||||
support_code = """
|
|
||||||
#include <omp.h>
|
|
||||||
#include <math.h>
|
|
||||||
"""
|
|
||||||
weave_options = {'headers' : ['<omp.h>'],
|
|
||||||
'extra_compile_args': ['-fopenmp -O3'], #-march=native'],
|
|
||||||
'extra_link_args' : ['-lgomp']}
|
|
||||||
|
|
||||||
N,num_inducing,input_dim = mu.shape[0],Z.shape[0],mu.shape[1]
|
|
||||||
weave.inline(code, support_code=support_code, libraries=['gomp'],
|
N,num_inducing,input_dim = int(mu.shape[0]),int(Z.shape[0]),int(mu.shape[1])
|
||||||
|
weave.inline(code, support_code=self.weave_support_code,
|
||||||
arg_names=['N','num_inducing','input_dim','AZA','target','dL_dpsi2'],
|
arg_names=['N','num_inducing','input_dim','AZA','target','dL_dpsi2'],
|
||||||
type_converters=weave.converters.blitz,**weave_options)
|
type_converters=weave.converters.blitz,**self.weave_options)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------#
|
#---------------------------------------#
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ class PeriodicMatern32(Kernpart):
|
||||||
|
|
||||||
@silence_errors
|
@silence_errors
|
||||||
def dK_dtheta(self,dL_dK,X,X2,target):
|
def dK_dtheta(self,dL_dK,X,X2,target):
|
||||||
"""derivative of the covariance matrix with respect to the parameters (shape is Nxnum_inducingxNparam)"""
|
"""derivative of the covariance matrix with respect to the parameters (shape is num_data x num_inducing x num_params)"""
|
||||||
if X2 is None: X2 = X
|
if X2 is None: X2 = X
|
||||||
FX = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X)
|
FX = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X)
|
||||||
FX2 = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X2)
|
FX2 = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X2)
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ class PeriodicMatern52(Kernpart):
|
||||||
|
|
||||||
@silence_errors
|
@silence_errors
|
||||||
def dK_dtheta(self,dL_dK,X,X2,target):
|
def dK_dtheta(self,dL_dK,X,X2,target):
|
||||||
"""derivative of the covariance matrix with respect to the parameters (shape is Nxnum_inducingxNparam)"""
|
"""derivative of the covariance matrix with respect to the parameters (shape is num_data x num_inducing x num_params)"""
|
||||||
if X2 is None: X2 = X
|
if X2 is None: X2 = X
|
||||||
FX = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X)
|
FX = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X)
|
||||||
FX2 = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X2)
|
FX2 = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X2)
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ class PeriodicExponential(Kernpart):
|
||||||
|
|
||||||
@silence_errors
|
@silence_errors
|
||||||
def dK_dtheta(self,dL_dK,X,X2,target):
|
def dK_dtheta(self,dL_dK,X,X2,target):
|
||||||
"""derivative of the covariance matrix with respect to the parameters (shape is Nxnum_inducingxNparam)"""
|
"""derivative of the covariance matrix with respect to the parameters (shape is N x num_inducing x num_params)"""
|
||||||
if X2 is None: X2 = X
|
if X2 is None: X2 = X
|
||||||
FX = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X)
|
FX = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X)
|
||||||
FX2 = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X2)
|
FX2 = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X2)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@ class Prod(Kernpart):
|
||||||
"""
|
"""
|
||||||
def __init__(self,k1,k2,tensor=False):
|
def __init__(self,k1,k2,tensor=False):
|
||||||
self.num_params = k1.num_params + k2.num_params
|
self.num_params = k1.num_params + k2.num_params
|
||||||
|
if tensor:
|
||||||
self.name = '['+k1.name + '**' + k2.name +']'
|
self.name = '['+k1.name + '**' + k2.name +']'
|
||||||
|
else:
|
||||||
|
self.name = '['+k1.name + '*' + k2.name +']'
|
||||||
self.k1 = k1
|
self.k1 = k1
|
||||||
self.k2 = k2
|
self.k2 = k2
|
||||||
if tensor:
|
if tensor:
|
||||||
|
|
@ -130,3 +133,13 @@ class Prod(Kernpart):
|
||||||
self.k1.K(X[:,self.slice1],X2[:,self.slice1],self._K1)
|
self.k1.K(X[:,self.slice1],X2[:,self.slice1],self._K1)
|
||||||
self.k2.K(X[:,self.slice2],X2[:,self.slice2],self._K2)
|
self.k2.K(X[:,self.slice2],X2[:,self.slice2],self._K2)
|
||||||
|
|
||||||
|
#def __getstate__(self):
|
||||||
|
#return [self.k1, self.k2, self.slice1, self.slice2, self.name, self.input_dim, self.num_params]
|
||||||
|
|
||||||
|
#def __setstate__(self, state):
|
||||||
|
#self.k1, self.k2, self.slice1, self.slice2, self.name, self.input_dim, self.num_params = state
|
||||||
|
#self._X, self._X2, self._params = np.empty(shape=(3,1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import numpy as np
|
||||||
from scipy import weave
|
from scipy import weave
|
||||||
from ...util.linalg import tdot
|
from ...util.linalg import tdot
|
||||||
from ...util.misc import fast_array_equal
|
from ...util.misc import fast_array_equal
|
||||||
|
from ...util.config import *
|
||||||
|
|
||||||
class RBF(Kernpart):
|
class RBF(Kernpart):
|
||||||
"""
|
"""
|
||||||
|
|
@ -57,12 +58,27 @@ class RBF(Kernpart):
|
||||||
self._X, self._X2, self._params = np.empty(shape=(3, 1))
|
self._X, self._X2, self._params = np.empty(shape=(3, 1))
|
||||||
|
|
||||||
# a set of optional args to pass to weave
|
# a set of optional args to pass to weave
|
||||||
self.weave_options = {'headers' : ['<omp.h>'],
|
weave_options_openmp = {'headers' : ['<omp.h>'],
|
||||||
'extra_compile_args': ['-fopenmp -O3'], # -march=native'],
|
'extra_compile_args': ['-fopenmp -O3'],
|
||||||
'extra_link_args' : ['-lgomp']}
|
'extra_link_args' : ['-lgomp'],
|
||||||
|
'libraries': ['gomp']}
|
||||||
|
weave_options_noopenmp = {'extra_compile_args': ['-O3']}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
self.weave_options = weave_options_openmp
|
||||||
|
self.weave_support_code = """
|
||||||
|
#include <omp.h>
|
||||||
|
#include <math.h>
|
||||||
|
"""
|
||||||
|
else:
|
||||||
|
self.weave_options = weave_options_noopenmp
|
||||||
|
self.weave_support_code = """
|
||||||
|
#include <math.h>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return np.hstack((self.variance, self.lengthscale))
|
return np.hstack((self.variance, self.lengthscale))
|
||||||
|
|
||||||
|
|
@ -110,7 +126,7 @@ class RBF(Kernpart):
|
||||||
target(q+1) += var_len3(q)*tmp;
|
target(q+1) += var_len3(q)*tmp;
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
num_data, num_inducing, input_dim = X.shape[0], X.shape[0], self.input_dim
|
num_data, num_inducing, input_dim = int(X.shape[0]), int(X.shape[0]), int(self.input_dim)
|
||||||
weave.inline(code, arg_names=['num_data', 'num_inducing', 'input_dim', 'X', 'X2', 'target', 'dvardLdK', 'var_len3'], type_converters=weave.converters.blitz, **self.weave_options)
|
weave.inline(code, arg_names=['num_data', 'num_inducing', 'input_dim', 'X', 'X2', 'target', 'dvardLdK', 'var_len3'], type_converters=weave.converters.blitz, **self.weave_options)
|
||||||
else:
|
else:
|
||||||
code = """
|
code = """
|
||||||
|
|
@ -126,7 +142,7 @@ class RBF(Kernpart):
|
||||||
target(q+1) += var_len3(q)*tmp;
|
target(q+1) += var_len3(q)*tmp;
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
num_data, num_inducing, input_dim = X.shape[0], X2.shape[0], self.input_dim
|
num_data, num_inducing, input_dim = int(X.shape[0]), int(X2.shape[0]), int(self.input_dim)
|
||||||
# [np.add(target[1+q:2+q],var_len3[q]*np.sum(dvardLdK*np.square(X[:,q][:,None]-X2[:,q][None,:])),target[1+q:2+q]) for q in range(self.input_dim)]
|
# [np.add(target[1+q:2+q],var_len3[q]*np.sum(dvardLdK*np.square(X[:,q][:,None]-X2[:,q][None,:])),target[1+q:2+q]) for q in range(self.input_dim)]
|
||||||
weave.inline(code, arg_names=['num_data', 'num_inducing', 'input_dim', 'X', 'X2', 'target', 'dvardLdK', 'var_len3'], type_converters=weave.converters.blitz, **self.weave_options)
|
weave.inline(code, arg_names=['num_data', 'num_inducing', 'input_dim', 'X', 'X2', 'target', 'dvardLdK', 'var_len3'], type_converters=weave.converters.blitz, **self.weave_options)
|
||||||
else:
|
else:
|
||||||
|
|
@ -170,7 +186,7 @@ class RBF(Kernpart):
|
||||||
self._psi_computations(Z, mu, S)
|
self._psi_computations(Z, mu, S)
|
||||||
target[0] += np.sum(dL_dpsi1 * self._psi1 / self.variance)
|
target[0] += np.sum(dL_dpsi1 * self._psi1 / self.variance)
|
||||||
d_length = self._psi1[:,:,None] * ((self._psi1_dist_sq - 1.)/(self.lengthscale*self._psi1_denom) +1./self.lengthscale)
|
d_length = self._psi1[:,:,None] * ((self._psi1_dist_sq - 1.)/(self.lengthscale*self._psi1_denom) +1./self.lengthscale)
|
||||||
dpsi1_dlength = d_length * dL_dpsi1[:, :, None]
|
dpsi1_dlength = d_length * np.atleast_3d(dL_dpsi1)
|
||||||
if not self.ARD:
|
if not self.ARD:
|
||||||
target[1] += dpsi1_dlength.sum()
|
target[1] += dpsi1_dlength.sum()
|
||||||
else:
|
else:
|
||||||
|
|
@ -192,12 +208,19 @@ class RBF(Kernpart):
|
||||||
self._psi_computations(Z, mu, S)
|
self._psi_computations(Z, mu, S)
|
||||||
target += self._psi2
|
target += self._psi2
|
||||||
|
|
||||||
|
def _crossterm_mu_S(self, Z, mu, S):
|
||||||
|
# compute the crossterm expectation for K as the other kernel:
|
||||||
|
Sigma = 1./self.lengthscale2[None,None,:] + 1./S[:,None,:] # is independent across M,
|
||||||
|
Sigma_tilde = (self.lengthscale2[None, :] + S)
|
||||||
|
M = (S*mu/Sigma_tilde)[:, None, :] + (self.lengthscale2[None,:]*Z)[None, :, :]/Sigma_tilde[:, None, :]
|
||||||
|
# make sure return is [N x M x Q]
|
||||||
|
return M, Sigma.repeat(Z.shape[0],1)
|
||||||
|
|
||||||
def dpsi2_dtheta(self, dL_dpsi2, Z, mu, S, target):
|
def dpsi2_dtheta(self, dL_dpsi2, Z, mu, S, target):
|
||||||
"""Shape N,num_inducing,num_inducing,Ntheta"""
|
"""Shape N,num_inducing,num_inducing,Ntheta"""
|
||||||
self._psi_computations(Z, mu, S)
|
self._psi_computations(Z, mu, S)
|
||||||
d_var = 2.*self._psi2 / self.variance
|
d_var = 2.*self._psi2 / self.variance
|
||||||
d_length = 2.*self._psi2[:, :, :, None] * (self._psi2_Zdist_sq * self._psi2_denom + self._psi2_mudist_sq + S[:, None, None, :] / self.lengthscale2) / (self.lengthscale * self._psi2_denom)
|
d_length = 2.*self._psi2[:, :, :, None] * (self._psi2_Zdist_sq * self._psi2_denom + self._psi2_mudist_sq + S[:, None, None, :] / self.lengthscale2) / (self.lengthscale * self._psi2_denom)
|
||||||
|
|
||||||
target[0] += np.sum(dL_dpsi2 * d_var)
|
target[0] += np.sum(dL_dpsi2 * d_var)
|
||||||
dpsi2_dlength = d_length * dL_dpsi2[:, :, :, None]
|
dpsi2_dlength = d_length * dL_dpsi2[:, :, :, None]
|
||||||
if not self.ARD:
|
if not self.ARD:
|
||||||
|
|
@ -280,17 +303,23 @@ class RBF(Kernpart):
|
||||||
psi2 = np.empty((N, num_inducing, num_inducing))
|
psi2 = np.empty((N, num_inducing, num_inducing))
|
||||||
|
|
||||||
psi2_Zdist_sq = self._psi2_Zdist_sq
|
psi2_Zdist_sq = self._psi2_Zdist_sq
|
||||||
_psi2_denom = self._psi2_denom.squeeze().reshape(N, self.input_dim)
|
_psi2_denom = self._psi2_denom.squeeze().reshape(-1, input_dim)
|
||||||
half_log_psi2_denom = 0.5 * np.log(self._psi2_denom).squeeze().reshape(N, self.input_dim)
|
half_log_psi2_denom = 0.5 * np.log(self._psi2_denom).squeeze().reshape(-1, input_dim)
|
||||||
variance_sq = float(np.square(self.variance))
|
variance_sq = float(np.square(self.variance))
|
||||||
if self.ARD:
|
if self.ARD:
|
||||||
lengthscale2 = self.lengthscale2
|
lengthscale2 = self.lengthscale2
|
||||||
else:
|
else:
|
||||||
lengthscale2 = np.ones(input_dim) * self.lengthscale2
|
lengthscale2 = np.ones(input_dim) * self.lengthscale2
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
pragma_string = '#pragma omp parallel for private(tmp)'
|
||||||
|
else:
|
||||||
|
pragma_string = ''
|
||||||
|
|
||||||
code = """
|
code = """
|
||||||
double tmp;
|
double tmp;
|
||||||
|
|
||||||
#pragma omp parallel for private(tmp)
|
%s
|
||||||
for (int n=0; n<N; n++){
|
for (int n=0; n<N; n++){
|
||||||
for (int m=0; m<num_inducing; m++){
|
for (int m=0; m<num_inducing; m++){
|
||||||
for (int mm=0; mm<(m+1); mm++){
|
for (int mm=0; mm<(m+1); mm++){
|
||||||
|
|
@ -320,13 +349,20 @@ class RBF(Kernpart):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"""
|
""" % pragma_string
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
pragma_string = '#include <omp.h>'
|
||||||
|
else:
|
||||||
|
pragma_string = ''
|
||||||
|
|
||||||
support_code = """
|
support_code = """
|
||||||
#include <omp.h>
|
%s
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
"""
|
""" % pragma_string
|
||||||
weave.inline(code, support_code=support_code, libraries=['gomp'],
|
|
||||||
|
N, num_inducing, input_dim = int(N), int(num_inducing), int(input_dim)
|
||||||
|
weave.inline(code, support_code=support_code,
|
||||||
arg_names=['N', 'num_inducing', 'input_dim', 'mu', 'Zhat', 'mudist_sq', 'mudist', 'lengthscale2', '_psi2_denom', 'psi2_Zdist_sq', 'psi2_exponent', 'half_log_psi2_denom', 'psi2', 'variance_sq'],
|
arg_names=['N', 'num_inducing', 'input_dim', 'mu', 'Zhat', 'mudist_sq', 'mudist', 'lengthscale2', '_psi2_denom', 'psi2_Zdist_sq', 'psi2_exponent', 'half_log_psi2_denom', 'psi2', 'variance_sq'],
|
||||||
type_converters=weave.converters.blitz, **self.weave_options)
|
type_converters=weave.converters.blitz, **self.weave_options)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import numpy as np
|
||||||
import hashlib
|
import hashlib
|
||||||
from scipy import weave
|
from scipy import weave
|
||||||
from ...util.linalg import tdot
|
from ...util.linalg import tdot
|
||||||
|
from ...util.config import *
|
||||||
|
|
||||||
|
|
||||||
class RBFInv(RBF):
|
class RBFInv(RBF):
|
||||||
"""
|
"""
|
||||||
|
|
@ -58,11 +60,23 @@ class RBFInv(RBF):
|
||||||
self._X, self._X2, self._params = np.empty(shape=(3, 1))
|
self._X, self._X2, self._params = np.empty(shape=(3, 1))
|
||||||
|
|
||||||
# a set of optional args to pass to weave
|
# a set of optional args to pass to weave
|
||||||
self.weave_options = {'headers' : ['<omp.h>'],
|
weave_options_openmp = {'headers' : ['<omp.h>'],
|
||||||
'extra_compile_args': ['-fopenmp -O3'], # -march=native'],
|
'extra_compile_args': ['-fopenmp -O3'],
|
||||||
'extra_link_args' : ['-lgomp']}
|
'extra_link_args' : ['-lgomp'],
|
||||||
|
'libraries': ['gomp']}
|
||||||
|
weave_options_noopenmp = {'extra_compile_args': ['-O3']}
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
self.weave_options = weave_options_openmp
|
||||||
|
self.weave_support_code = """
|
||||||
|
#include <omp.h>
|
||||||
|
#include <math.h>
|
||||||
|
"""
|
||||||
|
else:
|
||||||
|
self.weave_options = weave_options_noopenmp
|
||||||
|
self.weave_support_code = """
|
||||||
|
#include <math.h>
|
||||||
|
"""
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return np.hstack((self.variance, self.inv_lengthscale))
|
return np.hstack((self.variance, self.inv_lengthscale))
|
||||||
|
|
@ -109,7 +123,7 @@ class RBFInv(RBF):
|
||||||
target(q+1) += var_len3(q)*tmp*(-len2(q));
|
target(q+1) += var_len3(q)*tmp*(-len2(q));
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
num_data, num_inducing, input_dim = X.shape[0], X.shape[0], self.input_dim
|
num_data, num_inducing, input_dim = int(X.shape[0]), int(X.shape[0]), int(self.input_dim)
|
||||||
weave.inline(code, arg_names=['num_data', 'num_inducing', 'input_dim', 'X', 'X2', 'target', 'dvardLdK', 'var_len3', 'len2'], type_converters=weave.converters.blitz, **self.weave_options)
|
weave.inline(code, arg_names=['num_data', 'num_inducing', 'input_dim', 'X', 'X2', 'target', 'dvardLdK', 'var_len3', 'len2'], type_converters=weave.converters.blitz, **self.weave_options)
|
||||||
else:
|
else:
|
||||||
code = """
|
code = """
|
||||||
|
|
@ -125,7 +139,7 @@ class RBFInv(RBF):
|
||||||
target(q+1) += var_len3(q)*tmp*(-len2(q));
|
target(q+1) += var_len3(q)*tmp*(-len2(q));
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
num_data, num_inducing, input_dim = X.shape[0], X2.shape[0], self.input_dim
|
num_data, num_inducing, input_dim = int(X.shape[0]), int(X2.shape[0]), int(self.input_dim)
|
||||||
# [np.add(target[1+q:2+q],var_len3[q]*np.sum(dvardLdK*np.square(X[:,q][:,None]-X2[:,q][None,:])),target[1+q:2+q]) for q in range(self.input_dim)]
|
# [np.add(target[1+q:2+q],var_len3[q]*np.sum(dvardLdK*np.square(X[:,q][:,None]-X2[:,q][None,:])),target[1+q:2+q]) for q in range(self.input_dim)]
|
||||||
weave.inline(code, arg_names=['num_data', 'num_inducing', 'input_dim', 'X', 'X2', 'target', 'dvardLdK', 'var_len3', 'len2'], type_converters=weave.converters.blitz, **self.weave_options)
|
weave.inline(code, arg_names=['num_data', 'num_inducing', 'input_dim', 'X', 'X2', 'target', 'dvardLdK', 'var_len3', 'len2'], type_converters=weave.converters.blitz, **self.weave_options)
|
||||||
else:
|
else:
|
||||||
|
|
@ -263,8 +277,8 @@ class RBFInv(RBF):
|
||||||
self._Z, self._mu, self._S = Z, mu, S
|
self._Z, self._mu, self._S = Z, mu, S
|
||||||
|
|
||||||
def weave_psi2(self, mu, Zhat):
|
def weave_psi2(self, mu, Zhat):
|
||||||
N, input_dim = mu.shape
|
N, input_dim = int(mu.shape[0]), int(mu.shape[1])
|
||||||
num_inducing = Zhat.shape[0]
|
num_inducing = int(Zhat.shape[0])
|
||||||
|
|
||||||
mudist = np.empty((N, num_inducing, num_inducing, input_dim))
|
mudist = np.empty((N, num_inducing, num_inducing, input_dim))
|
||||||
mudist_sq = np.empty((N, num_inducing, num_inducing, input_dim))
|
mudist_sq = np.empty((N, num_inducing, num_inducing, input_dim))
|
||||||
|
|
@ -279,10 +293,16 @@ class RBFInv(RBF):
|
||||||
inv_lengthscale2 = self.inv_lengthscale2
|
inv_lengthscale2 = self.inv_lengthscale2
|
||||||
else:
|
else:
|
||||||
inv_lengthscale2 = np.ones(input_dim) * self.inv_lengthscale2
|
inv_lengthscale2 = np.ones(input_dim) * self.inv_lengthscale2
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
pragma_string = '#pragma omp parallel for private(tmp)'
|
||||||
|
else:
|
||||||
|
pragma_string = ''
|
||||||
|
|
||||||
code = """
|
code = """
|
||||||
double tmp;
|
double tmp;
|
||||||
|
|
||||||
#pragma omp parallel for private(tmp)
|
%s
|
||||||
for (int n=0; n<N; n++){
|
for (int n=0; n<N; n++){
|
||||||
for (int m=0; m<num_inducing; m++){
|
for (int m=0; m<num_inducing; m++){
|
||||||
for (int mm=0; mm<(m+1); mm++){
|
for (int mm=0; mm<(m+1); mm++){
|
||||||
|
|
@ -312,13 +332,9 @@ class RBFInv(RBF):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"""
|
""" % pragma_string
|
||||||
|
|
||||||
support_code = """
|
weave.inline(code, support_code=self.weave_support_code,
|
||||||
#include <omp.h>
|
|
||||||
#include <math.h>
|
|
||||||
"""
|
|
||||||
weave.inline(code, support_code=support_code, libraries=['gomp'],
|
|
||||||
arg_names=['N', 'num_inducing', 'input_dim', 'mu', 'Zhat', 'mudist_sq', 'mudist', 'inv_lengthscale2', '_psi2_denom', 'psi2_Zdist_sq', 'psi2_exponent', 'half_log_psi2_denom', 'psi2', 'variance_sq'],
|
arg_names=['N', 'num_inducing', 'input_dim', 'mu', 'Zhat', 'mudist_sq', 'mudist', 'inv_lengthscale2', '_psi2_denom', 'psi2_Zdist_sq', 'psi2_exponent', 'half_log_psi2_denom', 'psi2', 'variance_sq'],
|
||||||
type_converters=weave.converters.blitz, **self.weave_options)
|
type_converters=weave.converters.blitz, **self.weave_options)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class Symmetric(Kernpart):
|
||||||
AX = np.dot(X,self.transform)
|
AX = np.dot(X,self.transform)
|
||||||
if X2 is None:
|
if X2 is None:
|
||||||
X2 = X
|
X2 = X
|
||||||
ZX2 = AX
|
AX2 = AX
|
||||||
else:
|
else:
|
||||||
AX2 = np.dot(X2, self.transform)
|
AX2 = np.dot(X2, self.transform)
|
||||||
self.k.dK_dtheta(dL_dK,X,X2,target)
|
self.k.dK_dtheta(dL_dK,X,X2,target)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
|
#include "Python.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
double DiracDelta(double x){
|
double DiracDelta(double x){
|
||||||
// TODO: this doesn't seem to be a dirac delta ... should return infinity. Neil
|
// TODO: this doesn't seem to be a dirac delta ... should return infinity. Neil
|
||||||
if((x<0.000001) & (x>-0.000001))//go on, laugh at my c++ skills
|
if((x<0.000001) & (x>-0.000001))//go on, laugh at my c++ skills
|
||||||
|
|
@ -14,6 +16,7 @@ double DiracDelta(double x,int foo){
|
||||||
};
|
};
|
||||||
|
|
||||||
double sinc(double x){
|
double sinc(double x){
|
||||||
|
// compute the sinc function
|
||||||
if (x==0)
|
if (x==0)
|
||||||
return 1.0;
|
return 1.0;
|
||||||
else
|
else
|
||||||
|
|
@ -21,28 +24,39 @@ double sinc(double x){
|
||||||
}
|
}
|
||||||
|
|
||||||
double sinc_grad(double x){
|
double sinc_grad(double x){
|
||||||
|
// compute the gradient of the sinc function.
|
||||||
if (x==0)
|
if (x==0)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
else
|
else
|
||||||
return (x*cos(x) - sin(x))/(x*x);
|
return (x*cos(x) - sin(x))/(x*x);
|
||||||
}
|
}
|
||||||
|
|
||||||
double erfcx(double x){
|
double erfcx(double x){
|
||||||
|
// Based on code by Soren Hauberg 2010 for Octave.
|
||||||
|
// compute the scaled complex error function.
|
||||||
|
//return erfc(x)*exp(x*x);
|
||||||
double xneg=-sqrt(log(DBL_MAX/2));
|
double xneg=-sqrt(log(DBL_MAX/2));
|
||||||
double xmax = 1/(sqrt(M_PI)*DBL_MIN);
|
double xmax = 1/(sqrt(M_PI)*DBL_MIN);
|
||||||
xmax = DBL_MAX<xmax ? DBL_MAX : xmax;
|
xmax = DBL_MAX<xmax ? DBL_MAX : xmax;
|
||||||
// Find values where erfcx can be evaluated
|
// Find values where erfcx can be evaluated
|
||||||
double t = 3.97886080735226 / (abs(x) + 3.97886080735226);
|
double t = 3.97886080735226 / (fabs(x) + 3.97886080735226);
|
||||||
double u = t-0.5;
|
double u = t-0.5;
|
||||||
double y = (((((((((u * 0.00127109764952614092 + 1.19314022838340944e-4) * u
|
double y = (((((((((u * 0.00127109764952614092 + 1.19314022838340944e-4) * u
|
||||||
- 0.003963850973605135) * u - 8.70779635317295828e-4) * u
|
- 0.003963850973605135) * u - 8.70779635317295828e-4) * u
|
||||||
+ 0.00773672528313526668) * u + 0.00383335126264887303) * u
|
+ 0.00773672528313526668) * u + 0.00383335126264887303) * u
|
||||||
- 0.0127223813782122755) * u - 0.0133823644533460069) * u
|
- 0.0127223813782122755) * u - 0.0133823644533460069) * u
|
||||||
+ 0.0161315329733252248) * u + 0.0390976845588484035) * u + 0.00249367200053503304;
|
+ 0.0161315329733252248) * u + 0.0390976845588484035) * u + 0.00249367200053503304;
|
||||||
|
y = ((((((((((((y * u - 0.0838864557023001992) * u -
|
||||||
|
0.119463959964325415) * u + 0.0166207924969367356) * u +
|
||||||
|
0.357524274449531043) * u + 0.805276408752910567) * u +
|
||||||
|
1.18902982909273333) * u + 1.37040217682338167) * u +
|
||||||
|
1.31314653831023098) * u + 1.07925515155856677) * u +
|
||||||
|
0.774368199119538609) * u + 0.490165080585318424) * u +
|
||||||
|
0.275374741597376782) * t;
|
||||||
|
|
||||||
if (x<xneg)
|
if (x<xneg)
|
||||||
return -INFINITY;
|
return -INFINITY;
|
||||||
else if (x<0)
|
else if (x<0)
|
||||||
return 2*exp(x*x)-y;
|
return 2.0*exp(x*x)-y;
|
||||||
else if (x>xmax)
|
else if (x>xmax)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
else
|
else
|
||||||
|
|
@ -50,12 +64,133 @@ double erfcx(double x){
|
||||||
}
|
}
|
||||||
|
|
||||||
double ln_diff_erf(double x0, double x1){
|
double ln_diff_erf(double x0, double x1){
|
||||||
if (x0==x1)
|
// stably compute the log of difference between two erfs.
|
||||||
return INFINITY;
|
if (x1>x0){
|
||||||
else if(x0<0 && x1>0 || x0>0 && x1<0)
|
PyErr_SetString(PyExc_RuntimeError,"second argument must be smaller than or equal to first in ln_diff_erf");
|
||||||
|
throw 1;
|
||||||
|
}
|
||||||
|
if (x0==x1){
|
||||||
|
PyErr_WarnEx(PyExc_RuntimeWarning,"divide by zero encountered in log", 1);
|
||||||
|
return -INFINITY;
|
||||||
|
}
|
||||||
|
else if(x0<0 && x1>0 || x0>0 && x1<0) //x0 and x1 have opposite signs
|
||||||
return log(erf(x0)-erf(x1));
|
return log(erf(x0)-erf(x1));
|
||||||
else if(x1>0)
|
else if(x0>0) //x0 positive, x1 non-negative
|
||||||
return log(erfcx(x1)-erfcx(x0)*exp(x1*x1)- x0*x0)-x1*x1;
|
return log(erfcx(x1)-erfcx(x0)*exp(x1*x1- x0*x0))-x1*x1;
|
||||||
else
|
else //x0 and x1 non-positive
|
||||||
return log(erfcx(-x0)-erfcx(-x1)*exp(x0*x0 - x1*x1))-x0*x0;
|
return log(erfcx(-x0)-erfcx(-x1)*exp(x0*x0 - x1*x1))-x0*x0;
|
||||||
}
|
}
|
||||||
|
// TODO: For all these computations of h things are very efficient at the moment. Need to recode sympykern to allow the precomputations to take place and all the gradients to be computed in one function. Not sure of best way forward for that yet. Neil
|
||||||
|
double h(double t, double tprime, double d_i, double d_j, double l){
|
||||||
|
// Compute the h function for the sim covariance.
|
||||||
|
double half_l_di = 0.5*l*d_i;
|
||||||
|
double arg_1 = half_l_di + tprime/l;
|
||||||
|
double arg_2 = half_l_di - (t-tprime)/l;
|
||||||
|
double ln_part_1 = ln_diff_erf(arg_1, arg_2);
|
||||||
|
arg_2 = half_l_di - t/l;
|
||||||
|
double sign_val = 1.0;
|
||||||
|
if(t/l==0)
|
||||||
|
sign_val = 0.0;
|
||||||
|
else if (t/l < 0)
|
||||||
|
sign_val = -1.0;
|
||||||
|
arg_2 = half_l_di - t/l;
|
||||||
|
double ln_part_2 = ln_diff_erf(half_l_di, arg_2);
|
||||||
|
// if either ln_part_1 or ln_part_2 are -inf, don't bother computing rest of that term.
|
||||||
|
double part_1 = 0.0;
|
||||||
|
if(isfinite(ln_part_1))
|
||||||
|
part_1 = sign_val*exp(half_l_di*half_l_di - d_i*(t-tprime) + ln_part_1 - log(d_i + d_j));
|
||||||
|
double part_2 = 0.0;
|
||||||
|
if(isfinite(ln_part_2))
|
||||||
|
part_2 = sign_val*exp(half_l_di*half_l_di - d_i*t - d_j*tprime + ln_part_2 - log(d_i + d_j));
|
||||||
|
return part_1 - part_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double dh_dd_i(double t, double tprime, double d_i, double d_j, double l){
|
||||||
|
double diff_t = (t-tprime);
|
||||||
|
double l2 = l*l;
|
||||||
|
double hv = h(t, tprime, d_i, d_j, l);
|
||||||
|
double half_l_di = 0.5*l*d_i;
|
||||||
|
double arg_1 = half_l_di + tprime/l;
|
||||||
|
double arg_2 = half_l_di - (t-tprime)/l;
|
||||||
|
double ln_part_1 = ln_diff_erf(arg_1, arg_2);
|
||||||
|
arg_1 = half_l_di;
|
||||||
|
arg_2 = half_l_di - t/l;
|
||||||
|
double sign_val = 1.0;
|
||||||
|
if(t/l==0)
|
||||||
|
sign_val = 0.0;
|
||||||
|
else if (t/l < 0)
|
||||||
|
sign_val = -1.0;
|
||||||
|
double ln_part_2 = ln_diff_erf(half_l_di, half_l_di - t/l);
|
||||||
|
double base = (0.5*d_i*l2*(d_i+d_j)-1)*hv;
|
||||||
|
if(isfinite(ln_part_1))
|
||||||
|
base -= diff_t*sign_val*exp(half_l_di*half_l_di
|
||||||
|
-d_i*diff_t
|
||||||
|
+ln_part_1);
|
||||||
|
if(isfinite(ln_part_2))
|
||||||
|
base += t*sign_val*exp(half_l_di*half_l_di
|
||||||
|
-d_i*t-d_j*tprime
|
||||||
|
+ln_part_2);
|
||||||
|
base += l/sqrt(M_PI)*(-exp(-diff_t*diff_t/l2)
|
||||||
|
+exp(-tprime*tprime/l2-d_i*t)
|
||||||
|
+exp(-t*t/l2-d_j*tprime)
|
||||||
|
-exp(-(d_i*t + d_j*tprime)));
|
||||||
|
return base/(d_i+d_j);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
double dh_dd_j(double t, double tprime, double d_i, double d_j, double l){
|
||||||
|
double half_l_di = 0.5*l*d_i;
|
||||||
|
double hv = h(t, tprime, d_i, d_j, l);
|
||||||
|
double sign_val = 1.0;
|
||||||
|
if(t/l==0)
|
||||||
|
sign_val = 0.0;
|
||||||
|
else if (t/l < 0)
|
||||||
|
sign_val = -1.0;
|
||||||
|
double ln_part_2 = ln_diff_erf(half_l_di, half_l_di - t/l);
|
||||||
|
double base = -hv;
|
||||||
|
if(isfinite(ln_part_2))
|
||||||
|
base += tprime*sign_val*exp(half_l_di*half_l_di-(d_i*t+d_j*tprime)+ln_part_2);
|
||||||
|
return base/(d_i+d_j);
|
||||||
|
}
|
||||||
|
|
||||||
|
double dh_dl(double t, double tprime, double d_i, double d_j, double l){
|
||||||
|
// compute gradient of h function with respect to lengthscale for sim covariance
|
||||||
|
// TODO a lot of energy wasted recomputing things here, need to do this in a shared way somehow ... perhaps needs rewrite of sympykern.
|
||||||
|
double half_l_di = 0.5*l*d_i;
|
||||||
|
double arg_1 = half_l_di + tprime/l;
|
||||||
|
double arg_2 = half_l_di - (t-tprime)/l;
|
||||||
|
double ln_part_1 = ln_diff_erf(arg_1, arg_2);
|
||||||
|
arg_2 = half_l_di - t/l;
|
||||||
|
double ln_part_2 = ln_diff_erf(half_l_di, arg_2);
|
||||||
|
double diff_t = t - tprime;
|
||||||
|
double l2 = l*l;
|
||||||
|
double hv = h(t, tprime, d_i, d_j, l);
|
||||||
|
return 0.5*d_i*d_i*l*hv + 2/(sqrt(M_PI)*(d_i+d_j))*((-diff_t/l2-d_i/2)*exp(-diff_t*diff_t/l2)+(-tprime/l2+d_i/2)*exp(-tprime*tprime/l2-d_i*t)-(-t/l2-d_i/2)*exp(-t*t/l2-d_j*tprime)-d_i/2*exp(-(d_i*t+d_j*tprime)));
|
||||||
|
}
|
||||||
|
|
||||||
|
double dh_dt(double t, double tprime, double d_i, double d_j, double l){
|
||||||
|
// compute gradient of h function with respect to t.
|
||||||
|
double diff_t = t - tprime;
|
||||||
|
double half_l_di = 0.5*l*d_i;
|
||||||
|
double arg_1 = half_l_di + tprime/l;
|
||||||
|
double arg_2 = half_l_di - diff_t/l;
|
||||||
|
double ln_part_1 = ln_diff_erf(arg_1, arg_2);
|
||||||
|
arg_2 = half_l_di - t/l;
|
||||||
|
double ln_part_2 = ln_diff_erf(half_l_di, arg_2);
|
||||||
|
|
||||||
|
return (d_i*exp(ln_part_2-d_i*t - d_j*tprime) - d_i*exp(ln_part_1-d_i*diff_t) + 2*exp(-d_i*diff_t - pow(half_l_di - diff_t/l, 2))/(sqrt(M_PI)*l) - 2*exp(-d_i*t - d_j*tprime - pow(half_l_di - t/l,2))/(sqrt(M_PI)*l))*exp(half_l_di*half_l_di)/(d_i + d_j);
|
||||||
|
}
|
||||||
|
|
||||||
|
double dh_dtprime(double t, double tprime, double d_i, double d_j, double l){
|
||||||
|
// compute gradient of h function with respect to tprime.
|
||||||
|
double diff_t = t - tprime;
|
||||||
|
double half_l_di = 0.5*l*d_i;
|
||||||
|
double arg_1 = half_l_di + tprime/l;
|
||||||
|
double arg_2 = half_l_di - diff_t/l;
|
||||||
|
double ln_part_1 = ln_diff_erf(arg_1, arg_2);
|
||||||
|
arg_2 = half_l_di - t/l;
|
||||||
|
double ln_part_2 = ln_diff_erf(half_l_di, arg_2);
|
||||||
|
|
||||||
|
return (d_i*exp(ln_part_1-d_i*diff_t) + d_j*exp(ln_part_2-d_i*t - d_j*tprime) + (-2*exp(-pow(half_l_di - diff_t/l,2)) + 2*exp(-pow(half_l_di + tprime/l,2)))*exp(-d_i*diff_t)/(sqrt(M_PI)*l))*exp(half_l_di*half_l_di)/(d_i + d_j);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,10 @@ double sinc_grad(double x);
|
||||||
|
|
||||||
double erfcx(double x);
|
double erfcx(double x);
|
||||||
double ln_diff_erf(double x0, double x1);
|
double ln_diff_erf(double x0, double x1);
|
||||||
|
|
||||||
|
double h(double t, double tprime, double d_i, double d_j, double l);
|
||||||
|
double dh_dl(double t, double tprime, double d_i, double d_j, double l);
|
||||||
|
double dh_dd_i(double t, double tprime, double d_i, double d_j, double l);
|
||||||
|
double dh_dd_j(double t, double tprime, double d_i, double d_j, double l);
|
||||||
|
double dh_dt(double t, double tprime, double d_i, double d_j, double l);
|
||||||
|
double dh_dtprime(double t, double tprime, double d_i, double d_j, double l);
|
||||||
|
|
|
||||||
71
GPy/kern/parts/sympy_helpers.py
Normal file
71
GPy/kern/parts/sympy_helpers.py
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
# Code for testing functions written in sympy_helpers.cpp
|
||||||
|
from scipy import weave
|
||||||
|
import tempfile
|
||||||
|
import os
|
||||||
|
import numpy as np
|
||||||
|
current_dir = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
|
||||||
|
extra_compile_args = []
|
||||||
|
|
||||||
|
weave_kwargs = {
|
||||||
|
'support_code': "",
|
||||||
|
'include_dirs':[tempfile.gettempdir(), current_dir],
|
||||||
|
'headers':['"parts/sympy_helpers.h"'],
|
||||||
|
'sources':[os.path.join(current_dir,"parts/sympy_helpers.cpp")],
|
||||||
|
'extra_compile_args':extra_compile_args,
|
||||||
|
'extra_link_args':['-lgomp'],
|
||||||
|
'verbose':True}
|
||||||
|
|
||||||
|
def erfcx(x):
|
||||||
|
code = """
|
||||||
|
// Code for computing scaled complementary erf
|
||||||
|
int i;
|
||||||
|
int dim;
|
||||||
|
int elements = Ntarget[0];
|
||||||
|
for (dim=1; dim<Dtarget; dim++)
|
||||||
|
elements *= Ntarget[dim];
|
||||||
|
for (i=0;i<elements;i++)
|
||||||
|
target[i] = erfcx(x[i]);
|
||||||
|
"""
|
||||||
|
x = np.asarray(x)
|
||||||
|
arg_names = ['target','x']
|
||||||
|
target = np.zeros_like(x)
|
||||||
|
weave.inline(code=code, arg_names=arg_names,**weave_kwargs)
|
||||||
|
return target
|
||||||
|
|
||||||
|
def ln_diff_erf(x, y):
|
||||||
|
code = """
|
||||||
|
// Code for computing scaled complementary erf
|
||||||
|
int i;
|
||||||
|
int dim;
|
||||||
|
int elements = Ntarget[0];
|
||||||
|
for (dim=1; dim<Dtarget; dim++)
|
||||||
|
elements *= Ntarget[dim];
|
||||||
|
for (i=0;i<elements;i++)
|
||||||
|
target[i] = ln_diff_erf(x[i], y[i]);
|
||||||
|
"""
|
||||||
|
x = np.asarray(x)
|
||||||
|
y = np.asarray(y)
|
||||||
|
assert(x.shape==y.shape)
|
||||||
|
target = np.zeros_like(x)
|
||||||
|
arg_names = ['target','x', 'y']
|
||||||
|
weave.inline(code=code, arg_names=arg_names,**weave_kwargs)
|
||||||
|
return target
|
||||||
|
|
||||||
|
def h(t, tprime, d_i, d_j, l):
|
||||||
|
code = """
|
||||||
|
// Code for computing the 1st order ODE h helper function.
|
||||||
|
int i;
|
||||||
|
int dim;
|
||||||
|
int elements = Ntarget[0];
|
||||||
|
for (dim=1; dim<Dtarget; dim++)
|
||||||
|
elements *= Ntarget[dim];
|
||||||
|
for (i=0;i<elements;i++)
|
||||||
|
target[i] = h(t[i], tprime[i], d_i, d_j, l);
|
||||||
|
"""
|
||||||
|
t = np.asarray(t)
|
||||||
|
tprime = np.asarray(tprime)
|
||||||
|
assert(tprime.shape==t.shape)
|
||||||
|
target = np.zeros_like(t)
|
||||||
|
arg_names = ['target','t', 'tprime', 'd_i', 'd_j', 'l']
|
||||||
|
weave.inline(code=code, arg_names=arg_names,**weave_kwargs)
|
||||||
|
return target
|
||||||
|
|
@ -11,6 +11,7 @@ import tempfile
|
||||||
import pdb
|
import pdb
|
||||||
import ast
|
import ast
|
||||||
from kernpart import Kernpart
|
from kernpart import Kernpart
|
||||||
|
from ...util.config import config
|
||||||
|
|
||||||
class spkern(Kernpart):
|
class spkern(Kernpart):
|
||||||
"""
|
"""
|
||||||
|
|
@ -43,6 +44,7 @@ class spkern(Kernpart):
|
||||||
assert all([z.name=='z_%i'%i for i,z in enumerate(self._sp_z)])
|
assert all([z.name=='z_%i'%i for i,z in enumerate(self._sp_z)])
|
||||||
assert len(self._sp_x)==len(self._sp_z)
|
assert len(self._sp_x)==len(self._sp_z)
|
||||||
self.input_dim = len(self._sp_x)
|
self.input_dim = len(self._sp_x)
|
||||||
|
self._real_input_dim = self.input_dim
|
||||||
if output_dim > 1:
|
if output_dim > 1:
|
||||||
self.input_dim += 1
|
self.input_dim += 1
|
||||||
assert self.input_dim == input_dim
|
assert self.input_dim == input_dim
|
||||||
|
|
@ -63,26 +65,28 @@ class spkern(Kernpart):
|
||||||
self._sp_theta = [theta for theta in thetas if theta not in self._sp_theta_i and theta not in self._sp_theta_j]
|
self._sp_theta = [theta for theta in thetas if theta not in self._sp_theta_i and theta not in self._sp_theta_j]
|
||||||
|
|
||||||
self.num_split_params = len(self._sp_theta_i)
|
self.num_split_params = len(self._sp_theta_i)
|
||||||
self._split_param_names = ["%s"%theta.name[:-2] for theta in self._sp_theta_i]
|
self._split_theta_names = ["%s"%theta.name[:-2] for theta in self._sp_theta_i]
|
||||||
for params in self._split_param_names:
|
for theta in self._split_theta_names:
|
||||||
setattr(self, params, np.ones(self.output_dim))
|
setattr(self, theta, np.ones(self.output_dim))
|
||||||
|
|
||||||
self.num_shared_params = len(self._sp_theta)
|
self.num_shared_params = len(self._sp_theta)
|
||||||
self.num_params = self.num_shared_params+self.num_split_params*self.output_dim
|
self.num_params = self.num_shared_params+self.num_split_params*self.output_dim
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.num_split_params = 0
|
self.num_split_params = 0
|
||||||
self._split_param_names = []
|
self._split_theta_names = []
|
||||||
self._sp_theta = thetas
|
self._sp_theta = thetas
|
||||||
self.num_shared_params = len(self._sp_theta)
|
self.num_shared_params = len(self._sp_theta)
|
||||||
self.num_params = self.num_shared_params
|
self.num_params = self.num_shared_params
|
||||||
|
|
||||||
|
for theta in self._sp_theta:
|
||||||
|
val = 1.0
|
||||||
|
if param is not None:
|
||||||
|
if param.has_key(theta):
|
||||||
|
val = param[theta]
|
||||||
|
setattr(self, theta.name, val)
|
||||||
#deal with param
|
#deal with param
|
||||||
if param is None:
|
self._set_params(self._get_params())
|
||||||
param = np.ones(self.num_params)
|
|
||||||
|
|
||||||
assert param.size==self.num_params
|
|
||||||
self._set_params(param)
|
|
||||||
|
|
||||||
#Differentiate!
|
#Differentiate!
|
||||||
self._sp_dk_dtheta = [sp.diff(k,theta).simplify() for theta in self._sp_theta]
|
self._sp_dk_dtheta = [sp.diff(k,theta).simplify() for theta in self._sp_theta]
|
||||||
|
|
@ -90,54 +94,34 @@ class spkern(Kernpart):
|
||||||
self._sp_dk_dtheta_i = [sp.diff(k,theta).simplify() for theta in self._sp_theta_i]
|
self._sp_dk_dtheta_i = [sp.diff(k,theta).simplify() for theta in self._sp_theta_i]
|
||||||
|
|
||||||
self._sp_dk_dx = [sp.diff(k,xi).simplify() for xi in self._sp_x]
|
self._sp_dk_dx = [sp.diff(k,xi).simplify() for xi in self._sp_x]
|
||||||
#self._sp_dk_dz = [sp.diff(k,zi) for zi in self._sp_z]
|
|
||||||
|
|
||||||
#self.compute_psi_stats()
|
if False:
|
||||||
|
self.compute_psi_stats()
|
||||||
|
|
||||||
self._gen_code()
|
self._gen_code()
|
||||||
|
|
||||||
self.weave_kwargs = {\
|
if False:
|
||||||
'support_code':self._function_code,\
|
extra_compile_args = ['-ftree-vectorize', '-mssse3', '-ftree-vectorizer-verbose=5']
|
||||||
'include_dirs':[tempfile.gettempdir(), os.path.join(current_dir,'parts/')],\
|
else:
|
||||||
'headers':['"sympy_helpers.h"'],\
|
extra_compile_args = []
|
||||||
'sources':[os.path.join(current_dir,"parts/sympy_helpers.cpp")],\
|
|
||||||
#'extra_compile_args':['-ftree-vectorize', '-mssse3', '-ftree-vectorizer-verbose=5'],\
|
self.weave_kwargs = {
|
||||||
'extra_compile_args':[],\
|
'support_code':self._function_code,
|
||||||
'extra_link_args':['-lgomp'],\
|
'include_dirs':[tempfile.gettempdir(), os.path.join(current_dir,'parts/')],
|
||||||
|
'headers':['"sympy_helpers.h"'],
|
||||||
|
'sources':[os.path.join(current_dir,"parts/sympy_helpers.cpp")],
|
||||||
|
'extra_compile_args':extra_compile_args,
|
||||||
|
'extra_link_args':[],
|
||||||
'verbose':True}
|
'verbose':True}
|
||||||
|
if config.getboolean('parallel', 'openmp'): self.weave_kwargs.append('-lgomp')
|
||||||
|
|
||||||
def __add__(self,other):
|
def __add__(self,other):
|
||||||
return spkern(self._sp_k+other._sp_k)
|
return spkern(self._sp_k+other._sp_k)
|
||||||
|
|
||||||
def compute_psi_stats(self):
|
|
||||||
#define some normal distributions
|
|
||||||
mus = [sp.var('mu_%i'%i,real=True) for i in range(self.input_dim)]
|
|
||||||
Ss = [sp.var('S_%i'%i,positive=True) for i in range(self.input_dim)]
|
|
||||||
normals = [(2*sp.pi*Si)**(-0.5)*sp.exp(-0.5*(xi-mui)**2/Si) for xi, mui, Si in zip(self._sp_x, mus, Ss)]
|
|
||||||
|
|
||||||
#do some integration!
|
|
||||||
#self._sp_psi0 = ??
|
|
||||||
self._sp_psi1 = self._sp_k
|
|
||||||
for i in range(self.input_dim):
|
|
||||||
print 'perfoming integrals %i of %i'%(i+1,2*self.input_dim)
|
|
||||||
sys.stdout.flush()
|
|
||||||
self._sp_psi1 *= normals[i]
|
|
||||||
self._sp_psi1 = sp.integrate(self._sp_psi1,(self._sp_x[i],-sp.oo,sp.oo))
|
|
||||||
clear_cache()
|
|
||||||
self._sp_psi1 = self._sp_psi1.simplify()
|
|
||||||
|
|
||||||
#and here's psi2 (eek!)
|
|
||||||
zprime = [sp.Symbol('zp%i'%i) for i in range(self.input_dim)]
|
|
||||||
self._sp_psi2 = self._sp_k.copy()*self._sp_k.copy().subs(zip(self._sp_z,zprime))
|
|
||||||
for i in range(self.input_dim):
|
|
||||||
print 'perfoming integrals %i of %i'%(self.input_dim+i+1,2*self.input_dim)
|
|
||||||
sys.stdout.flush()
|
|
||||||
self._sp_psi2 *= normals[i]
|
|
||||||
self._sp_psi2 = sp.integrate(self._sp_psi2,(self._sp_x[i],-sp.oo,sp.oo))
|
|
||||||
clear_cache()
|
|
||||||
self._sp_psi2 = self._sp_psi2.simplify()
|
|
||||||
|
|
||||||
|
|
||||||
def _gen_code(self):
|
def _gen_code(self):
|
||||||
|
"""Generates the C functions necessary for computing the covariance function using the sympy objects as input."""
|
||||||
|
#TODO: maybe generate one C function only to save compile time? Also easier to take that as a basis and hand craft other covariances??
|
||||||
|
|
||||||
#generate c functions from sympy objects
|
#generate c functions from sympy objects
|
||||||
argument_sequence = self._sp_x+self._sp_z+self._sp_theta
|
argument_sequence = self._sp_x+self._sp_z+self._sp_theta
|
||||||
code_list = [('k',self._sp_k)]
|
code_list = [('k',self._sp_k)]
|
||||||
|
|
@ -159,30 +143,57 @@ class spkern(Kernpart):
|
||||||
# Substitute any known derivatives which sympy doesn't compute
|
# Substitute any known derivatives which sympy doesn't compute
|
||||||
self._function_code = re.sub('DiracDelta\(.+?,.+?\)','0.0',self._function_code)
|
self._function_code = re.sub('DiracDelta\(.+?,.+?\)','0.0',self._function_code)
|
||||||
|
|
||||||
# This is the basic argument construction for the C code.
|
|
||||||
arg_list = (["X[i*input_dim+%s]"%x.name[2:] for x in self._sp_x]
|
############################################################
|
||||||
+ ["Z[j*input_dim+%s]"%z.name[2:] for z in self._sp_z])
|
# This is the basic argument construction for the C code. #
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
arg_list = (["X2(i, %s)"%x.name[2:] for x in self._sp_x]
|
||||||
|
+ ["Z2(j, %s)"%z.name[2:] for z in self._sp_z])
|
||||||
|
|
||||||
|
# for multiple outputs need to also provide these arguments reversed.
|
||||||
if self.output_dim>1:
|
if self.output_dim>1:
|
||||||
reverse_arg_list = list(arg_list)
|
reverse_arg_list = list(arg_list)
|
||||||
reverse_arg_list.reverse()
|
reverse_arg_list.reverse()
|
||||||
|
|
||||||
param_arg_list = ["param[%i]"%i for i in range(self.num_shared_params)]
|
# Add in any 'shared' parameters to the list.
|
||||||
|
param_arg_list = [shared_params.name for shared_params in self._sp_theta]
|
||||||
arg_list += param_arg_list
|
arg_list += param_arg_list
|
||||||
|
|
||||||
precompute_list=[]
|
precompute_list=[]
|
||||||
if self.output_dim > 1:
|
if self.output_dim > 1:
|
||||||
reverse_arg_list+=list(param_arg_list)
|
reverse_arg_list+=list(param_arg_list)
|
||||||
split_param_arg_list = ["%s[%s]"%(theta.name[:-2],index) for index in ['ii', 'jj'] for theta in self._sp_theta_i]
|
split_param_arg_list = ["%s1(%s)"%(theta.name[:-2].upper(),index) for index in ['ii', 'jj'] for theta in self._sp_theta_i]
|
||||||
split_param_reverse_arg_list = ["%s[%s]"%(theta.name[:-2],index) for index in ['jj', 'ii'] for theta in self._sp_theta_i]
|
split_param_reverse_arg_list = ["%s1(%s)"%(theta.name[:-2].upper(),index) for index in ['jj', 'ii'] for theta in self._sp_theta_i]
|
||||||
arg_list += split_param_arg_list
|
arg_list += split_param_arg_list
|
||||||
reverse_arg_list += split_param_reverse_arg_list
|
reverse_arg_list += split_param_reverse_arg_list
|
||||||
precompute_list += [' '*16+"int %s=(int)%s[%s*input_dim+output_dim];"%(index, var, index2) for index, var, index2 in zip(['ii', 'jj'], ['X', 'Z'], ['i', 'j'])]
|
# Extract the right output indices from the inputs.
|
||||||
|
c_define_output_indices = [' '*16 + "int %s=(int)%s(%s, %i);"%(index, var, index2, self.input_dim-1) for index, var, index2 in zip(['ii', 'jj'], ['X2', 'Z2'], ['i', 'j'])]
|
||||||
|
precompute_list += c_define_output_indices
|
||||||
reverse_arg_string = ", ".join(reverse_arg_list)
|
reverse_arg_string = ", ".join(reverse_arg_list)
|
||||||
arg_string = ", ".join(arg_list)
|
arg_string = ", ".join(arg_list)
|
||||||
precompute_string = "\n".join(precompute_list)
|
precompute_string = "\n".join(precompute_list)
|
||||||
|
|
||||||
|
# Code to compute argments string needed when only X is provided.
|
||||||
|
X_arg_string = re.sub('Z','X',arg_string)
|
||||||
|
# Code to compute argument string when only diagonal is required.
|
||||||
|
diag_arg_string = re.sub('int jj','//int jj',X_arg_string)
|
||||||
|
diag_arg_string = re.sub('j','i',diag_arg_string)
|
||||||
|
if precompute_string == '':
|
||||||
|
# if it's not multioutput, the precompute strings are set to zero
|
||||||
|
diag_precompute_string = ''
|
||||||
|
diag_precompute_replace = ''
|
||||||
|
else:
|
||||||
|
# for multioutput we need to extract the index of the output form the input.
|
||||||
|
diag_precompute_string = precompute_list[0]
|
||||||
|
diag_precompute_replace = precompute_list[1]
|
||||||
|
|
||||||
|
|
||||||
# Here's the code to do the looping for K
|
# Here's the code to do the looping for K
|
||||||
self._K_code =\
|
self._K_code =\
|
||||||
"""
|
"""
|
||||||
|
// _K_code
|
||||||
|
// Code for computing the covariance function.
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
int N = target_array->dimensions[0];
|
int N = target_array->dimensions[0];
|
||||||
|
|
@ -192,42 +203,65 @@ class spkern(Kernpart):
|
||||||
for (i=0;i<N;i++){
|
for (i=0;i<N;i++){
|
||||||
for (j=0;j<num_inducing;j++){
|
for (j=0;j<num_inducing;j++){
|
||||||
%s
|
%s
|
||||||
target[i*num_inducing+j] = k(%s);
|
//target[i*num_inducing+j] =
|
||||||
|
TARGET2(i, j) += k(%s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%s
|
%s
|
||||||
"""%(precompute_string,arg_string,"/*"+str(self._sp_k)+"*/") #adding a string representation forces recompile when needed
|
"""%(precompute_string,arg_string,"/*"+str(self._sp_k)+"*/") #adding a string representation forces recompile when needed
|
||||||
|
|
||||||
|
self._K_code_X = """
|
||||||
|
// _K_code_X
|
||||||
|
// Code for computing the covariance function.
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
int N = target_array->dimensions[0];
|
||||||
|
int num_inducing = target_array->dimensions[1];
|
||||||
|
int input_dim = X_array->dimensions[1];
|
||||||
|
//#pragma omp parallel for private(j)
|
||||||
|
for (i=0;i<N;i++){
|
||||||
|
%s // int ii=(int)X2(i, 1);
|
||||||
|
TARGET2(i, i) += k(%s);
|
||||||
|
for (j=0;j<i;j++){
|
||||||
|
%s //int jj=(int)X2(j, 1);
|
||||||
|
double kval = k(%s); //double kval = k(X2(i, 0), shared_lengthscale, LENGTHSCALE1(ii), SCALE1(ii));
|
||||||
|
TARGET2(i, j) += kval;
|
||||||
|
TARGET2(j, i) += kval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*%s*/
|
||||||
|
"""%(diag_precompute_string, diag_arg_string, re.sub('Z2', 'X2', diag_precompute_replace), X_arg_string,str(self._sp_k)) #adding a string representation forces recompile when needed
|
||||||
|
|
||||||
# Code to compute diagonal of covariance.
|
|
||||||
diag_arg_string = re.sub('Z','X',arg_string)
|
|
||||||
diag_arg_string = re.sub('j','i',diag_arg_string)
|
|
||||||
diag_precompute_string = re.sub('Z','X',precompute_string)
|
|
||||||
diag_precompute_string = re.sub('j','i',diag_precompute_string)
|
|
||||||
# Code to do the looping for Kdiag
|
# Code to do the looping for Kdiag
|
||||||
self._Kdiag_code =\
|
self._Kdiag_code =\
|
||||||
"""
|
"""
|
||||||
|
// _Kdiag_code
|
||||||
|
// Code for computing diagonal of covariance function.
|
||||||
int i;
|
int i;
|
||||||
int N = target_array->dimensions[0];
|
int N = target_array->dimensions[0];
|
||||||
int input_dim = X_array->dimensions[1];
|
int input_dim = X_array->dimensions[1];
|
||||||
//#pragma omp parallel for
|
//#pragma omp parallel for
|
||||||
for (i=0;i<N;i++){
|
for (i=0;i<N;i++){
|
||||||
%s
|
%s
|
||||||
target[i] = k(%s);
|
//target[i] =
|
||||||
|
TARGET1(i)=k(%s);
|
||||||
}
|
}
|
||||||
%s
|
%s
|
||||||
"""%(diag_precompute_string,diag_arg_string,"/*"+str(self._sp_k)+"*/") #adding a string representation forces recompile when needed
|
"""%(diag_precompute_string,diag_arg_string,"/*"+str(self._sp_k)+"*/") #adding a string representation forces recompile when needed
|
||||||
|
|
||||||
# Code to compute gradients
|
# Code to compute gradients
|
||||||
func_list = ([' '*16 + 'target[%i] += partial[i*num_inducing+j]*dk_d%s(%s);'%(i,theta.name,arg_string) for i,theta in enumerate(self._sp_theta)])
|
grad_func_list = []
|
||||||
if self.output_dim>1:
|
if self.output_dim>1:
|
||||||
func_list += [' '*16 + "int %s=(int)%s[%s*input_dim+output_dim];"%(index, var, index2) for index, var, index2 in zip(['ii', 'jj'], ['X', 'Z'], ['i', 'j'])]
|
grad_func_list += c_define_output_indices
|
||||||
func_list += [' '*16 + 'target[%i+ii] += partial[i*num_inducing+j]*dk_d%s(%s);'%(self.num_shared_params+i*self.output_dim, theta.name, arg_string) for i, theta in enumerate(self._sp_theta_i)]
|
grad_func_list += [' '*16 + 'TARGET1(%i+ii) += PARTIAL2(i, j)*dk_d%s(%s);'%(self.num_shared_params+i*self.output_dim, theta.name, arg_string) for i, theta in enumerate(self._sp_theta_i)]
|
||||||
func_list += [' '*16 + 'target[%i+jj] += partial[i*num_inducing+j]*dk_d%s(%s);'%(self.num_shared_params+i*self.output_dim, theta.name, reverse_arg_string) for i, theta in enumerate(self._sp_theta_i)]
|
grad_func_list += [' '*16 + 'TARGET1(%i+jj) += PARTIAL2(i, j)*dk_d%s(%s);'%(self.num_shared_params+i*self.output_dim, theta.name, reverse_arg_string) for i, theta in enumerate(self._sp_theta_i)]
|
||||||
func_string = '\n'.join(func_list)
|
grad_func_list += ([' '*16 + 'TARGET1(%i) += PARTIAL2(i, j)*dk_d%s(%s);'%(i,theta.name,arg_string) for i,theta in enumerate(self._sp_theta)])
|
||||||
|
grad_func_string = '\n'.join(grad_func_list)
|
||||||
|
|
||||||
self._dK_dtheta_code =\
|
self._dK_dtheta_code =\
|
||||||
"""
|
"""
|
||||||
|
// _dK_dtheta_code
|
||||||
|
// Code for computing gradient of covariance with respect to parameters.
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
int N = partial_array->dimensions[0];
|
int N = partial_array->dimensions[0];
|
||||||
|
|
@ -240,15 +274,18 @@ class spkern(Kernpart):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%s
|
%s
|
||||||
"""%(func_string,"/*"+str(self._sp_k)+"*/") # adding a string representation forces recompile when needed
|
"""%(grad_func_string,"/*"+str(self._sp_k)+"*/") # adding a string representation forces recompile when needed
|
||||||
|
|
||||||
|
|
||||||
# Code to compute gradients for Kdiag TODO: needs clean up
|
# Code to compute gradients for Kdiag TODO: needs clean up
|
||||||
diag_func_string = re.sub('Z','X',func_string,count=0)
|
diag_grad_func_string = re.sub('Z','X',grad_func_string,count=0)
|
||||||
diag_func_string = re.sub('j','i',diag_func_string)
|
diag_grad_func_string = re.sub('int jj','//int jj',diag_grad_func_string)
|
||||||
diag_func_string = re.sub('partial\[i\*num_inducing\+i\]','partial[i]',diag_func_string)
|
diag_grad_func_string = re.sub('j','i',diag_grad_func_string)
|
||||||
|
diag_grad_func_string = re.sub('PARTIAL2\(i, i\)','PARTIAL1(i)',diag_grad_func_string)
|
||||||
self._dKdiag_dtheta_code =\
|
self._dKdiag_dtheta_code =\
|
||||||
"""
|
"""
|
||||||
|
// _dKdiag_dtheta_code
|
||||||
|
// Code for computing gradient of diagonal with respect to parameters.
|
||||||
int i;
|
int i;
|
||||||
int N = partial_array->dimensions[0];
|
int N = partial_array->dimensions[0];
|
||||||
int input_dim = X_array->dimensions[1];
|
int input_dim = X_array->dimensions[1];
|
||||||
|
|
@ -256,13 +293,19 @@ class spkern(Kernpart):
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
%s
|
%s
|
||||||
"""%(diag_func_string,"/*"+str(self._sp_k)+"*/") #adding a string representation forces recompile when needed
|
"""%(diag_grad_func_string,"/*"+str(self._sp_k)+"*/") #adding a string representation forces recompile when needed
|
||||||
|
|
||||||
# Code for gradients wrt X
|
# Code for gradients wrt X, TODO: may need to deal with special case where one input is actually an output.
|
||||||
gradient_funcs = "\n".join(["target[i*input_dim+%i] += partial[i*num_inducing+j]*dk_dx%i(%s);"%(q,q,arg_string) for q in range(self.input_dim)])
|
gradX_func_list = []
|
||||||
|
if self.output_dim>1:
|
||||||
|
gradX_func_list += c_define_output_indices
|
||||||
|
gradX_func_list += ["TARGET2(i, %i) += PARTIAL2(i, j)*dk_dx_%i(%s);"%(q,q,arg_string) for q in range(self._real_input_dim)]
|
||||||
|
gradX_func_string = "\n".join(gradX_func_list)
|
||||||
|
|
||||||
self._dK_dX_code = \
|
self._dK_dX_code = \
|
||||||
"""
|
"""
|
||||||
|
// _dK_dX_code
|
||||||
|
// Code for computing gradient of covariance with respect to inputs.
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
int N = partial_array->dimensions[0];
|
int N = partial_array->dimensions[0];
|
||||||
|
|
@ -275,52 +318,60 @@ class spkern(Kernpart):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%s
|
%s
|
||||||
"""%(gradient_funcs,"/*"+str(self._sp_k)+"*/") #adding a string representation forces recompile when needed
|
"""%(gradX_func_string,"/*"+str(self._sp_k)+"*/") #adding a string representation forces recompile when needed
|
||||||
|
|
||||||
|
|
||||||
diag_gradient_funcs = re.sub('Z','X',gradient_funcs,count=0)
|
diag_gradX_func_string = re.sub('Z','X',gradX_func_string,count=0)
|
||||||
diag_gradient_funcs = re.sub('j','i',diag_gradient_funcs)
|
diag_gradX_func_string = re.sub('int jj','//int jj',diag_gradX_func_string)
|
||||||
diag_gradient_funcs = re.sub('partial\[i\*num_inducing\+i\]','2*partial[i]',diag_gradient_funcs)
|
diag_gradX_func_string = re.sub('j','i',diag_gradX_func_string)
|
||||||
|
diag_gradX_func_string = re.sub('PARTIAL2\(i, i\)','2*PARTIAL1(i)',diag_gradX_func_string)
|
||||||
|
|
||||||
# Code for gradients of Kdiag wrt X
|
# Code for gradients of Kdiag wrt X
|
||||||
self._dKdiag_dX_code= \
|
self._dKdiag_dX_code= \
|
||||||
"""
|
"""
|
||||||
|
// _dKdiag_dX_code
|
||||||
|
// Code for computing gradient of diagonal with respect to inputs.
|
||||||
int N = partial_array->dimensions[0];
|
int N = partial_array->dimensions[0];
|
||||||
int input_dim = X_array->dimensions[1];
|
int input_dim = X_array->dimensions[1];
|
||||||
for (int i=0;i<N; i++){
|
for (int i=0;i<N; i++){
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
%s
|
%s
|
||||||
"""%(diag_gradient_funcs,"/*"+str(self._sp_k)+"*/") #adding a
|
"""%(diag_gradX_func_string,"/*"+str(self._sp_k)+"*/") #adding a
|
||||||
# string representation forces recompile when needed Get rid
|
# string representation forces recompile when needed Get rid
|
||||||
# of Zs in argument for diagonal. TODO: Why wasn't
|
# of Zs in argument for diagonal. TODO: Why wasn't
|
||||||
# diag_func_string called here? Need to check that.
|
# diag_func_string called here? Need to check that.
|
||||||
#self._dKdiag_dX_code = self._dKdiag_dX_code.replace('Z[j', 'X[i')
|
#self._dKdiag_dX_code = self._dKdiag_dX_code.replace('Z[j', 'X[i')
|
||||||
|
|
||||||
# Code to use when only X is provided.
|
# Code to use when only X is provided.
|
||||||
self._K_code_X = self._K_code.replace('Z[', 'X[')
|
|
||||||
self._dK_dtheta_code_X = self._dK_dtheta_code.replace('Z[', 'X[')
|
self._dK_dtheta_code_X = self._dK_dtheta_code.replace('Z[', 'X[')
|
||||||
self._dK_dX_code_X = self._dK_dX_code.replace('Z[', 'X[').replace('+= partial[', '+= 2*partial[')
|
self._dK_dX_code_X = self._dK_dX_code.replace('Z[', 'X[').replace('+= PARTIAL2(', '+= 2*PARTIAL2(')
|
||||||
|
self._dK_dtheta_code_X = self._dK_dtheta_code_X.replace('Z2(', 'X2(')
|
||||||
|
self._dK_dX_code_X = self._dK_dX_code_X.replace('Z2(', 'X2(')
|
||||||
|
|
||||||
|
|
||||||
#TODO: insert multiple functions here via string manipulation
|
#TODO: insert multiple functions here via string manipulation
|
||||||
#TODO: similar functions for psi_stats
|
#TODO: similar functions for psi_stats
|
||||||
def _get_arg_names(self, Z=None, partial=None):
|
def _get_arg_names(self, Z=None, partial=None):
|
||||||
arg_names = ['target','X','param']
|
arg_names = ['target','X']
|
||||||
|
for shared_params in self._sp_theta:
|
||||||
|
arg_names += [shared_params.name]
|
||||||
if Z is not None:
|
if Z is not None:
|
||||||
arg_names += ['Z']
|
arg_names += ['Z']
|
||||||
if partial is not None:
|
if partial is not None:
|
||||||
arg_names += ['partial']
|
arg_names += ['partial']
|
||||||
if self.output_dim>1:
|
if self.output_dim>1:
|
||||||
arg_names += self._split_param_names
|
arg_names += self._split_theta_names
|
||||||
arg_names += ['output_dim']
|
arg_names += ['output_dim']
|
||||||
return arg_names
|
return arg_names
|
||||||
|
|
||||||
def _weave_inline(self, code, X, target, Z=None, partial=None):
|
def _weave_inline(self, code, X, target, Z=None, partial=None):
|
||||||
param, output_dim = self._shared_params, self.output_dim
|
output_dim = self.output_dim
|
||||||
|
for shared_params in self._sp_theta:
|
||||||
|
locals()[shared_params.name] = getattr(self, shared_params.name)
|
||||||
|
|
||||||
# Need to extract parameters first
|
# Need to extract parameters first
|
||||||
for split_params in self._split_param_names:
|
for split_params in self._split_theta_names:
|
||||||
locals()[split_params] = getattr(self, split_params)
|
locals()[split_params] = getattr(self, split_params)
|
||||||
arg_names = self._get_arg_names(Z, partial)
|
arg_names = self._get_arg_names(Z, partial)
|
||||||
weave.inline(code=code, arg_names=arg_names,**self.weave_kwargs)
|
weave.inline(code=code, arg_names=arg_names,**self.weave_kwargs)
|
||||||
|
|
@ -351,23 +402,55 @@ class spkern(Kernpart):
|
||||||
self._weave_inline(self._dK_dX_code, X, target, Z, partial)
|
self._weave_inline(self._dK_dX_code, X, target, Z, partial)
|
||||||
|
|
||||||
def dKdiag_dX(self,partial,X,target):
|
def dKdiag_dX(self,partial,X,target):
|
||||||
self._weave.inline(self._dKdiag_dX_code, X, target, Z, partial)
|
self._weave_inline(self._dKdiag_dX_code, X, target, Z=None, partial=partial)
|
||||||
|
|
||||||
|
def compute_psi_stats(self):
|
||||||
|
#define some normal distributions
|
||||||
|
mus = [sp.var('mu_%i'%i,real=True) for i in range(self.input_dim)]
|
||||||
|
Ss = [sp.var('S_%i'%i,positive=True) for i in range(self.input_dim)]
|
||||||
|
normals = [(2*sp.pi*Si)**(-0.5)*sp.exp(-0.5*(xi-mui)**2/Si) for xi, mui, Si in zip(self._sp_x, mus, Ss)]
|
||||||
|
|
||||||
|
#do some integration!
|
||||||
|
#self._sp_psi0 = ??
|
||||||
|
self._sp_psi1 = self._sp_k
|
||||||
|
for i in range(self.input_dim):
|
||||||
|
print 'perfoming integrals %i of %i'%(i+1,2*self.input_dim)
|
||||||
|
sys.stdout.flush()
|
||||||
|
self._sp_psi1 *= normals[i]
|
||||||
|
self._sp_psi1 = sp.integrate(self._sp_psi1,(self._sp_x[i],-sp.oo,sp.oo))
|
||||||
|
clear_cache()
|
||||||
|
self._sp_psi1 = self._sp_psi1.simplify()
|
||||||
|
|
||||||
|
#and here's psi2 (eek!)
|
||||||
|
zprime = [sp.Symbol('zp%i'%i) for i in range(self.input_dim)]
|
||||||
|
self._sp_psi2 = self._sp_k.copy()*self._sp_k.copy().subs(zip(self._sp_z,zprime))
|
||||||
|
for i in range(self.input_dim):
|
||||||
|
print 'perfoming integrals %i of %i'%(self.input_dim+i+1,2*self.input_dim)
|
||||||
|
sys.stdout.flush()
|
||||||
|
self._sp_psi2 *= normals[i]
|
||||||
|
self._sp_psi2 = sp.integrate(self._sp_psi2,(self._sp_x[i],-sp.oo,sp.oo))
|
||||||
|
clear_cache()
|
||||||
|
self._sp_psi2 = self._sp_psi2.simplify()
|
||||||
|
|
||||||
|
|
||||||
def _set_params(self,param):
|
def _set_params(self,param):
|
||||||
#print param.flags['C_CONTIGUOUS']
|
|
||||||
assert param.size == (self.num_params)
|
assert param.size == (self.num_params)
|
||||||
self._shared_params = param[0:self.num_shared_params]
|
for i, shared_params in enumerate(self._sp_theta):
|
||||||
|
setattr(self, shared_params.name, param[i])
|
||||||
|
|
||||||
if self.output_dim>1:
|
if self.output_dim>1:
|
||||||
for i, split_params in enumerate(self._split_param_names):
|
for i, split_params in enumerate(self._split_theta_names):
|
||||||
start = self.num_shared_params + i*self.output_dim
|
start = self.num_shared_params + i*self.output_dim
|
||||||
end = self.num_shared_params + (i+1)*self.output_dim
|
end = self.num_shared_params + (i+1)*self.output_dim
|
||||||
setattr(self, split_params, param[start:end])
|
setattr(self, split_params, param[start:end])
|
||||||
|
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
params = self._shared_params
|
params = np.zeros(0)
|
||||||
|
for shared_params in self._sp_theta:
|
||||||
|
params = np.hstack((params, getattr(self, shared_params.name)))
|
||||||
if self.output_dim>1:
|
if self.output_dim>1:
|
||||||
for split_params in self._split_param_names:
|
for split_params in self._split_theta_names:
|
||||||
params = np.hstack((params, getattr(self, split_params).flatten()))
|
params = np.hstack((params, getattr(self, split_params).flatten()))
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
from ep import EP
|
from ep import EP
|
||||||
|
from laplace import Laplace
|
||||||
from ep_mixed_noise import EP_Mixed_Noise
|
from ep_mixed_noise import EP_Mixed_Noise
|
||||||
from gaussian import Gaussian
|
from gaussian import Gaussian
|
||||||
from gaussian_mixed_noise import Gaussian_Mixed_Noise
|
from gaussian_mixed_noise import Gaussian_Mixed_Noise
|
||||||
|
import noise_models
|
||||||
from noise_model_constructors import *
|
from noise_model_constructors import *
|
||||||
# TODO: from Laplace import Laplace
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,7 @@ class EP(likelihood):
|
||||||
self.data = data
|
self.data = data
|
||||||
self.num_data, self.output_dim = self.data.shape
|
self.num_data, self.output_dim = self.data.shape
|
||||||
self.is_heteroscedastic = True
|
self.is_heteroscedastic = True
|
||||||
self.Nparams = 0
|
self.num_params = 0
|
||||||
self._transf_data = self.noise_model._preprocess_values(data)
|
|
||||||
|
|
||||||
#Initial values - Likelihood approximation parameters:
|
#Initial values - Likelihood approximation parameters:
|
||||||
#p(y|f) = t(f|tau_tilde,v_tilde)
|
#p(y|f) = t(f|tau_tilde,v_tilde)
|
||||||
|
|
@ -50,10 +49,26 @@ class EP(likelihood):
|
||||||
self.VVT_factor = self.V
|
self.VVT_factor = self.V
|
||||||
self.trYYT = 0.
|
self.trYYT = 0.
|
||||||
|
|
||||||
def predictive_values(self,mu,var,full_cov):
|
def predictive_values(self,mu,var,full_cov,**noise_args):
|
||||||
if full_cov:
|
if full_cov:
|
||||||
raise NotImplementedError, "Cannot make correlated predictions with an EP likelihood"
|
raise NotImplementedError, "Cannot make correlated predictions with an EP likelihood"
|
||||||
return self.noise_model.predictive_values(mu,var)
|
return self.noise_model.predictive_values(mu,var,**noise_args)
|
||||||
|
|
||||||
|
def log_predictive_density(self, y_test, mu_star, var_star):
|
||||||
|
"""
|
||||||
|
Calculation of the log predictive density
|
||||||
|
|
||||||
|
.. math:
|
||||||
|
p(y_{*}|D) = p(y_{*}|f_{*})p(f_{*}|\mu_{*}\\sigma^{2}_{*})
|
||||||
|
|
||||||
|
:param y_test: test observations (y_{*})
|
||||||
|
:type y_test: (Nx1) array
|
||||||
|
:param mu_star: predictive mean of gaussian p(f_{*}|mu_{*}, var_{*})
|
||||||
|
:type mu_star: (Nx1) array
|
||||||
|
:param var_star: predictive variance of gaussian p(f_{*}|mu_{*}, var_{*})
|
||||||
|
:type var_star: (Nx1) array
|
||||||
|
"""
|
||||||
|
return self.noise_model.log_predictive_density(y_test, mu_star, var_star)
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
#return np.zeros(0)
|
#return np.zeros(0)
|
||||||
|
|
@ -134,7 +149,7 @@ class EP(likelihood):
|
||||||
self.tau_[i] = 1./Sigma[i,i] - self.eta*self.tau_tilde[i]
|
self.tau_[i] = 1./Sigma[i,i] - self.eta*self.tau_tilde[i]
|
||||||
self.v_[i] = mu[i]/Sigma[i,i] - self.eta*self.v_tilde[i]
|
self.v_[i] = mu[i]/Sigma[i,i] - self.eta*self.v_tilde[i]
|
||||||
#Marginal moments
|
#Marginal moments
|
||||||
self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self._transf_data[i],self.tau_[i],self.v_[i])
|
self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self.data[i],self.tau_[i],self.v_[i])
|
||||||
#Site parameters update
|
#Site parameters update
|
||||||
Delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma[i,i])
|
Delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma[i,i])
|
||||||
Delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma[i,i])
|
Delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma[i,i])
|
||||||
|
|
@ -233,7 +248,7 @@ class EP(likelihood):
|
||||||
self.tau_[i] = 1./Sigma_diag[i] - self.eta*self.tau_tilde[i]
|
self.tau_[i] = 1./Sigma_diag[i] - self.eta*self.tau_tilde[i]
|
||||||
self.v_[i] = mu[i]/Sigma_diag[i] - self.eta*self.v_tilde[i]
|
self.v_[i] = mu[i]/Sigma_diag[i] - self.eta*self.v_tilde[i]
|
||||||
#Marginal moments
|
#Marginal moments
|
||||||
self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self._transf_data[i],self.tau_[i],self.v_[i])
|
self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self.data[i],self.tau_[i],self.v_[i])
|
||||||
#Site parameters update
|
#Site parameters update
|
||||||
Delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma_diag[i])
|
Delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma_diag[i])
|
||||||
Delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma_diag[i])
|
Delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma_diag[i])
|
||||||
|
|
@ -336,7 +351,7 @@ class EP(likelihood):
|
||||||
self.tau_[i] = 1./Sigma_diag[i] - self.eta*self.tau_tilde[i]
|
self.tau_[i] = 1./Sigma_diag[i] - self.eta*self.tau_tilde[i]
|
||||||
self.v_[i] = mu[i]/Sigma_diag[i] - self.eta*self.v_tilde[i]
|
self.v_[i] = mu[i]/Sigma_diag[i] - self.eta*self.v_tilde[i]
|
||||||
#Marginal moments
|
#Marginal moments
|
||||||
self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self._transf_data[i],self.tau_[i],self.v_[i])
|
self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self.data[i],self.tau_[i],self.v_[i])
|
||||||
#Site parameters update
|
#Site parameters update
|
||||||
Delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma_diag[i])
|
Delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma_diag[i])
|
||||||
Delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma_diag[i])
|
Delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma_diag[i])
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ class EP_Mixed_Noise(likelihood):
|
||||||
self.data = np.vstack(data_list)
|
self.data = np.vstack(data_list)
|
||||||
self.N, self.output_dim = self.data.shape
|
self.N, self.output_dim = self.data.shape
|
||||||
self.is_heteroscedastic = True
|
self.is_heteroscedastic = True
|
||||||
self.Nparams = 0#FIXME
|
self.num_params = 0#FIXME
|
||||||
self._transf_data = np.vstack([noise_model._preprocess_values(data) for noise_model,data in zip(noise_model_list,data_list)])
|
self._transf_data = np.vstack([noise_model._preprocess_values(data) for noise_model,data in zip(noise_model_list,data_list)])
|
||||||
#TODO non-gaussian index
|
#TODO non-gaussian index
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class Gaussian(likelihood):
|
||||||
"""
|
"""
|
||||||
def __init__(self, data, variance=1., normalize=False):
|
def __init__(self, data, variance=1., normalize=False):
|
||||||
self.is_heteroscedastic = False
|
self.is_heteroscedastic = False
|
||||||
self.Nparams = 1
|
self.num_params = 1
|
||||||
self.Z = 0. # a correction factor which accounts for the approximation made
|
self.Z = 0. # a correction factor which accounts for the approximation made
|
||||||
N, self.output_dim = data.shape
|
N, self.output_dim = data.shape
|
||||||
|
|
||||||
|
|
@ -69,7 +69,7 @@ class Gaussian(likelihood):
|
||||||
self.covariance_matrix = np.eye(self.N) * x
|
self.covariance_matrix = np.eye(self.N) * x
|
||||||
self._variance = x
|
self._variance = x
|
||||||
|
|
||||||
def predictive_values(self, mu, var, full_cov):
|
def predictive_values(self, mu, var, full_cov, **likelihood_args):
|
||||||
"""
|
"""
|
||||||
Un-normalize the prediction and add the likelihood variance, then return the 5%, 95% interval
|
Un-normalize the prediction and add the likelihood variance, then return the 5%, 95% interval
|
||||||
"""
|
"""
|
||||||
|
|
@ -90,11 +90,25 @@ class Gaussian(likelihood):
|
||||||
_95pc = mean + 2.*np.sqrt(true_var)
|
_95pc = mean + 2.*np.sqrt(true_var)
|
||||||
return mean, true_var, _5pc, _95pc
|
return mean, true_var, _5pc, _95pc
|
||||||
|
|
||||||
def fit_full(self):
|
def log_predictive_density(self, y_test, mu_star, var_star):
|
||||||
"""
|
"""
|
||||||
No approximations needed
|
Calculation of the log predictive density
|
||||||
|
|
||||||
|
.. math:
|
||||||
|
p(y_{*}|D) = p(y_{*}|f_{*})p(f_{*}|\mu_{*}\\sigma^{2}_{*})
|
||||||
|
|
||||||
|
:param y_test: test observations (y_{*})
|
||||||
|
:type y_test: (Nx1) array
|
||||||
|
:param mu_star: predictive mean of gaussian p(f_{*}|mu_{*}, var_{*})
|
||||||
|
:type mu_star: (Nx1) array
|
||||||
|
:param var_star: predictive variance of gaussian p(f_{*}|mu_{*}, var_{*})
|
||||||
|
:type var_star: (Nx1) array
|
||||||
|
|
||||||
|
.. Note:
|
||||||
|
Works as if each test point was provided individually, i.e. not full_cov
|
||||||
"""
|
"""
|
||||||
pass
|
y_rescaled = (y_test - self._offset)/self._scale
|
||||||
|
return -0.5*np.log(2*np.pi) -0.5*np.log(var_star + self._variance) -0.5*(np.square(y_rescaled - mu_star))/(var_star + self._variance)
|
||||||
|
|
||||||
def _gradients(self, partial):
|
def _gradients(self, partial):
|
||||||
return np.sum(partial)
|
return np.sum(partial)
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ class Gaussian_Mixed_Noise(likelihood):
|
||||||
:type normalize: False|True
|
:type normalize: False|True
|
||||||
"""
|
"""
|
||||||
def __init__(self, data_list, noise_params=None, normalize=True):
|
def __init__(self, data_list, noise_params=None, normalize=True):
|
||||||
self.Nparams = len(data_list)
|
self.num_params = len(data_list)
|
||||||
self.n_list = [data.size for data in data_list]
|
self.n_list = [data.size for data in data_list]
|
||||||
self.index = np.vstack([np.repeat(i,n)[:,None] for i,n in zip(range(self.Nparams),self.n_list)])
|
self.index = np.vstack([np.repeat(i,n)[:,None] for i,n in zip(range(self.num_params),self.n_list)])
|
||||||
|
|
||||||
if noise_params is None:
|
if noise_params is None:
|
||||||
noise_params = [1.] * self.Nparams
|
noise_params = [1.] * self.num_params
|
||||||
else:
|
else:
|
||||||
assert self.Nparams == len(noise_params), 'Number of noise parameters does not match the number of noise models.'
|
assert self.num_params == len(noise_params), 'Number of noise parameters does not match the number of noise models.'
|
||||||
|
|
||||||
self.noise_model_list = [Gaussian(Y,variance=v,normalize = normalize) for Y,v in zip(data_list,noise_params)]
|
self.noise_model_list = [Gaussian(Y,variance=v,normalize = normalize) for Y,v in zip(data_list,noise_params)]
|
||||||
self.n_params = [noise_model._get_params().size for noise_model in self.noise_model_list]
|
self.n_params = [noise_model._get_params().size for noise_model in self.noise_model_list]
|
||||||
|
|
|
||||||
403
GPy/likelihoods/laplace.py
Normal file
403
GPy/likelihoods/laplace.py
Normal file
|
|
@ -0,0 +1,403 @@
|
||||||
|
# Copyright (c) 2013, GPy authors (see AUTHORS.txt).
|
||||||
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
#
|
||||||
|
#Parts of this file were influenced by the Matlab GPML framework written by
|
||||||
|
#Carl Edward Rasmussen & Hannes Nickisch, however all bugs are our own.
|
||||||
|
#
|
||||||
|
#The GPML code is released under the FreeBSD License.
|
||||||
|
#Copyright (c) 2005-2013 Carl Edward Rasmussen & Hannes Nickisch. All rights reserved.
|
||||||
|
#
|
||||||
|
#The code and associated documentation is available from
|
||||||
|
#http://gaussianprocess.org/gpml/code.
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import scipy as sp
|
||||||
|
from likelihood import likelihood
|
||||||
|
from ..util.linalg import mdot, jitchol, pddet, dpotrs
|
||||||
|
from functools import partial as partial_func
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
class Laplace(likelihood):
|
||||||
|
"""Laplace approximation to a posterior"""
|
||||||
|
|
||||||
|
def __init__(self, data, noise_model, extra_data=None):
|
||||||
|
"""
|
||||||
|
Laplace Approximation
|
||||||
|
|
||||||
|
Find the moments \hat{f} and the hessian at this point
|
||||||
|
(using Newton-Raphson) of the unnormalised posterior
|
||||||
|
|
||||||
|
Compute the GP variables (i.e. generate some Y^{squiggle} and
|
||||||
|
z^{squiggle} which makes a gaussian the same as the laplace
|
||||||
|
approximation to the posterior, but normalised
|
||||||
|
|
||||||
|
Arguments
|
||||||
|
---------
|
||||||
|
|
||||||
|
:param data: array of data the likelihood function is approximating
|
||||||
|
:type data: NxD
|
||||||
|
:param noise_model: likelihood function - subclass of noise_model
|
||||||
|
:type noise_model: noise_model
|
||||||
|
:param extra_data: additional data used by some likelihood functions,
|
||||||
|
"""
|
||||||
|
self.data = data
|
||||||
|
self.noise_model = noise_model
|
||||||
|
self.extra_data = extra_data
|
||||||
|
|
||||||
|
#Inital values
|
||||||
|
self.N, self.D = self.data.shape
|
||||||
|
self.is_heteroscedastic = True
|
||||||
|
self.Nparams = 0
|
||||||
|
self.NORMAL_CONST = ((0.5 * self.N) * np.log(2 * np.pi))
|
||||||
|
|
||||||
|
self.restart()
|
||||||
|
likelihood.__init__(self)
|
||||||
|
|
||||||
|
def restart(self):
|
||||||
|
"""
|
||||||
|
Reset likelihood variables to their defaults
|
||||||
|
"""
|
||||||
|
#Initial values for the GP variables
|
||||||
|
self.Y = np.zeros((self.N, 1))
|
||||||
|
self.covariance_matrix = np.eye(self.N)
|
||||||
|
self.precision = np.ones(self.N)[:, None]
|
||||||
|
self.Z = 0
|
||||||
|
self.YYT = None
|
||||||
|
|
||||||
|
self.old_Ki_f = None
|
||||||
|
self.bad_fhat = False
|
||||||
|
|
||||||
|
def predictive_values(self,mu,var,full_cov,**noise_args):
|
||||||
|
if full_cov:
|
||||||
|
raise NotImplementedError, "Cannot make correlated predictions with an EP likelihood"
|
||||||
|
return self.noise_model.predictive_values(mu,var,**noise_args)
|
||||||
|
|
||||||
|
def log_predictive_density(self, y_test, mu_star, var_star):
|
||||||
|
"""
|
||||||
|
Calculation of the log predictive density
|
||||||
|
|
||||||
|
.. math:
|
||||||
|
p(y_{*}|D) = p(y_{*}|f_{*})p(f_{*}|\mu_{*}\\sigma^{2}_{*})
|
||||||
|
|
||||||
|
:param y_test: test observations (y_{*})
|
||||||
|
:type y_test: (Nx1) array
|
||||||
|
:param mu_star: predictive mean of gaussian p(f_{*}|mu_{*}, var_{*})
|
||||||
|
:type mu_star: (Nx1) array
|
||||||
|
:param var_star: predictive variance of gaussian p(f_{*}|mu_{*}, var_{*})
|
||||||
|
:type var_star: (Nx1) array
|
||||||
|
"""
|
||||||
|
return self.noise_model.log_predictive_density(y_test, mu_star, var_star)
|
||||||
|
|
||||||
|
def _get_params(self):
|
||||||
|
return np.asarray(self.noise_model._get_params())
|
||||||
|
|
||||||
|
def _get_param_names(self):
|
||||||
|
return self.noise_model._get_param_names()
|
||||||
|
|
||||||
|
def _set_params(self, p):
|
||||||
|
return self.noise_model._set_params(p)
|
||||||
|
|
||||||
|
def _shared_gradients_components(self):
|
||||||
|
d3lik_d3fhat = self.noise_model.d3logpdf_df3(self.f_hat, self.data, extra_data=self.extra_data)
|
||||||
|
dL_dfhat = 0.5*(np.diag(self.Ki_W_i)[:, None]*d3lik_d3fhat).T #why isn't this -0.5?
|
||||||
|
I_KW_i = np.eye(self.N) - np.dot(self.K, self.Wi_K_i)
|
||||||
|
return dL_dfhat, I_KW_i
|
||||||
|
|
||||||
|
def _Kgradients(self):
|
||||||
|
"""
|
||||||
|
Gradients with respect to prior kernel parameters dL_dK to be chained
|
||||||
|
with dK_dthetaK to give dL_dthetaK
|
||||||
|
:returns: dL_dK matrix
|
||||||
|
:rtype: Matrix (1 x num_kernel_params)
|
||||||
|
"""
|
||||||
|
dL_dfhat, I_KW_i = self._shared_gradients_components()
|
||||||
|
dlp = self.noise_model.dlogpdf_df(self.f_hat, self.data, extra_data=self.extra_data)
|
||||||
|
|
||||||
|
#Explicit
|
||||||
|
#expl_a = np.dot(self.Ki_f, self.Ki_f.T)
|
||||||
|
#expl_b = self.Wi_K_i
|
||||||
|
#expl = 0.5*expl_a - 0.5*expl_b
|
||||||
|
#dL_dthetaK_exp = dK_dthetaK(expl, X)
|
||||||
|
|
||||||
|
#Implicit
|
||||||
|
impl = mdot(dlp, dL_dfhat, I_KW_i)
|
||||||
|
|
||||||
|
#No longer required as we are computing these in the gp already
|
||||||
|
#otherwise we would take them away and add them back
|
||||||
|
#dL_dthetaK_imp = dK_dthetaK(impl, X)
|
||||||
|
#dL_dthetaK = dL_dthetaK_exp + dL_dthetaK_imp
|
||||||
|
#dL_dK = expl + impl
|
||||||
|
|
||||||
|
#No need to compute explicit as we are computing dZ_dK to account
|
||||||
|
#for the difference between the K gradients of a normal GP,
|
||||||
|
#and the K gradients including the implicit part
|
||||||
|
dL_dK = impl
|
||||||
|
return dL_dK
|
||||||
|
|
||||||
|
def _gradients(self, partial):
|
||||||
|
"""
|
||||||
|
Gradients with respect to likelihood parameters (dL_dthetaL)
|
||||||
|
|
||||||
|
:param partial: Not needed by this likelihood
|
||||||
|
:type partial: lambda function
|
||||||
|
:rtype: array of derivatives (1 x num_likelihood_params)
|
||||||
|
"""
|
||||||
|
dL_dfhat, I_KW_i = self._shared_gradients_components()
|
||||||
|
dlik_dthetaL, dlik_grad_dthetaL, dlik_hess_dthetaL = self.noise_model._laplace_gradients(self.f_hat, self.data, extra_data=self.extra_data)
|
||||||
|
|
||||||
|
#len(dlik_dthetaL)
|
||||||
|
num_params = len(self._get_param_names())
|
||||||
|
# make space for one derivative for each likelihood parameter
|
||||||
|
dL_dthetaL = np.zeros(num_params)
|
||||||
|
for thetaL_i in range(num_params):
|
||||||
|
#Explicit
|
||||||
|
dL_dthetaL_exp = ( np.sum(dlik_dthetaL[:, thetaL_i])
|
||||||
|
#- 0.5*np.trace(mdot(self.Ki_W_i, (self.K, np.diagflat(dlik_hess_dthetaL[thetaL_i]))))
|
||||||
|
+ np.dot(0.5*np.diag(self.Ki_W_i)[:,None].T, dlik_hess_dthetaL[:, thetaL_i])
|
||||||
|
)
|
||||||
|
|
||||||
|
#Implicit
|
||||||
|
dfhat_dthetaL = mdot(I_KW_i, self.K, dlik_grad_dthetaL[:, thetaL_i])
|
||||||
|
dL_dthetaL_imp = np.dot(dL_dfhat, dfhat_dthetaL)
|
||||||
|
dL_dthetaL[thetaL_i] = dL_dthetaL_exp + dL_dthetaL_imp
|
||||||
|
|
||||||
|
return dL_dthetaL
|
||||||
|
|
||||||
|
def _compute_GP_variables(self):
|
||||||
|
"""
|
||||||
|
Generate data Y which would give the normal distribution identical
|
||||||
|
to the laplace approximation to the posterior, but normalised
|
||||||
|
|
||||||
|
GPy expects a likelihood to be gaussian, so need to caluclate
|
||||||
|
the data Y^{\tilde} that makes the posterior match that found
|
||||||
|
by a laplace approximation to a non-gaussian likelihood but with
|
||||||
|
a gaussian likelihood
|
||||||
|
|
||||||
|
Firstly,
|
||||||
|
The hessian of the unormalised posterior distribution is (K^{-1} + W)^{-1},
|
||||||
|
i.e. z*N(f|f^{\hat}, (K^{-1} + W)^{-1}) but this assumes a non-gaussian likelihood,
|
||||||
|
we wish to find the hessian \Sigma^{\tilde}
|
||||||
|
that has the same curvature but using our new simulated data Y^{\tilde}
|
||||||
|
i.e. we do N(Y^{\tilde}|f^{\hat}, \Sigma^{\tilde})N(f|0, K) = z*N(f|f^{\hat}, (K^{-1} + W)^{-1})
|
||||||
|
and we wish to find what Y^{\tilde} and \Sigma^{\tilde}
|
||||||
|
We find that Y^{\tilde} = W^{-1}(K^{-1} + W)f^{\hat} and \Sigma^{tilde} = W^{-1}
|
||||||
|
|
||||||
|
Secondly,
|
||||||
|
GPy optimizes the log marginal log p(y) = -0.5*ln|K+\Sigma^{\tilde}| - 0.5*Y^{\tilde}^{T}(K^{-1} + \Sigma^{tilde})^{-1}Y + lik.Z
|
||||||
|
So we can suck up any differences between that and our log marginal likelihood approximation
|
||||||
|
p^{\squiggle}(y) = -0.5*f^{\hat}K^{-1}f^{\hat} + log p(y|f^{\hat}) - 0.5*log |K||K^{-1} + W|
|
||||||
|
which we want to optimize instead, by equating them and rearranging, the difference is added onto
|
||||||
|
the log p(y) that GPy optimizes by default
|
||||||
|
|
||||||
|
Thirdly,
|
||||||
|
Since we have gradients that depend on how we move f^{\hat}, we have implicit components
|
||||||
|
aswell as the explicit dL_dK, we hold these differences in dZ_dK and add them to dL_dK in the
|
||||||
|
gp.py code
|
||||||
|
"""
|
||||||
|
Wi = 1.0/self.W
|
||||||
|
self.Sigma_tilde = np.diagflat(Wi)
|
||||||
|
|
||||||
|
Y_tilde = Wi*self.Ki_f + self.f_hat
|
||||||
|
|
||||||
|
self.Wi_K_i = self.W12BiW12
|
||||||
|
ln_det_Wi_K = pddet(self.Sigma_tilde + self.K)
|
||||||
|
lik = self.noise_model.logpdf(self.f_hat, self.data, extra_data=self.extra_data)
|
||||||
|
y_Wi_K_i_y = mdot(Y_tilde.T, self.Wi_K_i, Y_tilde)
|
||||||
|
|
||||||
|
Z_tilde = (+ lik
|
||||||
|
- 0.5*self.ln_B_det
|
||||||
|
+ 0.5*ln_det_Wi_K
|
||||||
|
- 0.5*self.f_Ki_f
|
||||||
|
+ 0.5*y_Wi_K_i_y
|
||||||
|
+ self.NORMAL_CONST
|
||||||
|
)
|
||||||
|
|
||||||
|
#Convert to float as its (1, 1) and Z must be a scalar
|
||||||
|
self.Z = np.float64(Z_tilde)
|
||||||
|
self.Y = Y_tilde
|
||||||
|
self.YYT = np.dot(self.Y, self.Y.T)
|
||||||
|
self.covariance_matrix = self.Sigma_tilde
|
||||||
|
self.precision = 1.0 / np.diag(self.covariance_matrix)[:, None]
|
||||||
|
|
||||||
|
#Compute dZ_dK which is how the approximated distributions gradients differ from the dL_dK computed for other likelihoods
|
||||||
|
self.dZ_dK = self._Kgradients()
|
||||||
|
#+ 0.5*self.Wi_K_i - 0.5*np.dot(self.Ki_f, self.Ki_f.T) #since we are not adding the K gradients explicit part theres no need to compute this again
|
||||||
|
|
||||||
|
def fit_full(self, K):
|
||||||
|
"""
|
||||||
|
The laplace approximation algorithm, find K and expand hessian
|
||||||
|
For nomenclature see Rasmussen & Williams 2006 - modified for numerical stability
|
||||||
|
|
||||||
|
:param K: Prior covariance matrix evaluated at locations X
|
||||||
|
:type K: NxN matrix
|
||||||
|
"""
|
||||||
|
self.K = K.copy()
|
||||||
|
|
||||||
|
#Find mode
|
||||||
|
self.f_hat = self.rasm_mode(self.K)
|
||||||
|
|
||||||
|
#Compute hessian and other variables at mode
|
||||||
|
self._compute_likelihood_variables()
|
||||||
|
|
||||||
|
#Compute fake variables replicating laplace approximation to posterior
|
||||||
|
self._compute_GP_variables()
|
||||||
|
|
||||||
|
def _compute_likelihood_variables(self):
|
||||||
|
"""
|
||||||
|
Compute the variables required to compute gaussian Y variables
|
||||||
|
"""
|
||||||
|
#At this point get the hessian matrix (or vector as W is diagonal)
|
||||||
|
self.W = -self.noise_model.d2logpdf_df2(self.f_hat, self.data, extra_data=self.extra_data)
|
||||||
|
|
||||||
|
if not self.noise_model.log_concave:
|
||||||
|
#print "Under 1e-10: {}".format(np.sum(self.W < 1e-6))
|
||||||
|
self.W[self.W < 1e-6] = 1e-6 # FIXME-HACK: This is a hack since GPy can't handle negative variances which can occur
|
||||||
|
|
||||||
|
self.W12BiW12, self.ln_B_det = self._compute_B_statistics(self.K, self.W, np.eye(self.N))
|
||||||
|
|
||||||
|
self.Ki_f = self.Ki_f
|
||||||
|
self.f_Ki_f = np.dot(self.f_hat.T, self.Ki_f)
|
||||||
|
self.Ki_W_i = self.K - mdot(self.K, self.W12BiW12, self.K)
|
||||||
|
|
||||||
|
def _compute_B_statistics(self, K, W, a):
|
||||||
|
"""
|
||||||
|
Rasmussen suggests the use of a numerically stable positive definite matrix B
|
||||||
|
Which has a positive diagonal element and can be easyily inverted
|
||||||
|
|
||||||
|
:param K: Prior Covariance matrix evaluated at locations X
|
||||||
|
:type K: NxN matrix
|
||||||
|
:param W: Negative hessian at a point (diagonal matrix)
|
||||||
|
:type W: Vector of diagonal values of hessian (1xN)
|
||||||
|
:param a: Matrix to calculate W12BiW12a
|
||||||
|
:type a: Matrix NxN
|
||||||
|
:returns: (W12BiW12, ln_B_det)
|
||||||
|
"""
|
||||||
|
if not self.noise_model.log_concave:
|
||||||
|
#print "Under 1e-10: {}".format(np.sum(W < 1e-6))
|
||||||
|
W[W < 1e-6] = 1e-6 # FIXME-HACK: This is a hack since GPy can't handle negative variances which can occur
|
||||||
|
# If the likelihood is non-log-concave. We wan't to say that there is a negative variance
|
||||||
|
# To cause the posterior to become less certain than the prior and likelihood,
|
||||||
|
# This is a property only held by non-log-concave likelihoods
|
||||||
|
|
||||||
|
|
||||||
|
#W is diagonal so its sqrt is just the sqrt of the diagonal elements
|
||||||
|
W_12 = np.sqrt(W)
|
||||||
|
B = np.eye(self.N) + W_12*K*W_12.T
|
||||||
|
L = jitchol(B)
|
||||||
|
|
||||||
|
W12BiW12a = W_12*dpotrs(L, np.asfortranarray(W_12*a), lower=1)[0]
|
||||||
|
ln_B_det = 2*np.sum(np.log(np.diag(L)))
|
||||||
|
return W12BiW12a, ln_B_det
|
||||||
|
|
||||||
|
def rasm_mode(self, K, MAX_ITER=40):
|
||||||
|
"""
|
||||||
|
Rasmussen's numerically stable mode finding
|
||||||
|
For nomenclature see Rasmussen & Williams 2006
|
||||||
|
Influenced by GPML (BSD) code, all errors are our own
|
||||||
|
|
||||||
|
:param K: Covariance matrix evaluated at locations X
|
||||||
|
:type K: NxD matrix
|
||||||
|
:param MAX_ITER: Maximum number of iterations of newton-raphson before forcing finish of optimisation
|
||||||
|
:type MAX_ITER: scalar
|
||||||
|
:returns: f_hat, mode on which to make laplace approxmiation
|
||||||
|
:rtype: NxD matrix
|
||||||
|
"""
|
||||||
|
#old_Ki_f = np.zeros((self.N, 1))
|
||||||
|
|
||||||
|
#Start f's at zero originally of if we have gone off track, try restarting
|
||||||
|
if self.old_Ki_f is None or self.bad_fhat:
|
||||||
|
old_Ki_f = np.random.rand(self.N, 1)/50.0
|
||||||
|
#old_Ki_f = self.Y
|
||||||
|
f = np.dot(K, old_Ki_f)
|
||||||
|
else:
|
||||||
|
#Start at the old best point
|
||||||
|
old_Ki_f = self.old_Ki_f.copy()
|
||||||
|
f = self.f_hat.copy()
|
||||||
|
|
||||||
|
new_obj = -np.inf
|
||||||
|
old_obj = np.inf
|
||||||
|
|
||||||
|
def obj(Ki_f, f):
|
||||||
|
return -0.5*np.dot(Ki_f.T, f) + self.noise_model.logpdf(f, self.data, extra_data=self.extra_data)
|
||||||
|
|
||||||
|
difference = np.inf
|
||||||
|
epsilon = 1e-7
|
||||||
|
#step_size = 1
|
||||||
|
#rs = 0
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
while difference > epsilon and i < MAX_ITER:
|
||||||
|
W = -self.noise_model.d2logpdf_df2(f, self.data, extra_data=self.extra_data)
|
||||||
|
|
||||||
|
W_f = W*f
|
||||||
|
grad = self.noise_model.dlogpdf_df(f, self.data, extra_data=self.extra_data)
|
||||||
|
|
||||||
|
b = W_f + grad
|
||||||
|
W12BiW12Kb, _ = self._compute_B_statistics(K, W.copy(), np.dot(K, b))
|
||||||
|
|
||||||
|
#Work out the DIRECTION that we want to move in, but don't choose the stepsize yet
|
||||||
|
full_step_Ki_f = b - W12BiW12Kb
|
||||||
|
dKi_f = full_step_Ki_f - old_Ki_f
|
||||||
|
|
||||||
|
f_old = f.copy()
|
||||||
|
def inner_obj(step_size, old_Ki_f, dKi_f, K):
|
||||||
|
Ki_f = old_Ki_f + step_size*dKi_f
|
||||||
|
f = np.dot(K, Ki_f)
|
||||||
|
# This is nasty, need to set something within an optimization though
|
||||||
|
self.tmp_Ki_f = Ki_f.copy()
|
||||||
|
self.tmp_f = f.copy()
|
||||||
|
return -obj(Ki_f, f)
|
||||||
|
|
||||||
|
i_o = partial_func(inner_obj, old_Ki_f=old_Ki_f, dKi_f=dKi_f, K=K)
|
||||||
|
#Find the stepsize that minimizes the objective function using a brent line search
|
||||||
|
#The tolerance and maxiter matter for speed! Seems to be best to keep them low and make more full
|
||||||
|
#steps than get this exact then make a step, if B was bigger it might be the other way around though
|
||||||
|
#new_obj = sp.optimize.minimize_scalar(i_o, method='brent', tol=1e-4, options={'maxiter':5}).fun
|
||||||
|
new_obj = sp.optimize.brent(i_o, tol=1e-4, maxiter=10)
|
||||||
|
f = self.tmp_f.copy()
|
||||||
|
Ki_f = self.tmp_Ki_f.copy()
|
||||||
|
|
||||||
|
#Optimize without linesearch
|
||||||
|
#f_old = f.copy()
|
||||||
|
#update_passed = False
|
||||||
|
#while not update_passed:
|
||||||
|
#Ki_f = old_Ki_f + step_size*dKi_f
|
||||||
|
#f = np.dot(K, Ki_f)
|
||||||
|
|
||||||
|
#old_obj = new_obj
|
||||||
|
#new_obj = obj(Ki_f, f)
|
||||||
|
#difference = new_obj - old_obj
|
||||||
|
##print "difference: ",difference
|
||||||
|
#if difference < 0:
|
||||||
|
##print "Objective function rose", np.float(difference)
|
||||||
|
##If the objective function isn't rising, restart optimization
|
||||||
|
#step_size *= 0.8
|
||||||
|
##print "Reducing step-size to {ss:.3} and restarting optimization".format(ss=step_size)
|
||||||
|
##objective function isn't increasing, try reducing step size
|
||||||
|
#f = f_old.copy() #it's actually faster not to go back to old location and just zigzag across the mode
|
||||||
|
#old_obj = new_obj
|
||||||
|
#rs += 1
|
||||||
|
#else:
|
||||||
|
#update_passed = True
|
||||||
|
|
||||||
|
#old_Ki_f = self.Ki_f.copy()
|
||||||
|
|
||||||
|
#difference = abs(new_obj - old_obj)
|
||||||
|
#old_obj = new_obj.copy()
|
||||||
|
difference = np.abs(np.sum(f - f_old)) + np.abs(np.sum(Ki_f - old_Ki_f))
|
||||||
|
#difference = np.abs(np.sum(Ki_f - old_Ki_f))/np.float(self.N)
|
||||||
|
old_Ki_f = Ki_f.copy()
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
self.old_Ki_f = old_Ki_f.copy()
|
||||||
|
|
||||||
|
#Warn of bad fits
|
||||||
|
if difference > epsilon:
|
||||||
|
self.bad_fhat = True
|
||||||
|
warnings.warn("Not perfect f_hat fit difference: {}".format(difference))
|
||||||
|
elif self.bad_fhat:
|
||||||
|
self.bad_fhat = False
|
||||||
|
warnings.warn("f_hat now perfect again")
|
||||||
|
|
||||||
|
self.Ki_f = Ki_f
|
||||||
|
return f
|
||||||
|
|
@ -23,6 +23,7 @@ class likelihood(Parameterized):
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Parameterized.__init__(self)
|
Parameterized.__init__(self)
|
||||||
|
self.dZ_dK = 0
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
@ -33,11 +34,36 @@ class likelihood(Parameterized):
|
||||||
def _set_params(self, x):
|
def _set_params(self, x):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def fit(self):
|
def fit_full(self, K):
|
||||||
raise NotImplementedError
|
"""
|
||||||
|
No approximations needed by default
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def restart(self):
|
||||||
|
"""
|
||||||
|
No need to restart if not an approximation
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
def _gradients(self, partial):
|
def _gradients(self, partial):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def predictive_values(self, mu, var):
|
def predictive_values(self, mu, var):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def log_predictive_density(self, y_test, mu_star, var_star):
|
||||||
|
"""
|
||||||
|
Calculation of the predictive density
|
||||||
|
|
||||||
|
.. math:
|
||||||
|
p(y_{*}|D) = p(y_{*}|f_{*})p(f_{*}|\mu_{*}\\sigma^{2}_{*})
|
||||||
|
|
||||||
|
:param y_test: test observations (y_{*})
|
||||||
|
:type y_test: (Nx1) array
|
||||||
|
:param mu_star: predictive mean of gaussian p(f_{*}|mu_{*}, var_{*})
|
||||||
|
:type mu_star: (Nx1) array
|
||||||
|
:param var_star: predictive variance of gaussian p(f_{*}|mu_{*}, var_{*})
|
||||||
|
:type var_star: (Nx1) array
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import noise_models
|
import noise_models
|
||||||
|
|
||||||
def binomial(gp_link=None):
|
def bernoulli(gp_link=None):
|
||||||
"""
|
"""
|
||||||
Construct a binomial likelihood
|
Construct a bernoulli likelihood
|
||||||
|
|
||||||
:param gp_link: a GPy gp_link function
|
:param gp_link: a GPy gp_link function
|
||||||
"""
|
"""
|
||||||
|
|
@ -27,16 +27,17 @@ def binomial(gp_link=None):
|
||||||
analytical_mean = False
|
analytical_mean = False
|
||||||
analytical_variance = False
|
analytical_variance = False
|
||||||
|
|
||||||
return noise_models.binomial_noise.Binomial(gp_link,analytical_mean,analytical_variance)
|
return noise_models.bernoulli_noise.Bernoulli(gp_link,analytical_mean,analytical_variance)
|
||||||
|
|
||||||
def exponential(gp_link=None):
|
def exponential(gp_link=None):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Construct a binomial likelihood
|
Construct a exponential likelihood
|
||||||
|
|
||||||
:param gp_link: a GPy gp_link function
|
:param gp_link: a GPy gp_link function
|
||||||
"""
|
"""
|
||||||
if gp_link is None:
|
if gp_link is None:
|
||||||
gp_link = noise_models.gp_transformations.Identity()
|
gp_link = noise_models.gp_transformations.Log_ex_1()
|
||||||
|
|
||||||
analytical_mean = False
|
analytical_mean = False
|
||||||
analytical_variance = False
|
analytical_variance = False
|
||||||
|
|
@ -85,4 +86,36 @@ def gamma(gp_link=None,beta=1.):
|
||||||
analytical_variance = False
|
analytical_variance = False
|
||||||
return noise_models.gamma_noise.Gamma(gp_link,analytical_mean,analytical_variance,beta)
|
return noise_models.gamma_noise.Gamma(gp_link,analytical_mean,analytical_variance,beta)
|
||||||
|
|
||||||
|
def gaussian(gp_link=None, variance=2, D=None, N=None):
|
||||||
|
"""
|
||||||
|
Construct a Gaussian likelihood
|
||||||
|
|
||||||
|
:param gp_link: a GPy gp_link function
|
||||||
|
:param variance: variance
|
||||||
|
:type variance: scalar
|
||||||
|
:returns: Gaussian noise model:
|
||||||
|
"""
|
||||||
|
if gp_link is None:
|
||||||
|
gp_link = noise_models.gp_transformations.Identity()
|
||||||
|
analytical_mean = True
|
||||||
|
analytical_variance = True # ?
|
||||||
|
return noise_models.gaussian_noise.Gaussian(gp_link, analytical_mean,
|
||||||
|
analytical_variance, variance=variance, D=D, N=N)
|
||||||
|
|
||||||
|
def student_t(gp_link=None, deg_free=5, sigma2=2):
|
||||||
|
"""
|
||||||
|
Construct a Student t likelihood
|
||||||
|
|
||||||
|
:param gp_link: a GPy gp_link function
|
||||||
|
:param deg_free: degrees of freedom of student-t
|
||||||
|
:type deg_free: scalar
|
||||||
|
:param sigma2: variance
|
||||||
|
:type sigma2: scalar
|
||||||
|
:returns: Student-T noise model
|
||||||
|
"""
|
||||||
|
if gp_link is None:
|
||||||
|
gp_link = noise_models.gp_transformations.Identity()
|
||||||
|
analytical_mean = True
|
||||||
|
analytical_variance = True
|
||||||
|
return noise_models.student_t_noise.StudentT(gp_link, analytical_mean,
|
||||||
|
analytical_variance,deg_free, sigma2)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import noise_distributions
|
import noise_distributions
|
||||||
import binomial_noise
|
import bernoulli_noise
|
||||||
import exponential_noise
|
import exponential_noise
|
||||||
import gaussian_noise
|
import gaussian_noise
|
||||||
import gamma_noise
|
import gamma_noise
|
||||||
import poisson_noise
|
import poisson_noise
|
||||||
|
import student_t_noise
|
||||||
import gp_transformations
|
import gp_transformations
|
||||||
|
|
|
||||||
222
GPy/likelihoods/noise_models/bernoulli_noise.py
Normal file
222
GPy/likelihoods/noise_models/bernoulli_noise.py
Normal file
|
|
@ -0,0 +1,222 @@
|
||||||
|
# Copyright (c) 2012, 2013 Ricardo Andrade
|
||||||
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from scipy import stats,special
|
||||||
|
import scipy as sp
|
||||||
|
from GPy.util.univariate_Gaussian import std_norm_pdf,std_norm_cdf
|
||||||
|
import gp_transformations
|
||||||
|
from noise_distributions import NoiseDistribution
|
||||||
|
|
||||||
|
class Bernoulli(NoiseDistribution):
|
||||||
|
"""
|
||||||
|
Bernoulli likelihood
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
p(y_{i}|\\lambda(f_{i})) = \\lambda(f_{i})^{y_{i}}(1-f_{i})^{1-y_{i}}
|
||||||
|
|
||||||
|
.. Note::
|
||||||
|
Y is expected to take values in {-1,1}
|
||||||
|
Probit likelihood usually used
|
||||||
|
"""
|
||||||
|
def __init__(self,gp_link=None,analytical_mean=False,analytical_variance=False):
|
||||||
|
super(Bernoulli, self).__init__(gp_link,analytical_mean,analytical_variance)
|
||||||
|
if isinstance(gp_link , (gp_transformations.Heaviside, gp_transformations.Probit)):
|
||||||
|
self.log_concave = True
|
||||||
|
|
||||||
|
def _preprocess_values(self,Y):
|
||||||
|
"""
|
||||||
|
Check if the values of the observations correspond to the values
|
||||||
|
assumed by the likelihood function.
|
||||||
|
|
||||||
|
..Note:: Binary classification algorithm works better with classes {-1,1}
|
||||||
|
"""
|
||||||
|
Y_prep = Y.copy()
|
||||||
|
Y1 = Y[Y.flatten()==1].size
|
||||||
|
Y2 = Y[Y.flatten()==0].size
|
||||||
|
assert Y1 + Y2 == Y.size, 'Bernoulli likelihood is meant to be used only with outputs in {0,1}.'
|
||||||
|
Y_prep[Y.flatten() == 0] = -1
|
||||||
|
return Y_prep
|
||||||
|
|
||||||
|
def _moments_match_analytical(self,data_i,tau_i,v_i):
|
||||||
|
"""
|
||||||
|
Moments match of the marginal approximation in EP algorithm
|
||||||
|
|
||||||
|
:param i: number of observation (int)
|
||||||
|
:param tau_i: precision of the cavity distribution (float)
|
||||||
|
:param v_i: mean/variance of the cavity distribution (float)
|
||||||
|
"""
|
||||||
|
if data_i == 1:
|
||||||
|
sign = 1.
|
||||||
|
elif data_i == 0:
|
||||||
|
sign = -1
|
||||||
|
else:
|
||||||
|
raise ValueError("bad value for Bernouilli observation (0,1)")
|
||||||
|
if isinstance(self.gp_link,gp_transformations.Probit):
|
||||||
|
z = sign*v_i/np.sqrt(tau_i**2 + tau_i)
|
||||||
|
Z_hat = std_norm_cdf(z)
|
||||||
|
phi = std_norm_pdf(z)
|
||||||
|
mu_hat = v_i/tau_i + sign*phi/(Z_hat*np.sqrt(tau_i**2 + tau_i))
|
||||||
|
sigma2_hat = 1./tau_i - (phi/((tau_i**2+tau_i)*Z_hat))*(z+phi/Z_hat)
|
||||||
|
|
||||||
|
elif isinstance(self.gp_link,gp_transformations.Heaviside):
|
||||||
|
a = sign*v_i/np.sqrt(tau_i)
|
||||||
|
Z_hat = std_norm_cdf(a)
|
||||||
|
N = std_norm_pdf(a)
|
||||||
|
mu_hat = v_i/tau_i + sign*N/Z_hat/np.sqrt(tau_i)
|
||||||
|
sigma2_hat = (1. - a*N/Z_hat - np.square(N/Z_hat))/tau_i
|
||||||
|
if np.any(np.isnan([Z_hat, mu_hat, sigma2_hat])):
|
||||||
|
stop
|
||||||
|
else:
|
||||||
|
raise ValueError("Exact moment matching not available for link {}".format(self.gp_link.gp_transformations.__name__))
|
||||||
|
|
||||||
|
return Z_hat, mu_hat, sigma2_hat
|
||||||
|
|
||||||
|
def _predictive_mean_analytical(self,mu,variance):
|
||||||
|
|
||||||
|
if isinstance(self.gp_link,gp_transformations.Probit):
|
||||||
|
return stats.norm.cdf(mu/np.sqrt(1+variance))
|
||||||
|
|
||||||
|
elif isinstance(self.gp_link,gp_transformations.Heaviside):
|
||||||
|
return stats.norm.cdf(mu/np.sqrt(variance))
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def _predictive_variance_analytical(self,mu,variance, pred_mean):
|
||||||
|
|
||||||
|
if isinstance(self.gp_link,gp_transformations.Heaviside):
|
||||||
|
return 0.
|
||||||
|
else:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def pdf_link(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Likelihood function given link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
p(y_{i}|\\lambda(f_{i})) = \\lambda(f_{i})^{y_{i}}(1-f_{i})^{1-y_{i}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in bernoulli
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
|
|
||||||
|
.. Note:
|
||||||
|
Each y_i must be in {0,1}
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
objective = (link_f**y) * ((1.-link_f)**(1.-y))
|
||||||
|
return np.exp(np.sum(np.log(objective)))
|
||||||
|
|
||||||
|
def logpdf_link(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Log Likelihood function given link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\ln p(y_{i}|\\lambda(f_{i})) = y_{i}\\log\\lambda(f_{i}) + (1-y_{i})\\log (1-f_{i})
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in bernoulli
|
||||||
|
:returns: log likelihood evaluated at points link(f)
|
||||||
|
:rtype: float
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
#objective = y*np.log(link_f) + (1.-y)*np.log(link_f)
|
||||||
|
objective = np.where(y==1, np.log(link_f), np.log(1-link_f))
|
||||||
|
return np.sum(objective)
|
||||||
|
|
||||||
|
def dlogpdf_dlink(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Gradient of the pdf at y, given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d\\ln p(y_{i}|\\lambda(f_{i}))}{d\\lambda(f)} = \\frac{y_{i}}{\\lambda(f_{i})} - \\frac{(1 - y_{i})}{(1 - \\lambda(f_{i}))}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in bernoulli
|
||||||
|
:returns: gradient of log likelihood evaluated at points link(f)
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
grad = (y/link_f) - (1.-y)/(1-link_f)
|
||||||
|
return grad
|
||||||
|
|
||||||
|
def d2logpdf_dlink2(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Hessian at y, given link_f, w.r.t link_f the hessian will be 0 unless i == j
|
||||||
|
i.e. second derivative logpdf at y given link(f_i) link(f_j) w.r.t link(f_i) and link(f_j)
|
||||||
|
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{2}\\ln p(y_{i}|\\lambda(f_{i}))}{d\\lambda(f)^{2}} = \\frac{-y_{i}}{\\lambda(f)^{2}} - \\frac{(1-y_{i})}{(1-\\lambda(f))^{2}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in bernoulli
|
||||||
|
:returns: Diagonal of log hessian matrix (second derivative of log likelihood evaluated at points link(f))
|
||||||
|
:rtype: Nx1 array
|
||||||
|
|
||||||
|
.. Note::
|
||||||
|
Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases
|
||||||
|
(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
d2logpdf_dlink2 = -y/(link_f**2) - (1-y)/((1-link_f)**2)
|
||||||
|
return d2logpdf_dlink2
|
||||||
|
|
||||||
|
def d3logpdf_dlink3(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Third order derivative log-likelihood function at y given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{3} \\ln p(y_{i}|\\lambda(f_{i}))}{d^{3}\\lambda(f)} = \\frac{2y_{i}}{\\lambda(f)^{3}} - \\frac{2(1-y_{i}}{(1-\\lambda(f))^{3}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in bernoulli
|
||||||
|
:returns: third derivative of log likelihood evaluated at points link(f)
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
d3logpdf_dlink3 = 2*(y/(link_f**3) - (1-y)/((1-link_f)**3))
|
||||||
|
return d3logpdf_dlink3
|
||||||
|
|
||||||
|
def _mean(self,gp):
|
||||||
|
"""
|
||||||
|
Mass (or density) function
|
||||||
|
"""
|
||||||
|
return self.gp_link.transf(gp)
|
||||||
|
|
||||||
|
def _variance(self,gp):
|
||||||
|
"""
|
||||||
|
Mass (or density) function
|
||||||
|
"""
|
||||||
|
p = self.gp_link.transf(gp)
|
||||||
|
return p*(1.-p)
|
||||||
|
|
||||||
|
def samples(self, gp):
|
||||||
|
"""
|
||||||
|
Returns a set of samples of observations based on a given value of the latent variable.
|
||||||
|
|
||||||
|
:param gp: latent variable
|
||||||
|
"""
|
||||||
|
orig_shape = gp.shape
|
||||||
|
gp = gp.flatten()
|
||||||
|
ns = np.ones_like(gp, dtype=int)
|
||||||
|
Ysim = np.random.binomial(ns, self.gp_link.transf(gp))
|
||||||
|
return Ysim.reshape(orig_shape)
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
# Copyright (c) 2012, 2013 Ricardo Andrade
|
|
||||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
from scipy import stats,special
|
|
||||||
import scipy as sp
|
|
||||||
from GPy.util.univariate_Gaussian import std_norm_pdf,std_norm_cdf
|
|
||||||
import gp_transformations
|
|
||||||
from noise_distributions import NoiseDistribution
|
|
||||||
|
|
||||||
class Binomial(NoiseDistribution):
|
|
||||||
"""
|
|
||||||
Probit likelihood
|
|
||||||
Y is expected to take values in {-1,1}
|
|
||||||
-----
|
|
||||||
$$
|
|
||||||
L(x) = \\Phi (Y_i*f_i)
|
|
||||||
$$
|
|
||||||
"""
|
|
||||||
def __init__(self,gp_link=None,analytical_mean=False,analytical_variance=False):
|
|
||||||
super(Binomial, self).__init__(gp_link,analytical_mean,analytical_variance)
|
|
||||||
|
|
||||||
def _preprocess_values(self,Y):
|
|
||||||
"""
|
|
||||||
Check if the values of the observations correspond to the values
|
|
||||||
assumed by the likelihood function.
|
|
||||||
|
|
||||||
..Note:: Binary classification algorithm works better with classes {-1,1}
|
|
||||||
"""
|
|
||||||
Y_prep = Y.copy()
|
|
||||||
Y1 = Y[Y.flatten()==1].size
|
|
||||||
Y2 = Y[Y.flatten()==0].size
|
|
||||||
assert Y1 + Y2 == Y.size, 'Binomial likelihood is meant to be used only with outputs in {0,1}.'
|
|
||||||
Y_prep[Y.flatten() == 0] = -1
|
|
||||||
return Y_prep
|
|
||||||
|
|
||||||
def _moments_match_analytical(self,data_i,tau_i,v_i):
|
|
||||||
"""
|
|
||||||
Moments match of the marginal approximation in EP algorithm
|
|
||||||
|
|
||||||
:param i: number of observation (int)
|
|
||||||
:param tau_i: precision of the cavity distribution (float)
|
|
||||||
:param v_i: mean/variance of the cavity distribution (float)
|
|
||||||
"""
|
|
||||||
if isinstance(self.gp_link,gp_transformations.Probit):
|
|
||||||
z = data_i*v_i/np.sqrt(tau_i**2 + tau_i)
|
|
||||||
Z_hat = std_norm_cdf(z)
|
|
||||||
phi = std_norm_pdf(z)
|
|
||||||
mu_hat = v_i/tau_i + data_i*phi/(Z_hat*np.sqrt(tau_i**2 + tau_i))
|
|
||||||
sigma2_hat = 1./tau_i - (phi/((tau_i**2+tau_i)*Z_hat))*(z+phi/Z_hat)
|
|
||||||
|
|
||||||
elif isinstance(self.gp_link,gp_transformations.Heaviside):
|
|
||||||
a = data_i*v_i/np.sqrt(tau_i)
|
|
||||||
Z_hat = std_norm_cdf(a)
|
|
||||||
N = std_norm_pdf(a)
|
|
||||||
mu_hat = v_i/tau_i + data_i*N/Z_hat/np.sqrt(tau_i)
|
|
||||||
sigma2_hat = (1. - a*N/Z_hat - np.square(N/Z_hat))/tau_i
|
|
||||||
if np.any(np.isnan([Z_hat, mu_hat, sigma2_hat])):
|
|
||||||
stop
|
|
||||||
|
|
||||||
return Z_hat, mu_hat, sigma2_hat
|
|
||||||
|
|
||||||
def _predictive_mean_analytical(self,mu,sigma):
|
|
||||||
if isinstance(self.gp_link,gp_transformations.Probit):
|
|
||||||
return stats.norm.cdf(mu/np.sqrt(1+sigma**2))
|
|
||||||
elif isinstance(self.gp_link,gp_transformations.Heaviside):
|
|
||||||
return stats.norm.cdf(mu/sigma)
|
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def _predictive_variance_analytical(self,mu,sigma, pred_mean):
|
|
||||||
if isinstance(self.gp_link,gp_transformations.Heaviside):
|
|
||||||
return 0.
|
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def _mass(self,gp,obs):
|
|
||||||
#NOTE obs must be in {0,1}
|
|
||||||
p = self.gp_link.transf(gp)
|
|
||||||
return p**obs * (1.-p)**(1.-obs)
|
|
||||||
|
|
||||||
def _nlog_mass(self,gp,obs):
|
|
||||||
p = self.gp_link.transf(gp)
|
|
||||||
return obs*np.log(p) + (1.-obs)*np.log(1-p)
|
|
||||||
|
|
||||||
def _dnlog_mass_dgp(self,gp,obs):
|
|
||||||
p = self.gp_link.transf(gp)
|
|
||||||
dp = self.gp_link.dtransf_df(gp)
|
|
||||||
return obs/p * dp - (1.-obs)/(1.-p) * dp
|
|
||||||
|
|
||||||
def _d2nlog_mass_dgp2(self,gp,obs):
|
|
||||||
p = self.gp_link.transf(gp)
|
|
||||||
return (obs/p + (1.-obs)/(1.-p))*self.gp_link.d2transf_df2(gp) + ((1.-obs)/(1.-p)**2-obs/p**2)*self.gp_link.dtransf_df(gp)
|
|
||||||
|
|
||||||
def _mean(self,gp):
|
|
||||||
"""
|
|
||||||
Mass (or density) function
|
|
||||||
"""
|
|
||||||
return self.gp_link.transf(gp)
|
|
||||||
|
|
||||||
def _dmean_dgp(self,gp):
|
|
||||||
return self.gp_link.dtransf_df(gp)
|
|
||||||
|
|
||||||
def _d2mean_dgp2(self,gp):
|
|
||||||
return self.gp_link.d2transf_df2(gp)
|
|
||||||
|
|
||||||
def _variance(self,gp):
|
|
||||||
"""
|
|
||||||
Mass (or density) function
|
|
||||||
"""
|
|
||||||
p = self.gp_link.transf(gp)
|
|
||||||
return p*(1.-p)
|
|
||||||
|
|
||||||
def _dvariance_dgp(self,gp):
|
|
||||||
return self.gp_link.dtransf_df(gp)*(1. - 2.*self.gp_link.transf(gp))
|
|
||||||
|
|
||||||
def _d2variance_dgp2(self,gp):
|
|
||||||
return self.gp_link.d2transf_df2(gp)*(1. - 2.*self.gp_link.transf(gp)) - 2*self.gp_link.dtransf_df(gp)**2
|
|
||||||
|
|
||||||
|
|
||||||
def samples(self, gp):
|
|
||||||
"""
|
|
||||||
Returns a set of samples of observations based on a given value of the latent variable.
|
|
||||||
|
|
||||||
:param size: number of samples to compute
|
|
||||||
:param gp: latent variable
|
|
||||||
"""
|
|
||||||
orig_shape = gp.shape
|
|
||||||
gp = gp.flatten()
|
|
||||||
Ysim = np.array([np.random.binomial(1,self.gp_link.transf(gpj),size=1) for gpj in gp])
|
|
||||||
return Ysim.reshape(orig_shape)
|
|
||||||
|
|
@ -24,24 +24,113 @@ class Exponential(NoiseDistribution):
|
||||||
def _preprocess_values(self,Y):
|
def _preprocess_values(self,Y):
|
||||||
return Y
|
return Y
|
||||||
|
|
||||||
def _mass(self,gp,obs):
|
def pdf_link(self, link_f, y, extra_data=None):
|
||||||
"""
|
"""
|
||||||
Mass (or density) function
|
Likelihood function given link(f)
|
||||||
"""
|
|
||||||
return np.exp(-obs/self.gp_link.transf(gp))/self.gp_link.transf(gp)
|
|
||||||
|
|
||||||
def _nlog_mass(self,gp,obs):
|
.. math::
|
||||||
"""
|
p(y_{i}|\\lambda(f_{i})) = \\lambda(f_{i})\\exp (-y\\lambda(f_{i}))
|
||||||
Negative logarithm of the un-normalized distribution: factors that are not a function of gp are omitted
|
|
||||||
"""
|
|
||||||
return obs/self.gp_link.transf(gp) + np.log(self.gp_link.transf(gp))
|
|
||||||
|
|
||||||
def _dnlog_mass_dgp(self,gp,obs):
|
:param link_f: latent variables link(f)
|
||||||
return ( 1./self.gp_link.transf(gp) - obs/self.gp_link.transf(gp)**2) * self.gp_link.dtransf_df(gp)
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in exponential distribution
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
log_objective = link_f*np.exp(-y*link_f)
|
||||||
|
return np.exp(np.sum(np.log(log_objective)))
|
||||||
|
#return np.exp(np.sum(-y/link_f - np.log(link_f) ))
|
||||||
|
|
||||||
def _d2nlog_mass_dgp2(self,gp,obs):
|
def logpdf_link(self, link_f, y, extra_data=None):
|
||||||
fgp = self.gp_link.transf(gp)
|
"""
|
||||||
return (2*obs/fgp**3 - 1./fgp**2) * self.gp_link.dtransf_df(gp)**2 + ( 1./fgp - obs/fgp**2) * self.gp_link.d2transf_df2(gp)
|
Log Likelihood Function given link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\ln p(y_{i}|\lambda(f_{i})) = \\ln \\lambda(f_{i}) - y_{i}\\lambda(f_{i})
|
||||||
|
|
||||||
|
:param link_f: latent variables (link(f))
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in exponential distribution
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
|
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
log_objective = np.log(link_f) - y*link_f
|
||||||
|
#logpdf_link = np.sum(-np.log(link_f) - y/link_f)
|
||||||
|
return np.sum(log_objective)
|
||||||
|
|
||||||
|
def dlogpdf_dlink(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Gradient of the log likelihood function at y, given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d \\ln p(y_{i}|\lambda(f_{i}))}{d\\lambda(f)} = \\frac{1}{\\lambda(f)} - y_{i}
|
||||||
|
|
||||||
|
:param link_f: latent variables (f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in exponential distribution
|
||||||
|
:returns: gradient of likelihood evaluated at points
|
||||||
|
:rtype: Nx1 array
|
||||||
|
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
grad = 1./link_f - y
|
||||||
|
#grad = y/(link_f**2) - 1./link_f
|
||||||
|
return grad
|
||||||
|
|
||||||
|
def d2logpdf_dlink2(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Hessian at y, given link(f), w.r.t link(f)
|
||||||
|
i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j)
|
||||||
|
The hessian will be 0 unless i == j
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{2} \\ln p(y_{i}|\lambda(f_{i}))}{d^{2}\\lambda(f)} = -\\frac{1}{\\lambda(f_{i})^{2}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in exponential distribution
|
||||||
|
:returns: Diagonal of hessian matrix (second derivative of likelihood evaluated at points f)
|
||||||
|
:rtype: Nx1 array
|
||||||
|
|
||||||
|
.. Note::
|
||||||
|
Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases
|
||||||
|
(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
hess = -1./(link_f**2)
|
||||||
|
#hess = -2*y/(link_f**3) + 1/(link_f**2)
|
||||||
|
return hess
|
||||||
|
|
||||||
|
def d3logpdf_dlink3(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Third order derivative log-likelihood function at y given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{3} \\ln p(y_{i}|\lambda(f_{i}))}{d^{3}\\lambda(f)} = \\frac{2}{\\lambda(f_{i})^{3}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in exponential distribution
|
||||||
|
:returns: third derivative of likelihood evaluated at points f
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
d3lik_dlink3 = 2./(link_f**3)
|
||||||
|
#d3lik_dlink3 = 6*y/(link_f**4) - 2./(link_f**3)
|
||||||
|
return d3lik_dlink3
|
||||||
|
|
||||||
def _mean(self,gp):
|
def _mean(self,gp):
|
||||||
"""
|
"""
|
||||||
|
|
@ -49,20 +138,19 @@ class Exponential(NoiseDistribution):
|
||||||
"""
|
"""
|
||||||
return self.gp_link.transf(gp)
|
return self.gp_link.transf(gp)
|
||||||
|
|
||||||
def _dmean_dgp(self,gp):
|
|
||||||
return self.gp_link.dtransf_df(gp)
|
|
||||||
|
|
||||||
def _d2mean_dgp2(self,gp):
|
|
||||||
return self.gp_link.d2transf_df2(gp)
|
|
||||||
|
|
||||||
def _variance(self,gp):
|
def _variance(self,gp):
|
||||||
"""
|
"""
|
||||||
Mass (or density) function
|
Mass (or density) function
|
||||||
"""
|
"""
|
||||||
return self.gp_link.transf(gp)**2
|
return self.gp_link.transf(gp)**2
|
||||||
|
|
||||||
def _dvariance_dgp(self,gp):
|
def samples(self, gp):
|
||||||
return 2*self.gp_link.transf(gp)*self.gp_link.dtransf_df(gp)
|
"""
|
||||||
|
Returns a set of samples of observations based on a given value of the latent variable.
|
||||||
|
|
||||||
def _d2variance_dgp2(self,gp):
|
:param gp: latent variable
|
||||||
return 2 * (self.gp_link.dtransf_df(gp)**2 + self.gp_link.transf(gp)*self.gp_link.d2transf_df2(gp))
|
"""
|
||||||
|
orig_shape = gp.shape
|
||||||
|
gp = gp.flatten()
|
||||||
|
Ysim = np.random.exponential(1.0/self.gp_link.transf(gp))
|
||||||
|
return Ysim.reshape(orig_shape)
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ from noise_distributions import NoiseDistribution
|
||||||
class Gamma(NoiseDistribution):
|
class Gamma(NoiseDistribution):
|
||||||
"""
|
"""
|
||||||
Gamma likelihood
|
Gamma likelihood
|
||||||
Y is expected to take values in {0,1,2,...}
|
|
||||||
-----
|
.. math::
|
||||||
$$
|
p(y_{i}|\\lambda(f_{i})) = \\frac{\\beta^{\\alpha_{i}}}{\\Gamma(\\alpha_{i})}y_{i}^{\\alpha_{i}-1}e^{-\\beta y_{i}}\\\\
|
||||||
L(x) = \exp(\lambda) * \lambda**Y_i / Y_i!
|
\\alpha_{i} = \\beta y_{i}
|
||||||
$$
|
|
||||||
"""
|
"""
|
||||||
def __init__(self,gp_link=None,analytical_mean=False,analytical_variance=False,beta=1.):
|
def __init__(self,gp_link=None,analytical_mean=False,analytical_variance=False,beta=1.):
|
||||||
self.beta = beta
|
self.beta = beta
|
||||||
|
|
@ -25,26 +25,122 @@ class Gamma(NoiseDistribution):
|
||||||
def _preprocess_values(self,Y):
|
def _preprocess_values(self,Y):
|
||||||
return Y
|
return Y
|
||||||
|
|
||||||
def _mass(self,gp,obs):
|
def pdf_link(self, link_f, y, extra_data=None):
|
||||||
"""
|
"""
|
||||||
Mass (or density) function
|
Likelihood function given link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
p(y_{i}|\\lambda(f_{i})) = \\frac{\\beta^{\\alpha_{i}}}{\\Gamma(\\alpha_{i})}y_{i}^{\\alpha_{i}-1}e^{-\\beta y_{i}}\\\\
|
||||||
|
\\alpha_{i} = \\beta y_{i}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in poisson distribution
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
"""
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
#return stats.gamma.pdf(obs,a = self.gp_link.transf(gp)/self.variance,scale=self.variance)
|
#return stats.gamma.pdf(obs,a = self.gp_link.transf(gp)/self.variance,scale=self.variance)
|
||||||
alpha = self.gp_link.transf(gp)*self.beta
|
alpha = link_f*self.beta
|
||||||
return obs**(alpha - 1.) * np.exp(-self.beta*obs) * self.beta**alpha / special.gamma(alpha)
|
objective = (y**(alpha - 1.) * np.exp(-self.beta*y) * self.beta**alpha)/ special.gamma(alpha)
|
||||||
|
return np.exp(np.sum(np.log(objective)))
|
||||||
|
|
||||||
def _nlog_mass(self,gp,obs):
|
def logpdf_link(self, link_f, y, extra_data=None):
|
||||||
"""
|
"""
|
||||||
Negative logarithm of the un-normalized distribution: factors that are not a function of gp are omitted
|
Log Likelihood Function given link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\ln p(y_{i}|\lambda(f_{i})) = \\alpha_{i}\\log \\beta - \\log \\Gamma(\\alpha_{i}) + (\\alpha_{i} - 1)\\log y_{i} - \\beta y_{i}\\\\
|
||||||
|
\\alpha_{i} = \\beta y_{i}
|
||||||
|
|
||||||
|
:param link_f: latent variables (link(f))
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in poisson distribution
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
|
|
||||||
"""
|
"""
|
||||||
alpha = self.gp_link.transf(gp)*self.beta
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
return (1. - alpha)*np.log(obs) + self.beta*obs - alpha * np.log(self.beta) + np.log(special.gamma(alpha))
|
#alpha = self.gp_link.transf(gp)*self.beta
|
||||||
|
#return (1. - alpha)*np.log(obs) + self.beta*obs - alpha * np.log(self.beta) + np.log(special.gamma(alpha))
|
||||||
|
alpha = link_f*self.beta
|
||||||
|
log_objective = alpha*np.log(self.beta) - np.log(special.gamma(alpha)) + (alpha - 1)*np.log(y) - self.beta*y
|
||||||
|
return np.sum(log_objective)
|
||||||
|
|
||||||
def _dnlog_mass_dgp(self,gp,obs):
|
def dlogpdf_dlink(self, link_f, y, extra_data=None):
|
||||||
return -self.gp_link.dtransf_df(gp)*self.beta*np.log(obs) + special.psi(self.gp_link.transf(gp)*self.beta) * self.gp_link.dtransf_df(gp)*self.beta
|
"""
|
||||||
|
Gradient of the log likelihood function at y, given link(f) w.r.t link(f)
|
||||||
|
|
||||||
def _d2nlog_mass_dgp2(self,gp,obs):
|
.. math::
|
||||||
return -self.gp_link.d2transf_df2(gp)*self.beta*np.log(obs) + special.polygamma(1,self.gp_link.transf(gp)*self.beta)*(self.gp_link.dtransf_df(gp)*self.beta)**2 + special.psi(self.gp_link.transf(gp)*self.beta)*self.gp_link.d2transf_df2(gp)*self.beta
|
\\frac{d \\ln p(y_{i}|\\lambda(f_{i}))}{d\\lambda(f)} = \\beta (\\log \\beta y_{i}) - \\Psi(\\alpha_{i})\\beta\\\\
|
||||||
|
\\alpha_{i} = \\beta y_{i}
|
||||||
|
|
||||||
|
:param link_f: latent variables (f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in gamma distribution
|
||||||
|
:returns: gradient of likelihood evaluated at points
|
||||||
|
:rtype: Nx1 array
|
||||||
|
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
grad = self.beta*np.log(self.beta*y) - special.psi(self.beta*link_f)*self.beta
|
||||||
|
#old
|
||||||
|
#return -self.gp_link.dtransf_df(gp)*self.beta*np.log(obs) + special.psi(self.gp_link.transf(gp)*self.beta) * self.gp_link.dtransf_df(gp)*self.beta
|
||||||
|
return grad
|
||||||
|
|
||||||
|
def d2logpdf_dlink2(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Hessian at y, given link(f), w.r.t link(f)
|
||||||
|
i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j)
|
||||||
|
The hessian will be 0 unless i == j
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{2} \\ln p(y_{i}|\lambda(f_{i}))}{d^{2}\\lambda(f)} = -\\beta^{2}\\frac{d\\Psi(\\alpha_{i})}{d\\alpha_{i}}\\\\
|
||||||
|
\\alpha_{i} = \\beta y_{i}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in gamma distribution
|
||||||
|
:returns: Diagonal of hessian matrix (second derivative of likelihood evaluated at points f)
|
||||||
|
:rtype: Nx1 array
|
||||||
|
|
||||||
|
.. Note::
|
||||||
|
Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases
|
||||||
|
(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
hess = -special.polygamma(1, self.beta*link_f)*(self.beta**2)
|
||||||
|
#old
|
||||||
|
#return -self.gp_link.d2transf_df2(gp)*self.beta*np.log(obs) + special.polygamma(1,self.gp_link.transf(gp)*self.beta)*(self.gp_link.dtransf_df(gp)*self.beta)**2 + special.psi(self.gp_link.transf(gp)*self.beta)*self.gp_link.d2transf_df2(gp)*self.beta
|
||||||
|
return hess
|
||||||
|
|
||||||
|
def d3logpdf_dlink3(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Third order derivative log-likelihood function at y given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{3} \\ln p(y_{i}|\lambda(f_{i}))}{d^{3}\\lambda(f)} = -\\beta^{3}\\frac{d^{2}\\Psi(\\alpha_{i})}{d\\alpha_{i}}\\\\
|
||||||
|
\\alpha_{i} = \\beta y_{i}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in gamma distribution
|
||||||
|
:returns: third derivative of likelihood evaluated at points f
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
d3lik_dlink3 = -special.polygamma(2, self.beta*link_f)*(self.beta**3)
|
||||||
|
return d3lik_dlink3
|
||||||
|
|
||||||
def _mean(self,gp):
|
def _mean(self,gp):
|
||||||
"""
|
"""
|
||||||
|
|
@ -52,20 +148,8 @@ class Gamma(NoiseDistribution):
|
||||||
"""
|
"""
|
||||||
return self.gp_link.transf(gp)
|
return self.gp_link.transf(gp)
|
||||||
|
|
||||||
def _dmean_dgp(self,gp):
|
|
||||||
return self.gp_link.dtransf_df(gp)
|
|
||||||
|
|
||||||
def _d2mean_dgp2(self,gp):
|
|
||||||
return self.gp_link.d2transf_df2(gp)
|
|
||||||
|
|
||||||
def _variance(self,gp):
|
def _variance(self,gp):
|
||||||
"""
|
"""
|
||||||
Mass (or density) function
|
Mass (or density) function
|
||||||
"""
|
"""
|
||||||
return self.gp_link.transf(gp)/self.beta
|
return self.gp_link.transf(gp)/self.beta
|
||||||
|
|
||||||
def _dvariance_dgp(self,gp):
|
|
||||||
return self.gp_link.dtransf_df(gp)/self.beta
|
|
||||||
|
|
||||||
def _d2variance_dgp2(self,gp):
|
|
||||||
return self.gp_link.d2transf_df2(gp)/self.beta
|
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,20 @@ class Gaussian(NoiseDistribution):
|
||||||
"""
|
"""
|
||||||
Gaussian likelihood
|
Gaussian likelihood
|
||||||
|
|
||||||
:param mean: mean value of the Gaussian distribution
|
.. math::
|
||||||
:param variance: mean value of the Gaussian distribution
|
\\ln p(y_{i}|\\lambda(f_{i})) = -\\frac{N \\ln 2\\pi}{2} - \\frac{\\ln |K|}{2} - \\frac{(y_{i} - \\lambda(f_{i}))^{T}\\sigma^{-2}(y_{i} - \\lambda(f_{i}))}{2}
|
||||||
|
|
||||||
|
:param variance: variance value of the Gaussian distribution
|
||||||
|
:param N: Number of data points
|
||||||
|
:type N: int
|
||||||
"""
|
"""
|
||||||
def __init__(self,gp_link=None,analytical_mean=False,analytical_variance=False,variance=1.):
|
def __init__(self,gp_link=None,analytical_mean=False,analytical_variance=False,variance=1., D=None, N=None):
|
||||||
self.variance = variance
|
self.variance = variance
|
||||||
|
self.N = N
|
||||||
|
self._set_params(np.asarray(variance))
|
||||||
super(Gaussian, self).__init__(gp_link,analytical_mean,analytical_variance)
|
super(Gaussian, self).__init__(gp_link,analytical_mean,analytical_variance)
|
||||||
|
if isinstance(gp_link , gp_transformations.Identity):
|
||||||
|
self.log_concave = True
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return np.array([self.variance])
|
return np.array([self.variance])
|
||||||
|
|
@ -26,7 +34,12 @@ class Gaussian(NoiseDistribution):
|
||||||
return ['noise_model_variance']
|
return ['noise_model_variance']
|
||||||
|
|
||||||
def _set_params(self, p):
|
def _set_params(self, p):
|
||||||
self.variance = p
|
self.variance = float(p)
|
||||||
|
self.I = np.eye(self.N)
|
||||||
|
self.covariance_matrix = self.I * self.variance
|
||||||
|
self.Ki = self.I*(1.0 / self.variance)
|
||||||
|
#self.ln_det_K = np.sum(np.log(np.diag(self.covariance_matrix)))
|
||||||
|
self.ln_det_K = self.N*np.log(self.variance)
|
||||||
|
|
||||||
def _gradients(self,partial):
|
def _gradients(self,partial):
|
||||||
return np.zeros(1)
|
return np.zeros(1)
|
||||||
|
|
@ -57,42 +70,231 @@ class Gaussian(NoiseDistribution):
|
||||||
new_sigma2 = self.predictive_variance(mu,sigma)
|
new_sigma2 = self.predictive_variance(mu,sigma)
|
||||||
return new_sigma2*(mu/sigma**2 + self.gp_link.transf(mu)/self.variance)
|
return new_sigma2*(mu/sigma**2 + self.gp_link.transf(mu)/self.variance)
|
||||||
|
|
||||||
def _predictive_variance_analytical(self,mu,sigma):
|
def _predictive_variance_analytical(self,mu,sigma,predictive_mean=None):
|
||||||
return 1./(1./self.variance + 1./sigma**2)
|
return 1./(1./self.variance + 1./sigma**2)
|
||||||
|
|
||||||
def _mass(self,gp,obs):
|
def _mass(self, link_f, y, extra_data=None):
|
||||||
#return std_norm_pdf( (self.gp_link.transf(gp)-obs)/np.sqrt(self.variance) )
|
NotImplementedError("Deprecated, now doing chain in noise_model.py for link function evaluation\
|
||||||
return stats.norm.pdf(obs,self.gp_link.transf(gp),np.sqrt(self.variance))
|
Please negate your function and use pdf in noise_model.py, if implementing a likelihood\
|
||||||
|
rederivate the derivative without doing the chain and put in logpdf, dlogpdf_dlink or\
|
||||||
|
its derivatives")
|
||||||
|
def _nlog_mass(self, link_f, y, extra_data=None):
|
||||||
|
NotImplementedError("Deprecated, now doing chain in noise_model.py for link function evaluation\
|
||||||
|
Please negate your function and use logpdf in noise_model.py, if implementing a likelihood\
|
||||||
|
rederivate the derivative without doing the chain and put in logpdf, dlogpdf_dlink or\
|
||||||
|
its derivatives")
|
||||||
|
|
||||||
def _nlog_mass(self,gp,obs):
|
def _dnlog_mass_dgp(self, link_f, y, extra_data=None):
|
||||||
return .5*((self.gp_link.transf(gp)-obs)**2/self.variance + np.log(2.*np.pi*self.variance))
|
NotImplementedError("Deprecated, now doing chain in noise_model.py for link function evaluation\
|
||||||
|
Please negate your function and use dlogpdf_df in noise_model.py, if implementing a likelihood\
|
||||||
|
rederivate the derivative without doing the chain and put in logpdf, dlogpdf_dlink or\
|
||||||
|
its derivatives")
|
||||||
|
|
||||||
def _dnlog_mass_dgp(self,gp,obs):
|
def _d2nlog_mass_dgp2(self, link_f, y, extra_data=None):
|
||||||
return (self.gp_link.transf(gp)-obs)/self.variance * self.gp_link.dtransf_df(gp)
|
NotImplementedError("Deprecated, now doing chain in noise_model.py for link function evaluation\
|
||||||
|
Please negate your function and use d2logpdf_df2 in noise_model.py, if implementing a likelihood\
|
||||||
|
rederivate the derivative without doing the chain and put in logpdf, dlogpdf_dlink or\
|
||||||
|
its derivatives")
|
||||||
|
|
||||||
def _d2nlog_mass_dgp2(self,gp,obs):
|
def pdf_link(self, link_f, y, extra_data=None):
|
||||||
return ((self.gp_link.transf(gp)-obs)*self.gp_link.d2transf_df2(gp) + self.gp_link.dtransf_df(gp)**2)/self.variance
|
"""
|
||||||
|
Likelihood function given link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\ln p(y_{i}|\\lambda(f_{i})) = -\\frac{N \\ln 2\\pi}{2} - \\frac{\\ln |K|}{2} - \\frac{(y_{i} - \\lambda(f_{i}))^{T}\\sigma^{-2}(y_{i} - \\lambda(f_{i}))}{2}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in gaussian
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
|
"""
|
||||||
|
#Assumes no covariance, exp, sum, log for numerical stability
|
||||||
|
return np.exp(np.sum(np.log(stats.norm.pdf(y, link_f, np.sqrt(self.variance)))))
|
||||||
|
|
||||||
|
def logpdf_link(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Log likelihood function given link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\ln p(y_{i}|\\lambda(f_{i})) = -\\frac{N \\ln 2\\pi}{2} - \\frac{\\ln |K|}{2} - \\frac{(y_{i} - \\lambda(f_{i}))^{T}\\sigma^{-2}(y_{i} - \\lambda(f_{i}))}{2}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in gaussian
|
||||||
|
:returns: log likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
|
"""
|
||||||
|
assert np.asarray(link_f).shape == np.asarray(y).shape
|
||||||
|
return -0.5*(np.sum((y-link_f)**2/self.variance) + self.ln_det_K + self.N*np.log(2.*np.pi))
|
||||||
|
|
||||||
|
def dlogpdf_dlink(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Gradient of the pdf at y, given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d \\ln p(y_{i}|\\lambda(f_{i}))}{d\\lambda(f)} = \\frac{1}{\\sigma^{2}}(y_{i} - \\lambda(f_{i}))
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in gaussian
|
||||||
|
:returns: gradient of log likelihood evaluated at points link(f)
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.asarray(link_f).shape == np.asarray(y).shape
|
||||||
|
s2_i = (1.0/self.variance)
|
||||||
|
grad = s2_i*y - s2_i*link_f
|
||||||
|
return grad
|
||||||
|
|
||||||
|
def d2logpdf_dlink2(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Hessian at y, given link_f, w.r.t link_f.
|
||||||
|
i.e. second derivative logpdf at y given link(f_i) link(f_j) w.r.t link(f_i) and link(f_j)
|
||||||
|
|
||||||
|
The hessian will be 0 unless i == j
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{2} \\ln p(y_{i}|\\lambda(f_{i}))}{d^{2}f} = -\\frac{1}{\\sigma^{2}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in gaussian
|
||||||
|
:returns: Diagonal of log hessian matrix (second derivative of log likelihood evaluated at points link(f))
|
||||||
|
:rtype: Nx1 array
|
||||||
|
|
||||||
|
.. Note::
|
||||||
|
Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases
|
||||||
|
(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))
|
||||||
|
"""
|
||||||
|
assert np.asarray(link_f).shape == np.asarray(y).shape
|
||||||
|
hess = -(1.0/self.variance)*np.ones((self.N, 1))
|
||||||
|
return hess
|
||||||
|
|
||||||
|
def d3logpdf_dlink3(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Third order derivative log-likelihood function at y given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{3} \\ln p(y_{i}|\\lambda(f_{i}))}{d^{3}\\lambda(f)} = 0
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in gaussian
|
||||||
|
:returns: third derivative of log likelihood evaluated at points link(f)
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.asarray(link_f).shape == np.asarray(y).shape
|
||||||
|
d3logpdf_dlink3 = np.diagonal(0*self.I)[:, None]
|
||||||
|
return d3logpdf_dlink3
|
||||||
|
|
||||||
|
def dlogpdf_link_dvar(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Gradient of the log-likelihood function at y given link(f), w.r.t variance parameter (noise_variance)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d \\ln p(y_{i}|\\lambda(f_{i}))}{d\\sigma^{2}} = -\\frac{N}{2\\sigma^{2}} + \\frac{(y_{i} - \\lambda(f_{i}))^{2}}{2\\sigma^{4}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in gaussian
|
||||||
|
:returns: derivative of log likelihood evaluated at points link(f) w.r.t variance parameter
|
||||||
|
:rtype: float
|
||||||
|
"""
|
||||||
|
assert np.asarray(link_f).shape == np.asarray(y).shape
|
||||||
|
e = y - link_f
|
||||||
|
s_4 = 1.0/(self.variance**2)
|
||||||
|
dlik_dsigma = -0.5*self.N/self.variance + 0.5*s_4*np.sum(np.square(e))
|
||||||
|
return np.sum(dlik_dsigma) # Sure about this sum?
|
||||||
|
|
||||||
|
def dlogpdf_dlink_dvar(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Derivative of the dlogpdf_dlink w.r.t variance parameter (noise_variance)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d}{d\\sigma^{2}}(\\frac{d \\ln p(y_{i}|\\lambda(f_{i}))}{d\\lambda(f)}) = \\frac{1}{\\sigma^{4}}(-y_{i} + \\lambda(f_{i}))
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in gaussian
|
||||||
|
:returns: derivative of log likelihood evaluated at points link(f) w.r.t variance parameter
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.asarray(link_f).shape == np.asarray(y).shape
|
||||||
|
s_4 = 1.0/(self.variance**2)
|
||||||
|
dlik_grad_dsigma = -s_4*y + s_4*link_f
|
||||||
|
return dlik_grad_dsigma
|
||||||
|
|
||||||
|
def d2logpdf_dlink2_dvar(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Gradient of the hessian (d2logpdf_dlink2) w.r.t variance parameter (noise_variance)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d}{d\\sigma^{2}}(\\frac{d^{2} \\ln p(y_{i}|\\lambda(f_{i}))}{d^{2}\\lambda(f)}) = \\frac{1}{\\sigma^{4}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data not used in gaussian
|
||||||
|
:returns: derivative of log hessian evaluated at points link(f_i) and link(f_j) w.r.t variance parameter
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.asarray(link_f).shape == np.asarray(y).shape
|
||||||
|
s_4 = 1.0/(self.variance**2)
|
||||||
|
d2logpdf_dlink2_dvar = np.diag(s_4*self.I)[:, None]
|
||||||
|
return d2logpdf_dlink2_dvar
|
||||||
|
|
||||||
|
def dlogpdf_link_dtheta(self, f, y, extra_data=None):
|
||||||
|
dlogpdf_dvar = self.dlogpdf_link_dvar(f, y, extra_data=extra_data)
|
||||||
|
return np.asarray([[dlogpdf_dvar]])
|
||||||
|
|
||||||
|
def dlogpdf_dlink_dtheta(self, f, y, extra_data=None):
|
||||||
|
dlogpdf_dlink_dvar = self.dlogpdf_dlink_dvar(f, y, extra_data=extra_data)
|
||||||
|
return dlogpdf_dlink_dvar
|
||||||
|
|
||||||
|
def d2logpdf_dlink2_dtheta(self, f, y, extra_data=None):
|
||||||
|
d2logpdf_dlink2_dvar = self.d2logpdf_dlink2_dvar(f, y, extra_data=extra_data)
|
||||||
|
return d2logpdf_dlink2_dvar
|
||||||
|
|
||||||
def _mean(self,gp):
|
def _mean(self,gp):
|
||||||
"""
|
"""
|
||||||
Mass (or density) function
|
Expected value of y under the Mass (or density) function p(y|f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
E_{p(y|f)}[y]
|
||||||
"""
|
"""
|
||||||
return self.gp_link.transf(gp)
|
return self.gp_link.transf(gp)
|
||||||
|
|
||||||
def _dmean_dgp(self,gp):
|
|
||||||
return self.gp_link.dtransf_df(gp)
|
|
||||||
|
|
||||||
def _d2mean_dgp2(self,gp):
|
|
||||||
return self.gp_link.d2transf_df2(gp)
|
|
||||||
|
|
||||||
def _variance(self,gp):
|
def _variance(self,gp):
|
||||||
"""
|
"""
|
||||||
Mass (or density) function
|
Variance of y under the Mass (or density) function p(y|f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
Var_{p(y|f)}[y]
|
||||||
"""
|
"""
|
||||||
return self.variance
|
return self.variance
|
||||||
|
|
||||||
def _dvariance_dgp(self,gp):
|
def samples(self, gp):
|
||||||
return 0
|
"""
|
||||||
|
Returns a set of samples of observations based on a given value of the latent variable.
|
||||||
|
|
||||||
def _d2variance_dgp2(self,gp):
|
:param gp: latent variable
|
||||||
return 0
|
"""
|
||||||
|
orig_shape = gp.shape
|
||||||
|
gp = gp.flatten()
|
||||||
|
Ysim = np.array([np.random.normal(self.gp_link.transf(gpj), scale=np.sqrt(self.variance), size=1) for gpj in gp])
|
||||||
|
return Ysim.reshape(orig_shape)
|
||||||
|
|
|
||||||
|
|
@ -24,19 +24,25 @@ class GPTransformation(object):
|
||||||
"""
|
"""
|
||||||
Gaussian process tranformation function, latent space -> output space
|
Gaussian process tranformation function, latent space -> output space
|
||||||
"""
|
"""
|
||||||
pass
|
raise NotImplementedError
|
||||||
|
|
||||||
def dtransf_df(self,f):
|
def dtransf_df(self,f):
|
||||||
"""
|
"""
|
||||||
derivative of transf(f) w.r.t. f
|
derivative of transf(f) w.r.t. f
|
||||||
"""
|
"""
|
||||||
pass
|
raise NotImplementedError
|
||||||
|
|
||||||
def d2transf_df2(self,f):
|
def d2transf_df2(self,f):
|
||||||
"""
|
"""
|
||||||
second derivative of transf(f) w.r.t. f
|
second derivative of transf(f) w.r.t. f
|
||||||
"""
|
"""
|
||||||
pass
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def d3transf_df3(self,f):
|
||||||
|
"""
|
||||||
|
third derivative of transf(f) w.r.t. f
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
class Identity(GPTransformation):
|
class Identity(GPTransformation):
|
||||||
"""
|
"""
|
||||||
|
|
@ -49,10 +55,13 @@ class Identity(GPTransformation):
|
||||||
return f
|
return f
|
||||||
|
|
||||||
def dtransf_df(self,f):
|
def dtransf_df(self,f):
|
||||||
return 1.
|
return np.ones_like(f)
|
||||||
|
|
||||||
def d2transf_df2(self,f):
|
def d2transf_df2(self,f):
|
||||||
return 0
|
return np.zeros_like(f)
|
||||||
|
|
||||||
|
def d3transf_df3(self,f):
|
||||||
|
return np.zeros_like(f)
|
||||||
|
|
||||||
|
|
||||||
class Probit(GPTransformation):
|
class Probit(GPTransformation):
|
||||||
|
|
@ -69,8 +78,14 @@ class Probit(GPTransformation):
|
||||||
return std_norm_pdf(f)
|
return std_norm_pdf(f)
|
||||||
|
|
||||||
def d2transf_df2(self,f):
|
def d2transf_df2(self,f):
|
||||||
|
#FIXME
|
||||||
return -f * std_norm_pdf(f)
|
return -f * std_norm_pdf(f)
|
||||||
|
|
||||||
|
def d3transf_df3(self,f):
|
||||||
|
#FIXME
|
||||||
|
f2 = f**2
|
||||||
|
return -(1/(np.sqrt(2*np.pi)))*np.exp(-0.5*(f2))*(1-f2)
|
||||||
|
|
||||||
class Log(GPTransformation):
|
class Log(GPTransformation):
|
||||||
"""
|
"""
|
||||||
.. math::
|
.. math::
|
||||||
|
|
@ -87,6 +102,9 @@ class Log(GPTransformation):
|
||||||
def d2transf_df2(self,f):
|
def d2transf_df2(self,f):
|
||||||
return np.exp(f)
|
return np.exp(f)
|
||||||
|
|
||||||
|
def d3transf_df3(self,f):
|
||||||
|
return np.exp(f)
|
||||||
|
|
||||||
class Log_ex_1(GPTransformation):
|
class Log_ex_1(GPTransformation):
|
||||||
"""
|
"""
|
||||||
.. math::
|
.. math::
|
||||||
|
|
@ -104,15 +122,23 @@ class Log_ex_1(GPTransformation):
|
||||||
aux = np.exp(f)/(1.+np.exp(f))
|
aux = np.exp(f)/(1.+np.exp(f))
|
||||||
return aux*(1.-aux)
|
return aux*(1.-aux)
|
||||||
|
|
||||||
|
def d3transf_df3(self,f):
|
||||||
|
aux = np.exp(f)/(1.+np.exp(f))
|
||||||
|
daux_df = aux*(1.-aux)
|
||||||
|
return daux_df - (2.*aux*daux_df)
|
||||||
|
|
||||||
class Reciprocal(GPTransformation):
|
class Reciprocal(GPTransformation):
|
||||||
def transf(sefl,f):
|
def transf(self,f):
|
||||||
return 1./f
|
return 1./f
|
||||||
|
|
||||||
def dtransf_df(self,f):
|
def dtransf_df(self,f):
|
||||||
return -1./f**2
|
return -1./(f**2)
|
||||||
|
|
||||||
def d2transf_df2(self,f):
|
def d2transf_df2(self,f):
|
||||||
return 2./f**3
|
return 2./(f**3)
|
||||||
|
|
||||||
|
def d3transf_df3(self,f):
|
||||||
|
return -6./(f**4)
|
||||||
|
|
||||||
class Heaviside(GPTransformation):
|
class Heaviside(GPTransformation):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,13 @@ import pylab as pb
|
||||||
from GPy.util.plot import gpplot
|
from GPy.util.plot import gpplot
|
||||||
from GPy.util.univariate_Gaussian import std_norm_pdf,std_norm_cdf
|
from GPy.util.univariate_Gaussian import std_norm_pdf,std_norm_cdf
|
||||||
import gp_transformations
|
import gp_transformations
|
||||||
|
from GPy.util.misc import chain_1, chain_2, chain_3
|
||||||
|
from scipy.integrate import quad
|
||||||
|
import warnings
|
||||||
|
|
||||||
class NoiseDistribution(object):
|
class NoiseDistribution(object):
|
||||||
"""
|
"""
|
||||||
Likelihood class for doing Expectation propagation
|
Likelihood class for doing approximations
|
||||||
|
|
||||||
:param Y: observed output (Nx1 numpy.darray)
|
|
||||||
|
|
||||||
.. note:: Y values allowed depend on the LikelihoodFunction used
|
|
||||||
"""
|
"""
|
||||||
def __init__(self,gp_link,analytical_mean=False,analytical_variance=False):
|
def __init__(self,gp_link,analytical_mean=False,analytical_variance=False):
|
||||||
assert isinstance(gp_link,gp_transformations.GPTransformation), "gp_link is not a valid GPTransformation."
|
assert isinstance(gp_link,gp_transformations.GPTransformation), "gp_link is not a valid GPTransformation."
|
||||||
|
|
@ -35,6 +33,8 @@ class NoiseDistribution(object):
|
||||||
else:
|
else:
|
||||||
self.predictive_variance = self._predictive_variance_numerical
|
self.predictive_variance = self._predictive_variance_numerical
|
||||||
|
|
||||||
|
self.log_concave = False
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return np.zeros(0)
|
return np.zeros(0)
|
||||||
|
|
||||||
|
|
@ -57,363 +57,372 @@ class NoiseDistribution(object):
|
||||||
"""
|
"""
|
||||||
return Y
|
return Y
|
||||||
|
|
||||||
def _product(self,gp,obs,mu,sigma):
|
|
||||||
"""
|
|
||||||
Product between the cavity distribution and a likelihood factor.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param obs: observed output
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return stats.norm.pdf(gp,loc=mu,scale=sigma) * self._mass(gp,obs)
|
|
||||||
|
|
||||||
def _nlog_product_scaled(self,gp,obs,mu,sigma):
|
|
||||||
"""
|
|
||||||
Negative log-product between the cavity distribution and a likelihood factor.
|
|
||||||
|
|
||||||
.. note:: The constant term in the Gaussian distribution is ignored.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param obs: observed output
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return .5*((gp-mu)/sigma)**2 + self._nlog_mass(gp,obs)
|
|
||||||
|
|
||||||
def _dnlog_product_dgp(self,gp,obs,mu,sigma):
|
|
||||||
"""
|
|
||||||
Derivative wrt latent variable of the log-product between the cavity distribution and a likelihood factor.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param obs: observed output
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return (gp - mu)/sigma**2 + self._dnlog_mass_dgp(gp,obs)
|
|
||||||
|
|
||||||
def _d2nlog_product_dgp2(self,gp,obs,mu,sigma):
|
|
||||||
"""
|
|
||||||
Second derivative wrt latent variable of the log-product between the cavity distribution and a likelihood factor.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param obs: observed output
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return 1./sigma**2 + self._d2nlog_mass_dgp2(gp,obs)
|
|
||||||
|
|
||||||
def _product_mode(self,obs,mu,sigma):
|
|
||||||
"""
|
|
||||||
Newton's CG method to find the mode in _product (cavity x likelihood factor).
|
|
||||||
|
|
||||||
:param obs: observed output
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return sp.optimize.fmin_ncg(self._nlog_product_scaled,x0=mu,fprime=self._dnlog_product_dgp,fhess=self._d2nlog_product_dgp2,args=(obs,mu,sigma),disp=False)
|
|
||||||
|
|
||||||
def _moments_match_analytical(self,obs,tau,v):
|
def _moments_match_analytical(self,obs,tau,v):
|
||||||
"""
|
"""
|
||||||
If available, this function computes the moments analytically.
|
If available, this function computes the moments analytically.
|
||||||
"""
|
"""
|
||||||
pass
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def log_predictive_density(self, y_test, mu_star, var_star):
|
||||||
|
"""
|
||||||
|
Calculation of the log predictive density
|
||||||
|
|
||||||
|
.. math:
|
||||||
|
p(y_{*}|D) = p(y_{*}|f_{*})p(f_{*}|\mu_{*}\\sigma^{2}_{*})
|
||||||
|
|
||||||
|
:param y_test: test observations (y_{*})
|
||||||
|
:type y_test: (Nx1) array
|
||||||
|
:param mu_star: predictive mean of gaussian p(f_{*}|mu_{*}, var_{*})
|
||||||
|
:type mu_star: (Nx1) array
|
||||||
|
:param var_star: predictive variance of gaussian p(f_{*}|mu_{*}, var_{*})
|
||||||
|
:type var_star: (Nx1) array
|
||||||
|
"""
|
||||||
|
assert y_test.shape==mu_star.shape
|
||||||
|
assert y_test.shape==var_star.shape
|
||||||
|
assert y_test.shape[1] == 1
|
||||||
|
def integral_generator(y, m, v):
|
||||||
|
"""Generate a function which can be integrated to give p(Y*|Y) = int p(Y*|f*)p(f*|Y) df*"""
|
||||||
|
def f(f_star):
|
||||||
|
return self.pdf(f_star, y)*np.exp(-(1./(2*v))*np.square(m-f_star))
|
||||||
|
return f
|
||||||
|
|
||||||
|
scaled_p_ystar, accuracy = zip(*[quad(integral_generator(y, m, v), -np.inf, np.inf) for y, m, v in zip(y_test.flatten(), mu_star.flatten(), var_star.flatten())])
|
||||||
|
scaled_p_ystar = np.array(scaled_p_ystar).reshape(-1,1)
|
||||||
|
p_ystar = scaled_p_ystar/np.sqrt(2*np.pi*var_star)
|
||||||
|
return np.log(p_ystar)
|
||||||
|
|
||||||
def _moments_match_numerical(self,obs,tau,v):
|
def _moments_match_numerical(self,obs,tau,v):
|
||||||
"""
|
"""
|
||||||
Lapace approximation to calculate the moments.
|
Calculation of moments using quadrature
|
||||||
|
|
||||||
:param obs: observed output
|
:param obs: observed output
|
||||||
:param tau: cavity distribution 1st natural parameter (precision)
|
:param tau: cavity distribution 1st natural parameter (precision)
|
||||||
:param v: cavity distribution 2nd natural paramenter (mu*precision)
|
:param v: cavity distribution 2nd natural paramenter (mu*precision)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
#Compute first integral for zeroth moment.
|
||||||
|
#NOTE constant np.sqrt(2*pi/tau) added at the end of the function
|
||||||
mu = v/tau
|
mu = v/tau
|
||||||
mu_hat = self._product_mode(obs,mu,np.sqrt(1./tau))
|
def int_1(f):
|
||||||
sigma2_hat = 1./(tau + self._d2nlog_mass_dgp2(mu_hat,obs))
|
return self.pdf(f, obs)*np.exp(-0.5*tau*np.square(mu-f))
|
||||||
Z_hat = np.exp(-.5*tau*(mu_hat-mu)**2) * self._mass(mu_hat,obs)*np.sqrt(tau*sigma2_hat)
|
z_scaled, accuracy = quad(int_1, -np.inf, np.inf)
|
||||||
return Z_hat,mu_hat,sigma2_hat
|
|
||||||
|
|
||||||
def _nlog_conditional_mean_scaled(self,gp,mu,sigma):
|
#Compute second integral for first moment
|
||||||
"""
|
def int_2(f):
|
||||||
Negative logarithm of the l.v.'s predictive distribution times the output's mean given the l.v.
|
return f*self.pdf(f, obs)*np.exp(-0.5*tau*np.square(mu-f))
|
||||||
|
mean, accuracy = quad(int_2, -np.inf, np.inf)
|
||||||
|
mean /= z_scaled
|
||||||
|
|
||||||
:param gp: latent variable
|
#Compute integral for variance
|
||||||
:param mu: cavity distribution mean
|
def int_3(f):
|
||||||
:param sigma: cavity distribution standard deviation
|
return (f**2)*self.pdf(f, obs)*np.exp(-0.5*tau*np.square(mu-f))
|
||||||
|
Ef2, accuracy = quad(int_3, -np.inf, np.inf)
|
||||||
|
Ef2 /= z_scaled
|
||||||
|
variance = Ef2 - mean**2
|
||||||
|
|
||||||
.. note:: This function helps computing E(Y_star) = E(E(Y_star|f_star))
|
#Add constant to the zeroth moment
|
||||||
|
#NOTE: this constant is not needed in the other moments because it cancells out.
|
||||||
|
z = z_scaled/np.sqrt(2*np.pi/tau)
|
||||||
|
|
||||||
"""
|
return z, mean, variance
|
||||||
return .5*((gp - mu)/sigma)**2 - np.log(self._mean(gp))
|
|
||||||
|
|
||||||
def _dnlog_conditional_mean_dgp(self,gp,mu,sigma):
|
|
||||||
"""
|
|
||||||
Derivative of _nlog_conditional_mean_scaled wrt. l.v.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return (gp - mu)/sigma**2 - self._dmean_dgp(gp)/self._mean(gp)
|
|
||||||
|
|
||||||
def _d2nlog_conditional_mean_dgp2(self,gp,mu,sigma):
|
|
||||||
"""
|
|
||||||
Second derivative of _nlog_conditional_mean_scaled wrt. l.v.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return 1./sigma**2 - self._d2mean_dgp2(gp)/self._mean(gp) + (self._dmean_dgp(gp)/self._mean(gp))**2
|
|
||||||
|
|
||||||
def _nlog_exp_conditional_variance_scaled(self,gp,mu,sigma):
|
|
||||||
"""
|
|
||||||
Negative logarithm of the l.v.'s predictive distribution times the output's variance given the l.v.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
.. note:: This function helps computing E(V(Y_star|f_star))
|
|
||||||
|
|
||||||
"""
|
|
||||||
return .5*((gp - mu)/sigma)**2 - np.log(self._variance(gp))
|
|
||||||
|
|
||||||
def _dnlog_exp_conditional_variance_dgp(self,gp,mu,sigma):
|
|
||||||
"""
|
|
||||||
Derivative of _nlog_exp_conditional_variance_scaled wrt. l.v.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return (gp - mu)/sigma**2 - self._dvariance_dgp(gp)/self._variance(gp)
|
|
||||||
|
|
||||||
def _d2nlog_exp_conditional_variance_dgp2(self,gp,mu,sigma):
|
|
||||||
"""
|
|
||||||
Second derivative of _nlog_exp_conditional_variance_scaled wrt. l.v.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return 1./sigma**2 - self._d2variance_dgp2(gp)/self._variance(gp) + (self._dvariance_dgp(gp)/self._variance(gp))**2
|
|
||||||
|
|
||||||
def _nlog_exp_conditional_mean_sq_scaled(self,gp,mu,sigma):
|
|
||||||
"""
|
|
||||||
Negative logarithm of the l.v.'s predictive distribution times the output's mean squared given the l.v.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
.. note:: This function helps computing E( E(Y_star|f_star)**2 )
|
|
||||||
|
|
||||||
"""
|
|
||||||
return .5*((gp - mu)/sigma)**2 - 2*np.log(self._mean(gp))
|
|
||||||
|
|
||||||
def _dnlog_exp_conditional_mean_sq_dgp(self,gp,mu,sigma):
|
|
||||||
"""
|
|
||||||
Derivative of _nlog_exp_conditional_mean_sq_scaled wrt. l.v.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return (gp - mu)/sigma**2 - 2*self._dmean_dgp(gp)/self._mean(gp)
|
|
||||||
|
|
||||||
def _d2nlog_exp_conditional_mean_sq_dgp2(self,gp,mu,sigma):
|
|
||||||
"""
|
|
||||||
Second derivative of _nlog_exp_conditional_mean_sq_scaled wrt. l.v.
|
|
||||||
|
|
||||||
:param gp: latent variable
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
|
|
||||||
"""
|
|
||||||
return 1./sigma**2 - 2*( self._d2mean_dgp2(gp)/self._mean(gp) - (self._dmean_dgp(gp)/self._mean(gp))**2 )
|
|
||||||
|
|
||||||
def _predictive_mean_analytical(self,mu,sigma):
|
def _predictive_mean_analytical(self,mu,sigma):
|
||||||
"""
|
"""
|
||||||
|
Predictive mean
|
||||||
|
.. math::
|
||||||
|
E(Y^{*}|Y) = E( E(Y^{*}|f^{*}, Y) )
|
||||||
|
|
||||||
If available, this function computes the predictive mean analytically.
|
If available, this function computes the predictive mean analytically.
|
||||||
"""
|
"""
|
||||||
pass
|
raise NotImplementedError
|
||||||
|
|
||||||
def _predictive_variance_analytical(self,mu,sigma):
|
def _predictive_variance_analytical(self,mu,sigma):
|
||||||
"""
|
"""
|
||||||
|
Predictive variance
|
||||||
|
.. math::
|
||||||
|
V(Y^{*}| Y) = E( V(Y^{*}|f^{*}, Y) ) + V( E(Y^{*}|f^{*}, Y) )
|
||||||
|
|
||||||
If available, this function computes the predictive variance analytically.
|
If available, this function computes the predictive variance analytically.
|
||||||
"""
|
"""
|
||||||
pass
|
raise NotImplementedError
|
||||||
|
|
||||||
def _predictive_mean_numerical(self,mu,sigma):
|
def _predictive_mean_numerical(self,mu,variance):
|
||||||
"""
|
"""
|
||||||
Laplace approximation to the predictive mean: E(Y_star) = E( E(Y_star|f_star) )
|
Quadrature calculation of the predictive mean: E(Y_star|Y) = E( E(Y_star|f_star, Y) )
|
||||||
|
|
||||||
:param mu: cavity distribution mean
|
:param mu: mean of posterior
|
||||||
:param sigma: cavity distribution standard deviation
|
:param sigma: standard deviation of posterior
|
||||||
|
|
||||||
"""
|
"""
|
||||||
maximum = sp.optimize.fmin_ncg(self._nlog_conditional_mean_scaled,x0=self._mean(mu),fprime=self._dnlog_conditional_mean_dgp,fhess=self._d2nlog_conditional_mean_dgp2,args=(mu,sigma),disp=False)
|
def int_mean(f,m,v):
|
||||||
mean = np.exp(-self._nlog_conditional_mean_scaled(maximum,mu,sigma))/(np.sqrt(self._d2nlog_conditional_mean_dgp2(maximum,mu,sigma))*sigma)
|
return self._mean(f)*np.exp(-(0.5/v)*np.square(f - m))
|
||||||
"""
|
scaled_mean = [quad(int_mean, -np.inf, np.inf,args=(mj,s2j))[0] for mj,s2j in zip(mu,variance)]
|
||||||
|
mean = np.array(scaled_mean)[:,None] / np.sqrt(2*np.pi*(variance))
|
||||||
|
|
||||||
pb.figure()
|
|
||||||
x = np.array([mu + step*sigma for step in np.linspace(-7,7,100)])
|
|
||||||
f = np.array([np.exp(-self._nlog_conditional_mean_scaled(xi,mu,sigma))/np.sqrt(2*np.pi*sigma**2) for xi in x])
|
|
||||||
pb.plot(x,f,'b-')
|
|
||||||
sigma2 = 1./self._d2nlog_conditional_mean_dgp2(maximum,mu,sigma)
|
|
||||||
f2 = np.exp(-.5*(x-maximum)**2/sigma2)/np.sqrt(2*np.pi*sigma2)
|
|
||||||
k = np.exp(-self._nlog_conditional_mean_scaled(maximum,mu,sigma))*np.sqrt(sigma2)/np.sqrt(sigma**2)
|
|
||||||
pb.plot(x,f2*mean,'r-')
|
|
||||||
pb.vlines(maximum,0,f.max())
|
|
||||||
"""
|
|
||||||
return mean
|
return mean
|
||||||
|
|
||||||
def _predictive_mean_sq(self,mu,sigma):
|
def _predictive_variance_numerical(self,mu,variance,predictive_mean=None):
|
||||||
"""
|
"""
|
||||||
Laplace approximation to the predictive mean squared: E(Y_star**2) = E( E(Y_star|f_star)**2 )
|
Numerical approximation to the predictive variance: V(Y_star)
|
||||||
|
|
||||||
:param mu: cavity distribution mean
|
The following variance decomposition is used:
|
||||||
:param sigma: cavity distribution standard deviation
|
V(Y_star) = E( V(Y_star|f_star) ) + V( E(Y_star|f_star) )
|
||||||
|
|
||||||
"""
|
:param mu: mean of posterior
|
||||||
maximum = sp.optimize.fmin_ncg(self._nlog_exp_conditional_mean_sq_scaled,x0=self._mean(mu),fprime=self._dnlog_exp_conditional_mean_sq_dgp,fhess=self._d2nlog_exp_conditional_mean_sq_dgp2,args=(mu,sigma),disp=False)
|
:param sigma: standard deviation of posterior
|
||||||
mean_squared = np.exp(-self._nlog_exp_conditional_mean_sq_scaled(maximum,mu,sigma))/(np.sqrt(self._d2nlog_exp_conditional_mean_sq_dgp2(maximum,mu,sigma))*sigma)
|
|
||||||
return mean_squared
|
|
||||||
|
|
||||||
def _predictive_variance_numerical(self,mu,sigma,predictive_mean=None):
|
|
||||||
"""
|
|
||||||
Laplace approximation to the predictive variance: V(Y_star) = E( V(Y_star|f_star) ) + V( E(Y_star|f_star) )
|
|
||||||
|
|
||||||
:param mu: cavity distribution mean
|
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
:predictive_mean: output's predictive mean, if None _predictive_mean function will be called.
|
:predictive_mean: output's predictive mean, if None _predictive_mean function will be called.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
#sigma2 = sigma**2
|
||||||
|
normalizer = np.sqrt(2*np.pi*variance)
|
||||||
|
|
||||||
# E( V(Y_star|f_star) )
|
# E( V(Y_star|f_star) )
|
||||||
maximum = sp.optimize.fmin_ncg(self._nlog_exp_conditional_variance_scaled,x0=self._variance(mu),fprime=self._dnlog_exp_conditional_variance_dgp,fhess=self._d2nlog_exp_conditional_variance_dgp2,args=(mu,sigma),disp=False)
|
def int_var(f,m,v):
|
||||||
exp_var = np.exp(-self._nlog_exp_conditional_variance_scaled(maximum,mu,sigma))/(np.sqrt(self._d2nlog_exp_conditional_variance_dgp2(maximum,mu,sigma))*sigma)
|
return self._variance(f)*np.exp(-(0.5/v)*np.square(f - m))
|
||||||
|
scaled_exp_variance = [quad(int_var, -np.inf, np.inf,args=(mj,s2j))[0] for mj,s2j in zip(mu,variance)]
|
||||||
|
exp_var = np.array(scaled_exp_variance)[:,None] / normalizer
|
||||||
|
|
||||||
"""
|
#V( E(Y_star|f_star) ) = E( E(Y_star|f_star)**2 ) - E( E(Y_star|f_star) )**2
|
||||||
pb.figure()
|
|
||||||
x = np.array([mu + step*sigma for step in np.linspace(-7,7,100)])
|
|
||||||
f = np.array([np.exp(-self._nlog_exp_conditional_variance_scaled(xi,mu,sigma))/np.sqrt(2*np.pi*sigma**2) for xi in x])
|
|
||||||
pb.plot(x,f,'b-')
|
|
||||||
sigma2 = 1./self._d2nlog_exp_conditional_variance_dgp2(maximum,mu,sigma)
|
|
||||||
f2 = np.exp(-.5*(x-maximum)**2/sigma2)/np.sqrt(2*np.pi*sigma2)
|
|
||||||
k = np.exp(-self._nlog_exp_conditional_variance_scaled(maximum,mu,sigma))*np.sqrt(sigma2)/np.sqrt(sigma**2)
|
|
||||||
pb.plot(x,f2*exp_var,'r--')
|
|
||||||
pb.vlines(maximum,0,f.max())
|
|
||||||
"""
|
|
||||||
|
|
||||||
#V( E(Y_star|f_star) ) = E( E(Y_star|f_star)**2 ) - E( E(Y_star|f_star)**2 )
|
#E( E(Y_star|f_star) )**2
|
||||||
exp_exp2 = self._predictive_mean_sq(mu,sigma)
|
|
||||||
if predictive_mean is None:
|
if predictive_mean is None:
|
||||||
predictive_mean = self.predictive_mean(mu,sigma)
|
predictive_mean = self.predictive_mean(mu,variance)
|
||||||
var_exp = exp_exp2 - predictive_mean**2
|
predictive_mean_sq = predictive_mean**2
|
||||||
|
|
||||||
|
#E( E(Y_star|f_star)**2 )
|
||||||
|
def int_pred_mean_sq(f,m,v,predictive_mean_sq):
|
||||||
|
return self._mean(f)**2*np.exp(-(0.5/v)*np.square(f - m))
|
||||||
|
scaled_exp_exp2 = [quad(int_pred_mean_sq, -np.inf, np.inf,args=(mj,s2j,pm2j))[0] for mj,s2j,pm2j in zip(mu,variance,predictive_mean_sq)]
|
||||||
|
exp_exp2 = np.array(scaled_exp_exp2)[:,None] / normalizer
|
||||||
|
|
||||||
|
var_exp = exp_exp2 - predictive_mean_sq
|
||||||
|
|
||||||
|
# V(Y_star) = E( V(Y_star|f_star) ) + V( E(Y_star|f_star) )
|
||||||
return exp_var + var_exp
|
return exp_var + var_exp
|
||||||
|
|
||||||
def _predictive_percentiles(self,p,mu,sigma):
|
def pdf_link(self, link_f, y, extra_data=None):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def logpdf_link(self, link_f, y, extra_data=None):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def dlogpdf_dlink(self, link_f, y, extra_data=None):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def d2logpdf_dlink2(self, link_f, y, extra_data=None):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def d3logpdf_dlink3(self, link_f, y, extra_data=None):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def dlogpdf_link_dtheta(self, link_f, y, extra_data=None):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def dlogpdf_dlink_dtheta(self, link_f, y, extra_data=None):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def d2logpdf_dlink2_dtheta(self, link_f, y, extra_data=None):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def pdf(self, f, y, extra_data=None):
|
||||||
"""
|
"""
|
||||||
Percentiles of the predictive distribution
|
Evaluates the link function link(f) then computes the likelihood (pdf) using it
|
||||||
|
|
||||||
:parm p: lower tail probability
|
.. math:
|
||||||
:param mu: cavity distribution mean
|
p(y|\\lambda(f))
|
||||||
:param sigma: cavity distribution standard deviation
|
|
||||||
:predictive_mean: output's predictive mean, if None _predictive_mean function will be called.
|
|
||||||
|
|
||||||
|
:param f: latent variables f
|
||||||
|
:type f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution - not used
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
"""
|
"""
|
||||||
qf = stats.norm.ppf(p,mu,sigma)
|
link_f = self.gp_link.transf(f)
|
||||||
return self.gp_link.transf(qf)
|
return self.pdf_link(link_f, y, extra_data=extra_data)
|
||||||
|
|
||||||
def _nlog_joint_predictive_scaled(self,x,mu,sigma):
|
def logpdf(self, f, y, extra_data=None):
|
||||||
"""
|
"""
|
||||||
Negative logarithm of the joint predictive distribution (latent variable and output).
|
Evaluates the link function link(f) then computes the log likelihood (log pdf) using it
|
||||||
|
|
||||||
:param x: tuple (latent variable,output)
|
.. math:
|
||||||
:param mu: latent variable's predictive mean
|
\\log p(y|\\lambda(f))
|
||||||
:param sigma: latent variable's predictive standard deviation
|
|
||||||
|
|
||||||
|
:param f: latent variables f
|
||||||
|
:type f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution - not used
|
||||||
|
:returns: log likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
"""
|
"""
|
||||||
return self._nlog_product_scaled(x[0],x[1],mu,sigma)
|
link_f = self.gp_link.transf(f)
|
||||||
|
return self.logpdf_link(link_f, y, extra_data=extra_data)
|
||||||
|
|
||||||
def _gradient_nlog_joint_predictive(self,x,mu,sigma):
|
def dlogpdf_df(self, f, y, extra_data=None):
|
||||||
"""
|
"""
|
||||||
Gradient of _nlog_joint_predictive_scaled.
|
Evaluates the link function link(f) then computes the derivative of log likelihood using it
|
||||||
|
Uses the Faa di Bruno's formula for the chain rule
|
||||||
|
|
||||||
:param x: tuple (latent variable,output)
|
.. math::
|
||||||
:param mu: latent variable's predictive mean
|
\\frac{d\\log p(y|\\lambda(f))}{df} = \\frac{d\\log p(y|\\lambda(f))}{d\\lambda(f)}\\frac{d\\lambda(f)}{df}
|
||||||
:param sigma: latent variable's predictive standard deviation
|
|
||||||
|
|
||||||
.. note: Only available when the output is continuous
|
|
||||||
|
|
||||||
|
:param f: latent variables f
|
||||||
|
:type f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution - not used
|
||||||
|
:returns: derivative of log likelihood evaluated for this point
|
||||||
|
:rtype: 1xN array
|
||||||
"""
|
"""
|
||||||
assert not self.discrete, "Gradient not available for discrete outputs."
|
link_f = self.gp_link.transf(f)
|
||||||
return np.array((self._dnlog_product_dgp(gp=x[0],obs=x[1],mu=mu,sigma=sigma),self._dnlog_mass_dobs(obs=x[1],gp=x[0])))
|
dlogpdf_dlink = self.dlogpdf_dlink(link_f, y, extra_data=extra_data)
|
||||||
|
dlink_df = self.gp_link.dtransf_df(f)
|
||||||
|
return chain_1(dlogpdf_dlink, dlink_df)
|
||||||
|
|
||||||
def _hessian_nlog_joint_predictive(self,x,mu,sigma):
|
def d2logpdf_df2(self, f, y, extra_data=None):
|
||||||
"""
|
"""
|
||||||
Hessian of _nlog_joint_predictive_scaled.
|
Evaluates the link function link(f) then computes the second derivative of log likelihood using it
|
||||||
|
Uses the Faa di Bruno's formula for the chain rule
|
||||||
|
|
||||||
:param x: tuple (latent variable,output)
|
.. math::
|
||||||
:param mu: latent variable's predictive mean
|
\\frac{d^{2}\\log p(y|\\lambda(f))}{df^{2}} = \\frac{d^{2}\\log p(y|\\lambda(f))}{d^{2}\\lambda(f)}\\left(\\frac{d\\lambda(f)}{df}\\right)^{2} + \\frac{d\\log p(y|\\lambda(f))}{d\\lambda(f)}\\frac{d^{2}\\lambda(f)}{df^{2}}
|
||||||
:param sigma: latent variable's predictive standard deviation
|
|
||||||
|
|
||||||
.. note: Only available when the output is continuous
|
|
||||||
|
|
||||||
|
:param f: latent variables f
|
||||||
|
:type f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution - not used
|
||||||
|
:returns: second derivative of log likelihood evaluated for this point (diagonal only)
|
||||||
|
:rtype: 1xN array
|
||||||
"""
|
"""
|
||||||
assert not self.discrete, "Hessian not available for discrete outputs."
|
link_f = self.gp_link.transf(f)
|
||||||
cross_derivative = self._d2nlog_mass_dcross(gp=x[0],obs=x[1])
|
d2logpdf_dlink2 = self.d2logpdf_dlink2(link_f, y, extra_data=extra_data)
|
||||||
return np.array((self._d2nlog_product_dgp2(gp=x[0],obs=x[1],mu=mu,sigma=sigma),cross_derivative,cross_derivative,self._d2nlog_mass_dobs2(obs=x[1],gp=x[0]))).reshape(2,2)
|
dlink_df = self.gp_link.dtransf_df(f)
|
||||||
|
dlogpdf_dlink = self.dlogpdf_dlink(link_f, y, extra_data=extra_data)
|
||||||
|
d2link_df2 = self.gp_link.d2transf_df2(f)
|
||||||
|
return chain_2(d2logpdf_dlink2, dlink_df, dlogpdf_dlink, d2link_df2)
|
||||||
|
|
||||||
def _joint_predictive_mode(self,mu,sigma):
|
def d3logpdf_df3(self, f, y, extra_data=None):
|
||||||
"""
|
"""
|
||||||
Negative logarithm of the joint predictive distribution (latent variable and output).
|
Evaluates the link function link(f) then computes the third derivative of log likelihood using it
|
||||||
|
Uses the Faa di Bruno's formula for the chain rule
|
||||||
|
|
||||||
:param x: tuple (latent variable,output)
|
.. math::
|
||||||
:param mu: latent variable's predictive mean
|
\\frac{d^{3}\\log p(y|\\lambda(f))}{df^{3}} = \\frac{d^{3}\\log p(y|\\lambda(f)}{d\\lambda(f)^{3}}\\left(\\frac{d\\lambda(f)}{df}\\right)^{3} + 3\\frac{d^{2}\\log p(y|\\lambda(f)}{d\\lambda(f)^{2}}\\frac{d\\lambda(f)}{df}\\frac{d^{2}\\lambda(f)}{df^{2}} + \\frac{d\\log p(y|\\lambda(f)}{d\\lambda(f)}\\frac{d^{3}\\lambda(f)}{df^{3}}
|
||||||
:param sigma: latent variable's predictive standard deviation
|
|
||||||
|
|
||||||
|
:param f: latent variables f
|
||||||
|
:type f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution - not used
|
||||||
|
:returns: third derivative of log likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
"""
|
"""
|
||||||
return sp.optimize.fmin_ncg(self._nlog_joint_predictive_scaled,x0=(mu,self.gp_link.transf(mu)),fprime=self._gradient_nlog_joint_predictive,fhess=self._hessian_nlog_joint_predictive,args=(mu,sigma),disp=False)
|
link_f = self.gp_link.transf(f)
|
||||||
|
d3logpdf_dlink3 = self.d3logpdf_dlink3(link_f, y, extra_data=extra_data)
|
||||||
|
dlink_df = self.gp_link.dtransf_df(f)
|
||||||
|
d2logpdf_dlink2 = self.d2logpdf_dlink2(link_f, y, extra_data=extra_data)
|
||||||
|
d2link_df2 = self.gp_link.d2transf_df2(f)
|
||||||
|
dlogpdf_dlink = self.dlogpdf_dlink(link_f, y, extra_data=extra_data)
|
||||||
|
d3link_df3 = self.gp_link.d3transf_df3(f)
|
||||||
|
return chain_3(d3logpdf_dlink3, dlink_df, d2logpdf_dlink2, d2link_df2, dlogpdf_dlink, d3link_df3)
|
||||||
|
|
||||||
def predictive_values(self,mu,var):
|
def dlogpdf_dtheta(self, f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
TODO: Doc strings
|
||||||
|
"""
|
||||||
|
if len(self._get_param_names()) > 0:
|
||||||
|
link_f = self.gp_link.transf(f)
|
||||||
|
return self.dlogpdf_link_dtheta(link_f, y, extra_data=extra_data)
|
||||||
|
else:
|
||||||
|
#Is no parameters so return an empty array for its derivatives
|
||||||
|
return np.empty([1, 0])
|
||||||
|
|
||||||
|
def dlogpdf_df_dtheta(self, f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
TODO: Doc strings
|
||||||
|
"""
|
||||||
|
if len(self._get_param_names()) > 0:
|
||||||
|
link_f = self.gp_link.transf(f)
|
||||||
|
dlink_df = self.gp_link.dtransf_df(f)
|
||||||
|
dlogpdf_dlink_dtheta = self.dlogpdf_dlink_dtheta(link_f, y, extra_data=extra_data)
|
||||||
|
return chain_1(dlogpdf_dlink_dtheta, dlink_df)
|
||||||
|
else:
|
||||||
|
#Is no parameters so return an empty array for its derivatives
|
||||||
|
return np.empty([f.shape[0], 0])
|
||||||
|
|
||||||
|
def d2logpdf_df2_dtheta(self, f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
TODO: Doc strings
|
||||||
|
"""
|
||||||
|
if len(self._get_param_names()) > 0:
|
||||||
|
link_f = self.gp_link.transf(f)
|
||||||
|
dlink_df = self.gp_link.dtransf_df(f)
|
||||||
|
d2link_df2 = self.gp_link.d2transf_df2(f)
|
||||||
|
d2logpdf_dlink2_dtheta = self.d2logpdf_dlink2_dtheta(link_f, y, extra_data=extra_data)
|
||||||
|
dlogpdf_dlink_dtheta = self.dlogpdf_dlink_dtheta(link_f, y, extra_data=extra_data)
|
||||||
|
return chain_2(d2logpdf_dlink2_dtheta, dlink_df, dlogpdf_dlink_dtheta, d2link_df2)
|
||||||
|
else:
|
||||||
|
#Is no parameters so return an empty array for its derivatives
|
||||||
|
return np.empty([f.shape[0], 0])
|
||||||
|
|
||||||
|
def _laplace_gradients(self, f, y, extra_data=None):
|
||||||
|
dlogpdf_dtheta = self.dlogpdf_dtheta(f, y, extra_data=extra_data)
|
||||||
|
dlogpdf_df_dtheta = self.dlogpdf_df_dtheta(f, y, extra_data=extra_data)
|
||||||
|
d2logpdf_df2_dtheta = self.d2logpdf_df2_dtheta(f, y, extra_data=extra_data)
|
||||||
|
|
||||||
|
#Parameters are stacked vertically. Must be listed in same order as 'get_param_names'
|
||||||
|
# ensure we have gradients for every parameter we want to optimize
|
||||||
|
assert dlogpdf_dtheta.shape[1] == len(self._get_param_names())
|
||||||
|
assert dlogpdf_df_dtheta.shape[1] == len(self._get_param_names())
|
||||||
|
assert d2logpdf_df2_dtheta.shape[1] == len(self._get_param_names())
|
||||||
|
return dlogpdf_dtheta, dlogpdf_df_dtheta, d2logpdf_df2_dtheta
|
||||||
|
|
||||||
|
def predictive_values(self, mu, var, full_cov=False, sampling=False, num_samples=10000):
|
||||||
"""
|
"""
|
||||||
Compute mean, variance and conficence interval (percentiles 5 and 95) of the prediction.
|
Compute mean, variance and conficence interval (percentiles 5 and 95) of the prediction.
|
||||||
|
|
||||||
:param mu: mean of the latent variable
|
:param mu: mean of the latent variable, f, of posterior
|
||||||
:param var: variance of the latent variable
|
:param var: variance of the latent variable, f, of posterior
|
||||||
|
:param full_cov: whether to use the full covariance or just the diagonal
|
||||||
|
:type full_cov: Boolean
|
||||||
|
:param num_samples: number of samples to use in computing quantiles and
|
||||||
|
possibly mean variance
|
||||||
|
:type num_samples: integer
|
||||||
|
:param sampling: Whether to use samples for mean and variances anyway
|
||||||
|
:type sampling: Boolean
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(mu,float) or isinstance(mu,int):
|
|
||||||
mu = [mu]
|
|
||||||
var = [var]
|
|
||||||
pred_mean = []
|
|
||||||
pred_var = []
|
|
||||||
q1 = []
|
|
||||||
q3 = []
|
|
||||||
for m,s in zip(mu,np.sqrt(var)):
|
|
||||||
pred_mean.append(self.predictive_mean(m,s))
|
|
||||||
pred_var.append(self.predictive_variance(m,s,pred_mean[-1]))
|
|
||||||
q1.append(self._predictive_percentiles(.025,m,s))
|
|
||||||
q3.append(self._predictive_percentiles(.975,m,s))
|
|
||||||
pred_mean = np.vstack(pred_mean)
|
|
||||||
pred_var = np.vstack(pred_var)
|
|
||||||
q1 = np.vstack(q1)
|
|
||||||
q3 = np.vstack(q3)
|
|
||||||
return pred_mean, pred_var, q1, q3
|
|
||||||
|
|
||||||
|
if sampling:
|
||||||
|
#Get gp_samples f* using posterior mean and variance
|
||||||
|
if not full_cov:
|
||||||
|
gp_samples = np.random.multivariate_normal(mu.flatten(), np.diag(var.flatten()),
|
||||||
|
size=num_samples).T
|
||||||
|
else:
|
||||||
|
gp_samples = np.random.multivariate_normal(mu.flatten(), var,
|
||||||
|
size=num_samples).T
|
||||||
|
#Push gp samples (f*) through likelihood to give p(y*|f*)
|
||||||
|
samples = self.samples(gp_samples)
|
||||||
|
axis=-1
|
||||||
|
|
||||||
|
#Calculate mean, variance and precentiles from samples
|
||||||
|
print "WARNING: Using sampling to calculate mean, variance and predictive quantiles."
|
||||||
|
pred_mean = np.mean(samples, axis=axis)[:,None]
|
||||||
|
pred_var = np.var(samples, axis=axis)[:,None]
|
||||||
|
q1 = np.percentile(samples, 2.5, axis=axis)[:,None]
|
||||||
|
q3 = np.percentile(samples, 97.5, axis=axis)[:,None]
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
pred_mean = self.predictive_mean(mu, var)
|
||||||
|
pred_var = self.predictive_variance(mu, var, pred_mean)
|
||||||
|
print "WARNING: Predictive quantiles are only computed when sampling."
|
||||||
|
q1 = np.repeat(np.nan,pred_mean.size)[:,None]
|
||||||
|
q3 = q1.copy()
|
||||||
|
|
||||||
|
return pred_mean, pred_var, q1, q3
|
||||||
|
|
||||||
def samples(self, gp):
|
def samples(self, gp):
|
||||||
"""
|
"""
|
||||||
|
|
@ -421,5 +430,4 @@ class NoiseDistribution(object):
|
||||||
|
|
||||||
:param gp: latent variable
|
:param gp: latent variable
|
||||||
"""
|
"""
|
||||||
pass
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
from __future__ import division
|
||||||
# Copyright (c) 2012, 2013 Ricardo Andrade
|
# Copyright (c) 2012, 2013 Ricardo Andrade
|
||||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy import stats,special
|
from scipy import stats,special
|
||||||
import scipy as sp
|
import scipy as sp
|
||||||
|
|
@ -14,9 +14,10 @@ class Poisson(NoiseDistribution):
|
||||||
Poisson likelihood
|
Poisson likelihood
|
||||||
|
|
||||||
.. math::
|
.. math::
|
||||||
L(x) = \\exp(\\lambda) * \\frac{\\lambda^Y_i}{Y_i!}
|
p(y_{i}|\\lambda(f_{i})) = \\frac{\\lambda(f_{i})^{y_{i}}}{y_{i}!}e^{-\\lambda(f_{i})}
|
||||||
|
|
||||||
..Note: Y is expected to take values in {0,1,2,...}
|
.. Note::
|
||||||
|
Y is expected to take values in {0,1,2,...}
|
||||||
"""
|
"""
|
||||||
def __init__(self,gp_link=None,analytical_mean=False,analytical_variance=False):
|
def __init__(self,gp_link=None,analytical_mean=False,analytical_variance=False):
|
||||||
super(Poisson, self).__init__(gp_link,analytical_mean,analytical_variance)
|
super(Poisson, self).__init__(gp_link,analytical_mean,analytical_variance)
|
||||||
|
|
@ -24,25 +25,108 @@ class Poisson(NoiseDistribution):
|
||||||
def _preprocess_values(self,Y): #TODO
|
def _preprocess_values(self,Y): #TODO
|
||||||
return Y
|
return Y
|
||||||
|
|
||||||
def _mass(self,gp,obs):
|
def pdf_link(self, link_f, y, extra_data=None):
|
||||||
"""
|
"""
|
||||||
Mass (or density) function
|
Likelihood function given link(f)
|
||||||
"""
|
|
||||||
return stats.poisson.pmf(obs,self.gp_link.transf(gp))
|
|
||||||
|
|
||||||
def _nlog_mass(self,gp,obs):
|
.. math::
|
||||||
"""
|
p(y_{i}|\\lambda(f_{i})) = \\frac{\\lambda(f_{i})^{y_{i}}}{y_{i}!}e^{-\\lambda(f_{i})}
|
||||||
Negative logarithm of the un-normalized distribution: factors that are not a function of gp are omitted
|
|
||||||
"""
|
|
||||||
return self.gp_link.transf(gp) - obs * np.log(self.gp_link.transf(gp)) + np.log(special.gamma(obs+1))
|
|
||||||
|
|
||||||
def _dnlog_mass_dgp(self,gp,obs):
|
:param link_f: latent variables link(f)
|
||||||
return self.gp_link.dtransf_df(gp) * (1. - obs/self.gp_link.transf(gp))
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in poisson distribution
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
return np.prod(stats.poisson.pmf(y,link_f))
|
||||||
|
|
||||||
def _d2nlog_mass_dgp2(self,gp,obs):
|
def logpdf_link(self, link_f, y, extra_data=None):
|
||||||
d2_df = self.gp_link.d2transf_df2(gp)
|
"""
|
||||||
transf = self.gp_link.transf(gp)
|
Log Likelihood Function given link(f)
|
||||||
return obs * ((self.gp_link.dtransf_df(gp)/transf)**2 - d2_df/transf) + d2_df
|
|
||||||
|
.. math::
|
||||||
|
\\ln p(y_{i}|\lambda(f_{i})) = -\\lambda(f_{i}) + y_{i}\\log \\lambda(f_{i}) - \\log y_{i}!
|
||||||
|
|
||||||
|
:param link_f: latent variables (link(f))
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in poisson distribution
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
|
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
return np.sum(-link_f + y*np.log(link_f) - special.gammaln(y+1))
|
||||||
|
|
||||||
|
def dlogpdf_dlink(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Gradient of the log likelihood function at y, given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d \\ln p(y_{i}|\lambda(f_{i}))}{d\\lambda(f)} = \\frac{y_{i}}{\\lambda(f_{i})} - 1
|
||||||
|
|
||||||
|
:param link_f: latent variables (f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in poisson distribution
|
||||||
|
:returns: gradient of likelihood evaluated at points
|
||||||
|
:rtype: Nx1 array
|
||||||
|
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
return y/link_f - 1
|
||||||
|
|
||||||
|
def d2logpdf_dlink2(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Hessian at y, given link(f), w.r.t link(f)
|
||||||
|
i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j)
|
||||||
|
The hessian will be 0 unless i == j
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{2} \\ln p(y_{i}|\lambda(f_{i}))}{d^{2}\\lambda(f)} = \\frac{-y_{i}}{\\lambda(f_{i})^{2}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in poisson distribution
|
||||||
|
:returns: Diagonal of hessian matrix (second derivative of likelihood evaluated at points f)
|
||||||
|
:rtype: Nx1 array
|
||||||
|
|
||||||
|
.. Note::
|
||||||
|
Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases
|
||||||
|
(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
hess = -y/(link_f**2)
|
||||||
|
return hess
|
||||||
|
#d2_df = self.gp_link.d2transf_df2(gp)
|
||||||
|
#transf = self.gp_link.transf(gp)
|
||||||
|
#return obs * ((self.gp_link.dtransf_df(gp)/transf)**2 - d2_df/transf) + d2_df
|
||||||
|
|
||||||
|
def d3logpdf_dlink3(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Third order derivative log-likelihood function at y given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{3} \\ln p(y_{i}|\lambda(f_{i}))}{d^{3}\\lambda(f)} = \\frac{2y_{i}}{\\lambda(f_{i})^{3}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in poisson distribution
|
||||||
|
:returns: third derivative of likelihood evaluated at points f
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
d3lik_dlink3 = 2*y/(link_f)**3
|
||||||
|
return d3lik_dlink3
|
||||||
|
|
||||||
def _mean(self,gp):
|
def _mean(self,gp):
|
||||||
"""
|
"""
|
||||||
|
|
@ -50,20 +134,19 @@ class Poisson(NoiseDistribution):
|
||||||
"""
|
"""
|
||||||
return self.gp_link.transf(gp)
|
return self.gp_link.transf(gp)
|
||||||
|
|
||||||
def _dmean_dgp(self,gp):
|
|
||||||
return self.gp_link.dtransf_df(gp)
|
|
||||||
|
|
||||||
def _d2mean_dgp2(self,gp):
|
|
||||||
return self.gp_link.d2transf_df2(gp)
|
|
||||||
|
|
||||||
def _variance(self,gp):
|
def _variance(self,gp):
|
||||||
"""
|
"""
|
||||||
Mass (or density) function
|
Mass (or density) function
|
||||||
"""
|
"""
|
||||||
return self.gp_link.transf(gp)
|
return self.gp_link.transf(gp)
|
||||||
|
|
||||||
def _dvariance_dgp(self,gp):
|
def samples(self, gp):
|
||||||
return self.gp_link.dtransf_df(gp)
|
"""
|
||||||
|
Returns a set of samples of observations based on a given value of the latent variable.
|
||||||
|
|
||||||
def _d2variance_dgp2(self,gp):
|
:param gp: latent variable
|
||||||
return self.gp_link.d2transf_df2(gp)
|
"""
|
||||||
|
orig_shape = gp.shape
|
||||||
|
gp = gp.flatten()
|
||||||
|
Ysim = np.random.poisson(self.gp_link.transf(gp))
|
||||||
|
return Ysim.reshape(orig_shape)
|
||||||
|
|
|
||||||
277
GPy/likelihoods/noise_models/student_t_noise.py
Normal file
277
GPy/likelihoods/noise_models/student_t_noise.py
Normal file
|
|
@ -0,0 +1,277 @@
|
||||||
|
# Copyright (c) 2012, 2013 Ricardo Andrade
|
||||||
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from scipy import stats, special
|
||||||
|
import scipy as sp
|
||||||
|
import gp_transformations
|
||||||
|
from noise_distributions import NoiseDistribution
|
||||||
|
from scipy import stats, integrate
|
||||||
|
from scipy.special import gammaln, gamma
|
||||||
|
|
||||||
|
class StudentT(NoiseDistribution):
|
||||||
|
"""
|
||||||
|
Student T likelihood
|
||||||
|
|
||||||
|
For nomanclature see Bayesian Data Analysis 2003 p576
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
p(y_{i}|\\lambda(f_{i})) = \\frac{\\Gamma\\left(\\frac{v+1}{2}\\right)}{\\Gamma\\left(\\frac{v}{2}\\right)\\sqrt{v\\pi\\sigma^{2}}}\\left(1 + \\frac{1}{v}\\left(\\frac{(y_{i} - f_{i})^{2}}{\\sigma^{2}}\\right)\\right)^{\\frac{-v+1}{2}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self,gp_link=None,analytical_mean=True,analytical_variance=True, deg_free=5, sigma2=2):
|
||||||
|
self.v = deg_free
|
||||||
|
self.sigma2 = sigma2
|
||||||
|
|
||||||
|
self._set_params(np.asarray(sigma2))
|
||||||
|
super(StudentT, self).__init__(gp_link,analytical_mean,analytical_variance)
|
||||||
|
self.log_concave = False
|
||||||
|
|
||||||
|
def _get_params(self):
|
||||||
|
return np.asarray(self.sigma2)
|
||||||
|
|
||||||
|
def _get_param_names(self):
|
||||||
|
return ["t_noise_std2"]
|
||||||
|
|
||||||
|
def _set_params(self, x):
|
||||||
|
self.sigma2 = float(x)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def variance(self, extra_data=None):
|
||||||
|
return (self.v / float(self.v - 2)) * self.sigma2
|
||||||
|
|
||||||
|
def pdf_link(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Likelihood function given link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
p(y_{i}|\\lambda(f_{i})) = \\frac{\\Gamma\\left(\\frac{v+1}{2}\\right)}{\\Gamma\\left(\\frac{v}{2}\\right)\\sqrt{v\\pi\\sigma^{2}}}\\left(1 + \\frac{1}{v}\\left(\\frac{(y_{i} - \\lambda(f_{i}))^{2}}{\\sigma^{2}}\\right)\\right)^{\\frac{-v+1}{2}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
e = y - link_f
|
||||||
|
#Careful gamma(big_number) is infinity!
|
||||||
|
objective = ((np.exp(gammaln((self.v + 1)*0.5) - gammaln(self.v * 0.5))
|
||||||
|
/ (np.sqrt(self.v * np.pi * self.sigma2)))
|
||||||
|
* ((1 + (1./float(self.v))*((e**2)/float(self.sigma2)))**(-0.5*(self.v + 1)))
|
||||||
|
)
|
||||||
|
return np.prod(objective)
|
||||||
|
|
||||||
|
def logpdf_link(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Log Likelihood Function given link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\ln p(y_{i}|\lambda(f_{i})) = \\ln \\Gamma\\left(\\frac{v+1}{2}\\right) - \\ln \\Gamma\\left(\\frac{v}{2}\\right) - \\ln \\sqrt{v \\pi\\sigma^{2}} - \\frac{v+1}{2}\\ln \\left(1 + \\frac{1}{v}\\left(\\frac{(y_{i} - \lambda(f_{i}))^{2}}{\\sigma^{2}}\\right)\\right)
|
||||||
|
|
||||||
|
:param link_f: latent variables (link(f))
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution
|
||||||
|
:returns: likelihood evaluated for this point
|
||||||
|
:rtype: float
|
||||||
|
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
e = y - link_f
|
||||||
|
objective = (+ gammaln((self.v + 1) * 0.5)
|
||||||
|
- gammaln(self.v * 0.5)
|
||||||
|
- 0.5*np.log(self.sigma2 * self.v * np.pi)
|
||||||
|
- 0.5*(self.v + 1)*np.log(1 + (1/np.float(self.v))*((e**2)/self.sigma2))
|
||||||
|
)
|
||||||
|
return np.sum(objective)
|
||||||
|
|
||||||
|
def dlogpdf_dlink(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Gradient of the log likelihood function at y, given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d \\ln p(y_{i}|\lambda(f_{i}))}{d\\lambda(f)} = \\frac{(v+1)(y_{i}-\lambda(f_{i}))}{(y_{i}-\lambda(f_{i}))^{2} + \\sigma^{2}v}
|
||||||
|
|
||||||
|
:param link_f: latent variables (f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution
|
||||||
|
:returns: gradient of likelihood evaluated at points
|
||||||
|
:rtype: Nx1 array
|
||||||
|
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
e = y - link_f
|
||||||
|
grad = ((self.v + 1) * e) / (self.v * self.sigma2 + (e**2))
|
||||||
|
return grad
|
||||||
|
|
||||||
|
def d2logpdf_dlink2(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Hessian at y, given link(f), w.r.t link(f)
|
||||||
|
i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j)
|
||||||
|
The hessian will be 0 unless i == j
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{2} \\ln p(y_{i}|\lambda(f_{i}))}{d^{2}\\lambda(f)} = \\frac{(v+1)((y_{i}-\lambda(f_{i}))^{2} - \\sigma^{2}v)}{((y_{i}-\lambda(f_{i}))^{2} + \\sigma^{2}v)^{2}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution
|
||||||
|
:returns: Diagonal of hessian matrix (second derivative of likelihood evaluated at points f)
|
||||||
|
:rtype: Nx1 array
|
||||||
|
|
||||||
|
.. Note::
|
||||||
|
Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases
|
||||||
|
(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
e = y - link_f
|
||||||
|
hess = ((self.v + 1)*(e**2 - self.v*self.sigma2)) / ((self.sigma2*self.v + e**2)**2)
|
||||||
|
return hess
|
||||||
|
|
||||||
|
def d3logpdf_dlink3(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Third order derivative log-likelihood function at y given link(f) w.r.t link(f)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{3} \\ln p(y_{i}|\lambda(f_{i}))}{d^{3}\\lambda(f)} = \\frac{-2(v+1)((y_{i} - \lambda(f_{i}))^3 - 3(y_{i} - \lambda(f_{i})) \\sigma^{2} v))}{((y_{i} - \lambda(f_{i})) + \\sigma^{2} v)^3}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution
|
||||||
|
:returns: third derivative of likelihood evaluated at points f
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
e = y - link_f
|
||||||
|
d3lik_dlink3 = ( -(2*(self.v + 1)*(-e)*(e**2 - 3*self.v*self.sigma2)) /
|
||||||
|
((e**2 + self.sigma2*self.v)**3)
|
||||||
|
)
|
||||||
|
return d3lik_dlink3
|
||||||
|
|
||||||
|
def dlogpdf_link_dvar(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Gradient of the log-likelihood function at y given f, w.r.t variance parameter (t_noise)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d \\ln p(y_{i}|\lambda(f_{i}))}{d\\sigma^{2}} = \\frac{v((y_{i} - \lambda(f_{i}))^{2} - \\sigma^{2})}{2\\sigma^{2}(\\sigma^{2}v + (y_{i} - \lambda(f_{i}))^{2})}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution
|
||||||
|
:returns: derivative of likelihood evaluated at points f w.r.t variance parameter
|
||||||
|
:rtype: float
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
e = y - link_f
|
||||||
|
dlogpdf_dvar = self.v*(e**2 - self.sigma2)/(2*self.sigma2*(self.sigma2*self.v + e**2))
|
||||||
|
return np.sum(dlogpdf_dvar)
|
||||||
|
|
||||||
|
def dlogpdf_dlink_dvar(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Derivative of the dlogpdf_dlink w.r.t variance parameter (t_noise)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d}{d\\sigma^{2}}(\\frac{d \\ln p(y_{i}|\lambda(f_{i}))}{df}) = \\frac{-2\\sigma v(v + 1)(y_{i}-\lambda(f_{i}))}{(y_{i}-\lambda(f_{i}))^2 + \\sigma^2 v)^2}
|
||||||
|
|
||||||
|
:param link_f: latent variables link_f
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution
|
||||||
|
:returns: derivative of likelihood evaluated at points f w.r.t variance parameter
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
e = y - link_f
|
||||||
|
dlogpdf_dlink_dvar = (self.v*(self.v+1)*(-e))/((self.sigma2*self.v + e**2)**2)
|
||||||
|
return dlogpdf_dlink_dvar
|
||||||
|
|
||||||
|
def d2logpdf_dlink2_dvar(self, link_f, y, extra_data=None):
|
||||||
|
"""
|
||||||
|
Gradient of the hessian (d2logpdf_dlink2) w.r.t variance parameter (t_noise)
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d}{d\\sigma^{2}}(\\frac{d^{2} \\ln p(y_{i}|\lambda(f_{i}))}{d^{2}f}) = \\frac{v(v+1)(\\sigma^{2}v - 3(y_{i} - \lambda(f_{i}))^{2})}{(\\sigma^{2}v + (y_{i} - \lambda(f_{i}))^{2})^{3}}
|
||||||
|
|
||||||
|
:param link_f: latent variables link(f)
|
||||||
|
:type link_f: Nx1 array
|
||||||
|
:param y: data
|
||||||
|
:type y: Nx1 array
|
||||||
|
:param extra_data: extra_data which is not used in student t distribution
|
||||||
|
:returns: derivative of hessian evaluated at points f and f_j w.r.t variance parameter
|
||||||
|
:rtype: Nx1 array
|
||||||
|
"""
|
||||||
|
assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
|
||||||
|
e = y - link_f
|
||||||
|
d2logpdf_dlink2_dvar = ( (self.v*(self.v+1)*(self.sigma2*self.v - 3*(e**2)))
|
||||||
|
/ ((self.sigma2*self.v + (e**2))**3)
|
||||||
|
)
|
||||||
|
return d2logpdf_dlink2_dvar
|
||||||
|
|
||||||
|
def dlogpdf_link_dtheta(self, f, y, extra_data=None):
|
||||||
|
dlogpdf_dvar = self.dlogpdf_link_dvar(f, y, extra_data=extra_data)
|
||||||
|
return np.asarray([[dlogpdf_dvar]])
|
||||||
|
|
||||||
|
def dlogpdf_dlink_dtheta(self, f, y, extra_data=None):
|
||||||
|
dlogpdf_dlink_dvar = self.dlogpdf_dlink_dvar(f, y, extra_data=extra_data)
|
||||||
|
return dlogpdf_dlink_dvar
|
||||||
|
|
||||||
|
def d2logpdf_dlink2_dtheta(self, f, y, extra_data=None):
|
||||||
|
d2logpdf_dlink2_dvar = self.d2logpdf_dlink2_dvar(f, y, extra_data=extra_data)
|
||||||
|
return d2logpdf_dlink2_dvar
|
||||||
|
|
||||||
|
def _predictive_variance_analytical(self, mu, sigma, predictive_mean=None):
|
||||||
|
"""
|
||||||
|
Compute predictive variance of student_t*normal p(y*|f*)p(f*)
|
||||||
|
|
||||||
|
Need to find what the variance is at the latent points for a student t*normal p(y*|f*)p(f*)
|
||||||
|
(((g((v+1)/2))/(g(v/2)*s*sqrt(v*pi)))*(1+(1/v)*((y-f)/s)^2)^(-(v+1)/2))
|
||||||
|
*((1/(s*sqrt(2*pi)))*exp(-(1/(2*(s^2)))*((y-f)^2)))
|
||||||
|
"""
|
||||||
|
|
||||||
|
#FIXME: Not correct
|
||||||
|
#We want the variance around test points y which comes from int p(y*|f*)p(f*) df*
|
||||||
|
#Var(y*) = Var(E[y*|f*]) + E[Var(y*|f*)]
|
||||||
|
#Since we are given f* (mu) which is our mean (expected) value of y*|f* then the variance is the variance around this
|
||||||
|
#Which was also given to us as (var)
|
||||||
|
#We also need to know the expected variance of y* around samples f*, this is the variance of the student t distribution
|
||||||
|
#However the variance of the student t distribution is not dependent on f, only on sigma and the degrees of freedom
|
||||||
|
true_var = 1/(1/sigma**2 + 1/self.variance)
|
||||||
|
|
||||||
|
return true_var
|
||||||
|
|
||||||
|
def _predictive_mean_analytical(self, mu, sigma):
|
||||||
|
"""
|
||||||
|
Compute mean of the prediction
|
||||||
|
"""
|
||||||
|
#FIXME: Not correct
|
||||||
|
return mu
|
||||||
|
|
||||||
|
def samples(self, gp):
|
||||||
|
"""
|
||||||
|
Returns a set of samples of observations based on a given value of the latent variable.
|
||||||
|
|
||||||
|
:param gp: latent variable
|
||||||
|
"""
|
||||||
|
orig_shape = gp.shape
|
||||||
|
gp = gp.flatten()
|
||||||
|
#FIXME: Very slow as we are computing a new random variable per input!
|
||||||
|
#Can't get it to sample all at the same time
|
||||||
|
#student_t_samples = np.array([stats.t.rvs(self.v, self.gp_link.transf(gpj),scale=np.sqrt(self.sigma2), size=1) for gpj in gp])
|
||||||
|
dfs = np.ones_like(gp)*self.v
|
||||||
|
scales = np.ones_like(gp)*np.sqrt(self.sigma2)
|
||||||
|
student_t_samples = stats.t.rvs(dfs, loc=self.gp_link.transf(gp),
|
||||||
|
scale=scales)
|
||||||
|
return student_t_samples.reshape(orig_shape)
|
||||||
31
GPy/models.py
Normal file
31
GPy/models.py
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
'''
|
||||||
|
GPy Models
|
||||||
|
==========
|
||||||
|
|
||||||
|
Implementations for common models used in GP regression and classification.
|
||||||
|
The different models can be viewed in :mod:`GPy.models_modules`, which holds
|
||||||
|
detailed explanations for the different models.
|
||||||
|
|
||||||
|
:warning: This module is a convienince module for endusers to use. For developers
|
||||||
|
see :mod:`GPy.models_modules`, which holds the implementions for each model.
|
||||||
|
'''
|
||||||
|
|
||||||
|
__updated__ = '2013-11-28'
|
||||||
|
|
||||||
|
from models_modules.bayesian_gplvm import BayesianGPLVM
|
||||||
|
from models_modules.gp_regression import GPRegression
|
||||||
|
from models_modules.gp_classification import GPClassification#; _gp_classification = gp_classification ; del gp_classification
|
||||||
|
from models_modules.sparse_gp_regression import SparseGPRegression#; _sparse_gp_regression = sparse_gp_regression ; del sparse_gp_regression
|
||||||
|
from models_modules.svigp_regression import SVIGPRegression#; _svigp_regression = svigp_regression ; del svigp_regression
|
||||||
|
from models_modules.sparse_gp_classification import SparseGPClassification#; _sparse_gp_classification = sparse_gp_classification ; del sparse_gp_classification
|
||||||
|
from models_modules.fitc_classification import FITCClassification#; _fitc_classification = fitc_classification ; del fitc_classification
|
||||||
|
from models_modules.gplvm import GPLVM#; _gplvm = gplvm ; del gplvm
|
||||||
|
from models_modules.bcgplvm import BCGPLVM#; _bcgplvm = bcgplvm; del bcgplvm
|
||||||
|
from models_modules.sparse_gplvm import SparseGPLVM#; _sparse_gplvm = sparse_gplvm ; del sparse_gplvm
|
||||||
|
from models_modules.warped_gp import WarpedGP#; _warped_gp = warped_gp ; del warped_gp
|
||||||
|
from models_modules.bayesian_gplvm import BayesianGPLVM#; _bayesian_gplvm = bayesian_gplvm ; del bayesian_gplvm
|
||||||
|
from models_modules.mrd import MRD#; _mrd = mrd; del mrd
|
||||||
|
from models_modules.gradient_checker import GradientChecker#; _gradient_checker = gradient_checker ; del gradient_checker
|
||||||
|
from models_modules.gp_multioutput_regression import GPMultioutputRegression#; _gp_multioutput_regression = gp_multioutput_regression ; del gp_multioutput_regression
|
||||||
|
from models_modules.sparse_gp_multioutput_regression import SparseGPMultioutputRegression#; _sparse_gp_multioutput_regression = sparse_gp_multioutput_regression ; del sparse_gp_multioutput_regression
|
||||||
|
from models_modules.gradient_checker import GradientChecker
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
|
||||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
|
||||||
|
|
||||||
from gp_regression import GPRegression
|
|
||||||
from gp_classification import GPClassification
|
|
||||||
from sparse_gp_regression import SparseGPRegression
|
|
||||||
from svigp_regression import SVIGPRegression
|
|
||||||
from sparse_gp_classification import SparseGPClassification
|
|
||||||
from fitc_classification import FITCClassification
|
|
||||||
from gplvm import GPLVM
|
|
||||||
from bcgplvm import BCGPLVM
|
|
||||||
from sparse_gplvm import SparseGPLVM
|
|
||||||
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
|
|
||||||
19
GPy/models_modules/__init__.py
Normal file
19
GPy/models_modules/__init__.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||||
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
|
||||||
|
# from gp_regression import GPRegression; _gp_regression = gp_regression ; del gp_regression
|
||||||
|
# from gp_classification import GPClassification; _gp_classification = gp_classification ; del gp_classification
|
||||||
|
# from sparse_gp_regression import SparseGPRegression; _sparse_gp_regression = sparse_gp_regression ; del sparse_gp_regression
|
||||||
|
# from svigp_regression import SVIGPRegression; _svigp_regression = svigp_regression ; del svigp_regression
|
||||||
|
# from sparse_gp_classification import SparseGPClassification; _sparse_gp_classification = sparse_gp_classification ; del sparse_gp_classification
|
||||||
|
# from fitc_classification import FITCClassification; _fitc_classification = fitc_classification ; del fitc_classification
|
||||||
|
# from gplvm import GPLVM; _gplvm = gplvm ; del gplvm
|
||||||
|
# from bcgplvm import BCGPLVM; _bcgplvm = bcgplvm; del bcgplvm
|
||||||
|
# from sparse_gplvm import SparseGPLVM; _sparse_gplvm = sparse_gplvm ; del sparse_gplvm
|
||||||
|
# from warped_gp import WarpedGP; _warped_gp = warped_gp ; del warped_gp
|
||||||
|
# from bayesian_gplvm import BayesianGPLVM; _bayesian_gplvm = bayesian_gplvm ; del bayesian_gplvm
|
||||||
|
# from mrd import MRD; _mrd = mrd ; del mrd
|
||||||
|
# from gradient_checker import GradientChecker; _gradient_checker = gradient_checker ; del gradient_checker
|
||||||
|
# from gp_multioutput_regression import GPMultioutputRegression; _gp_multioutput_regression = gp_multioutput_regression ; del gp_multioutput_regression
|
||||||
|
# from sparse_gp_multioutput_regression import SparseGPMultioutputRegression; _sparse_gp_multioutput_regression = sparse_gp_multioutput_regression ; del sparse_gp_multioutput_regression
|
||||||
|
|
||||||
|
|
@ -2,16 +2,17 @@
|
||||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from ..core import SparseGP
|
from ..core.sparse_gp import SparseGP
|
||||||
from ..likelihoods import Gaussian
|
from ..likelihoods import Gaussian
|
||||||
from .. import kern
|
from .. import kern
|
||||||
import itertools
|
import itertools
|
||||||
from matplotlib.colors import colorConverter
|
from matplotlib.colors import colorConverter
|
||||||
from GPy.inference.optimization import SCG
|
from GPy.inference.optimization import SCG
|
||||||
from GPy.util import plot_latent, linalg
|
from GPy.util import plot_latent, linalg
|
||||||
from GPy.models.gplvm import GPLVM
|
from .gplvm import GPLVM
|
||||||
from GPy.util.plot_latent import most_significant_input_dimensions
|
from GPy.util.plot_latent import most_significant_input_dimensions
|
||||||
from matplotlib import pyplot
|
from matplotlib import pyplot
|
||||||
|
from GPy.core.model import Model
|
||||||
|
|
||||||
class BayesianGPLVM(SparseGP, GPLVM):
|
class BayesianGPLVM(SparseGP, GPLVM):
|
||||||
"""
|
"""
|
||||||
|
|
@ -49,18 +50,6 @@ class BayesianGPLVM(SparseGP, GPLVM):
|
||||||
SparseGP.__init__(self, X, likelihood, kernel, Z=Z, X_variance=X_variance, **kwargs)
|
SparseGP.__init__(self, X, likelihood, kernel, Z=Z, X_variance=X_variance, **kwargs)
|
||||||
self.ensure_default_constraints()
|
self.ensure_default_constraints()
|
||||||
|
|
||||||
def getstate(self):
|
|
||||||
"""
|
|
||||||
Get the current state of the class,
|
|
||||||
here just all the indices, rest can get recomputed
|
|
||||||
"""
|
|
||||||
return SparseGP.getstate(self) + [self.init]
|
|
||||||
|
|
||||||
def setstate(self, state):
|
|
||||||
self._const_jitter = None
|
|
||||||
self.init = state.pop()
|
|
||||||
SparseGP.setstate(self, state)
|
|
||||||
|
|
||||||
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)], [])
|
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)], [])
|
S_names = sum([['X_variance_%i_%i' % (n, q) for q in range(self.input_dim)] for n in range(self.num_data)], [])
|
||||||
|
|
@ -285,6 +274,70 @@ class BayesianGPLVM(SparseGP, GPLVM):
|
||||||
fig.tight_layout(h_pad=.01) # , rect=(0, 0, 1, .95))
|
fig.tight_layout(h_pad=.01) # , rect=(0, 0, 1, .95))
|
||||||
return fig
|
return fig
|
||||||
|
|
||||||
|
def getstate(self):
|
||||||
|
"""
|
||||||
|
Get the current state of the class,
|
||||||
|
here just all the indices, rest can get recomputed
|
||||||
|
"""
|
||||||
|
return SparseGP.getstate(self) + [self.init]
|
||||||
|
|
||||||
|
def setstate(self, state):
|
||||||
|
self._const_jitter = None
|
||||||
|
self.init = state.pop()
|
||||||
|
SparseGP.setstate(self, state)
|
||||||
|
|
||||||
|
class BayesianGPLVMWithMissingData(Model):
|
||||||
|
"""
|
||||||
|
Bayesian Gaussian Process Latent Variable Model with missing data support.
|
||||||
|
NOTE: Missing data is assumed to be missing at random!
|
||||||
|
|
||||||
|
This extension comes with a large memory and computing time deficiency.
|
||||||
|
Use only if fraction of missing data at random is higher than 60%.
|
||||||
|
Otherwise, try filtering data before using this extension.
|
||||||
|
|
||||||
|
Y can hold missing data as given by `missing`, standard is :class:`~numpy.nan`.
|
||||||
|
|
||||||
|
If likelihood is given for Y, this likelihood will be discarded, but the parameters
|
||||||
|
of the likelihood will be taken. Also every effort of creating the same likelihood
|
||||||
|
will be done.
|
||||||
|
|
||||||
|
:param likelihood_or_Y: observed data (np.ndarray) or GPy.likelihood
|
||||||
|
:type likelihood_or_Y: :class:`~numpy.ndarray` | :class:`~GPy.likelihoods.likelihood.likelihood` instance
|
||||||
|
:param int input_dim: latent dimensionality
|
||||||
|
:param init: initialisation method for the latent space
|
||||||
|
:type init: 'PCA' | 'random'
|
||||||
|
"""
|
||||||
|
def __init__(self, likelihood_or_Y, input_dim, X=None, X_variance=None, init='PCA', num_inducing=10,
|
||||||
|
Z=None, kernel=None, missing=np.nan, **kwargs):
|
||||||
|
if type(likelihood_or_Y) is np.ndarray:
|
||||||
|
likelihood = Gaussian(likelihood_or_Y)
|
||||||
|
else:
|
||||||
|
likelihood = likelihood_or_Y
|
||||||
|
|
||||||
|
if X == None:
|
||||||
|
X = self.initialise_latent(init, input_dim, likelihood.Y)
|
||||||
|
self.init = init
|
||||||
|
|
||||||
|
if X_variance is None:
|
||||||
|
X_variance = np.clip((np.ones_like(X) * 0.5) + .01 * np.random.randn(*X.shape), 0.001, 1)
|
||||||
|
|
||||||
|
if Z is None:
|
||||||
|
Z = np.random.permutation(X.copy())[:num_inducing]
|
||||||
|
assert Z.shape[1] == X.shape[1]
|
||||||
|
|
||||||
|
if kernel is None:
|
||||||
|
kernel = kern.rbf(input_dim) # + kern.white(input_dim)
|
||||||
|
|
||||||
|
SparseGP.__init__(self, X, likelihood, kernel, Z=Z, X_variance=X_variance, **kwargs)
|
||||||
|
self.ensure_default_constraints()
|
||||||
|
|
||||||
|
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)], [])
|
||||||
|
return (X_names + S_names + SparseGP._get_param_names(self))
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
def latent_cost_and_grad(mu_S, kern, Z, dL_dpsi0, dL_dpsi1, dL_dpsi2):
|
def latent_cost_and_grad(mu_S, kern, Z, dL_dpsi0, dL_dpsi1, dL_dpsi2):
|
||||||
"""
|
"""
|
||||||
objective function for fitting the latent variables for test points
|
objective function for fitting the latent variables for test points
|
||||||
|
|
@ -7,7 +7,7 @@ import pylab as pb
|
||||||
import sys, pdb
|
import sys, pdb
|
||||||
from ..core import GP
|
from ..core import GP
|
||||||
from ..models import GPLVM
|
from ..models import GPLVM
|
||||||
from ..mappings import *
|
from ..mappings import Kernel
|
||||||
|
|
||||||
|
|
||||||
class BCGPLVM(GPLVM):
|
class BCGPLVM(GPLVM):
|
||||||
|
|
@ -16,7 +16,7 @@ class FITCClassification(FITC):
|
||||||
|
|
||||||
:param X: input observations
|
:param X: input observations
|
||||||
:param Y: observed values
|
:param Y: observed values
|
||||||
:param likelihood: a GPy likelihood, defaults to Binomial with probit link function
|
:param likelihood: a GPy likelihood, defaults to Bernoulli with probit link function
|
||||||
:param kernel: a GPy kernel, defaults to rbf+white
|
:param kernel: a GPy kernel, defaults to rbf+white
|
||||||
:param normalize_X: whether to normalize the input data before computing (predictions will be in original scales)
|
:param normalize_X: whether to normalize the input data before computing (predictions will be in original scales)
|
||||||
:type normalize_X: False|True
|
:type normalize_X: False|True
|
||||||
|
|
@ -31,7 +31,7 @@ class FITCClassification(FITC):
|
||||||
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:
|
if likelihood is None:
|
||||||
noise_model = likelihoods.binomial()
|
noise_model = likelihoods.bernoulli()
|
||||||
likelihood = likelihoods.EP(Y, noise_model)
|
likelihood = likelihoods.EP(Y, noise_model)
|
||||||
elif Y is not None:
|
elif Y is not None:
|
||||||
if not all(Y.flatten() == likelihood.data.flatten()):
|
if not all(Y.flatten() == likelihood.data.flatten()):
|
||||||
|
|
@ -15,7 +15,7 @@ class GPClassification(GP):
|
||||||
|
|
||||||
:param X: input observations
|
:param X: input observations
|
||||||
:param Y: observed values, can be None if likelihood is not None
|
: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 likelihood: a GPy likelihood, defaults to Bernoulli with Probit link_function
|
||||||
:param kernel: a GPy kernel, defaults to rbf
|
: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)
|
:param normalize_X: whether to normalize the input data before computing (predictions will be in original scales)
|
||||||
:type normalize_X: False|True
|
:type normalize_X: False|True
|
||||||
|
|
@ -31,7 +31,7 @@ class GPClassification(GP):
|
||||||
kernel = kern.rbf(X.shape[1])
|
kernel = kern.rbf(X.shape[1])
|
||||||
|
|
||||||
if likelihood is None:
|
if likelihood is None:
|
||||||
noise_model = likelihoods.binomial()
|
noise_model = likelihoods.bernoulli()
|
||||||
likelihood = likelihoods.EP(Y, noise_model)
|
likelihood = likelihoods.EP(Y, noise_model)
|
||||||
elif Y is not None:
|
elif Y is not None:
|
||||||
if not all(Y.flatten() == likelihood.data.flatten()):
|
if not all(Y.flatten() == likelihood.data.flatten()):
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
from ..core import GP
|
from ..core import GP
|
||||||
from .. import likelihoods
|
from .. import likelihoods
|
||||||
from .. import kern
|
from .. import kern
|
||||||
|
|
@ -25,10 +24,11 @@ class GPRegression(GP):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, X, Y, kernel=None, normalize_X=False, normalize_Y=False):
|
def __init__(self, X, Y, kernel=None, normalize_X=False, normalize_Y=False, likelihood=None):
|
||||||
if kernel is None:
|
if kernel is None:
|
||||||
kernel = kern.rbf(X.shape[1])
|
kernel = kern.rbf(X.shape[1])
|
||||||
|
|
||||||
|
if likelihood is None:
|
||||||
likelihood = likelihoods.Gaussian(Y, normalize=normalize_Y)
|
likelihood = likelihoods.Gaussian(Y, normalize=normalize_Y)
|
||||||
|
|
||||||
GP.__init__(self, X, likelihood, kernel, normalize_X=normalize_X)
|
GP.__init__(self, X, likelihood, kernel, normalize_X=normalize_X)
|
||||||
|
|
@ -39,5 +39,3 @@ class GPRegression(GP):
|
||||||
|
|
||||||
def setstate(self, state):
|
def setstate(self, state):
|
||||||
return GP.setstate(self, state)
|
return GP.setstate(self, state)
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
@ -4,15 +4,11 @@
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pylab as pb
|
import pylab as pb
|
||||||
import sys, pdb
|
|
||||||
from .. import kern
|
from .. import kern
|
||||||
from ..core import Model
|
from ..core import priors
|
||||||
from ..util.linalg import pdinv, PCA
|
|
||||||
from ..core.priors import Gaussian as Gaussian_prior
|
|
||||||
from ..core import GP
|
from ..core import GP
|
||||||
from ..likelihoods import Gaussian
|
from ..likelihoods import Gaussian
|
||||||
from .. import util
|
from .. import util
|
||||||
from GPy.util import plot_latent
|
|
||||||
|
|
||||||
|
|
||||||
class GPLVM(GP):
|
class GPLVM(GP):
|
||||||
|
|
@ -34,22 +30,17 @@ class GPLVM(GP):
|
||||||
kernel = kern.rbf(input_dim, ARD=input_dim > 1) + kern.bias(input_dim, np.exp(-2))
|
kernel = kern.rbf(input_dim, ARD=input_dim > 1) + kern.bias(input_dim, np.exp(-2))
|
||||||
likelihood = Gaussian(Y, normalize=normalize_Y, variance=np.exp(-2.))
|
likelihood = Gaussian(Y, normalize=normalize_Y, variance=np.exp(-2.))
|
||||||
GP.__init__(self, X, likelihood, kernel, normalize_X=False)
|
GP.__init__(self, X, likelihood, kernel, normalize_X=False)
|
||||||
self.set_prior('.*X', Gaussian_prior(0, 1))
|
self.set_prior('.*X', priors.Gaussian(0, 1))
|
||||||
self.ensure_default_constraints()
|
self.ensure_default_constraints()
|
||||||
|
|
||||||
def initialise_latent(self, init, input_dim, Y):
|
def initialise_latent(self, init, input_dim, Y):
|
||||||
Xr = np.random.randn(Y.shape[0], input_dim)
|
Xr = np.random.randn(Y.shape[0], input_dim)
|
||||||
if init == 'PCA':
|
if init == 'PCA':
|
||||||
|
from ..util.linalg import PCA
|
||||||
PC = PCA(Y, input_dim)[0]
|
PC = PCA(Y, input_dim)[0]
|
||||||
Xr[:PC.shape[0], :PC.shape[1]] = PC
|
Xr[:PC.shape[0], :PC.shape[1]] = PC
|
||||||
return Xr
|
return Xr
|
||||||
|
|
||||||
def getstate(self):
|
|
||||||
return GP.getstate(self)
|
|
||||||
|
|
||||||
def setstate(self, state):
|
|
||||||
GP.setstate(self, state)
|
|
||||||
|
|
||||||
def _get_param_names(self):
|
def _get_param_names(self):
|
||||||
return sum([['X_%i_%i' % (n, q) for q in range(self.input_dim)] for n in range(self.num_data)], []) + GP._get_param_names(self)
|
return sum([['X_%i_%i' % (n, q) for q in range(self.input_dim)] for n in range(self.num_data)], []) + GP._get_param_names(self)
|
||||||
|
|
||||||
|
|
@ -91,3 +82,11 @@ class GPLVM(GP):
|
||||||
|
|
||||||
def plot_magnification(self, *args, **kwargs):
|
def plot_magnification(self, *args, **kwargs):
|
||||||
return util.plot_latent.plot_magnification(self, *args, **kwargs)
|
return util.plot_latent.plot_magnification(self, *args, **kwargs)
|
||||||
|
|
||||||
|
def getstate(self):
|
||||||
|
return GP.getstate(self)
|
||||||
|
|
||||||
|
def setstate(self, state):
|
||||||
|
GP.setstate(self, state)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -28,15 +28,14 @@ class GradientChecker(Model):
|
||||||
:param df: Gradient of function to check
|
:param df: Gradient of function to check
|
||||||
:param x0:
|
:param x0:
|
||||||
Initial guess for inputs x (if it has a shape (a,b) this will be reflected in the parameter names).
|
Initial guess for inputs x (if it has a shape (a,b) this will be reflected in the parameter names).
|
||||||
Can be a list of arrays, if takes a list of arrays. This list will be passed
|
Can be a list of arrays, if f takes a list of arrays. This list will be passed
|
||||||
to f and df in the same order as given here.
|
to f and df in the same order as given here.
|
||||||
If only one argument, make sure not to pass a list!!!
|
If f takes only one argument, make sure not to pass a list for x0!!!
|
||||||
|
|
||||||
:type x0: [array-like] | array-like | float | int
|
:type x0: [array-like] | array-like | float | int
|
||||||
:param names:
|
:param list names:
|
||||||
Names to print, when performing gradcheck. If a list was passed to x0
|
Names to print, when performing gradcheck. If a list was passed to x0
|
||||||
a list of names with the same length is expected.
|
a list of names with the same length is expected.
|
||||||
:param args: Arguments passed as f(x, *args, **kwargs) and df(x, *args, **kwargs)
|
:param args kwargs: Arguments passed as f(x, *args, **kwargs) and df(x, *args, **kwargs)
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
---------
|
---------
|
||||||
|
|
@ -46,7 +45,7 @@ class GradientChecker(Model):
|
||||||
Sinusoid:
|
Sinusoid:
|
||||||
|
|
||||||
X = numpy.random.rand(N, Q)
|
X = numpy.random.rand(N, Q)
|
||||||
grad = GradientChecker(numpy.sin,numpy.cos,X,'x')
|
grad = GradientChecker(numpy.sin,numpy.cos,X,'sin_in')
|
||||||
grad.checkgrad(verbose=1)
|
grad.checkgrad(verbose=1)
|
||||||
|
|
||||||
Using GPy:
|
Using GPy:
|
||||||
|
|
@ -54,9 +53,9 @@ class GradientChecker(Model):
|
||||||
X, Z = numpy.random.randn(N,Q), numpy.random.randn(M,Q)
|
X, Z = numpy.random.randn(N,Q), numpy.random.randn(M,Q)
|
||||||
kern = GPy.kern.linear(Q, ARD=True) + GPy.kern.rbf(Q, ARD=True)
|
kern = GPy.kern.linear(Q, ARD=True) + GPy.kern.rbf(Q, ARD=True)
|
||||||
grad = GradientChecker(kern.K,
|
grad = GradientChecker(kern.K,
|
||||||
lambda x: 2*kern.dK_dX(numpy.ones((1,1)), x),
|
lambda x: kern.dK_dX(numpy.ones((1,1)), x),
|
||||||
x0 = X.copy(),
|
x0 = X.copy(),
|
||||||
names='X')
|
names=['X_input'])
|
||||||
grad.checkgrad(verbose=1)
|
grad.checkgrad(verbose=1)
|
||||||
grad.randomize()
|
grad.randomize()
|
||||||
grad.checkgrad(verbose=1)
|
grad.checkgrad(verbose=1)
|
||||||
|
|
@ -75,14 +74,14 @@ class GradientChecker(Model):
|
||||||
self.names = names
|
self.names = names
|
||||||
self.shapes = [get_shape(x0)]
|
self.shapes = [get_shape(x0)]
|
||||||
for name, xi in zip(self.names, at_least_one_element(x0)):
|
for name, xi in zip(self.names, at_least_one_element(x0)):
|
||||||
self.__setattr__(name, xi)
|
self.__setattr__(name, numpy.float_(xi))
|
||||||
# self._param_names = []
|
# self._param_names = []
|
||||||
# for name, shape in zip(self.names, self.shapes):
|
# for name, shape in zip(self.names, self.shapes):
|
||||||
# self._param_names.extend(map(lambda nameshape: ('_'.join(nameshape)).strip('_'), itertools.izip(itertools.repeat(name), itertools.imap(lambda t: '_'.join(map(str, t)), itertools.product(*map(lambda xi: range(xi), shape))))))
|
# self._param_names.extend(map(lambda nameshape: ('_'.join(nameshape)).strip('_'), itertools.izip(itertools.repeat(name), itertools.imap(lambda t: '_'.join(map(str, t)), itertools.product(*map(lambda xi: range(xi), shape))))))
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.f = f
|
self._f = f
|
||||||
self.df = df
|
self._df = df
|
||||||
|
|
||||||
def _get_x(self):
|
def _get_x(self):
|
||||||
if len(self.names) > 1:
|
if len(self.names) > 1:
|
||||||
|
|
@ -90,10 +89,10 @@ class GradientChecker(Model):
|
||||||
return [self.__getattribute__(self.names[0])] + list(self.args)
|
return [self.__getattribute__(self.names[0])] + list(self.args)
|
||||||
|
|
||||||
def log_likelihood(self):
|
def log_likelihood(self):
|
||||||
return float(numpy.sum(self.f(*self._get_x(), **self.kwargs)))
|
return float(numpy.sum(self._f(*self._get_x(), **self.kwargs)))
|
||||||
|
|
||||||
def _log_likelihood_gradients(self):
|
def _log_likelihood_gradients(self):
|
||||||
return numpy.atleast_1d(self.df(*self._get_x(), **self.kwargs)).flatten()
|
return numpy.atleast_1d(self._df(*self._get_x(), **self.kwargs)).flatten()
|
||||||
|
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
|
|
@ -9,8 +9,8 @@ from GPy.util.linalg import PCA
|
||||||
import numpy
|
import numpy
|
||||||
import itertools
|
import itertools
|
||||||
import pylab
|
import pylab
|
||||||
from GPy.kern.kern import kern
|
from ..kern import kern
|
||||||
from GPy.models.bayesian_gplvm import BayesianGPLVM
|
from bayesian_gplvm import BayesianGPLVM
|
||||||
|
|
||||||
class MRD(Model):
|
class MRD(Model):
|
||||||
"""
|
"""
|
||||||
|
|
@ -81,29 +81,6 @@ class MRD(Model):
|
||||||
Model.__init__(self)
|
Model.__init__(self)
|
||||||
self.ensure_default_constraints()
|
self.ensure_default_constraints()
|
||||||
|
|
||||||
def getstate(self):
|
|
||||||
return Model.getstate(self) + [self.names,
|
|
||||||
self.bgplvms,
|
|
||||||
self.gref,
|
|
||||||
self.nparams,
|
|
||||||
self.input_dim,
|
|
||||||
self.num_inducing,
|
|
||||||
self.num_data,
|
|
||||||
self.NQ,
|
|
||||||
self.MQ]
|
|
||||||
|
|
||||||
def setstate(self, state):
|
|
||||||
self.MQ = state.pop()
|
|
||||||
self.NQ = state.pop()
|
|
||||||
self.num_data = state.pop()
|
|
||||||
self.num_inducing = state.pop()
|
|
||||||
self.input_dim = state.pop()
|
|
||||||
self.nparams = state.pop()
|
|
||||||
self.gref = state.pop()
|
|
||||||
self.bgplvms = state.pop()
|
|
||||||
self.names = state.pop()
|
|
||||||
Model.setstate(self, state)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def X(self):
|
def X(self):
|
||||||
return self.gref.X
|
return self.gref.X
|
||||||
|
|
@ -211,8 +188,8 @@ class MRD(Model):
|
||||||
# g.Z = Z.reshape(self.num_inducing, self.input_dim)
|
# g.Z = Z.reshape(self.num_inducing, self.input_dim)
|
||||||
#
|
#
|
||||||
# def _set_kern_params(self, g, p):
|
# def _set_kern_params(self, g, p):
|
||||||
# g.kern._set_params(p[:g.kern.Nparam])
|
# g.kern._set_params(p[:g.kern.num_params])
|
||||||
# g.likelihood._set_params(p[g.kern.Nparam:])
|
# g.likelihood._set_params(p[g.kern.num_params:])
|
||||||
|
|
||||||
def _set_params(self, x):
|
def _set_params(self, x):
|
||||||
start = 0; end = self.NQ
|
start = 0; end = self.NQ
|
||||||
|
|
@ -371,4 +348,28 @@ class MRD(Model):
|
||||||
pylab.draw()
|
pylab.draw()
|
||||||
fig.tight_layout()
|
fig.tight_layout()
|
||||||
|
|
||||||
|
def getstate(self):
|
||||||
|
return Model.getstate(self) + [self.names,
|
||||||
|
self.bgplvms,
|
||||||
|
self.gref,
|
||||||
|
self.nparams,
|
||||||
|
self.input_dim,
|
||||||
|
self.num_inducing,
|
||||||
|
self.num_data,
|
||||||
|
self.NQ,
|
||||||
|
self.MQ]
|
||||||
|
|
||||||
|
def setstate(self, state):
|
||||||
|
self.MQ = state.pop()
|
||||||
|
self.NQ = state.pop()
|
||||||
|
self.num_data = state.pop()
|
||||||
|
self.num_inducing = state.pop()
|
||||||
|
self.input_dim = state.pop()
|
||||||
|
self.nparams = state.pop()
|
||||||
|
self.gref = state.pop()
|
||||||
|
self.bgplvms = state.pop()
|
||||||
|
self.names = state.pop()
|
||||||
|
Model.setstate(self, state)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@ class SparseGPClassification(SparseGP):
|
||||||
|
|
||||||
:param X: input observations
|
:param X: input observations
|
||||||
:param Y: observed values
|
:param Y: observed values
|
||||||
:param likelihood: a GPy likelihood, defaults to Binomial with probit link_function
|
:param likelihood: a GPy likelihood, defaults to Bernoulli with probit link_function
|
||||||
:param kernel: a GPy kernel, defaults to rbf+white
|
:param kernel: a GPy kernel, defaults to rbf+white
|
||||||
:param normalize_X: whether to normalize the input data before computing (predictions will be in original scales)
|
:param normalize_X: whether to normalize the input data before computing (predictions will be in original scales)
|
||||||
:type normalize_X: False|True
|
:type normalize_X: False|True
|
||||||
|
|
@ -31,7 +31,7 @@ class SparseGPClassification(SparseGP):
|
||||||
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:
|
if likelihood is None:
|
||||||
noise_model = likelihoods.binomial()
|
noise_model = likelihoods.bernoulli()
|
||||||
likelihood = likelihoods.EP(Y, noise_model)
|
likelihood = likelihoods.EP(Y, noise_model)
|
||||||
elif Y is not None:
|
elif Y is not None:
|
||||||
if not all(Y.flatten() == likelihood.data.flatten()):
|
if not all(Y.flatten() == likelihood.data.flatten()):
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pylab as pb
|
import pylab as pb
|
||||||
import sys, pdb
|
import sys, pdb
|
||||||
from GPy.models.sparse_gp_regression import SparseGPRegression
|
from sparse_gp_regression import SparseGPRegression
|
||||||
from GPy.models.gplvm import GPLVM
|
from gplvm import GPLVM
|
||||||
# from .. import kern
|
# from .. import kern
|
||||||
# from ..core import model
|
# from ..core import model
|
||||||
# from ..util.linalg import pdinv, PCA
|
# from ..util.linalg import pdinv, PCA
|
||||||
|
|
@ -66,5 +66,5 @@ class SparseGPLVM(SparseGPRegression, GPLVM):
|
||||||
pb.plot(mu[:, 0] , mu[:, 1], 'ko')
|
pb.plot(mu[:, 0] , mu[:, 1], 'ko')
|
||||||
|
|
||||||
def plot_latent(self, *args, **kwargs):
|
def plot_latent(self, *args, **kwargs):
|
||||||
input_1, input_2 = GPLVM.plot_latent(*args, **kwargs)
|
GPLVM.plot_latent(self, *args, **kwargs)
|
||||||
pb.plot(m.Z[:, input_1], m.Z[:, input_2], '^w')
|
#pb.plot(self.Z[:, input_1], self.Z[:, input_2], '^w')
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
import unittest
|
import unittest
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import GPy
|
import GPy
|
||||||
from GPy.models.bayesian_gplvm import BayesianGPLVM
|
from ..models import BayesianGPLVM
|
||||||
|
|
||||||
class BGPLVMTests(unittest.TestCase):
|
class BGPLVMTests(unittest.TestCase):
|
||||||
def test_bias_kern(self):
|
def test_bias_kern(self):
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import os
|
||||||
import random
|
import random
|
||||||
from nose.tools import nottest
|
from nose.tools import nottest
|
||||||
import sys
|
import sys
|
||||||
|
import itertools
|
||||||
|
|
||||||
class ExamplesTests(unittest.TestCase):
|
class ExamplesTests(unittest.TestCase):
|
||||||
def _checkgrad(self, Model):
|
def _checkgrad(self, Model):
|
||||||
|
|
@ -37,10 +38,21 @@ def model_checkgrads(model):
|
||||||
|
|
||||||
def model_instance(model):
|
def model_instance(model):
|
||||||
#assert isinstance(model, GPy.core.model)
|
#assert isinstance(model, GPy.core.model)
|
||||||
return isinstance(model, GPy.core.model)
|
return isinstance(model, GPy.core.model.Model)
|
||||||
|
|
||||||
@nottest
|
def flatten_nested(lst):
|
||||||
|
result = []
|
||||||
|
for element in lst:
|
||||||
|
if hasattr(element, '__iter__'):
|
||||||
|
result.extend(flatten_nested(element))
|
||||||
|
else:
|
||||||
|
result.append(element)
|
||||||
|
return result
|
||||||
|
|
||||||
|
#@nottest
|
||||||
def test_models():
|
def test_models():
|
||||||
|
optimize=False
|
||||||
|
plot=True
|
||||||
examples_path = os.path.dirname(GPy.examples.__file__)
|
examples_path = os.path.dirname(GPy.examples.__file__)
|
||||||
# Load modules
|
# Load modules
|
||||||
failing_models = {}
|
failing_models = {}
|
||||||
|
|
@ -54,20 +66,24 @@ def test_models():
|
||||||
print "After"
|
print "After"
|
||||||
print functions
|
print functions
|
||||||
for example in functions:
|
for example in functions:
|
||||||
if example[0] in ['oil', 'silhouette', 'GPLVM_oil_100']:
|
#if example[0] in ['oil', 'silhouette', 'GPLVM_oil_100', 'brendan_faces']:
|
||||||
print "SKIPPING"
|
#print "SKIPPING"
|
||||||
continue
|
#continue
|
||||||
|
|
||||||
print "Testing example: ", example[0]
|
print "Testing example: ", example[0]
|
||||||
# Generate model
|
# Generate model
|
||||||
|
|
||||||
try:
|
try:
|
||||||
model = example[1]()
|
models = [ example[1](optimize=optimize, plot=plot) ]
|
||||||
|
#If more than one model returned, flatten them
|
||||||
|
models = flatten_nested(models)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
failing_models[example[0]] = "Cannot make model: \n{e}".format(e=e)
|
failing_models[example[0]] = "Cannot make model: \n{e}".format(e=e)
|
||||||
else:
|
else:
|
||||||
print model
|
print models
|
||||||
model_checkgrads.description = 'test_checkgrads_%s' % example[0]
|
model_checkgrads.description = 'test_checkgrads_%s' % example[0]
|
||||||
try:
|
try:
|
||||||
|
for model in models:
|
||||||
if not model_checkgrads(model):
|
if not model_checkgrads(model):
|
||||||
failing_models[model_checkgrads.description] = False
|
failing_models[model_checkgrads.description] = False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -75,6 +91,7 @@ def test_models():
|
||||||
|
|
||||||
model_instance.description = 'test_instance_%s' % example[0]
|
model_instance.description = 'test_instance_%s' % example[0]
|
||||||
try:
|
try:
|
||||||
|
for model in models:
|
||||||
if not model_instance(model):
|
if not model_instance(model):
|
||||||
failing_models[model_instance.description] = False
|
failing_models[model_instance.description] = False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
61
GPy/testing/gp_transformation_tests.py
Normal file
61
GPy/testing/gp_transformation_tests.py
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
from nose.tools import with_setup
|
||||||
|
from GPy.models import GradientChecker
|
||||||
|
from GPy.likelihoods.noise_models import gp_transformations
|
||||||
|
import inspect
|
||||||
|
import unittest
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
class TestTransformations(object):
|
||||||
|
"""
|
||||||
|
Generic transformations checker
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
N = 30
|
||||||
|
self.fs = [np.random.rand(N, 1), float(np.random.rand(1))]
|
||||||
|
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.fs = None
|
||||||
|
|
||||||
|
def test_transformations(self):
|
||||||
|
self.setUp()
|
||||||
|
transformations = [gp_transformations.Identity(),
|
||||||
|
gp_transformations.Log(),
|
||||||
|
gp_transformations.Probit(),
|
||||||
|
gp_transformations.Log_ex_1(),
|
||||||
|
gp_transformations.Reciprocal(),
|
||||||
|
]
|
||||||
|
|
||||||
|
for transformation in transformations:
|
||||||
|
for f in self.fs:
|
||||||
|
yield self.t_dtransf_df, transformation, f
|
||||||
|
yield self.t_d2transf_df2, transformation, f
|
||||||
|
yield self.t_d3transf_df3, transformation, f
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_dtransf_df(self, transformation, f):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
grad = GradientChecker(transformation.transf, transformation.dtransf_df, f, 'f')
|
||||||
|
grad.randomize()
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
assert grad.checkgrad()
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_d2transf_df2(self, transformation, f):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
grad = GradientChecker(transformation.dtransf_df, transformation.d2transf_df2, f, 'f')
|
||||||
|
grad.randomize()
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
assert grad.checkgrad()
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_d3transf_df3(self, transformation, f):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
grad = GradientChecker(transformation.d2transf_df2, transformation.d3transf_df3, f, 'f')
|
||||||
|
grad.randomize()
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
assert grad.checkgrad()
|
||||||
|
|
||||||
|
#if __name__ == "__main__":
|
||||||
|
#print "Running unit tests"
|
||||||
|
#unittest.main()
|
||||||
|
|
@ -7,6 +7,13 @@ import GPy
|
||||||
|
|
||||||
verbose = False
|
verbose = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
import sympy
|
||||||
|
SYMPY_AVAILABLE=True
|
||||||
|
except ImportError:
|
||||||
|
SYMPY_AVAILABLE=False
|
||||||
|
|
||||||
|
|
||||||
class KernelTests(unittest.TestCase):
|
class KernelTests(unittest.TestCase):
|
||||||
def test_kerneltie(self):
|
def test_kerneltie(self):
|
||||||
K = GPy.kern.rbf(5, ARD=True)
|
K = GPy.kern.rbf(5, ARD=True)
|
||||||
|
|
@ -22,9 +29,20 @@ class KernelTests(unittest.TestCase):
|
||||||
self.assertTrue(GPy.kern.kern_test(kern, verbose=verbose))
|
self.assertTrue(GPy.kern.kern_test(kern, verbose=verbose))
|
||||||
|
|
||||||
def test_rbf_sympykernel(self):
|
def test_rbf_sympykernel(self):
|
||||||
|
if SYMPY_AVAILABLE:
|
||||||
kern = GPy.kern.rbf_sympy(5)
|
kern = GPy.kern.rbf_sympy(5)
|
||||||
self.assertTrue(GPy.kern.kern_test(kern, verbose=verbose))
|
self.assertTrue(GPy.kern.kern_test(kern, verbose=verbose))
|
||||||
|
|
||||||
|
def test_eq_sympykernel(self):
|
||||||
|
if SYMPY_AVAILABLE:
|
||||||
|
kern = GPy.kern.eq_sympy(5, 3)
|
||||||
|
self.assertTrue(GPy.kern.kern_test(kern, output_ind=4, verbose=verbose))
|
||||||
|
|
||||||
|
def test_ode1_eqkernel(self):
|
||||||
|
if SYMPY_AVAILABLE:
|
||||||
|
kern = GPy.kern.ode1_eq(3)
|
||||||
|
self.assertTrue(GPy.kern.kern_test(kern, output_ind=1, verbose=verbose, X_positive=True))
|
||||||
|
|
||||||
def test_rbf_invkernel(self):
|
def test_rbf_invkernel(self):
|
||||||
kern = GPy.kern.rbf_inv(5)
|
kern = GPy.kern.rbf_inv(5)
|
||||||
self.assertTrue(GPy.kern.kern_test(kern, verbose=verbose))
|
self.assertTrue(GPy.kern.kern_test(kern, verbose=verbose))
|
||||||
|
|
|
||||||
687
GPy/testing/likelihoods_tests.py
Normal file
687
GPy/testing/likelihoods_tests.py
Normal file
|
|
@ -0,0 +1,687 @@
|
||||||
|
import numpy as np
|
||||||
|
import unittest
|
||||||
|
import GPy
|
||||||
|
from GPy.models import GradientChecker
|
||||||
|
import functools
|
||||||
|
import inspect
|
||||||
|
from GPy.likelihoods.noise_models import gp_transformations
|
||||||
|
from functools import partial
|
||||||
|
#np.random.seed(300)
|
||||||
|
np.random.seed(7)
|
||||||
|
|
||||||
|
def dparam_partial(inst_func, *args):
|
||||||
|
"""
|
||||||
|
If we have a instance method that needs to be called but that doesn't
|
||||||
|
take the parameter we wish to change to checkgrad, then this function
|
||||||
|
will change the variable using set params.
|
||||||
|
|
||||||
|
inst_func: should be a instance function of an object that we would like
|
||||||
|
to change
|
||||||
|
param: the param that will be given to set_params
|
||||||
|
args: anything else that needs to be given to the function (for example
|
||||||
|
the f or Y that are being used in the function whilst we tweak the
|
||||||
|
param
|
||||||
|
"""
|
||||||
|
def param_func(param, inst_func, args):
|
||||||
|
inst_func.im_self._set_params(param)
|
||||||
|
return inst_func(*args)
|
||||||
|
return functools.partial(param_func, inst_func=inst_func, args=args)
|
||||||
|
|
||||||
|
def dparam_checkgrad(func, dfunc, params, args, constraints=None, randomize=False, verbose=False):
|
||||||
|
"""
|
||||||
|
checkgrad expects a f: R^N -> R^1 and df: R^N -> R^N
|
||||||
|
However if we are holding other parameters fixed and moving something else
|
||||||
|
We need to check the gradient of each of the fixed parameters
|
||||||
|
(f and y for example) seperately, whilst moving another parameter.
|
||||||
|
Otherwise f: gives back R^N and
|
||||||
|
df: gives back R^NxM where M is
|
||||||
|
The number of parameters and N is the number of data
|
||||||
|
Need to take a slice out from f and a slice out of df
|
||||||
|
"""
|
||||||
|
#print "\n{} likelihood: {} vs {}".format(func.im_self.__class__.__name__,
|
||||||
|
#func.__name__, dfunc.__name__)
|
||||||
|
partial_f = dparam_partial(func, *args)
|
||||||
|
partial_df = dparam_partial(dfunc, *args)
|
||||||
|
gradchecking = True
|
||||||
|
for param in params:
|
||||||
|
fnum = np.atleast_1d(partial_f(param)).shape[0]
|
||||||
|
dfnum = np.atleast_1d(partial_df(param)).shape[0]
|
||||||
|
for fixed_val in range(dfnum):
|
||||||
|
#dlik and dlik_dvar gives back 1 value for each
|
||||||
|
f_ind = min(fnum, fixed_val+1) - 1
|
||||||
|
print "fnum: {} dfnum: {} f_ind: {} fixed_val: {}".format(fnum, dfnum, f_ind, fixed_val)
|
||||||
|
#Make grad checker with this param moving, note that set_params is NOT being called
|
||||||
|
#The parameter is being set directly with __setattr__
|
||||||
|
grad = GradientChecker(lambda x: np.atleast_1d(partial_f(x))[f_ind],
|
||||||
|
lambda x : np.atleast_1d(partial_df(x))[fixed_val],
|
||||||
|
param, 'p')
|
||||||
|
#This is not general for more than one param...
|
||||||
|
if constraints is not None:
|
||||||
|
for constraint in constraints:
|
||||||
|
constraint('p', grad)
|
||||||
|
if randomize:
|
||||||
|
grad.randomize()
|
||||||
|
if verbose:
|
||||||
|
print grad
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
if not grad.checkgrad():
|
||||||
|
gradchecking = False
|
||||||
|
|
||||||
|
return gradchecking
|
||||||
|
|
||||||
|
|
||||||
|
from nose.tools import with_setup
|
||||||
|
class TestNoiseModels(object):
|
||||||
|
"""
|
||||||
|
Generic model checker
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
self.N = 5
|
||||||
|
self.D = 3
|
||||||
|
self.X = np.random.rand(self.N, self.D)*10
|
||||||
|
|
||||||
|
self.real_std = 0.1
|
||||||
|
noise = np.random.randn(*self.X[:, 0].shape)*self.real_std
|
||||||
|
self.Y = (np.sin(self.X[:, 0]*2*np.pi) + noise)[:, None]
|
||||||
|
self.f = np.random.rand(self.N, 1)
|
||||||
|
self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=np.int)[:, None]
|
||||||
|
self.positive_Y = np.exp(self.Y.copy())
|
||||||
|
tmp = np.round(self.X[:, 0]*3-3)[:, None] + np.random.randint(0,3, self.X.shape[0])[:, None]
|
||||||
|
self.integer_Y = np.where(tmp > 0, tmp, 0)
|
||||||
|
|
||||||
|
self.var = 0.2
|
||||||
|
|
||||||
|
self.var = np.random.rand(1)
|
||||||
|
|
||||||
|
#Make a bigger step as lower bound can be quite curved
|
||||||
|
self.step = 1e-3
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.Y = None
|
||||||
|
self.f = None
|
||||||
|
self.X = None
|
||||||
|
|
||||||
|
def test_noise_models(self):
|
||||||
|
self.setUp()
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
# Constraint wrappers so we can just list them off #
|
||||||
|
####################################################
|
||||||
|
def constrain_negative(regex, model):
|
||||||
|
model.constrain_negative(regex)
|
||||||
|
|
||||||
|
def constrain_positive(regex, model):
|
||||||
|
model.constrain_positive(regex)
|
||||||
|
|
||||||
|
def constrain_bounded(regex, model, lower, upper):
|
||||||
|
"""
|
||||||
|
Used like: partial(constrain_bounded, lower=0, upper=1)
|
||||||
|
"""
|
||||||
|
model.constrain_bounded(regex, lower, upper)
|
||||||
|
|
||||||
|
"""
|
||||||
|
Dictionary where we nest models we would like to check
|
||||||
|
Name: {
|
||||||
|
"model": model_instance,
|
||||||
|
"grad_params": {
|
||||||
|
"names": [names_of_params_we_want, to_grad_check],
|
||||||
|
"vals": [values_of_params, to_start_at],
|
||||||
|
"constrain": [constraint_wrappers, listed_here]
|
||||||
|
},
|
||||||
|
"laplace": boolean_of_whether_model_should_work_for_laplace,
|
||||||
|
"ep": boolean_of_whether_model_should_work_for_laplace,
|
||||||
|
"link_f_constraints": [constraint_wrappers, listed_here]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
noise_models = {"Student_t_default": {
|
||||||
|
"model": GPy.likelihoods.student_t(deg_free=5, sigma2=self.var),
|
||||||
|
"grad_params": {
|
||||||
|
"names": ["t_noise"],
|
||||||
|
"vals": [self.var],
|
||||||
|
"constraints": [constrain_positive]
|
||||||
|
},
|
||||||
|
"laplace": True
|
||||||
|
},
|
||||||
|
"Student_t_1_var": {
|
||||||
|
"model": GPy.likelihoods.student_t(deg_free=5, sigma2=self.var),
|
||||||
|
"grad_params": {
|
||||||
|
"names": ["t_noise"],
|
||||||
|
"vals": [1.0],
|
||||||
|
"constraints": [constrain_positive]
|
||||||
|
},
|
||||||
|
"laplace": True
|
||||||
|
},
|
||||||
|
"Student_t_small_var": {
|
||||||
|
"model": GPy.likelihoods.student_t(deg_free=5, sigma2=self.var),
|
||||||
|
"grad_params": {
|
||||||
|
"names": ["t_noise"],
|
||||||
|
"vals": [0.01],
|
||||||
|
"constraints": [constrain_positive]
|
||||||
|
},
|
||||||
|
"laplace": True
|
||||||
|
},
|
||||||
|
"Student_t_large_var": {
|
||||||
|
"model": GPy.likelihoods.student_t(deg_free=5, sigma2=self.var),
|
||||||
|
"grad_params": {
|
||||||
|
"names": ["t_noise"],
|
||||||
|
"vals": [10.0],
|
||||||
|
"constraints": [constrain_positive]
|
||||||
|
},
|
||||||
|
"laplace": True
|
||||||
|
},
|
||||||
|
"Student_t_approx_gauss": {
|
||||||
|
"model": GPy.likelihoods.student_t(deg_free=1000, sigma2=self.var),
|
||||||
|
"grad_params": {
|
||||||
|
"names": ["t_noise"],
|
||||||
|
"vals": [self.var],
|
||||||
|
"constraints": [constrain_positive]
|
||||||
|
},
|
||||||
|
"laplace": True
|
||||||
|
},
|
||||||
|
"Student_t_log": {
|
||||||
|
"model": GPy.likelihoods.student_t(gp_link=gp_transformations.Log(), deg_free=5, sigma2=self.var),
|
||||||
|
"grad_params": {
|
||||||
|
"names": ["t_noise"],
|
||||||
|
"vals": [self.var],
|
||||||
|
"constraints": [constrain_positive]
|
||||||
|
},
|
||||||
|
"laplace": True
|
||||||
|
},
|
||||||
|
"Gaussian_default": {
|
||||||
|
"model": GPy.likelihoods.gaussian(variance=self.var, D=self.D, N=self.N),
|
||||||
|
"grad_params": {
|
||||||
|
"names": ["noise_model_variance"],
|
||||||
|
"vals": [self.var],
|
||||||
|
"constraints": [constrain_positive]
|
||||||
|
},
|
||||||
|
"laplace": True,
|
||||||
|
"ep": True
|
||||||
|
},
|
||||||
|
#"Gaussian_log": {
|
||||||
|
#"model": GPy.likelihoods.gaussian(gp_link=gp_transformations.Log(), variance=self.var, D=self.D, N=self.N),
|
||||||
|
#"grad_params": {
|
||||||
|
#"names": ["noise_model_variance"],
|
||||||
|
#"vals": [self.var],
|
||||||
|
#"constraints": [constrain_positive]
|
||||||
|
#},
|
||||||
|
#"laplace": True
|
||||||
|
#},
|
||||||
|
#"Gaussian_probit": {
|
||||||
|
#"model": GPy.likelihoods.gaussian(gp_link=gp_transformations.Probit(), variance=self.var, D=self.D, N=self.N),
|
||||||
|
#"grad_params": {
|
||||||
|
#"names": ["noise_model_variance"],
|
||||||
|
#"vals": [self.var],
|
||||||
|
#"constraints": [constrain_positive]
|
||||||
|
#},
|
||||||
|
#"laplace": True
|
||||||
|
#},
|
||||||
|
#"Gaussian_log_ex": {
|
||||||
|
#"model": GPy.likelihoods.gaussian(gp_link=gp_transformations.Log_ex_1(), variance=self.var, D=self.D, N=self.N),
|
||||||
|
#"grad_params": {
|
||||||
|
#"names": ["noise_model_variance"],
|
||||||
|
#"vals": [self.var],
|
||||||
|
#"constraints": [constrain_positive]
|
||||||
|
#},
|
||||||
|
#"laplace": True
|
||||||
|
#},
|
||||||
|
"Bernoulli_default": {
|
||||||
|
"model": GPy.likelihoods.bernoulli(),
|
||||||
|
"link_f_constraints": [partial(constrain_bounded, lower=0, upper=1)],
|
||||||
|
"laplace": True,
|
||||||
|
"Y": self.binary_Y,
|
||||||
|
"ep": True
|
||||||
|
},
|
||||||
|
"Exponential_default": {
|
||||||
|
"model": GPy.likelihoods.exponential(),
|
||||||
|
"link_f_constraints": [constrain_positive],
|
||||||
|
"Y": self.positive_Y,
|
||||||
|
"laplace": True,
|
||||||
|
},
|
||||||
|
"Poisson_default": {
|
||||||
|
"model": GPy.likelihoods.poisson(),
|
||||||
|
"link_f_constraints": [constrain_positive],
|
||||||
|
"Y": self.integer_Y,
|
||||||
|
"laplace": True,
|
||||||
|
"ep": False #Should work though...
|
||||||
|
},
|
||||||
|
"Gamma_default": {
|
||||||
|
"model": GPy.likelihoods.gamma(),
|
||||||
|
"link_f_constraints": [constrain_positive],
|
||||||
|
"Y": self.positive_Y,
|
||||||
|
"laplace": True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, attributes in noise_models.iteritems():
|
||||||
|
model = attributes["model"]
|
||||||
|
if "grad_params" in attributes:
|
||||||
|
params = attributes["grad_params"]
|
||||||
|
param_vals = params["vals"]
|
||||||
|
param_names= params["names"]
|
||||||
|
param_constraints = params["constraints"]
|
||||||
|
else:
|
||||||
|
params = []
|
||||||
|
param_vals = []
|
||||||
|
param_names = []
|
||||||
|
constrain_positive = []
|
||||||
|
param_constraints = [] # ??? TODO: Saul to Fix.
|
||||||
|
if "link_f_constraints" in attributes:
|
||||||
|
link_f_constraints = attributes["link_f_constraints"]
|
||||||
|
else:
|
||||||
|
link_f_constraints = []
|
||||||
|
if "Y" in attributes:
|
||||||
|
Y = attributes["Y"].copy()
|
||||||
|
else:
|
||||||
|
Y = self.Y.copy()
|
||||||
|
if "f" in attributes:
|
||||||
|
f = attributes["f"].copy()
|
||||||
|
else:
|
||||||
|
f = self.f.copy()
|
||||||
|
if "laplace" in attributes:
|
||||||
|
laplace = attributes["laplace"]
|
||||||
|
else:
|
||||||
|
laplace = False
|
||||||
|
if "ep" in attributes:
|
||||||
|
ep = attributes["ep"]
|
||||||
|
else:
|
||||||
|
ep = False
|
||||||
|
|
||||||
|
if len(param_vals) > 1:
|
||||||
|
raise NotImplementedError("Cannot support multiple params in likelihood yet!")
|
||||||
|
|
||||||
|
#Required by all
|
||||||
|
#Normal derivatives
|
||||||
|
yield self.t_logpdf, model, Y, f
|
||||||
|
yield self.t_dlogpdf_df, model, Y, f
|
||||||
|
yield self.t_d2logpdf_df2, model, Y, f
|
||||||
|
#Link derivatives
|
||||||
|
yield self.t_dlogpdf_dlink, model, Y, f, link_f_constraints
|
||||||
|
yield self.t_d2logpdf_dlink2, model, Y, f, link_f_constraints
|
||||||
|
if laplace:
|
||||||
|
#Laplace only derivatives
|
||||||
|
yield self.t_d3logpdf_df3, model, Y, f
|
||||||
|
yield self.t_d3logpdf_dlink3, model, Y, f, link_f_constraints
|
||||||
|
#Params
|
||||||
|
yield self.t_dlogpdf_dparams, model, Y, f, param_vals, param_constraints
|
||||||
|
yield self.t_dlogpdf_df_dparams, model, Y, f, param_vals, param_constraints
|
||||||
|
yield self.t_d2logpdf2_df2_dparams, model, Y, f, param_vals, param_constraints
|
||||||
|
#Link params
|
||||||
|
yield self.t_dlogpdf_link_dparams, model, Y, f, param_vals, param_constraints
|
||||||
|
yield self.t_dlogpdf_dlink_dparams, model, Y, f, param_vals, param_constraints
|
||||||
|
yield self.t_d2logpdf2_dlink2_dparams, model, Y, f, param_vals, param_constraints
|
||||||
|
|
||||||
|
#laplace likelihood gradcheck
|
||||||
|
yield self.t_laplace_fit_rbf_white, model, self.X, Y, f, self.step, param_vals, param_names, param_constraints
|
||||||
|
if ep:
|
||||||
|
#ep likelihood gradcheck
|
||||||
|
yield self.t_ep_fit_rbf_white, model, self.X, Y, f, self.step, param_vals, param_names, param_constraints
|
||||||
|
|
||||||
|
|
||||||
|
self.tearDown()
|
||||||
|
|
||||||
|
#############
|
||||||
|
# dpdf_df's #
|
||||||
|
#############
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_logpdf(self, model, Y, f):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
print model
|
||||||
|
print model._get_params()
|
||||||
|
np.testing.assert_almost_equal(
|
||||||
|
model.pdf(f.copy(), Y.copy()),
|
||||||
|
np.exp(model.logpdf(f.copy(), Y.copy()))
|
||||||
|
)
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_dlogpdf_df(self, model, Y, f):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
self.description = "\n{}".format(inspect.stack()[0][3])
|
||||||
|
logpdf = functools.partial(model.logpdf, y=Y)
|
||||||
|
dlogpdf_df = functools.partial(model.dlogpdf_df, y=Y)
|
||||||
|
grad = GradientChecker(logpdf, dlogpdf_df, f.copy(), 'g')
|
||||||
|
grad.randomize()
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
print model
|
||||||
|
assert grad.checkgrad()
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_d2logpdf_df2(self, model, Y, f):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
dlogpdf_df = functools.partial(model.dlogpdf_df, y=Y)
|
||||||
|
d2logpdf_df2 = functools.partial(model.d2logpdf_df2, y=Y)
|
||||||
|
grad = GradientChecker(dlogpdf_df, d2logpdf_df2, f.copy(), 'g')
|
||||||
|
grad.randomize()
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
print model
|
||||||
|
assert grad.checkgrad()
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_d3logpdf_df3(self, model, Y, f):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
d2logpdf_df2 = functools.partial(model.d2logpdf_df2, y=Y)
|
||||||
|
d3logpdf_df3 = functools.partial(model.d3logpdf_df3, y=Y)
|
||||||
|
grad = GradientChecker(d2logpdf_df2, d3logpdf_df3, f.copy(), 'g')
|
||||||
|
grad.randomize()
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
print model
|
||||||
|
assert grad.checkgrad()
|
||||||
|
|
||||||
|
##############
|
||||||
|
# df_dparams #
|
||||||
|
##############
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_dlogpdf_dparams(self, model, Y, f, params, param_constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
print model
|
||||||
|
assert (
|
||||||
|
dparam_checkgrad(model.logpdf, model.dlogpdf_dtheta,
|
||||||
|
params, args=(f, Y), constraints=param_constraints,
|
||||||
|
randomize=True, verbose=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_dlogpdf_df_dparams(self, model, Y, f, params, param_constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
print model
|
||||||
|
assert (
|
||||||
|
dparam_checkgrad(model.dlogpdf_df, model.dlogpdf_df_dtheta,
|
||||||
|
params, args=(f, Y), constraints=param_constraints,
|
||||||
|
randomize=True, verbose=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_d2logpdf2_df2_dparams(self, model, Y, f, params, param_constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
print model
|
||||||
|
assert (
|
||||||
|
dparam_checkgrad(model.d2logpdf_df2, model.d2logpdf_df2_dtheta,
|
||||||
|
params, args=(f, Y), constraints=param_constraints,
|
||||||
|
randomize=True, verbose=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
################
|
||||||
|
# dpdf_dlink's #
|
||||||
|
################
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_dlogpdf_dlink(self, model, Y, f, link_f_constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
logpdf = functools.partial(model.logpdf_link, y=Y)
|
||||||
|
dlogpdf_dlink = functools.partial(model.dlogpdf_dlink, y=Y)
|
||||||
|
grad = GradientChecker(logpdf, dlogpdf_dlink, f.copy(), 'g')
|
||||||
|
|
||||||
|
#Apply constraints to link_f values
|
||||||
|
for constraint in link_f_constraints:
|
||||||
|
constraint('g', grad)
|
||||||
|
|
||||||
|
grad.randomize()
|
||||||
|
print grad
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
assert grad.checkgrad()
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_d2logpdf_dlink2(self, model, Y, f, link_f_constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
dlogpdf_dlink = functools.partial(model.dlogpdf_dlink, y=Y)
|
||||||
|
d2logpdf_dlink2 = functools.partial(model.d2logpdf_dlink2, y=Y)
|
||||||
|
grad = GradientChecker(dlogpdf_dlink, d2logpdf_dlink2, f.copy(), 'g')
|
||||||
|
|
||||||
|
#Apply constraints to link_f values
|
||||||
|
for constraint in link_f_constraints:
|
||||||
|
constraint('g', grad)
|
||||||
|
|
||||||
|
grad.randomize()
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
print grad
|
||||||
|
assert grad.checkgrad()
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_d3logpdf_dlink3(self, model, Y, f, link_f_constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
d2logpdf_dlink2 = functools.partial(model.d2logpdf_dlink2, y=Y)
|
||||||
|
d3logpdf_dlink3 = functools.partial(model.d3logpdf_dlink3, y=Y)
|
||||||
|
grad = GradientChecker(d2logpdf_dlink2, d3logpdf_dlink3, f.copy(), 'g')
|
||||||
|
|
||||||
|
#Apply constraints to link_f values
|
||||||
|
for constraint in link_f_constraints:
|
||||||
|
constraint('g', grad)
|
||||||
|
|
||||||
|
grad.randomize()
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
print grad
|
||||||
|
assert grad.checkgrad()
|
||||||
|
|
||||||
|
#################
|
||||||
|
# dlink_dparams #
|
||||||
|
#################
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_dlogpdf_link_dparams(self, model, Y, f, params, param_constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
print model
|
||||||
|
assert (
|
||||||
|
dparam_checkgrad(model.logpdf_link, model.dlogpdf_link_dtheta,
|
||||||
|
params, args=(f, Y), constraints=param_constraints,
|
||||||
|
randomize=False, verbose=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_dlogpdf_dlink_dparams(self, model, Y, f, params, param_constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
print model
|
||||||
|
assert (
|
||||||
|
dparam_checkgrad(model.dlogpdf_dlink, model.dlogpdf_dlink_dtheta,
|
||||||
|
params, args=(f, Y), constraints=param_constraints,
|
||||||
|
randomize=False, verbose=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_d2logpdf2_dlink2_dparams(self, model, Y, f, params, param_constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
print model
|
||||||
|
assert (
|
||||||
|
dparam_checkgrad(model.d2logpdf_dlink2, model.d2logpdf_dlink2_dtheta,
|
||||||
|
params, args=(f, Y), constraints=param_constraints,
|
||||||
|
randomize=False, verbose=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
################
|
||||||
|
# laplace test #
|
||||||
|
################
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_laplace_fit_rbf_white(self, model, X, Y, f, step, param_vals, param_names, constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
#Normalize
|
||||||
|
Y = Y/Y.max()
|
||||||
|
white_var = 1e-6
|
||||||
|
kernel = GPy.kern.rbf(X.shape[1]) + GPy.kern.white(X.shape[1])
|
||||||
|
laplace_likelihood = GPy.likelihoods.Laplace(Y.copy(), model)
|
||||||
|
m = GPy.models.GPRegression(X.copy(), Y.copy(), kernel, likelihood=laplace_likelihood)
|
||||||
|
m.ensure_default_constraints()
|
||||||
|
m.constrain_fixed('white', white_var)
|
||||||
|
|
||||||
|
for param_num in range(len(param_names)):
|
||||||
|
name = param_names[param_num]
|
||||||
|
m[name] = param_vals[param_num]
|
||||||
|
constraints[param_num](name, m)
|
||||||
|
|
||||||
|
print m
|
||||||
|
m.randomize()
|
||||||
|
#m.optimize(max_iters=8)
|
||||||
|
print m
|
||||||
|
m.checkgrad(verbose=1, step=step)
|
||||||
|
#if not m.checkgrad(step=step):
|
||||||
|
#m.checkgrad(verbose=1, step=step)
|
||||||
|
#import ipdb; ipdb.set_trace()
|
||||||
|
#NOTE this test appears to be stochastic for some likelihoods (student t?)
|
||||||
|
# appears to all be working in test mode right now...
|
||||||
|
assert m.checkgrad(step=step)
|
||||||
|
|
||||||
|
###########
|
||||||
|
# EP test #
|
||||||
|
###########
|
||||||
|
@with_setup(setUp, tearDown)
|
||||||
|
def t_ep_fit_rbf_white(self, model, X, Y, f, step, param_vals, param_names, constraints):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
#Normalize
|
||||||
|
Y = Y/Y.max()
|
||||||
|
white_var = 1e-6
|
||||||
|
kernel = GPy.kern.rbf(X.shape[1]) + GPy.kern.white(X.shape[1])
|
||||||
|
ep_likelihood = GPy.likelihoods.EP(Y.copy(), model)
|
||||||
|
m = GPy.models.GPRegression(X.copy(), Y.copy(), kernel, likelihood=ep_likelihood)
|
||||||
|
m.ensure_default_constraints()
|
||||||
|
m.constrain_fixed('white', white_var)
|
||||||
|
|
||||||
|
for param_num in range(len(param_names)):
|
||||||
|
name = param_names[param_num]
|
||||||
|
m[name] = param_vals[param_num]
|
||||||
|
constraints[param_num](name, m)
|
||||||
|
|
||||||
|
m.randomize()
|
||||||
|
m.checkgrad(verbose=1, step=step)
|
||||||
|
print m
|
||||||
|
assert m.checkgrad(step=step)
|
||||||
|
|
||||||
|
|
||||||
|
class LaplaceTests(unittest.TestCase):
|
||||||
|
"""
|
||||||
|
Specific likelihood tests, not general enough for the above tests
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.N = 5
|
||||||
|
self.D = 3
|
||||||
|
self.X = np.random.rand(self.N, self.D)*10
|
||||||
|
|
||||||
|
self.real_std = 0.1
|
||||||
|
noise = np.random.randn(*self.X[:, 0].shape)*self.real_std
|
||||||
|
self.Y = (np.sin(self.X[:, 0]*2*np.pi) + noise)[:, None]
|
||||||
|
self.f = np.random.rand(self.N, 1)
|
||||||
|
|
||||||
|
self.var = 0.2
|
||||||
|
|
||||||
|
self.var = np.random.rand(1)
|
||||||
|
self.stu_t = GPy.likelihoods.student_t(deg_free=5, sigma2=self.var)
|
||||||
|
self.gauss = GPy.likelihoods.gaussian(gp_transformations.Log(), variance=self.var, D=self.D, N=self.N)
|
||||||
|
|
||||||
|
#Make a bigger step as lower bound can be quite curved
|
||||||
|
self.step = 1e-6
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.stu_t = None
|
||||||
|
self.gauss = None
|
||||||
|
self.Y = None
|
||||||
|
self.f = None
|
||||||
|
self.X = None
|
||||||
|
|
||||||
|
def test_gaussian_d2logpdf_df2_2(self):
|
||||||
|
print "\n{}".format(inspect.stack()[0][3])
|
||||||
|
self.Y = None
|
||||||
|
self.gauss = None
|
||||||
|
|
||||||
|
self.N = 2
|
||||||
|
self.D = 1
|
||||||
|
self.X = np.linspace(0, self.D, self.N)[:, None]
|
||||||
|
self.real_std = 0.2
|
||||||
|
noise = np.random.randn(*self.X.shape)*self.real_std
|
||||||
|
self.Y = np.sin(self.X*2*np.pi) + noise
|
||||||
|
self.f = np.random.rand(self.N, 1)
|
||||||
|
self.gauss = GPy.likelihoods.gaussian(variance=self.var, D=self.D, N=self.N)
|
||||||
|
|
||||||
|
dlogpdf_df = functools.partial(self.gauss.dlogpdf_df, y=self.Y)
|
||||||
|
d2logpdf_df2 = functools.partial(self.gauss.d2logpdf_df2, y=self.Y)
|
||||||
|
grad = GradientChecker(dlogpdf_df, d2logpdf_df2, self.f.copy(), 'g')
|
||||||
|
grad.randomize()
|
||||||
|
grad.checkgrad(verbose=1)
|
||||||
|
self.assertTrue(grad.checkgrad())
|
||||||
|
|
||||||
|
#@unittest.skip('Not working yet, needs to be checked')
|
||||||
|
def test_laplace_log_likelihood(self):
|
||||||
|
debug = False
|
||||||
|
real_std = 0.1
|
||||||
|
initial_var_guess = 0.5
|
||||||
|
|
||||||
|
#Start a function, any function
|
||||||
|
X = np.linspace(0.0, np.pi*2, 100)[:, None]
|
||||||
|
Y = np.sin(X) + np.random.randn(*X.shape)*real_std
|
||||||
|
Y = Y/Y.max()
|
||||||
|
#Yc = Y.copy()
|
||||||
|
#Yc[75:80] += 1
|
||||||
|
kernel1 = GPy.kern.rbf(X.shape[1]) + GPy.kern.white(X.shape[1])
|
||||||
|
kernel2 = kernel1.copy()
|
||||||
|
|
||||||
|
m1 = GPy.models.GPRegression(X, Y.copy(), kernel=kernel1)
|
||||||
|
m1.constrain_fixed('white', 1e-6)
|
||||||
|
m1['noise'] = initial_var_guess
|
||||||
|
m1.constrain_bounded('noise', 1e-4, 10)
|
||||||
|
m1.constrain_bounded('rbf', 1e-4, 10)
|
||||||
|
m1.ensure_default_constraints()
|
||||||
|
m1.randomize()
|
||||||
|
|
||||||
|
gauss_distr = GPy.likelihoods.gaussian(variance=initial_var_guess, D=1, N=Y.shape[0])
|
||||||
|
laplace_likelihood = GPy.likelihoods.Laplace(Y.copy(), gauss_distr)
|
||||||
|
m2 = GPy.models.GPRegression(X, Y.copy(), kernel=kernel2, likelihood=laplace_likelihood)
|
||||||
|
m2.ensure_default_constraints()
|
||||||
|
m2.constrain_fixed('white', 1e-6)
|
||||||
|
m2.constrain_bounded('rbf', 1e-4, 10)
|
||||||
|
m2.constrain_bounded('noise', 1e-4, 10)
|
||||||
|
m2.randomize()
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print m1
|
||||||
|
print m2
|
||||||
|
optimizer = 'scg'
|
||||||
|
print "Gaussian"
|
||||||
|
m1.optimize(optimizer, messages=debug)
|
||||||
|
print "Laplace Gaussian"
|
||||||
|
m2.optimize(optimizer, messages=debug)
|
||||||
|
if debug:
|
||||||
|
print m1
|
||||||
|
print m2
|
||||||
|
|
||||||
|
m2._set_params(m1._get_params())
|
||||||
|
|
||||||
|
#Predict for training points to get posterior mean and variance
|
||||||
|
post_mean, post_var, _, _ = m1.predict(X)
|
||||||
|
post_mean_approx, post_var_approx, _, _ = m2.predict(X)
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
import pylab as pb
|
||||||
|
pb.figure(5)
|
||||||
|
pb.title('posterior means')
|
||||||
|
pb.scatter(X, post_mean, c='g')
|
||||||
|
pb.scatter(X, post_mean_approx, c='r', marker='x')
|
||||||
|
|
||||||
|
pb.figure(6)
|
||||||
|
pb.title('plot_f')
|
||||||
|
m1.plot_f(fignum=6)
|
||||||
|
m2.plot_f(fignum=6)
|
||||||
|
fig, axes = pb.subplots(2, 1)
|
||||||
|
fig.suptitle('Covariance matricies')
|
||||||
|
a1 = pb.subplot(121)
|
||||||
|
a1.matshow(m1.likelihood.covariance_matrix)
|
||||||
|
a2 = pb.subplot(122)
|
||||||
|
a2.matshow(m2.likelihood.covariance_matrix)
|
||||||
|
|
||||||
|
pb.figure(8)
|
||||||
|
pb.scatter(X, m1.likelihood.Y, c='g')
|
||||||
|
pb.scatter(X, m2.likelihood.Y, c='r', marker='x')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Check Y's are the same
|
||||||
|
np.testing.assert_almost_equal(Y, m2.likelihood.Y, decimal=5)
|
||||||
|
#Check marginals are the same
|
||||||
|
np.testing.assert_almost_equal(m1.log_likelihood(), m2.log_likelihood(), decimal=2)
|
||||||
|
#Check marginals are the same with random
|
||||||
|
m1.randomize()
|
||||||
|
m2._set_params(m1._get_params())
|
||||||
|
np.testing.assert_almost_equal(m1.log_likelihood(), m2.log_likelihood(), decimal=2)
|
||||||
|
|
||||||
|
#Check they are checkgradding
|
||||||
|
#m1.checkgrad(verbose=1)
|
||||||
|
#m2.checkgrad(verbose=1)
|
||||||
|
self.assertTrue(m1.checkgrad())
|
||||||
|
self.assertTrue(m2.checkgrad())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print "Running unit tests"
|
||||||
|
unittest.main()
|
||||||
|
|
@ -27,9 +27,9 @@ def ard(p):
|
||||||
@testing.deepTest(__test__())
|
@testing.deepTest(__test__())
|
||||||
class Test(unittest.TestCase):
|
class Test(unittest.TestCase):
|
||||||
input_dim = 9
|
input_dim = 9
|
||||||
num_inducing = 4
|
num_inducing = 13
|
||||||
N = 3
|
N = 300
|
||||||
Nsamples = 5e6
|
Nsamples = 1e6
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
i_s_dim_list = [2,4,3]
|
i_s_dim_list = [2,4,3]
|
||||||
|
|
@ -45,16 +45,25 @@ class Test(unittest.TestCase):
|
||||||
input_slices = input_slices
|
input_slices = input_slices
|
||||||
)
|
)
|
||||||
self.kerns = (
|
self.kerns = (
|
||||||
input_slice_kern,
|
# input_slice_kern,
|
||||||
# (GPy.kern.rbf(self.input_dim, ARD=True) +
|
# (GPy.kern.rbf(self.input_dim, ARD=True) +
|
||||||
# GPy.kern.linear(self.input_dim, ARD=True) +
|
# GPy.kern.linear(self.input_dim, ARD=True) +
|
||||||
# GPy.kern.bias(self.input_dim) +
|
# GPy.kern.bias(self.input_dim) +
|
||||||
# GPy.kern.white(self.input_dim)),
|
# GPy.kern.white(self.input_dim)),
|
||||||
|
(#GPy.kern.rbf(self.input_dim, np.random.rand(), np.random.rand(self.input_dim), ARD=True)
|
||||||
|
GPy.kern.linear(self.input_dim, np.random.rand(self.input_dim), ARD=True)
|
||||||
|
+GPy.kern.rbf(self.input_dim, np.random.rand(), np.random.rand(self.input_dim), ARD=True)
|
||||||
|
# +GPy.kern.bias(self.input_dim)
|
||||||
|
# +GPy.kern.white(self.input_dim)),
|
||||||
|
),
|
||||||
# (GPy.kern.rbf(self.input_dim, np.random.rand(), np.random.rand(self.input_dim), ARD=True) +
|
# (GPy.kern.rbf(self.input_dim, np.random.rand(), np.random.rand(self.input_dim), ARD=True) +
|
||||||
# GPy.kern.rbf(self.input_dim, np.random.rand(), np.random.rand(self.input_dim), ARD=True) +
|
# GPy.kern.bias(self.input_dim, np.random.rand())),
|
||||||
# GPy.kern.linear(self.input_dim, np.random.rand(self.input_dim), ARD=True) +
|
# (GPy.kern.rbf(self.input_dim, np.random.rand(), np.random.rand(self.input_dim), ARD=True)
|
||||||
# GPy.kern.bias(self.input_dim) +
|
# +GPy.kern.rbf(self.input_dim, np.random.rand(), np.random.rand(self.input_dim), ARD=True)
|
||||||
# GPy.kern.white(self.input_dim)),
|
# #+GPy.kern.bias(self.input_dim, np.random.rand())
|
||||||
|
# #+GPy.kern.white(self.input_dim, np.random.rand())),
|
||||||
|
# ),
|
||||||
|
# GPy.kern.white(self.input_dim, np.random.rand())),
|
||||||
# GPy.kern.rbf(self.input_dim), GPy.kern.rbf(self.input_dim, ARD=True),
|
# GPy.kern.rbf(self.input_dim), GPy.kern.rbf(self.input_dim, ARD=True),
|
||||||
# GPy.kern.linear(self.input_dim, ARD=False), GPy.kern.linear(self.input_dim, ARD=True),
|
# GPy.kern.linear(self.input_dim, ARD=False), GPy.kern.linear(self.input_dim, ARD=True),
|
||||||
# GPy.kern.linear(self.input_dim) + GPy.kern.bias(self.input_dim),
|
# GPy.kern.linear(self.input_dim) + GPy.kern.bias(self.input_dim),
|
||||||
|
|
@ -79,7 +88,7 @@ class Test(unittest.TestCase):
|
||||||
|
|
||||||
def test_psi1(self):
|
def test_psi1(self):
|
||||||
for kern in self.kerns:
|
for kern in self.kerns:
|
||||||
Nsamples = np.floor(self.Nsamples/300.)
|
Nsamples = np.floor(self.Nsamples/self.N)
|
||||||
psi1 = kern.psi1(self.Z, self.q_x_mean, self.q_x_variance)
|
psi1 = kern.psi1(self.Z, self.q_x_mean, self.q_x_variance)
|
||||||
K_ = np.zeros((Nsamples, self.num_inducing))
|
K_ = np.zeros((Nsamples, self.num_inducing))
|
||||||
diffs = []
|
diffs = []
|
||||||
|
|
@ -105,37 +114,37 @@ class Test(unittest.TestCase):
|
||||||
|
|
||||||
def test_psi2(self):
|
def test_psi2(self):
|
||||||
for kern in self.kerns:
|
for kern in self.kerns:
|
||||||
Nsamples = self.Nsamples/300.
|
Nsamples = int(np.floor(self.Nsamples/self.N))
|
||||||
psi2 = kern.psi2(self.Z, self.q_x_mean, self.q_x_variance)
|
psi2 = kern.psi2(self.Z, self.q_x_mean, self.q_x_variance)
|
||||||
K_ = np.zeros((self.num_inducing, self.num_inducing))
|
K_ = np.zeros((self.num_inducing, self.num_inducing))
|
||||||
diffs = []
|
diffs = []
|
||||||
for i, q_x_sample_stripe in enumerate(np.array_split(self.q_x_samples, self.Nsamples / Nsamples)):
|
for i, q_x_sample_stripe in enumerate(np.array_split(self.q_x_samples, self.Nsamples / Nsamples)):
|
||||||
K = kern.K(q_x_sample_stripe, self.Z)
|
K = kern.K(q_x_sample_stripe, self.Z)
|
||||||
K = (K[:, :, None] * K[:, None, :]).mean(0)
|
K = (K[:, :, None] * K[:, None, :])
|
||||||
K_ += K
|
K_ += K.sum(0) / self.Nsamples
|
||||||
diffs.append(((psi2 - (K_ / (i + 1)))**2).mean())
|
diffs.append(((psi2 - (K_*self.Nsamples/((i+1)*Nsamples)))**2).mean())
|
||||||
K_ /= self.Nsamples / Nsamples
|
#K_ /= self.Nsamples / Nsamples
|
||||||
msg = "psi2: {}".format("+".join([p.name + ard(p) for p in kern.parts]))
|
msg = "psi2: {}".format("+".join([p.name + ard(p) for p in kern.parts]))
|
||||||
try:
|
try:
|
||||||
import pylab
|
import pylab
|
||||||
pylab.figure(msg)
|
pylab.figure(msg)
|
||||||
pylab.plot(diffs)
|
pylab.plot(diffs, marker='x', mew=.2)
|
||||||
# print msg, np.allclose(psi2.squeeze(), K_, rtol=1e-1, atol=.1)
|
# print msg, np.allclose(psi2.squeeze(), K_, rtol=1e-1, atol=.1)
|
||||||
self.assertTrue(np.allclose(psi2.squeeze(), K_,
|
self.assertTrue(np.allclose(psi2.squeeze(), K_),
|
||||||
rtol=1e-1, atol=.1),
|
#rtol=1e-1, atol=.1),
|
||||||
msg=msg + ": not matching")
|
msg=msg + ": not matching")
|
||||||
# sys.stdout.write(".")
|
# sys.stdout.write(".")
|
||||||
except:
|
except:
|
||||||
# import ipdb;ipdb.set_trace()
|
|
||||||
# kern.psi2(self.Z, self.q_x_mean, self.q_x_variance)
|
# kern.psi2(self.Z, self.q_x_mean, self.q_x_variance)
|
||||||
# sys.stdout.write("E")
|
# sys.stdout.write("E")
|
||||||
print msg + ": not matching"
|
print msg + ": not matching"
|
||||||
|
import ipdb;ipdb.set_trace()
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.argv = ['',
|
sys.argv = ['',
|
||||||
#'Test.test_psi0',
|
#'Test.test_psi0',
|
||||||
'Test.test_psi1',
|
#'Test.test_psi1',
|
||||||
'Test.test_psi2',
|
'Test.test_psi2',
|
||||||
]
|
]
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,9 @@ class PsiStatModel(Model):
|
||||||
return self.kern.__getattribute__(self.which)(self.Z, self.X, self.X_variance).sum()
|
return self.kern.__getattribute__(self.which)(self.Z, self.X, self.X_variance).sum()
|
||||||
def _log_likelihood_gradients(self):
|
def _log_likelihood_gradients(self):
|
||||||
psimu, psiS = self.kern.__getattribute__("d" + self.which + "_dmuS")(numpy.ones_like(self.psi_), self.Z, self.X, self.X_variance)
|
psimu, psiS = self.kern.__getattribute__("d" + self.which + "_dmuS")(numpy.ones_like(self.psi_), self.Z, self.X, self.X_variance)
|
||||||
try:
|
#psimu, psiS = numpy.ones(self.N * self.input_dim), numpy.ones(self.N * self.input_dim)
|
||||||
psiZ = self.kern.__getattribute__("d" + self.which + "_dZ")(numpy.ones_like(self.psi_), self.Z, self.X, self.X_variance)
|
psiZ = self.kern.__getattribute__("d" + self.which + "_dZ")(numpy.ones_like(self.psi_), self.Z, self.X, self.X_variance)
|
||||||
except AttributeError:
|
#psiZ = numpy.ones(self.num_inducing * self.input_dim)
|
||||||
psiZ = numpy.zeros(self.num_inducing * self.input_dim)
|
|
||||||
thetagrad = self.kern.__getattribute__("d" + self.which + "_dtheta")(numpy.ones_like(self.psi_), self.Z, self.X, self.X_variance).flatten()
|
thetagrad = self.kern.__getattribute__("d" + self.which + "_dtheta")(numpy.ones_like(self.psi_), self.Z, self.X, self.X_variance).flatten()
|
||||||
return numpy.hstack((psimu.flatten(), psiS.flatten(), psiZ.flatten(), thetagrad))
|
return numpy.hstack((psimu.flatten(), psiS.flatten(), psiZ.flatten(), thetagrad))
|
||||||
|
|
||||||
|
|
@ -64,40 +63,54 @@ class DPsiStatTest(unittest.TestCase):
|
||||||
|
|
||||||
def testPsi0(self):
|
def testPsi0(self):
|
||||||
for k in self.kernels:
|
for k in self.kernels:
|
||||||
m = PsiStatModel('psi0', X=self.X, X_variance=self.X_var, Z=self.Z,
|
m = PsiStatModel('psi0', X=self.X, X_variance=self.X_var, Z=self.Z,\
|
||||||
num_inducing=self.num_inducing, kernel=k)
|
num_inducing=self.num_inducing, kernel=k)
|
||||||
|
m.ensure_default_constraints()
|
||||||
|
m.randomize()
|
||||||
assert m.checkgrad(), "{} x psi0".format("+".join(map(lambda x: x.name, k.parts)))
|
assert m.checkgrad(), "{} x psi0".format("+".join(map(lambda x: x.name, k.parts)))
|
||||||
|
|
||||||
# def testPsi1(self):
|
def testPsi1(self):
|
||||||
# for k in self.kernels:
|
for k in self.kernels:
|
||||||
# m = PsiStatModel('psi1', X=self.X, X_variance=self.X_var, Z=self.Z,
|
m = PsiStatModel('psi1', X=self.X, X_variance=self.X_var, Z=self.Z,
|
||||||
# num_inducing=self.num_inducing, kernel=k)
|
num_inducing=self.num_inducing, kernel=k)
|
||||||
# assert m.checkgrad(), "{} x psi1".format("+".join(map(lambda x: x.name, k.parts)))
|
m.ensure_default_constraints()
|
||||||
|
m.randomize()
|
||||||
|
assert m.checkgrad(), "{} x psi1".format("+".join(map(lambda x: x.name, k.parts)))
|
||||||
|
|
||||||
def testPsi2_lin(self):
|
def testPsi2_lin(self):
|
||||||
k = self.kernels[0]
|
k = self.kernels[0]
|
||||||
m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z,
|
m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z,
|
||||||
num_inducing=self.num_inducing, kernel=k)
|
num_inducing=self.num_inducing, kernel=k)
|
||||||
|
m.ensure_default_constraints()
|
||||||
|
m.randomize()
|
||||||
assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k.parts)))
|
assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k.parts)))
|
||||||
def testPsi2_lin_bia(self):
|
def testPsi2_lin_bia(self):
|
||||||
k = self.kernels[3]
|
k = self.kernels[3]
|
||||||
m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z,
|
m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z,
|
||||||
num_inducing=self.num_inducing, kernel=k)
|
num_inducing=self.num_inducing, kernel=k)
|
||||||
|
m.ensure_default_constraints()
|
||||||
|
m.randomize()
|
||||||
assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k.parts)))
|
assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k.parts)))
|
||||||
def testPsi2_rbf(self):
|
def testPsi2_rbf(self):
|
||||||
k = self.kernels[1]
|
k = self.kernels[1]
|
||||||
m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z,
|
m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z,
|
||||||
num_inducing=self.num_inducing, kernel=k)
|
num_inducing=self.num_inducing, kernel=k)
|
||||||
|
m.ensure_default_constraints()
|
||||||
|
m.randomize()
|
||||||
assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k.parts)))
|
assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k.parts)))
|
||||||
def testPsi2_rbf_bia(self):
|
def testPsi2_rbf_bia(self):
|
||||||
k = self.kernels[-1]
|
k = self.kernels[-1]
|
||||||
m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z,
|
m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z,
|
||||||
num_inducing=self.num_inducing, kernel=k)
|
num_inducing=self.num_inducing, kernel=k)
|
||||||
|
m.ensure_default_constraints()
|
||||||
|
m.randomize()
|
||||||
assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k.parts)))
|
assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k.parts)))
|
||||||
def testPsi2_bia(self):
|
def testPsi2_bia(self):
|
||||||
k = self.kernels[2]
|
k = self.kernels[2]
|
||||||
m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z,
|
m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z,
|
||||||
num_inducing=self.num_inducing, kernel=k)
|
num_inducing=self.num_inducing, kernel=k)
|
||||||
|
m.ensure_default_constraints()
|
||||||
|
m.randomize()
|
||||||
assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k.parts)))
|
assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k.parts)))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -116,9 +129,9 @@ if __name__ == "__main__":
|
||||||
# m.randomize()
|
# m.randomize()
|
||||||
# # self.assertTrue(m.checkgrad())
|
# # self.assertTrue(m.checkgrad())
|
||||||
numpy.random.seed(0)
|
numpy.random.seed(0)
|
||||||
input_dim = 5
|
input_dim = 3
|
||||||
N = 50
|
N = 3
|
||||||
num_inducing = 10
|
num_inducing = 2
|
||||||
D = 15
|
D = 15
|
||||||
X = numpy.random.randn(N, input_dim)
|
X = numpy.random.randn(N, input_dim)
|
||||||
X_var = .5 * numpy.ones_like(X) + .1 * numpy.clip(numpy.random.randn(*X.shape), 0, 1)
|
X_var = .5 * numpy.ones_like(X) + .1 * numpy.clip(numpy.random.randn(*X.shape), 0, 1)
|
||||||
|
|
@ -135,18 +148,35 @@ if __name__ == "__main__":
|
||||||
# num_inducing=num_inducing, kernel=k)
|
# num_inducing=num_inducing, kernel=k)
|
||||||
# assert m.checkgrad(), "{} x psi1".format("+".join(map(lambda x: x.name, k.parts)))
|
# assert m.checkgrad(), "{} x psi1".format("+".join(map(lambda x: x.name, k.parts)))
|
||||||
#
|
#
|
||||||
# m0 = PsiStatModel('psi0', X=X, X_variance=X_var, Z=Z,
|
m0 = PsiStatModel('psi0', X=X, X_variance=X_var, Z=Z,
|
||||||
# num_inducing=num_inducing, kernel=GPy.kern.linear(input_dim))
|
num_inducing=num_inducing, kernel=GPy.kern.rbf(input_dim)+GPy.kern.bias(input_dim))
|
||||||
# m1 = PsiStatModel('psi1', X=X, X_variance=X_var, Z=Z,
|
# m1 = PsiStatModel('psi1', X=X, X_variance=X_var, Z=Z,
|
||||||
# num_inducing=num_inducing, kernel=kernel)
|
# num_inducing=num_inducing, kernel=kernel)
|
||||||
# m1 = PsiStatModel('psi1', X=X, X_variance=X_var, Z=Z,
|
# m1 = PsiStatModel('psi1', X=X, X_variance=X_var, Z=Z,
|
||||||
# num_inducing=num_inducing, kernel=kernel)
|
# num_inducing=num_inducing, kernel=kernel)
|
||||||
# m2 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z,
|
# m2 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z,
|
||||||
# num_inducing=num_inducing, kernel=GPy.kern.rbf(input_dim))
|
# num_inducing=num_inducing, kernel=GPy.kern.rbf(input_dim))
|
||||||
m3 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z,
|
# m3 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z,
|
||||||
num_inducing=num_inducing, kernel=GPy.kern.linear(input_dim, ARD=True, variances=numpy.random.rand(input_dim)))
|
# num_inducing=num_inducing, kernel=GPy.kern.linear(input_dim, ARD=True, variances=numpy.random.rand(input_dim)))
|
||||||
# + GPy.kern.bias(input_dim))
|
# + GPy.kern.bias(input_dim))
|
||||||
# m4 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z,
|
# m = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z,
|
||||||
# num_inducing=num_inducing, kernel=GPy.kern.rbf(input_dim) + GPy.kern.bias(input_dim))
|
# num_inducing=num_inducing,
|
||||||
|
# kernel=(
|
||||||
|
# GPy.kern.rbf(input_dim, ARD=1)
|
||||||
|
# +GPy.kern.linear(input_dim, ARD=1)
|
||||||
|
# +GPy.kern.bias(input_dim))
|
||||||
|
# )
|
||||||
|
# m.ensure_default_constraints()
|
||||||
|
m2 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z,
|
||||||
|
num_inducing=num_inducing, kernel=(
|
||||||
|
GPy.kern.rbf(input_dim, numpy.random.rand(), numpy.random.rand(input_dim), ARD=1)
|
||||||
|
#+GPy.kern.linear(input_dim, numpy.random.rand(input_dim), ARD=1)
|
||||||
|
#+GPy.kern.rbf(input_dim, numpy.random.rand(), numpy.random.rand(input_dim), ARD=1)
|
||||||
|
#+GPy.kern.rbf(input_dim, numpy.random.rand(), numpy.random.rand(), ARD=0)
|
||||||
|
+GPy.kern.bias(input_dim)
|
||||||
|
+GPy.kern.white(input_dim)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
m2.ensure_default_constraints()
|
||||||
else:
|
else:
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
import unittest
|
import unittest
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import GPy
|
import GPy
|
||||||
from GPy.models.sparse_gplvm import SparseGPLVM
|
from ..models import SparseGPLVM
|
||||||
|
|
||||||
class sparse_GPLVMTests(unittest.TestCase):
|
class sparse_GPLVMTests(unittest.TestCase):
|
||||||
def test_bias_kern(self):
|
def test_bias_kern(self):
|
||||||
|
|
|
||||||
|
|
@ -163,14 +163,18 @@ class GradientTests(unittest.TestCase):
|
||||||
rbflin = GPy.kern.rbf(2) + GPy.kern.linear(2)
|
rbflin = GPy.kern.rbf(2) + GPy.kern.linear(2)
|
||||||
self.check_model(rbflin, model_type='SparseGPRegression', dimension=2)
|
self.check_model(rbflin, model_type='SparseGPRegression', dimension=2)
|
||||||
|
|
||||||
|
#@unittest.expectedFailure
|
||||||
def test_SparseGPRegression_rbf_linear_white_kern_2D_uncertain_inputs(self):
|
def test_SparseGPRegression_rbf_linear_white_kern_2D_uncertain_inputs(self):
|
||||||
''' Testing the sparse GP regression with rbf, linear kernel on 2d data with uncertain inputs'''
|
''' Testing the sparse GP regression with rbf, linear kernel on 2d data with uncertain inputs'''
|
||||||
rbflin = GPy.kern.rbf(2) + GPy.kern.linear(2)
|
rbflin = GPy.kern.rbf(2) + GPy.kern.linear(2)
|
||||||
|
raise unittest.SkipTest("This is not implemented yet!")
|
||||||
self.check_model(rbflin, model_type='SparseGPRegression', dimension=2, uncertain_inputs=1)
|
self.check_model(rbflin, model_type='SparseGPRegression', dimension=2, uncertain_inputs=1)
|
||||||
|
|
||||||
|
#@unittest.expectedFailure
|
||||||
def test_SparseGPRegression_rbf_linear_white_kern_1D_uncertain_inputs(self):
|
def test_SparseGPRegression_rbf_linear_white_kern_1D_uncertain_inputs(self):
|
||||||
''' Testing the sparse GP regression with rbf, linear kernel on 1d data with uncertain inputs'''
|
''' Testing the sparse GP regression with rbf, linear kernel on 1d data with uncertain inputs'''
|
||||||
rbflin = GPy.kern.rbf(1) + GPy.kern.linear(1)
|
rbflin = GPy.kern.rbf(1) + GPy.kern.linear(1)
|
||||||
|
raise unittest.SkipTest("This is not implemented yet!")
|
||||||
self.check_model(rbflin, model_type='SparseGPRegression', dimension=1, uncertain_inputs=1)
|
self.check_model(rbflin, model_type='SparseGPRegression', dimension=1, uncertain_inputs=1)
|
||||||
|
|
||||||
def test_GPLVM_rbf_bias_white_kern_2D(self):
|
def test_GPLVM_rbf_bias_white_kern_2D(self):
|
||||||
|
|
@ -209,7 +213,7 @@ class GradientTests(unittest.TestCase):
|
||||||
Z = np.linspace(0, 15, 4)[:, None]
|
Z = np.linspace(0, 15, 4)[:, None]
|
||||||
kernel = GPy.kern.rbf(1)
|
kernel = GPy.kern.rbf(1)
|
||||||
m = GPy.models.SparseGPClassification(X,Y,kernel=kernel,Z=Z)
|
m = GPy.models.SparseGPClassification(X,Y,kernel=kernel,Z=Z)
|
||||||
#distribution = GPy.likelihoods.likelihood_functions.Binomial()
|
#distribution = GPy.likelihoods.likelihood_functions.Bernoulli()
|
||||||
#likelihood = GPy.likelihoods.EP(Y, distribution)
|
#likelihood = GPy.likelihoods.EP(Y, distribution)
|
||||||
#m = GPy.core.SparseGP(X, likelihood, kernel, Z)
|
#m = GPy.core.SparseGP(X, likelihood, kernel, Z)
|
||||||
#m.ensure_default_constraints()
|
#m.ensure_default_constraints()
|
||||||
|
|
|
||||||
|
|
@ -14,3 +14,15 @@ import visualize
|
||||||
import decorators
|
import decorators
|
||||||
import classification
|
import classification
|
||||||
import latent_space_visualizations
|
import latent_space_visualizations
|
||||||
|
|
||||||
|
try:
|
||||||
|
import sympy
|
||||||
|
_sympy_available = True
|
||||||
|
del sympy
|
||||||
|
except ImportError as e:
|
||||||
|
_sympy_available = False
|
||||||
|
|
||||||
|
if _sympy_available:
|
||||||
|
import symbolic
|
||||||
|
|
||||||
|
import netpbmfile
|
||||||
|
|
|
||||||
24
GPy/util/block_matrices.py
Normal file
24
GPy/util/block_matrices.py
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def get_blocks(A, blocksizes):
|
||||||
|
assert (A.shape[0]==A.shape[1]) and len(A.shape)==2, "can;t blockify this non-square matrix"
|
||||||
|
N = np.sum(blocksizes)
|
||||||
|
assert A.shape[0] == N, "bad blocksizes"
|
||||||
|
num_blocks = len(blocksizes)
|
||||||
|
B = np.empty(shape=(num_blocks, num_blocks), dtype=np.object)
|
||||||
|
count_i = 0
|
||||||
|
for Bi, i in enumerate(blocksizes):
|
||||||
|
count_j = 0
|
||||||
|
for Bj, j in enumerate(blocksizes):
|
||||||
|
B[Bi, Bj] = A[count_i:count_i + i, count_j : count_j + j]
|
||||||
|
count_j += j
|
||||||
|
count_i += i
|
||||||
|
return B
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
A = np.zeros((5,5))
|
||||||
|
B = get_blocks(A,[2,3])
|
||||||
|
B[0,0] += 7
|
||||||
|
print B
|
||||||
22
GPy/util/config.py
Normal file
22
GPy/util/config.py
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#
|
||||||
|
# This loads the configuration
|
||||||
|
#
|
||||||
|
import ConfigParser
|
||||||
|
import os
|
||||||
|
config = ConfigParser.ConfigParser()
|
||||||
|
|
||||||
|
home = os.getenv('HOME') or os.getenv('USERPROFILE')
|
||||||
|
user_file = os.path.join(home,'.gpy_config.cfg')
|
||||||
|
default_file = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'gpy_config.cfg'))
|
||||||
|
print user_file, os.path.isfile(user_file)
|
||||||
|
print default_file, os.path.isfile(default_file)
|
||||||
|
|
||||||
|
# 1. check if the user has a ~/.gpy_config.cfg
|
||||||
|
if os.path.isfile(user_file):
|
||||||
|
config.read(user_file)
|
||||||
|
elif os.path.isfile(default_file):
|
||||||
|
# 2. if not, use the default one
|
||||||
|
config.read(default_file)
|
||||||
|
else:
|
||||||
|
#3. panic
|
||||||
|
raise ValueError, "no configuration file found"
|
||||||
319
GPy/util/data_resources.json
Normal file
319
GPy/util/data_resources.json
Normal file
|
|
@ -0,0 +1,319 @@
|
||||||
|
{
|
||||||
|
"rogers_girolami_data":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"firstcoursemldata.tar.gz"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"A First Course in Machine Learning. Simon Rogers and Mark Girolami: Chapman & Hall/CRC, ISBN-13: 978-1439824146",
|
||||||
|
"details":"Data from the textbook 'A First Course in Machine Learning'. Available from http://www.dcs.gla.ac.uk/~srogers/firstcourseml/.",
|
||||||
|
"urls":[
|
||||||
|
"https://www.dropbox.com/sh/7p6tu1t29idgliq/_XqlH_3nt9/"
|
||||||
|
],
|
||||||
|
"suffices":[
|
||||||
|
[
|
||||||
|
"?dl=1"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"size":21949154
|
||||||
|
},
|
||||||
|
"ankur_pose_data":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"ankurDataPoseSilhouette.mat"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"citation":"3D Human Pose from Silhouettes by Relevance Vector Regression (In CVPR'04). A. Agarwal and B. Triggs.",
|
||||||
|
"license":null,
|
||||||
|
"urls":[
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/ankur_pose_data/"
|
||||||
|
],
|
||||||
|
"details":"Artificially generated data of silhouettes given poses. Note that the data does not display a left/right ambiguity because across the entire data set one of the arms sticks out more the the other, disambiguating the pose as to which way the individual is facing."
|
||||||
|
},
|
||||||
|
"osu_accad":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"swagger1TXT.ZIP",
|
||||||
|
"handspring1TXT.ZIP",
|
||||||
|
"quickwalkTXT.ZIP",
|
||||||
|
"run1TXT.ZIP",
|
||||||
|
"sprintTXT.ZIP",
|
||||||
|
"dogwalkTXT.ZIP",
|
||||||
|
"camper_04TXT.ZIP",
|
||||||
|
"dance_KB3_TXT.ZIP",
|
||||||
|
"per20_TXT.ZIP",
|
||||||
|
"perTWO07_TXT.ZIP",
|
||||||
|
"perTWO13_TXT.ZIP",
|
||||||
|
"perTWO14_TXT.ZIP",
|
||||||
|
"perTWO15_TXT.ZIP",
|
||||||
|
"perTWO16_TXT.ZIP"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"connections.txt"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":"Data is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License (http://creativecommons.org/licenses/by-nc-sa/3.0/).",
|
||||||
|
"citation":"The Open Motion Data Project by The Ohio State University Advanced Computing Center for the Arts and Design, http://accad.osu.edu/research/mocap/mocap_data.htm.",
|
||||||
|
"details":"Motion capture data of different motions from the Open Motion Data Project at Ohio State University.",
|
||||||
|
"urls":[
|
||||||
|
"http://accad.osu.edu/research/mocap/data/",
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/stick/"
|
||||||
|
],
|
||||||
|
"size":15922790
|
||||||
|
},
|
||||||
|
"isomap_face_data":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"face_data.mat"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"A Global Geometric Framework for Nonlinear Dimensionality Reduction, J. B. Tenenbaum, V. de Silva and J. C. Langford, Science 290 (5500): 2319-2323, 22 December 2000",
|
||||||
|
"details":"Face data made available by Tenenbaum, de Silva and Langford to demonstrate isomap, available from http://isomap.stanford.edu/datasets.html.",
|
||||||
|
"urls":[
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/isomap_face_data/"
|
||||||
|
],
|
||||||
|
"size":24229368
|
||||||
|
},
|
||||||
|
"boston_housing":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"Index",
|
||||||
|
"housing.data",
|
||||||
|
"housing.names"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"Harrison, D. and Rubinfeld, D.L. 'Hedonic prices and the demand for clean air', J. Environ. Economics & Management, vol.5, 81-102, 1978.",
|
||||||
|
"details":"The Boston Housing data relates house values in Boston to a range of input variables.",
|
||||||
|
"urls":[
|
||||||
|
"http://archive.ics.uci.edu/ml/machine-learning-databases/housing/"
|
||||||
|
],
|
||||||
|
"size":51276
|
||||||
|
},
|
||||||
|
"cmu_mocap_full":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"allasfamc.zip"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":"From http://mocap.cs.cmu.edu. This data is free for use in research projects. You may include this data in commercially-sold products, but you may not resell this data directly, even in converted form. If you publish results obtained using this data, we would appreciate it if you would send the citation to your published paper to jkh+mocap@cs.cmu.edu, and also would add this text to your acknowledgments section: The data used in this project was obtained from mocap.cs.cmu.edu. The database was created with funding from NSF EIA-0196217.",
|
||||||
|
"citation":"Please include this in your acknowledgements: The data used in this project was obtained from mocap.cs.cmu.edu.\nThe database was created with funding from NSF EIA-0196217.",
|
||||||
|
"details":"CMU Motion Capture data base. Captured by a Vicon motion capture system consisting of 12 infrared MX-40 cameras, each of which is capable of recording at 120 Hz with images of 4 megapixel resolution. Motions are captured in a working volume of approximately 3m x 8m. The capture subject wears 41 markers and a stylish black garment.",
|
||||||
|
"urls":[
|
||||||
|
"http://mocap.cs.cmu.edu/subjects"
|
||||||
|
],
|
||||||
|
"size":null
|
||||||
|
},
|
||||||
|
"brendan_faces":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"frey_rawface.mat"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"Frey, B. J., Colmenarez, A and Huang, T. S. Mixtures of Local Linear Subspaces for Face Recognition. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition 1998, 32-37, June 1998. Computer Society Press, Los Alamitos, CA.",
|
||||||
|
"details":"A video of Brendan Frey's face popularized as a benchmark for visualization by the Locally Linear Embedding.",
|
||||||
|
"urls":[
|
||||||
|
"http://www.cs.nyu.edu/~roweis/data/"
|
||||||
|
],
|
||||||
|
"size":1100584
|
||||||
|
},
|
||||||
|
"olympic_marathon_men":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"olympicMarathonTimes.csv"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":null,
|
||||||
|
"details":"Olympic mens' marathon gold medal winning times from 1896 to 2012. Time given in pace (minutes per kilometer). Data is originally downloaded and collated from Wikipedia, we are not responsible for errors in the data",
|
||||||
|
"urls":[
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/olympic_marathon_men/"
|
||||||
|
],
|
||||||
|
"size":584
|
||||||
|
},
|
||||||
|
"pumadyn-32nm":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"pumadyn-32nm.tar.gz"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":"Data is made available by the Delve system at the University of Toronto",
|
||||||
|
"citation":"Created by Zoubin Ghahramani using the Matlab Robotics Toolbox of Peter Corke. Corke, P. I. (1996). A Robotics Toolbox for MATLAB. IEEE Robotics and Automation Magazine, 3 (1): 24-32.",
|
||||||
|
"details":"Pumadyn non linear 32 input data set with moderate noise. See http://www.cs.utoronto.ca/~delve/data/pumadyn/desc.html for details.",
|
||||||
|
"urls":[
|
||||||
|
"ftp://ftp.cs.toronto.edu/pub/neuron/delve/data/tarfiles/pumadyn-family/"
|
||||||
|
],
|
||||||
|
"size":5861646
|
||||||
|
},
|
||||||
|
"ripley_prnn_data":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"Cushings.dat",
|
||||||
|
"README",
|
||||||
|
"crabs.dat",
|
||||||
|
"fglass.dat",
|
||||||
|
"fglass.grp",
|
||||||
|
"pima.te",
|
||||||
|
"pima.tr",
|
||||||
|
"pima.tr2",
|
||||||
|
"synth.te",
|
||||||
|
"synth.tr",
|
||||||
|
"viruses.dat",
|
||||||
|
"virus3.dat"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"Pattern Recognition and Neural Networks by B.D. Ripley (1996) Cambridge University Press ISBN 0 521 46986 7",
|
||||||
|
"details":"Data sets from Brian Ripley's Pattern Recognition and Neural Networks",
|
||||||
|
"urls":[
|
||||||
|
"http://www.stats.ox.ac.uk/pub/PRNN/"
|
||||||
|
],
|
||||||
|
"size":93565
|
||||||
|
},
|
||||||
|
"three_phase_oil_flow":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"DataTrnLbls.txt",
|
||||||
|
"DataTrn.txt",
|
||||||
|
"DataTst.txt",
|
||||||
|
"DataTstLbls.txt",
|
||||||
|
"DataVdn.txt",
|
||||||
|
"DataVdnLbls.txt"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"Bishop, C. M. and G. D. James (1993). Analysis of multiphase flows using dual-energy gamma densitometry and neural networks. Nuclear Instruments and Methods in Physics Research A327, 580-593",
|
||||||
|
"details":"The three phase oil data used initially for demonstrating the Generative Topographic mapping.",
|
||||||
|
"urls":[
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/three_phase_oil_flow/"
|
||||||
|
],
|
||||||
|
"size":712796
|
||||||
|
},
|
||||||
|
"robot_wireless":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"uw-floor.txt"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"WiFi-SLAM using Gaussian Process Latent Variable Models by Brian Ferris, Dieter Fox and Neil Lawrence in IJCAI'07 Proceedings pages 2480-2485. Data used in A Unifying Probabilistic Perspective for Spectral Dimensionality Reduction: Insights and New Models by Neil D. Lawrence, JMLR 13 pg 1609--1638, 2012.",
|
||||||
|
"details":"Data created by Brian Ferris and Dieter Fox. Consists of WiFi access point strengths taken during a circuit of the Paul Allen building at the University of Washington.",
|
||||||
|
"urls":[
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/robot_wireless/"
|
||||||
|
],
|
||||||
|
"size":284390
|
||||||
|
},
|
||||||
|
"xw_pen":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"xw_pen_15.csv"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"Michael E. Tipping and Neil D. Lawrence. Variational inference for Student-t models: Robust Bayesian interpolation and generalised component analysis. Neurocomputing, 69:123--141, 2005",
|
||||||
|
"details":"Accelerometer pen data used for robust regression by Tipping and Lawrence.",
|
||||||
|
"urls":[
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/xw_pen/"
|
||||||
|
],
|
||||||
|
"size":3410
|
||||||
|
},
|
||||||
|
"swiss_roll":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"swiss_roll_data.mat"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"A Global Geometric Framework for Nonlinear Dimensionality Reduction, J. B. Tenenbaum, V. de Silva and J. C. Langford, Science 290 (5500): 2319-2323, 22 December 2000",
|
||||||
|
"details":"Swiss roll data made available by Tenenbaum, de Silva and Langford to demonstrate isomap, available from http://isomap.stanford.edu/datasets.html.",
|
||||||
|
"urls":[
|
||||||
|
"http://isomap.stanford.edu/"
|
||||||
|
],
|
||||||
|
"size":800256
|
||||||
|
},
|
||||||
|
"osu_run1":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"run1TXT.ZIP"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"connections.txt"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":"Data is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License (http://creativecommons.org/licenses/by-nc-sa/3.0/).",
|
||||||
|
"citation":"The Open Motion Data Project by The Ohio State University Advanced Computing Center for the Arts and Design, http://accad.osu.edu/research/mocap/mocap_data.htm.",
|
||||||
|
"details":"Motion capture data of a stick man running from the Open Motion Data Project at Ohio State University.",
|
||||||
|
"urls":[
|
||||||
|
"http://accad.osu.edu/research/mocap/data/",
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/stick/"
|
||||||
|
],
|
||||||
|
"size":338103
|
||||||
|
},
|
||||||
|
"creep_rupture":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"creeprupt.tar"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"Materials Algorithms Project Data Library: MAP_DATA_CREEP_RUPTURE. F. Brun and T. Yoshida.",
|
||||||
|
"details":"Provides 2066 creep rupture test results of steels (mainly of two kinds of steels: 2.25Cr and 9-12 wt% Cr ferritic steels). See http://www.msm.cam.ac.uk/map/data/materials/creeprupt-b.html.",
|
||||||
|
"urls":[
|
||||||
|
"http://www.msm.cam.ac.uk/map/data/tar/"
|
||||||
|
],
|
||||||
|
"size":602797
|
||||||
|
},
|
||||||
|
"olivetti_faces":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"att_faces.zip"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"olivettifaces.mat"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"Ferdinando Samaria and Andy Harter, Parameterisation of a Stochastic Model for Human Face Identification. Proceedings of 2nd IEEE Workshop on Applications of Computer Vision, Sarasota FL, December 1994",
|
||||||
|
"details":"Olivetti Research Labs Face data base, acquired between December 1992 and December 1994 in the Olivetti Research Lab, Cambridge (which later became AT&T Laboratories, Cambridge). When using these images please give credit to AT&T Laboratories, Cambridge. ",
|
||||||
|
"urls":[
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/olivetti_faces/",
|
||||||
|
"http://www.cs.nyu.edu/~roweis/data/"
|
||||||
|
],
|
||||||
|
"size":8561331
|
||||||
|
},
|
||||||
|
"della_gatta":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"DellaGattadata.mat"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"Direct targets of the TRP63 transcription factor revealed by a combination of gene expression profiling and reverse engineering. Giusy Della Gatta, Mukesh Bansal, Alberto Ambesi-Impiombato, Dario Antonini, Caterina Missero, and Diego di Bernardo, Genome Research 2008",
|
||||||
|
"details":"The full gene expression data set from della Gatta et al (http://www.ncbi.nlm.nih.gov/pmc/articles/PMC2413161/) processed by RMA.",
|
||||||
|
"urls":[
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/della_gatta/"
|
||||||
|
],
|
||||||
|
"size":3729650
|
||||||
|
},
|
||||||
|
"epomeo_gpx":{
|
||||||
|
"files":[
|
||||||
|
[
|
||||||
|
"endomondo_1.gpx",
|
||||||
|
"endomondo_2.gpx",
|
||||||
|
"garmin_watch_via_endomondo.gpx",
|
||||||
|
"viewranger_phone.gpx",
|
||||||
|
"viewranger_tablet.gpx"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"license":null,
|
||||||
|
"citation":"",
|
||||||
|
"details":"Five different GPS traces of the same run up Mount Epomeo in Ischia. The traces are from different sources. endomondo_1 and endomondo_2 are traces from the mobile phone app Endomondo, with a split in the middle. garmin_watch_via_endomondo is the trace from a Garmin watch, with a segment missing about 4 kilometers in. viewranger_phone and viewranger_tablet are traces from a phone and a tablet through the viewranger app. The viewranger_phone data comes from the same mobile phone as the Endomondo data (i.e. there are 3 GPS devices, but one device recorded two traces).",
|
||||||
|
"urls":[
|
||||||
|
"http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/epomeo_gpx/"
|
||||||
|
],
|
||||||
|
"size":2031872
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,24 +3,18 @@ import numpy as np
|
||||||
import GPy
|
import GPy
|
||||||
import scipy.io
|
import scipy.io
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
import urllib as url
|
|
||||||
import zipfile
|
import zipfile
|
||||||
import tarfile
|
import tarfile
|
||||||
import datetime
|
import datetime
|
||||||
|
import json
|
||||||
|
ipython_available=True
|
||||||
|
try:
|
||||||
|
import IPython
|
||||||
|
except ImportError:
|
||||||
|
ipython_available=False
|
||||||
|
|
||||||
ipython_notebook = False
|
|
||||||
if ipython_notebook:
|
|
||||||
import IPython.core.display
|
|
||||||
def ipynb_input(varname, prompt=''):
|
|
||||||
"""Prompt user for input and assign string val to given variable name."""
|
|
||||||
js_code = ("""
|
|
||||||
var value = prompt("{prompt}","");
|
|
||||||
var py_code = "{varname} = '" + value + "'";
|
|
||||||
IPython.notebook.kernel.execute(py_code);
|
|
||||||
""").format(prompt=prompt, varname=varname)
|
|
||||||
return IPython.core.display.Javascript(js_code)
|
|
||||||
|
|
||||||
import sys, urllib
|
import sys, urllib2
|
||||||
|
|
||||||
def reporthook(a,b,c):
|
def reporthook(a,b,c):
|
||||||
# ',' at the end of the line is important!
|
# ',' at the end of the line is important!
|
||||||
|
|
@ -34,133 +28,39 @@ data_path = os.path.join(os.path.dirname(__file__), 'datasets')
|
||||||
default_seed = 10000
|
default_seed = 10000
|
||||||
overide_manual_authorize=False
|
overide_manual_authorize=False
|
||||||
neil_url = 'http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/'
|
neil_url = 'http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/'
|
||||||
cmu_url = 'http://mocap.cs.cmu.edu/subjects/'
|
|
||||||
# Note: there may be a better way of storing data resources. One of the pythonistas will need to take a look.
|
|
||||||
data_resources = {'ankur_pose_data' : {'urls' : [neil_url + 'ankur_pose_data/'],
|
|
||||||
'files' : [['ankurDataPoseSilhouette.mat']],
|
|
||||||
'license' : None,
|
|
||||||
'citation' : """3D Human Pose from Silhouettes by Relevance Vector Regression (In CVPR'04). A. Agarwal and B. Triggs.""",
|
|
||||||
'details' : """Artificially generated data of silhouettes given poses. Note that the data does not display a left/right ambiguity because across the entire data set one of the arms sticks out more the the other, disambiguating the pose as to which way the individual is facing."""},
|
|
||||||
|
|
||||||
'boston_housing' : {'urls' : ['http://archive.ics.uci.edu/ml/machine-learning-databases/housing/'],
|
# Read data resources from json file.
|
||||||
'files' : [['Index', 'housing.data', 'housing.names']],
|
path = os.path.join(os.path.dirname(__file__), 'data_resources.json')
|
||||||
'citation' : """Harrison, D. and Rubinfeld, D.L. 'Hedonic prices and the demand for clean air', J. Environ. Economics & Management, vol.5, 81-102, 1978.""",
|
json_data=open(path).read()
|
||||||
'details' : """The Boston Housing data relates house values in Boston to a range of input variables.""",
|
data_resources = json.loads(json_data)
|
||||||
'license' : None,
|
|
||||||
'size' : 51276
|
|
||||||
},
|
|
||||||
'brendan_faces' : {'urls' : ['http://www.cs.nyu.edu/~roweis/data/'],
|
|
||||||
'files': [['frey_rawface.mat']],
|
|
||||||
'citation' : 'Frey, B. J., Colmenarez, A and Huang, T. S. Mixtures of Local Linear Subspaces for Face Recognition. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition 1998, 32-37, June 1998. Computer Society Press, Los Alamitos, CA.',
|
|
||||||
'details' : """A video of Brendan Frey's face popularized as a benchmark for visualization by the Locally Linear Embedding.""",
|
|
||||||
'license': None,
|
|
||||||
'size' : 1100584},
|
|
||||||
'cmu_mocap_full' : {'urls' : ['http://mocap.cs.cmu.edu'],
|
|
||||||
'files' : [['allasfamc.zip']],
|
|
||||||
'citation' : """Please include this in your acknowledgements: The data used in this project was obtained from mocap.cs.cmu.edu.
|
|
||||||
The database was created with funding from NSF EIA-0196217.""",
|
|
||||||
'details' : """CMU Motion Capture data base. Captured by a Vicon motion capture system consisting of 12 infrared MX-40 cameras, each of which is capable of recording at 120 Hz with images of 4 megapixel resolution. Motions are captured in a working volume of approximately 3m x 8m. The capture subject wears 41 markers and a stylish black garment.""",
|
|
||||||
'license' : """From http://mocap.cs.cmu.edu. This data is free for use in research projects. You may include this data in commercially-sold products, but you may not resell this data directly, even in converted form. If you publish results obtained using this data, we would appreciate it if you would send the citation to your published paper to jkh+mocap@cs.cmu.edu, and also would add this text to your acknowledgments section: The data used in this project was obtained from mocap.cs.cmu.edu. The database was created with funding from NSF EIA-0196217.""",
|
|
||||||
'size' : None},
|
|
||||||
'creep_rupture' : {'urls' : ['http://www.msm.cam.ac.uk/map/data/tar/'],
|
|
||||||
'files' : [['creeprupt.tar']],
|
|
||||||
'citation' : 'Materials Algorithms Project Data Library: MAP_DATA_CREEP_RUPTURE. F. Brun and T. Yoshida.',
|
|
||||||
'details' : """Provides 2066 creep rupture test results of steels (mainly of two kinds of steels: 2.25Cr and 9-12 wt% Cr ferritic steels). See http://www.msm.cam.ac.uk/map/data/materials/creeprupt-b.html.""",
|
|
||||||
'license' : None,
|
|
||||||
'size' : 602797},
|
|
||||||
'della_gatta' : {'urls' : [neil_url + 'della_gatta/'],
|
|
||||||
'files': [['DellaGattadata.mat']],
|
|
||||||
'citation' : 'Direct targets of the TRP63 transcription factor revealed by a combination of gene expression profiling and reverse engineering. Giusy Della Gatta, Mukesh Bansal, Alberto Ambesi-Impiombato, Dario Antonini, Caterina Missero, and Diego di Bernardo, Genome Research 2008',
|
|
||||||
'details': "The full gene expression data set from della Gatta et al (http://www.ncbi.nlm.nih.gov/pmc/articles/PMC2413161/) processed by RMA.",
|
|
||||||
'license':None,
|
|
||||||
'size':3729650},
|
|
||||||
'epomeo_gpx' : {'urls' : [neil_url + 'epomeo_gpx/'],
|
|
||||||
'files': [['endomondo_1.gpx', 'endomondo_2.gpx', 'garmin_watch_via_endomondo.gpx','viewranger_phone.gpx','viewranger_tablet.gpx']],
|
|
||||||
'citation' : '',
|
|
||||||
'details': "Five different GPS traces of the same run up Mount Epomeo in Ischia. The traces are from different sources. endomondo_1 and endomondo_2 are traces from the mobile phone app Endomondo, with a split in the middle. garmin_watch_via_endomondo is the trace from a Garmin watch, with a segment missing about 4 kilometers in. viewranger_phone and viewranger_tablet are traces from a phone and a tablet through the viewranger app. The viewranger_phone data comes from the same mobile phone as the Endomondo data (i.e. there are 3 GPS devices, but one device recorded two traces).",
|
|
||||||
'license':None,
|
|
||||||
'size': 2031872},
|
|
||||||
'three_phase_oil_flow': {'urls' : [neil_url + 'three_phase_oil_flow/'],
|
|
||||||
'files' : [['DataTrnLbls.txt', 'DataTrn.txt', 'DataTst.txt', 'DataTstLbls.txt', 'DataVdn.txt', 'DataVdnLbls.txt']],
|
|
||||||
'citation' : 'Bishop, C. M. and G. D. James (1993). Analysis of multiphase flows using dual-energy gamma densitometry and neural networks. Nuclear Instruments and Methods in Physics Research A327, 580-593',
|
|
||||||
'details' : """The three phase oil data used initially for demonstrating the Generative Topographic mapping.""",
|
|
||||||
'license' : None,
|
|
||||||
'size' : 712796},
|
|
||||||
'rogers_girolami_data' : {'urls' : ['https://www.dropbox.com/sh/7p6tu1t29idgliq/_XqlH_3nt9/'],
|
|
||||||
'files' : [['firstcoursemldata.tar.gz']],
|
|
||||||
'suffices' : [['?dl=1']],
|
|
||||||
'citation' : 'A First Course in Machine Learning. Simon Rogers and Mark Girolami: Chapman & Hall/CRC, ISBN-13: 978-1439824146',
|
|
||||||
'details' : """Data from the textbook 'A First Course in Machine Learning'. Available from http://www.dcs.gla.ac.uk/~srogers/firstcourseml/.""",
|
|
||||||
'license' : None,
|
|
||||||
'size' : 21949154},
|
|
||||||
'olympic_marathon_men' : {'urls' : [neil_url + 'olympic_marathon_men/'],
|
|
||||||
'files' : [['olympicMarathonTimes.csv']],
|
|
||||||
'citation' : None,
|
|
||||||
'details' : """Olympic mens' marathon gold medal winning times from 1896 to 2012. Time given in pace (minutes per kilometer). Data is originally downloaded and collated from Wikipedia, we are not responsible for errors in the data""",
|
|
||||||
'license': None,
|
|
||||||
'size' : 584},
|
|
||||||
'osu_run1' : {'urls': ['http://accad.osu.edu/research/mocap/data/', neil_url + 'stick/'],
|
|
||||||
'files': [['run1TXT.ZIP'],['connections.txt']],
|
|
||||||
'details' : "Motion capture data of a stick man running from the Open Motion Data Project at Ohio State University.",
|
|
||||||
'citation' : 'The Open Motion Data Project by The Ohio State University Advanced Computing Center for the Arts and Design, http://accad.osu.edu/research/mocap/mocap_data.htm.',
|
|
||||||
'license' : 'Data is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License (http://creativecommons.org/licenses/by-nc-sa/3.0/).',
|
|
||||||
'size': 338103},
|
|
||||||
'osu_accad' : {'urls': ['http://accad.osu.edu/research/mocap/data/', neil_url + 'stick/'],
|
|
||||||
'files': [['swagger1TXT.ZIP','handspring1TXT.ZIP','quickwalkTXT.ZIP','run1TXT.ZIP','sprintTXT.ZIP','dogwalkTXT.ZIP','camper_04TXT.ZIP','dance_KB3_TXT.ZIP','per20_TXT.ZIP','perTWO07_TXT.ZIP','perTWO13_TXT.ZIP','perTWO14_TXT.ZIP','perTWO15_TXT.ZIP','perTWO16_TXT.ZIP'],['connections.txt']],
|
|
||||||
'details' : "Motion capture data of different motions from the Open Motion Data Project at Ohio State University.",
|
|
||||||
'citation' : 'The Open Motion Data Project by The Ohio State University Advanced Computing Center for the Arts and Design, http://accad.osu.edu/research/mocap/mocap_data.htm.',
|
|
||||||
'license' : 'Data is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License (http://creativecommons.org/licenses/by-nc-sa/3.0/).',
|
|
||||||
'size': 15922790},
|
|
||||||
'pumadyn-32nm' : {'urls' : ['ftp://ftp.cs.toronto.edu/pub/neuron/delve/data/tarfiles/pumadyn-family/'],
|
|
||||||
'files' : [['pumadyn-32nm.tar.gz']],
|
|
||||||
'details' : """Pumadyn non linear 32 input data set with moderate noise. See http://www.cs.utoronto.ca/~delve/data/pumadyn/desc.html for details.""",
|
|
||||||
'citation' : """Created by Zoubin Ghahramani using the Matlab Robotics Toolbox of Peter Corke. Corke, P. I. (1996). A Robotics Toolbox for MATLAB. IEEE Robotics and Automation Magazine, 3 (1): 24-32.""",
|
|
||||||
'license' : """Data is made available by the Delve system at the University of Toronto""",
|
|
||||||
'size' : 5861646},
|
|
||||||
'robot_wireless' : {'urls' : [neil_url + 'robot_wireless/'],
|
|
||||||
'files' : [['uw-floor.txt']],
|
|
||||||
'citation' : """WiFi-SLAM using Gaussian Process Latent Variable Models by Brian Ferris, Dieter Fox and Neil Lawrence in IJCAI'07 Proceedings pages 2480-2485. Data used in A Unifying Probabilistic Perspective for Spectral Dimensionality Reduction: Insights and New Models by Neil D. Lawrence, JMLR 13 pg 1609--1638, 2012.""",
|
|
||||||
'details' : """Data created by Brian Ferris and Dieter Fox. Consists of WiFi access point strengths taken during a circuit of the Paul Allen building at the University of Washington.""",
|
|
||||||
'license' : None,
|
|
||||||
'size' : 284390},
|
|
||||||
'swiss_roll' : {'urls' : ['http://isomap.stanford.edu/'],
|
|
||||||
'files' : [['swiss_roll_data.mat']],
|
|
||||||
'details' : """Swiss roll data made available by Tenenbaum, de Silva and Langford to demonstrate isomap, available from http://isomap.stanford.edu/datasets.html.""",
|
|
||||||
'citation' : 'A Global Geometric Framework for Nonlinear Dimensionality Reduction, J. B. Tenenbaum, V. de Silva and J. C. Langford, Science 290 (5500): 2319-2323, 22 December 2000',
|
|
||||||
'license' : None,
|
|
||||||
'size' : 800256},
|
|
||||||
'ripley_prnn_data' : {'urls' : ['http://www.stats.ox.ac.uk/pub/PRNN/'],
|
|
||||||
'files' : [['Cushings.dat', 'README', 'crabs.dat', 'fglass.dat', 'fglass.grp', 'pima.te', 'pima.tr', 'pima.tr2', 'synth.te', 'synth.tr', 'viruses.dat', 'virus3.dat']],
|
|
||||||
'details' : """Data sets from Brian Ripley's Pattern Recognition and Neural Networks""",
|
|
||||||
'citation': """Pattern Recognition and Neural Networks by B.D. Ripley (1996) Cambridge University Press ISBN 0 521 46986 7""",
|
|
||||||
'license' : None,
|
|
||||||
'size' : 93565},
|
|
||||||
'isomap_face_data' : {'urls' : [neil_url + 'isomap_face_data/'],
|
|
||||||
'files' : [['face_data.mat']],
|
|
||||||
'details' : """Face data made available by Tenenbaum, de Silva and Langford to demonstrate isomap, available from http://isomap.stanford.edu/datasets.html.""",
|
|
||||||
'citation' : 'A Global Geometric Framework for Nonlinear Dimensionality Reduction, J. B. Tenenbaum, V. de Silva and J. C. Langford, Science 290 (5500): 2319-2323, 22 December 2000',
|
|
||||||
'license' : None,
|
|
||||||
'size' : 24229368},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def prompt_user():
|
def prompt_user(prompt):
|
||||||
"""Ask user for agreeing to data set licenses."""
|
"""Ask user for agreeing to data set licenses."""
|
||||||
# raw_input returns the empty string for "enter"
|
# raw_input returns the empty string for "enter"
|
||||||
yes = set(['yes', 'y'])
|
yes = set(['yes', 'y'])
|
||||||
no = set(['no','n'])
|
no = set(['no','n'])
|
||||||
choice = ''
|
|
||||||
if ipython_notebook:
|
try:
|
||||||
ipynb_input(choice, prompt='provide your answer here')
|
print(prompt)
|
||||||
else:
|
|
||||||
choice = raw_input().lower()
|
choice = raw_input().lower()
|
||||||
|
# would like to test for exception here, but not sure if we can do that without importing IPython
|
||||||
|
except:
|
||||||
|
print('Stdin is not implemented.')
|
||||||
|
print('You need to set')
|
||||||
|
print('overide_manual_authorize=True')
|
||||||
|
print('to proceed with the download. Please set that variable and continue.')
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
if choice in yes:
|
if choice in yes:
|
||||||
return True
|
return True
|
||||||
elif choice in no:
|
elif choice in no:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
sys.stdout.write("Please respond with 'yes', 'y' or 'no', 'n'")
|
print("Your response was a " + choice)
|
||||||
return prompt_user()
|
print("Please respond with 'yes', 'y' or 'no', 'n'")
|
||||||
|
#return prompt_user()
|
||||||
|
|
||||||
|
|
||||||
def data_available(dataset_name=None):
|
def data_available(dataset_name=None):
|
||||||
|
|
@ -181,7 +81,21 @@ def download_url(url, store_directory, save_name = None, messages = True, suffix
|
||||||
print "Downloading ", url, "->", os.path.join(store_directory, file)
|
print "Downloading ", url, "->", os.path.join(store_directory, file)
|
||||||
if not os.path.exists(dir_name):
|
if not os.path.exists(dir_name):
|
||||||
os.makedirs(dir_name)
|
os.makedirs(dir_name)
|
||||||
urllib.urlretrieve(url+suffix, save_name, reporthook)
|
try:
|
||||||
|
response = urllib2.urlopen(url+suffix)
|
||||||
|
except urllib2.URLError, e:
|
||||||
|
if not hasattr(e, "code"):
|
||||||
|
raise
|
||||||
|
response = e
|
||||||
|
if response.code > 399 and response.code<500:
|
||||||
|
raise ValueError('Tried url ' + url + suffix + ' and received client error ' + str(response.code))
|
||||||
|
elif response.code > 499:
|
||||||
|
raise ValueError('Tried url ' + url + suffix + ' and received server error ' + str(response.code))
|
||||||
|
# if we wanted to get more sophisticated maybe we should check the response code here again even for successes.
|
||||||
|
with open(save_name, 'wb') as f:
|
||||||
|
f.write(response.read())
|
||||||
|
|
||||||
|
#urllib.urlretrieve(url+suffix, save_name, reporthook)
|
||||||
|
|
||||||
def authorize_download(dataset_name=None):
|
def authorize_download(dataset_name=None):
|
||||||
"""Check with the user that the are happy with terms and conditions for the data set."""
|
"""Check with the user that the are happy with terms and conditions for the data set."""
|
||||||
|
|
@ -212,15 +126,14 @@ def authorize_download(dataset_name=None):
|
||||||
print('You must also agree to the following license:')
|
print('You must also agree to the following license:')
|
||||||
print(dr['license'])
|
print(dr['license'])
|
||||||
print('')
|
print('')
|
||||||
print('Do you wish to proceed with the download? [yes/no]')
|
return prompt_user('Do you wish to proceed with the download? [yes/no]')
|
||||||
return prompt_user()
|
|
||||||
|
|
||||||
def download_data(dataset_name=None):
|
def download_data(dataset_name=None):
|
||||||
"""Check with the user that the are happy with terms and conditions for the data set, then download it."""
|
"""Check with the user that the are happy with terms and conditions for the data set, then download it."""
|
||||||
|
|
||||||
dr = data_resources[dataset_name]
|
dr = data_resources[dataset_name]
|
||||||
if not authorize_download(dataset_name):
|
if not authorize_download(dataset_name):
|
||||||
return False
|
raise Exception("Permission to download data set denied.")
|
||||||
|
|
||||||
if dr.has_key('suffices'):
|
if dr.has_key('suffices'):
|
||||||
for url, files, suffices in zip(dr['urls'], dr['files'], dr['suffices']):
|
for url, files, suffices in zip(dr['urls'], dr['files'], dr['suffices']):
|
||||||
|
|
@ -242,6 +155,8 @@ def cmu_urls_files(subj_motions, messages = True):
|
||||||
'''
|
'''
|
||||||
Find which resources are missing on the local disk for the requested CMU motion capture motions.
|
Find which resources are missing on the local disk for the requested CMU motion capture motions.
|
||||||
'''
|
'''
|
||||||
|
dr = data_resources['cmu_mocap_full']
|
||||||
|
cmu_url = dr['urls'][0]
|
||||||
|
|
||||||
subjects_num = subj_motions[0]
|
subjects_num = subj_motions[0]
|
||||||
motions_num = subj_motions[1]
|
motions_num = subj_motions[1]
|
||||||
|
|
@ -287,7 +202,7 @@ def cmu_urls_files(subj_motions, messages = True):
|
||||||
url_required = True
|
url_required = True
|
||||||
file_download.append(subjects[i] + '_' + motions[i][j] + '.amc')
|
file_download.append(subjects[i] + '_' + motions[i][j] + '.amc')
|
||||||
if url_required:
|
if url_required:
|
||||||
resource['urls'].append(cmu_url + subjects[i] + '/')
|
resource['urls'].append(cmu_url + '/' + subjects[i] + '/')
|
||||||
resource['files'].append(file_download)
|
resource['files'].append(file_download)
|
||||||
return resource
|
return resource
|
||||||
|
|
||||||
|
|
@ -489,13 +404,13 @@ def ripley_synth(data_set='ripley_prnn_data'):
|
||||||
return data_details_return({'X': X, 'y': y, 'Xtest': Xtest, 'ytest': ytest, 'info': 'Synthetic data generated by Ripley for a two class classification problem.'}, data_set)
|
return data_details_return({'X': X, 'y': y, 'Xtest': Xtest, 'ytest': ytest, 'info': 'Synthetic data generated by Ripley for a two class classification problem.'}, data_set)
|
||||||
|
|
||||||
def osu_run1(data_set='osu_run1', sample_every=4):
|
def osu_run1(data_set='osu_run1', sample_every=4):
|
||||||
|
path = os.path.join(data_path, data_set)
|
||||||
if not data_available(data_set):
|
if not data_available(data_set):
|
||||||
download_data(data_set)
|
download_data(data_set)
|
||||||
zip = zipfile.ZipFile(os.path.join(data_path, data_set, 'sprintTXT.ZIP'), 'r')
|
zip = zipfile.ZipFile(os.path.join(data_path, data_set, 'run1TXT.ZIP'), 'r')
|
||||||
path = os.path.join(data_path, data_set)
|
|
||||||
for name in zip.namelist():
|
for name in zip.namelist():
|
||||||
zip.extract(name, path)
|
zip.extract(name, path)
|
||||||
Y, connect = GPy.util.mocap.load_text_data('Aug210107', path)
|
Y, connect = GPy.util.mocap.load_text_data('Aug210106', path)
|
||||||
Y = Y[0:-1:sample_every, :]
|
Y = Y[0:-1:sample_every, :]
|
||||||
return data_details_return({'Y': Y, 'connect' : connect}, data_set)
|
return data_details_return({'Y': Y, 'connect' : connect}, data_set)
|
||||||
|
|
||||||
|
|
@ -535,7 +450,7 @@ def simulation_BGPLVM():
|
||||||
Y = np.array(mat_data['Y'], dtype=float)
|
Y = np.array(mat_data['Y'], dtype=float)
|
||||||
S = np.array(mat_data['initS'], dtype=float)
|
S = np.array(mat_data['initS'], dtype=float)
|
||||||
mu = np.array(mat_data['initMu'], dtype=float)
|
mu = np.array(mat_data['initMu'], dtype=float)
|
||||||
return data_details_return({'S': S, 'Y': Y, 'mu': mu}, data_set)
|
#return data_details_return({'S': S, 'Y': Y, 'mu': mu}, data_set)
|
||||||
return {'Y': Y, 'S': S,
|
return {'Y': Y, 'S': S,
|
||||||
'mu' : mu,
|
'mu' : mu,
|
||||||
'info': "Simulated test dataset generated in MATLAB to compare BGPLVM between python and MATLAB"}
|
'info': "Simulated test dataset generated in MATLAB to compare BGPLVM between python and MATLAB"}
|
||||||
|
|
@ -579,8 +494,34 @@ def toy_linear_1d_classification(seed=default_seed):
|
||||||
X = (np.r_[x1, x2])[:, None]
|
X = (np.r_[x1, x2])[:, None]
|
||||||
return {'X': X, 'Y': sample_class(2.*X), 'F': 2.*X, 'seed' : seed}
|
return {'X': X, 'Y': sample_class(2.*X), 'F': 2.*X, 'seed' : seed}
|
||||||
|
|
||||||
def olympic_100m_men(data_set='rogers_girolami_data'):
|
def olivetti_faces(data_set='olivetti_faces'):
|
||||||
|
path = os.path.join(data_path, data_set)
|
||||||
if not data_available(data_set):
|
if not data_available(data_set):
|
||||||
|
download_data(data_set)
|
||||||
|
zip = zipfile.ZipFile(os.path.join(path, 'att_faces.zip'), 'r')
|
||||||
|
for name in zip.namelist():
|
||||||
|
zip.extract(name, path)
|
||||||
|
Y = []
|
||||||
|
lbls = []
|
||||||
|
for subject in range(40):
|
||||||
|
for image in range(10):
|
||||||
|
image_path = os.path.join(path, 'orl_faces', 's'+str(subject+1), str(image+1) + '.pgm')
|
||||||
|
Y.append(GPy.util.netpbmfile.imread(image_path).flatten())
|
||||||
|
lbls.append(subject)
|
||||||
|
Y = np.asarray(Y)
|
||||||
|
lbls = np.asarray(lbls)[:, None]
|
||||||
|
return data_details_return({'Y': Y, 'lbls' : lbls, 'info': "ORL Faces processed to 64x64 images."}, data_set)
|
||||||
|
|
||||||
|
def xw_pen(data_set='xw_pen'):
|
||||||
|
if not data_available(data_set):
|
||||||
|
download_data(data_set)
|
||||||
|
Y = np.loadtxt(os.path.join(data_path, data_set, 'xw_pen_15.csv'), delimiter=',')
|
||||||
|
X = np.arange(485)[:, None]
|
||||||
|
return data_details_return({'Y': Y, 'X': X, 'info': "Tilt data from a personalized digital assistant pen. Plot in original paper showed regression between time steps 175 and 275."}, data_set)
|
||||||
|
|
||||||
|
|
||||||
|
def download_rogers_girolami_data(data_set='rogers_girolami_data'):
|
||||||
|
if not data_available('rogers_girolami_data'):
|
||||||
download_data(data_set)
|
download_data(data_set)
|
||||||
path = os.path.join(data_path, data_set)
|
path = os.path.join(data_path, data_set)
|
||||||
tar_file = os.path.join(path, 'firstcoursemldata.tar.gz')
|
tar_file = os.path.join(path, 'firstcoursemldata.tar.gz')
|
||||||
|
|
@ -588,6 +529,9 @@ def olympic_100m_men(data_set='rogers_girolami_data'):
|
||||||
print('Extracting file.')
|
print('Extracting file.')
|
||||||
tar.extractall(path=path)
|
tar.extractall(path=path)
|
||||||
tar.close()
|
tar.close()
|
||||||
|
|
||||||
|
def olympic_100m_men(data_set='rogers_girolami_data'):
|
||||||
|
download_rogers_girolami_data()
|
||||||
olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['male100']
|
olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['male100']
|
||||||
|
|
||||||
X = olympic_data[:, 0][:, None]
|
X = olympic_data[:, 0][:, None]
|
||||||
|
|
@ -595,20 +539,45 @@ def olympic_100m_men(data_set='rogers_girolami_data'):
|
||||||
return data_details_return({'X': X, 'Y': Y, 'info': "Olympic sprint times for 100 m men from 1896 until 2008. Example is from Rogers and Girolami's First Course in Machine Learning."}, data_set)
|
return data_details_return({'X': X, 'Y': Y, 'info': "Olympic sprint times for 100 m men from 1896 until 2008. Example is from Rogers and Girolami's First Course in Machine Learning."}, data_set)
|
||||||
|
|
||||||
def olympic_100m_women(data_set='rogers_girolami_data'):
|
def olympic_100m_women(data_set='rogers_girolami_data'):
|
||||||
if not data_available(data_set):
|
download_rogers_girolami_data()
|
||||||
download_data(data_set)
|
|
||||||
path = os.path.join(data_path, data_set)
|
|
||||||
tar_file = os.path.join(path, 'firstcoursemldata.tar.gz')
|
|
||||||
tar = tarfile.open(tar_file)
|
|
||||||
print('Extracting file.')
|
|
||||||
tar.extractall(path=path)
|
|
||||||
tar.close()
|
|
||||||
olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['female100']
|
olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['female100']
|
||||||
|
|
||||||
X = olympic_data[:, 0][:, None]
|
X = olympic_data[:, 0][:, None]
|
||||||
Y = olympic_data[:, 1][:, None]
|
Y = olympic_data[:, 1][:, None]
|
||||||
return data_details_return({'X': X, 'Y': Y, 'info': "Olympic sprint times for 100 m women from 1896 until 2008. Example is from Rogers and Girolami's First Course in Machine Learning."}, data_set)
|
return data_details_return({'X': X, 'Y': Y, 'info': "Olympic sprint times for 100 m women from 1896 until 2008. Example is from Rogers and Girolami's First Course in Machine Learning."}, data_set)
|
||||||
|
|
||||||
|
def olympic_200m_women(data_set='rogers_girolami_data'):
|
||||||
|
download_rogers_girolami_data()
|
||||||
|
olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['female200']
|
||||||
|
|
||||||
|
X = olympic_data[:, 0][:, None]
|
||||||
|
Y = olympic_data[:, 1][:, None]
|
||||||
|
return data_details_return({'X': X, 'Y': Y, 'info': "Olympic 200 m winning times for women from 1896 until 2008. Data is from Rogers and Girolami's First Course in Machine Learning."}, data_set)
|
||||||
|
|
||||||
|
def olympic_200m_men(data_set='rogers_girolami_data'):
|
||||||
|
download_rogers_girolami_data()
|
||||||
|
olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['male200']
|
||||||
|
|
||||||
|
X = olympic_data[:, 0][:, None]
|
||||||
|
Y = olympic_data[:, 1][:, None]
|
||||||
|
return data_details_return({'X': X, 'Y': Y, 'info': "Male 200 m winning times for women from 1896 until 2008. Data is from Rogers and Girolami's First Course in Machine Learning."}, data_set)
|
||||||
|
|
||||||
|
def olympic_400m_women(data_set='rogers_girolami_data'):
|
||||||
|
download_rogers_girolami_data()
|
||||||
|
olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['female400']
|
||||||
|
|
||||||
|
X = olympic_data[:, 0][:, None]
|
||||||
|
Y = olympic_data[:, 1][:, None]
|
||||||
|
return data_details_return({'X': X, 'Y': Y, 'info': "Olympic 400 m winning times for women until 2008. Data is from Rogers and Girolami's First Course in Machine Learning."}, data_set)
|
||||||
|
|
||||||
|
def olympic_400m_men(data_set='rogers_girolami_data'):
|
||||||
|
download_rogers_girolami_data()
|
||||||
|
olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['male400']
|
||||||
|
|
||||||
|
X = olympic_data[:, 0][:, None]
|
||||||
|
Y = olympic_data[:, 1][:, None]
|
||||||
|
return data_details_return({'X': X, 'Y': Y, 'info': "Male 400 m winning times for women until 2008. Data is from Rogers and Girolami's First Course in Machine Learning."}, data_set)
|
||||||
|
|
||||||
def olympic_marathon_men(data_set='olympic_marathon_men'):
|
def olympic_marathon_men(data_set='olympic_marathon_men'):
|
||||||
if not data_available(data_set):
|
if not data_available(data_set):
|
||||||
download_data(data_set)
|
download_data(data_set)
|
||||||
|
|
@ -617,6 +586,37 @@ def olympic_marathon_men(data_set='olympic_marathon_men'):
|
||||||
Y = olympics[:, 1:2]
|
Y = olympics[:, 1:2]
|
||||||
return data_details_return({'X': X, 'Y': Y}, data_set)
|
return data_details_return({'X': X, 'Y': Y}, data_set)
|
||||||
|
|
||||||
|
def olympic_sprints(data_set='rogers_girolami_data'):
|
||||||
|
"""All olympics sprint winning times for multiple output prediction."""
|
||||||
|
X = np.zeros((0, 2))
|
||||||
|
Y = np.zeros((0, 1))
|
||||||
|
for i, dataset in enumerate([olympic_100m_men,
|
||||||
|
olympic_100m_women,
|
||||||
|
olympic_200m_men,
|
||||||
|
olympic_200m_women,
|
||||||
|
olympic_400m_men,
|
||||||
|
olympic_400m_women]):
|
||||||
|
data = dataset()
|
||||||
|
year = data['X']
|
||||||
|
time = data['Y']
|
||||||
|
X = np.vstack((X, np.hstack((year, np.ones_like(year)*i))))
|
||||||
|
Y = np.vstack((Y, time))
|
||||||
|
data['X'] = X
|
||||||
|
data['Y'] = Y
|
||||||
|
data['info'] = "Olympics sprint event winning for men and women to 2008. Data is from Rogers and Girolami's First Course in Machine Learning."
|
||||||
|
return data_details_return({
|
||||||
|
'X': X,
|
||||||
|
'Y': Y,
|
||||||
|
'info': "Olympics sprint event winning for men and women to 2008. Data is from Rogers and Girolami's First Course in Machine Learning.",
|
||||||
|
'output_info': {
|
||||||
|
0:'100m Men',
|
||||||
|
1:'100m Women',
|
||||||
|
2:'200m Men',
|
||||||
|
3:'200m Women',
|
||||||
|
4:'400m Men',
|
||||||
|
5:'400m Women'}
|
||||||
|
}, data_set)
|
||||||
|
|
||||||
# def movielens_small(partNo=1,seed=default_seed):
|
# def movielens_small(partNo=1,seed=default_seed):
|
||||||
# np.random.seed(seed=seed)
|
# np.random.seed(seed=seed)
|
||||||
|
|
||||||
|
|
@ -708,15 +708,15 @@ def creep_data(data_set='creep_rupture'):
|
||||||
X = all_data[:, features].copy()
|
X = all_data[:, features].copy()
|
||||||
return data_details_return({'X': X, 'y': y}, data_set)
|
return data_details_return({'X': X, 'y': y}, data_set)
|
||||||
|
|
||||||
def cmu_mocap_49_balance():
|
def cmu_mocap_49_balance(data_set='cmu_mocap'):
|
||||||
"""Load CMU subject 49's one legged balancing motion that was used by Alvarez, Luengo and Lawrence at AISTATS 2009."""
|
"""Load CMU subject 49's one legged balancing motion that was used by Alvarez, Luengo and Lawrence at AISTATS 2009."""
|
||||||
train_motions = ['18', '19']
|
train_motions = ['18', '19']
|
||||||
test_motions = ['20']
|
test_motions = ['20']
|
||||||
data = cmu_mocap('49', train_motions, test_motions, sample_every=4)
|
data = cmu_mocap('49', train_motions, test_motions, sample_every=4, data_set=data_set)
|
||||||
data['info'] = "One legged balancing motions from CMU data base subject 49. As used in Alvarez, Luengo and Lawrence at AISTATS 2009. It consists of " + data['info']
|
data['info'] = "One legged balancing motions from CMU data base subject 49. As used in Alvarez, Luengo and Lawrence at AISTATS 2009. It consists of " + data['info']
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def cmu_mocap_35_walk_jog():
|
def cmu_mocap_35_walk_jog(data_set='cmu_mocap'):
|
||||||
"""Load CMU subject 35's walking and jogging motions, the same data that was used by Taylor, Roweis and Hinton at NIPS 2007. but without their preprocessing. Also used by Lawrence at AISTATS 2007."""
|
"""Load CMU subject 35's walking and jogging motions, the same data that was used by Taylor, Roweis and Hinton at NIPS 2007. but without their preprocessing. Also used by Lawrence at AISTATS 2007."""
|
||||||
train_motions = ['01', '02', '03', '04', '05', '06',
|
train_motions = ['01', '02', '03', '04', '05', '06',
|
||||||
'07', '08', '09', '10', '11', '12',
|
'07', '08', '09', '10', '11', '12',
|
||||||
|
|
@ -724,7 +724,7 @@ def cmu_mocap_35_walk_jog():
|
||||||
'20', '21', '22', '23', '24', '25',
|
'20', '21', '22', '23', '24', '25',
|
||||||
'26', '28', '30', '31', '32', '33', '34']
|
'26', '28', '30', '31', '32', '33', '34']
|
||||||
test_motions = ['18', '29']
|
test_motions = ['18', '29']
|
||||||
data = cmu_mocap('35', train_motions, test_motions, sample_every=4)
|
data = cmu_mocap('35', train_motions, test_motions, sample_every=4, data_set=data_set)
|
||||||
data['info'] = "Walk and jog data from CMU data base subject 35. As used in Tayor, Roweis and Hinton at NIPS 2007, but without their pre-processing (i.e. as used by Lawrence at AISTATS 2007). It consists of " + data['info']
|
data['info'] = "Walk and jog data from CMU data base subject 35. As used in Tayor, Roweis and Hinton at NIPS 2007, but without their pre-processing (i.e. as used by Lawrence at AISTATS 2007). It consists of " + data['info']
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
@ -736,7 +736,7 @@ def cmu_mocap(subject, train_motions, test_motions=[], sample_every=4, data_set=
|
||||||
# Make sure the data is downloaded.
|
# Make sure the data is downloaded.
|
||||||
all_motions = train_motions + test_motions
|
all_motions = train_motions + test_motions
|
||||||
resource = cmu_urls_files(([subject], [all_motions]))
|
resource = cmu_urls_files(([subject], [all_motions]))
|
||||||
data_resources[data_set] = data_resources['cmu_mocap_full']
|
data_resources[data_set] = data_resources['cmu_mocap_full'].copy()
|
||||||
data_resources[data_set]['files'] = resource['files']
|
data_resources[data_set]['files'] = resource['files']
|
||||||
data_resources[data_set]['urls'] = resource['urls']
|
data_resources[data_set]['urls'] = resource['urls']
|
||||||
if resource['urls']:
|
if resource['urls']:
|
||||||
|
|
@ -806,3 +806,5 @@ def cmu_mocap(subject, train_motions, test_motions=[], sample_every=4, data_set=
|
||||||
if sample_every != 1:
|
if sample_every != 1:
|
||||||
info += ' Data is sub-sampled to every ' + str(sample_every) + ' frames.'
|
info += ' Data is sub-sampled to every ' + str(sample_every) + ' frames.'
|
||||||
return data_details_return({'Y': Y, 'lbls' : lbls, 'Ytest': Ytest, 'lblstest' : lblstest, 'info': info, 'skel': skel}, data_set)
|
return data_details_return({'Y': Y, 'lbls' : lbls, 'Ytest': Ytest, 'lblstest' : lblstest, 'info': info, 'skel': skel}, data_set)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
127
GPy/util/datasets/data_resources_create.py
Normal file
127
GPy/util/datasets/data_resources_create.py
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
neil_url = 'http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/'
|
||||||
|
sam_url = 'http://www.cs.nyu.edu/~roweis/data/'
|
||||||
|
cmu_url = 'http://mocap.cs.cmu.edu/subjects/'
|
||||||
|
|
||||||
|
data_resources = {'ankur_pose_data' : {'urls' : [neil_url + 'ankur_pose_data/'],
|
||||||
|
'files' : [['ankurDataPoseSilhouette.mat']],
|
||||||
|
'license' : None,
|
||||||
|
'citation' : """3D Human Pose from Silhouettes by Relevance Vector Regression (In CVPR'04). A. Agarwal and B. Triggs.""",
|
||||||
|
'details' : """Artificially generated data of silhouettes given poses. Note that the data does not display a left/right ambiguity because across the entire data set one of the arms sticks out more the the other, disambiguating the pose as to which way the individual is facing."""},
|
||||||
|
|
||||||
|
'boston_housing' : {'urls' : ['http://archive.ics.uci.edu/ml/machine-learning-databases/housing/'],
|
||||||
|
'files' : [['Index', 'housing.data', 'housing.names']],
|
||||||
|
'citation' : """Harrison, D. and Rubinfeld, D.L. 'Hedonic prices and the demand for clean air', J. Environ. Economics & Management, vol.5, 81-102, 1978.""",
|
||||||
|
'details' : """The Boston Housing data relates house values in Boston to a range of input variables.""",
|
||||||
|
'license' : None,
|
||||||
|
'size' : 51276
|
||||||
|
},
|
||||||
|
'brendan_faces' : {'urls' : [sam_url],
|
||||||
|
'files': [['frey_rawface.mat']],
|
||||||
|
'citation' : 'Frey, B. J., Colmenarez, A and Huang, T. S. Mixtures of Local Linear Subspaces for Face Recognition. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition 1998, 32-37, June 1998. Computer Society Press, Los Alamitos, CA.',
|
||||||
|
'details' : """A video of Brendan Frey's face popularized as a benchmark for visualization by the Locally Linear Embedding.""",
|
||||||
|
'license': None,
|
||||||
|
'size' : 1100584},
|
||||||
|
'cmu_mocap_full' : {'urls' : ['http://mocap.cs.cmu.edu'],
|
||||||
|
'files' : [['allasfamc.zip']],
|
||||||
|
'citation' : """Please include this in your acknowledgements: The data used in this project was obtained from mocap.cs.cmu.edu.
|
||||||
|
The database was created with funding from NSF EIA-0196217.""",
|
||||||
|
'details' : """CMU Motion Capture data base. Captured by a Vicon motion capture system consisting of 12 infrared MX-40 cameras, each of which is capable of recording at 120 Hz with images of 4 megapixel resolution. Motions are captured in a working volume of approximately 3m x 8m. The capture subject wears 41 markers and a stylish black garment.""",
|
||||||
|
'license' : """From http://mocap.cs.cmu.edu. This data is free for use in research projects. You may include this data in commercially-sold products, but you may not resell this data directly, even in converted form. If you publish results obtained using this data, we would appreciate it if you would send the citation to your published paper to jkh+mocap@cs.cmu.edu, and also would add this text to your acknowledgments section: The data used in this project was obtained from mocap.cs.cmu.edu. The database was created with funding from NSF EIA-0196217.""",
|
||||||
|
'size' : None},
|
||||||
|
'creep_rupture' : {'urls' : ['http://www.msm.cam.ac.uk/map/data/tar/'],
|
||||||
|
'files' : [['creeprupt.tar']],
|
||||||
|
'citation' : 'Materials Algorithms Project Data Library: MAP_DATA_CREEP_RUPTURE. F. Brun and T. Yoshida.',
|
||||||
|
'details' : """Provides 2066 creep rupture test results of steels (mainly of two kinds of steels: 2.25Cr and 9-12 wt% Cr ferritic steels). See http://www.msm.cam.ac.uk/map/data/materials/creeprupt-b.html.""",
|
||||||
|
'license' : None,
|
||||||
|
'size' : 602797},
|
||||||
|
'della_gatta' : {'urls' : [neil_url + 'della_gatta/'],
|
||||||
|
'files': [['DellaGattadata.mat']],
|
||||||
|
'citation' : 'Direct targets of the TRP63 transcription factor revealed by a combination of gene expression profiling and reverse engineering. Giusy Della Gatta, Mukesh Bansal, Alberto Ambesi-Impiombato, Dario Antonini, Caterina Missero, and Diego di Bernardo, Genome Research 2008',
|
||||||
|
'details': "The full gene expression data set from della Gatta et al (http://www.ncbi.nlm.nih.gov/pmc/articles/PMC2413161/) processed by RMA.",
|
||||||
|
'license':None,
|
||||||
|
'size':3729650},
|
||||||
|
'epomeo_gpx' : {'urls' : [neil_url + 'epomeo_gpx/'],
|
||||||
|
'files': [['endomondo_1.gpx', 'endomondo_2.gpx', 'garmin_watch_via_endomondo.gpx','viewranger_phone.gpx','viewranger_tablet.gpx']],
|
||||||
|
'citation' : '',
|
||||||
|
'details': "Five different GPS traces of the same run up Mount Epomeo in Ischia. The traces are from different sources. endomondo_1 and endomondo_2 are traces from the mobile phone app Endomondo, with a split in the middle. garmin_watch_via_endomondo is the trace from a Garmin watch, with a segment missing about 4 kilometers in. viewranger_phone and viewranger_tablet are traces from a phone and a tablet through the viewranger app. The viewranger_phone data comes from the same mobile phone as the Endomondo data (i.e. there are 3 GPS devices, but one device recorded two traces).",
|
||||||
|
'license':None,
|
||||||
|
'size': 2031872},
|
||||||
|
'three_phase_oil_flow': {'urls' : [neil_url + 'three_phase_oil_flow/'],
|
||||||
|
'files' : [['DataTrnLbls.txt', 'DataTrn.txt', 'DataTst.txt', 'DataTstLbls.txt', 'DataVdn.txt', 'DataVdnLbls.txt']],
|
||||||
|
'citation' : 'Bishop, C. M. and G. D. James (1993). Analysis of multiphase flows using dual-energy gamma densitometry and neural networks. Nuclear Instruments and Methods in Physics Research A327, 580-593',
|
||||||
|
'details' : """The three phase oil data used initially for demonstrating the Generative Topographic mapping.""",
|
||||||
|
'license' : None,
|
||||||
|
'size' : 712796},
|
||||||
|
'rogers_girolami_data' : {'urls' : ['https://www.dropbox.com/sh/7p6tu1t29idgliq/_XqlH_3nt9/'],
|
||||||
|
'files' : [['firstcoursemldata.tar.gz']],
|
||||||
|
'suffices' : [['?dl=1']],
|
||||||
|
'citation' : 'A First Course in Machine Learning. Simon Rogers and Mark Girolami: Chapman & Hall/CRC, ISBN-13: 978-1439824146',
|
||||||
|
'details' : """Data from the textbook 'A First Course in Machine Learning'. Available from http://www.dcs.gla.ac.uk/~srogers/firstcourseml/.""",
|
||||||
|
'license' : None,
|
||||||
|
'size' : 21949154},
|
||||||
|
'olivetti_faces' : {'urls' : [neil_url + 'olivetti_faces/', sam_url],
|
||||||
|
'files' : [['att_faces.zip'], ['olivettifaces.mat']],
|
||||||
|
'citation' : 'Ferdinando Samaria and Andy Harter, Parameterisation of a Stochastic Model for Human Face Identification. Proceedings of 2nd IEEE Workshop on Applications of Computer Vision, Sarasota FL, December 1994',
|
||||||
|
'details' : """Olivetti Research Labs Face data base, acquired between December 1992 and December 1994 in the Olivetti Research Lab, Cambridge (which later became AT&T Laboratories, Cambridge). When using these images please give credit to AT&T Laboratories, Cambridge. """,
|
||||||
|
'license': None,
|
||||||
|
'size' : 8561331},
|
||||||
|
'olympic_marathon_men' : {'urls' : [neil_url + 'olympic_marathon_men/'],
|
||||||
|
'files' : [['olympicMarathonTimes.csv']],
|
||||||
|
'citation' : None,
|
||||||
|
'details' : """Olympic mens' marathon gold medal winning times from 1896 to 2012. Time given in pace (minutes per kilometer). Data is originally downloaded and collated from Wikipedia, we are not responsible for errors in the data""",
|
||||||
|
'license': None,
|
||||||
|
'size' : 584},
|
||||||
|
'osu_run1' : {'urls': ['http://accad.osu.edu/research/mocap/data/', neil_url + 'stick/'],
|
||||||
|
'files': [['run1TXT.ZIP'],['connections.txt']],
|
||||||
|
'details' : "Motion capture data of a stick man running from the Open Motion Data Project at Ohio State University.",
|
||||||
|
'citation' : 'The Open Motion Data Project by The Ohio State University Advanced Computing Center for the Arts and Design, http://accad.osu.edu/research/mocap/mocap_data.htm.',
|
||||||
|
'license' : 'Data is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License (http://creativecommons.org/licenses/by-nc-sa/3.0/).',
|
||||||
|
'size': 338103},
|
||||||
|
'osu_accad' : {'urls': ['http://accad.osu.edu/research/mocap/data/', neil_url + 'stick/'],
|
||||||
|
'files': [['swagger1TXT.ZIP','handspring1TXT.ZIP','quickwalkTXT.ZIP','run1TXT.ZIP','sprintTXT.ZIP','dogwalkTXT.ZIP','camper_04TXT.ZIP','dance_KB3_TXT.ZIP','per20_TXT.ZIP','perTWO07_TXT.ZIP','perTWO13_TXT.ZIP','perTWO14_TXT.ZIP','perTWO15_TXT.ZIP','perTWO16_TXT.ZIP'],['connections.txt']],
|
||||||
|
'details' : "Motion capture data of different motions from the Open Motion Data Project at Ohio State University.",
|
||||||
|
'citation' : 'The Open Motion Data Project by The Ohio State University Advanced Computing Center for the Arts and Design, http://accad.osu.edu/research/mocap/mocap_data.htm.',
|
||||||
|
'license' : 'Data is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License (http://creativecommons.org/licenses/by-nc-sa/3.0/).',
|
||||||
|
'size': 15922790},
|
||||||
|
'pumadyn-32nm' : {'urls' : ['ftp://ftp.cs.toronto.edu/pub/neuron/delve/data/tarfiles/pumadyn-family/'],
|
||||||
|
'files' : [['pumadyn-32nm.tar.gz']],
|
||||||
|
'details' : """Pumadyn non linear 32 input data set with moderate noise. See http://www.cs.utoronto.ca/~delve/data/pumadyn/desc.html for details.""",
|
||||||
|
'citation' : """Created by Zoubin Ghahramani using the Matlab Robotics Toolbox of Peter Corke. Corke, P. I. (1996). A Robotics Toolbox for MATLAB. IEEE Robotics and Automation Magazine, 3 (1): 24-32.""",
|
||||||
|
'license' : """Data is made available by the Delve system at the University of Toronto""",
|
||||||
|
'size' : 5861646},
|
||||||
|
'robot_wireless' : {'urls' : [neil_url + 'robot_wireless/'],
|
||||||
|
'files' : [['uw-floor.txt']],
|
||||||
|
'citation' : """WiFi-SLAM using Gaussian Process Latent Variable Models by Brian Ferris, Dieter Fox and Neil Lawrence in IJCAI'07 Proceedings pages 2480-2485. Data used in A Unifying Probabilistic Perspective for Spectral Dimensionality Reduction: Insights and New Models by Neil D. Lawrence, JMLR 13 pg 1609--1638, 2012.""",
|
||||||
|
'details' : """Data created by Brian Ferris and Dieter Fox. Consists of WiFi access point strengths taken during a circuit of the Paul Allen building at the University of Washington.""",
|
||||||
|
'license' : None,
|
||||||
|
'size' : 284390},
|
||||||
|
'swiss_roll' : {'urls' : ['http://isomap.stanford.edu/'],
|
||||||
|
'files' : [['swiss_roll_data.mat']],
|
||||||
|
'details' : """Swiss roll data made available by Tenenbaum, de Silva and Langford to demonstrate isomap, available from http://isomap.stanford.edu/datasets.html.""",
|
||||||
|
'citation' : 'A Global Geometric Framework for Nonlinear Dimensionality Reduction, J. B. Tenenbaum, V. de Silva and J. C. Langford, Science 290 (5500): 2319-2323, 22 December 2000',
|
||||||
|
'license' : None,
|
||||||
|
'size' : 800256},
|
||||||
|
'ripley_prnn_data' : {'urls' : ['http://www.stats.ox.ac.uk/pub/PRNN/'],
|
||||||
|
'files' : [['Cushings.dat', 'README', 'crabs.dat', 'fglass.dat', 'fglass.grp', 'pima.te', 'pima.tr', 'pima.tr2', 'synth.te', 'synth.tr', 'viruses.dat', 'virus3.dat']],
|
||||||
|
'details' : """Data sets from Brian Ripley's Pattern Recognition and Neural Networks""",
|
||||||
|
'citation': """Pattern Recognition and Neural Networks by B.D. Ripley (1996) Cambridge University Press ISBN 0 521 46986 7""",
|
||||||
|
'license' : None,
|
||||||
|
'size' : 93565},
|
||||||
|
'isomap_face_data' : {'urls' : [neil_url + 'isomap_face_data/'],
|
||||||
|
'files' : [['face_data.mat']],
|
||||||
|
'details' : """Face data made available by Tenenbaum, de Silva and Langford to demonstrate isomap, available from http://isomap.stanford.edu/datasets.html.""",
|
||||||
|
'citation' : 'A Global Geometric Framework for Nonlinear Dimensionality Reduction, J. B. Tenenbaum, V. de Silva and J. C. Langford, Science 290 (5500): 2319-2323, 22 December 2000',
|
||||||
|
'license' : None,
|
||||||
|
'size' : 24229368},
|
||||||
|
'xw_pen' : {'urls' : [neil_url + 'xw_pen/'],
|
||||||
|
'files' : [['xw_pen_15.csv']],
|
||||||
|
'details' : """Accelerometer pen data used for robust regression by Tipping and Lawrence.""",
|
||||||
|
'citation' : 'Michael E. Tipping and Neil D. Lawrence. Variational inference for Student-t models: Robust Bayesian interpolation and generalised component analysis. Neurocomputing, 69:123--141, 2005',
|
||||||
|
'license' : None,
|
||||||
|
'size' : 3410}
|
||||||
|
}
|
||||||
|
|
||||||
|
with open('data_resources.json', 'w') as file:
|
||||||
|
json.dump(data_resources, file)
|
||||||
|
|
@ -12,6 +12,7 @@ import ctypes
|
||||||
from ctypes import byref, c_char, c_int, c_double # TODO
|
from ctypes import byref, c_char, c_int, c_double # TODO
|
||||||
# import scipy.lib.lapack
|
# import scipy.lib.lapack
|
||||||
import scipy
|
import scipy
|
||||||
|
import warnings
|
||||||
|
|
||||||
if np.all(np.float64((scipy.__version__).split('.')[:2]) >= np.array([0, 12])):
|
if np.all(np.float64((scipy.__version__).split('.')[:2]) >= np.array([0, 12])):
|
||||||
import scipy.linalg.lapack as lapack
|
import scipy.linalg.lapack as lapack
|
||||||
|
|
@ -21,10 +22,13 @@ else:
|
||||||
try:
|
try:
|
||||||
_blaslib = ctypes.cdll.LoadLibrary(np.core._dotblas.__file__) # @UndefinedVariable
|
_blaslib = ctypes.cdll.LoadLibrary(np.core._dotblas.__file__) # @UndefinedVariable
|
||||||
_blas_available = True
|
_blas_available = True
|
||||||
assert hasattr('dsyrk_',_blaslib)
|
assert hasattr(_blaslib, 'dsyrk_')
|
||||||
assert hasattr('dsyr_',_blaslib)
|
assert hasattr(_blaslib, 'dsyr_')
|
||||||
except:
|
except AssertionError:
|
||||||
_blas_available = False
|
_blas_available = False
|
||||||
|
except AttributeError as e:
|
||||||
|
_blas_available = False
|
||||||
|
warnings.warn("warning: caught this exception:" + str(e))
|
||||||
|
|
||||||
def dtrtrs(A, B, lower=0, trans=0, unitdiag=0):
|
def dtrtrs(A, B, lower=0, trans=0, unitdiag=0):
|
||||||
"""
|
"""
|
||||||
|
|
@ -61,6 +65,14 @@ def dpotri(A, lower=0):
|
||||||
"""
|
"""
|
||||||
return lapack.dpotri(A, lower=lower)
|
return lapack.dpotri(A, lower=lower)
|
||||||
|
|
||||||
|
def pddet(A):
|
||||||
|
"""
|
||||||
|
Determinant of a positive definite matrix, only symmetric matricies though
|
||||||
|
"""
|
||||||
|
L = jitchol(A)
|
||||||
|
logdetA = 2*sum(np.log(np.diag(L)))
|
||||||
|
return logdetA
|
||||||
|
|
||||||
def trace_dot(a, b):
|
def trace_dot(a, b):
|
||||||
"""
|
"""
|
||||||
Efficiently compute the trace of the matrix product of a and b
|
Efficiently compute the trace of the matrix product of a and b
|
||||||
|
|
@ -325,6 +337,7 @@ def symmetrify(A, upper=False):
|
||||||
"""
|
"""
|
||||||
N, M = A.shape
|
N, M = A.shape
|
||||||
assert N == M
|
assert N == M
|
||||||
|
|
||||||
c_contig_code = """
|
c_contig_code = """
|
||||||
int iN;
|
int iN;
|
||||||
for (int i=1; i<N; i++){
|
for (int i=1; i<N; i++){
|
||||||
|
|
@ -343,6 +356,8 @@ def symmetrify(A, upper=False):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
N = int(N) # for safe type casting
|
||||||
if A.flags['C_CONTIGUOUS'] and upper:
|
if A.flags['C_CONTIGUOUS'] and upper:
|
||||||
weave.inline(f_contig_code, ['A', 'N'], extra_compile_args=['-O3'])
|
weave.inline(f_contig_code, ['A', 'N'], extra_compile_args=['-O3'])
|
||||||
elif A.flags['C_CONTIGUOUS'] and not upper:
|
elif A.flags['C_CONTIGUOUS'] and not upper:
|
||||||
|
|
@ -403,4 +418,3 @@ def backsub_both_sides(L, X, transpose='left'):
|
||||||
else:
|
else:
|
||||||
tmp, _ = lapack.dtrtrs(L, np.asfortranarray(X), lower=1, trans=0)
|
tmp, _ = lapack.dtrtrs(L, np.asfortranarray(X), lower=1, trans=0)
|
||||||
return lapack.dtrtrs(L, np.asfortranarray(tmp.T), lower=1, trans=0)[0].T
|
return lapack.dtrtrs(L, np.asfortranarray(tmp.T), lower=1, trans=0)[0].T
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,34 @@
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy import weave
|
from scipy import weave
|
||||||
|
from config import *
|
||||||
|
|
||||||
|
def chain_1(df_dg, dg_dx):
|
||||||
|
"""
|
||||||
|
Generic chaining function for first derivative
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d(f . g)}{dx} = \\frac{df}{dg} \\frac{dg}{dx}
|
||||||
|
"""
|
||||||
|
return df_dg * dg_dx
|
||||||
|
|
||||||
|
def chain_2(d2f_dg2, dg_dx, df_dg, d2g_dx2):
|
||||||
|
"""
|
||||||
|
Generic chaining function for second derivative
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{2}(f . g)}{dx^{2}} = \\frac{d^{2}f}{dg^{2}}(\\frac{dg}{dx})^{2} + \\frac{df}{dg}\\frac{d^{2}g}{dx^{2}}
|
||||||
|
"""
|
||||||
|
return d2f_dg2*(dg_dx**2) + df_dg*d2g_dx2
|
||||||
|
|
||||||
|
def chain_3(d3f_dg3, dg_dx, d2f_dg2, d2g_dx2, df_dg, d3g_dx3):
|
||||||
|
"""
|
||||||
|
Generic chaining function for third derivative
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\\frac{d^{3}(f . g)}{dx^{3}} = \\frac{d^{3}f}{dg^{3}}(\\frac{dg}{dx})^{3} + 3\\frac{d^{2}f}{dg^{2}}\\frac{dg}{dx}\\frac{d^{2}g}{dx^{2}} + \\frac{df}{dg}\\frac{d^{3}g}{dx^{3}}
|
||||||
|
"""
|
||||||
|
return d3f_dg3*(dg_dx**3) + 3*d2f_dg2*dg_dx*d2g_dx2 + df_dg*d3g_dx3
|
||||||
|
|
||||||
def opt_wrapper(m, **kwargs):
|
def opt_wrapper(m, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
@ -57,11 +85,18 @@ def kmm_init(X, m = 10):
|
||||||
return X[inducing]
|
return X[inducing]
|
||||||
|
|
||||||
def fast_array_equal(A, B):
|
def fast_array_equal(A, B):
|
||||||
|
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
pragma_string = '#pragma omp parallel for private(i, j)'
|
||||||
|
else:
|
||||||
|
pragma_string = ''
|
||||||
|
|
||||||
code2="""
|
code2="""
|
||||||
int i, j;
|
int i, j;
|
||||||
return_val = 1;
|
return_val = 1;
|
||||||
|
|
||||||
#pragma omp parallel for private(i, j)
|
%s
|
||||||
for(i=0;i<N;i++){
|
for(i=0;i<N;i++){
|
||||||
for(j=0;j<D;j++){
|
for(j=0;j<D;j++){
|
||||||
if(A(i, j) != B(i, j)){
|
if(A(i, j) != B(i, j)){
|
||||||
|
|
@ -70,13 +105,18 @@ def fast_array_equal(A, B):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""" % pragma_string
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
pragma_string = '#pragma omp parallel for private(i, j, z)'
|
||||||
|
else:
|
||||||
|
pragma_string = ''
|
||||||
|
|
||||||
code3="""
|
code3="""
|
||||||
int i, j, z;
|
int i, j, z;
|
||||||
return_val = 1;
|
return_val = 1;
|
||||||
|
|
||||||
#pragma omp parallel for private(i, j, z)
|
%s
|
||||||
for(i=0;i<N;i++){
|
for(i=0;i<N;i++){
|
||||||
for(j=0;j<D;j++){
|
for(j=0;j<D;j++){
|
||||||
for(z=0;z<Q;z++){
|
for(z=0;z<Q;z++){
|
||||||
|
|
@ -87,33 +127,46 @@ def fast_array_equal(A, B):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""" % pragma_string
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
pragma_string = '#include <omp.h>'
|
||||||
|
else:
|
||||||
|
pragma_string = ''
|
||||||
|
|
||||||
support_code = """
|
support_code = """
|
||||||
#include <omp.h>
|
%s
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
"""
|
""" % pragma_string
|
||||||
|
|
||||||
weave_options = {'headers' : ['<omp.h>'],
|
|
||||||
|
weave_options_openmp = {'headers' : ['<omp.h>'],
|
||||||
'extra_compile_args': ['-fopenmp -O3'],
|
'extra_compile_args': ['-fopenmp -O3'],
|
||||||
'extra_link_args' : ['-lgomp']}
|
'extra_link_args' : ['-lgomp'],
|
||||||
|
'libraries': ['gomp']}
|
||||||
|
weave_options_noopenmp = {'extra_compile_args': ['-O3']}
|
||||||
|
|
||||||
|
if config.getboolean('parallel', 'openmp'):
|
||||||
|
weave_options = weave_options_openmp
|
||||||
|
else:
|
||||||
|
weave_options = weave_options_noopenmp
|
||||||
|
|
||||||
value = False
|
value = False
|
||||||
|
|
||||||
|
|
||||||
if (A == None) and (B == None):
|
if (A == None) and (B == None):
|
||||||
return True
|
return True
|
||||||
elif ((A == None) and (B != None)) or ((A != None) and (B == None)):
|
elif ((A == None) and (B != None)) or ((A != None) and (B == None)):
|
||||||
return False
|
return False
|
||||||
elif A.shape == B.shape:
|
elif A.shape == B.shape:
|
||||||
if A.ndim == 2:
|
if A.ndim == 2:
|
||||||
N, D = A.shape
|
N, D = [int(i) for i in A.shape]
|
||||||
value = weave.inline(code2, support_code=support_code, libraries=['gomp'],
|
value = weave.inline(code2, support_code=support_code,
|
||||||
arg_names=['A', 'B', 'N', 'D'],
|
arg_names=['A', 'B', 'N', 'D'],
|
||||||
type_converters=weave.converters.blitz, **weave_options)
|
type_converters=weave.converters.blitz, **weave_options)
|
||||||
elif A.ndim == 3:
|
elif A.ndim == 3:
|
||||||
N, D, Q = A.shape
|
N, D, Q = [int(i) for i in A.shape]
|
||||||
value = weave.inline(code3, support_code=support_code, libraries=['gomp'],
|
value = weave.inline(code3, support_code=support_code,
|
||||||
arg_names=['A', 'B', 'N', 'D', 'Q'],
|
arg_names=['A', 'B', 'N', 'D', 'Q'],
|
||||||
type_converters=weave.converters.blitz, **weave_options)
|
type_converters=weave.converters.blitz, **weave_options)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -67,14 +67,14 @@ class tree:
|
||||||
for i in range(len(self.vertices)):
|
for i in range(len(self.vertices)):
|
||||||
if self.vertices[i].id == id:
|
if self.vertices[i].id == id:
|
||||||
return i
|
return i
|
||||||
raise Error, 'Reverse look up of id failed.'
|
raise ValueError('Reverse look up of id failed.')
|
||||||
|
|
||||||
def get_index_by_name(self, name):
|
def get_index_by_name(self, name):
|
||||||
"""Give the index associated with a given vertex name."""
|
"""Give the index associated with a given vertex name."""
|
||||||
for i in range(len(self.vertices)):
|
for i in range(len(self.vertices)):
|
||||||
if self.vertices[i].name == name:
|
if self.vertices[i].name == name:
|
||||||
return i
|
return i
|
||||||
raise Error, 'Reverse look up of name failed.'
|
raise ValueError('Reverse look up of name failed.')
|
||||||
|
|
||||||
def order_vertices(self):
|
def order_vertices(self):
|
||||||
"""Order vertices in the graph such that parents always have a lower index than children."""
|
"""Order vertices in the graph such that parents always have a lower index than children."""
|
||||||
|
|
@ -433,6 +433,8 @@ class acclaim_skeleton(skeleton):
|
||||||
lin = self.read_line(fid)
|
lin = self.read_line(fid)
|
||||||
while lin != ':DEGREES':
|
while lin != ':DEGREES':
|
||||||
lin = self.read_line(fid)
|
lin = self.read_line(fid)
|
||||||
|
if lin == '':
|
||||||
|
raise ValueError('Could not find :DEGREES in ' + fid.name)
|
||||||
|
|
||||||
counter = 0
|
counter = 0
|
||||||
lin = self.read_line(fid)
|
lin = self.read_line(fid)
|
||||||
|
|
@ -443,9 +445,9 @@ class acclaim_skeleton(skeleton):
|
||||||
if frame_no:
|
if frame_no:
|
||||||
counter += 1
|
counter += 1
|
||||||
if counter != frame_no:
|
if counter != frame_no:
|
||||||
raise Error, 'Unexpected frame number.'
|
raise ValueError('Unexpected frame number.')
|
||||||
else:
|
else:
|
||||||
raise Error, 'Single bone name ...'
|
raise ValueError('Single bone name ...')
|
||||||
else:
|
else:
|
||||||
ind = self.get_index_by_name(parts[0])
|
ind = self.get_index_by_name(parts[0])
|
||||||
bones[ind].append(np.array([float(channel) for channel in parts[1:]]))
|
bones[ind].append(np.array([float(channel) for channel in parts[1:]]))
|
||||||
|
|
@ -573,7 +575,7 @@ class acclaim_skeleton(skeleton):
|
||||||
return
|
return
|
||||||
lin = self.read_line(fid)
|
lin = self.read_line(fid)
|
||||||
else:
|
else:
|
||||||
raise Error, 'Unrecognised file format'
|
raise ValueError('Unrecognised file format')
|
||||||
self.finalize()
|
self.finalize()
|
||||||
|
|
||||||
def read_units(self, fid):
|
def read_units(self, fid):
|
||||||
|
|
|
||||||
331
GPy/util/netpbmfile.py
Normal file
331
GPy/util/netpbmfile.py
Normal file
|
|
@ -0,0 +1,331 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# netpbmfile.py
|
||||||
|
|
||||||
|
# Copyright (c) 2011-2013, Christoph Gohlke
|
||||||
|
# Copyright (c) 2011-2013, The Regents of the University of California
|
||||||
|
# Produced at the Laboratory for Fluorescence Dynamics.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of the copyright holders nor the names of any
|
||||||
|
# contributors may be used to endorse or promote products derived
|
||||||
|
# from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
"""Read and write image data from respectively to Netpbm files.
|
||||||
|
|
||||||
|
This implementation follows the Netpbm format specifications at
|
||||||
|
http://netpbm.sourceforge.net/doc/. No gamma correction is performed.
|
||||||
|
|
||||||
|
The following image formats are supported: PBM (bi-level), PGM (grayscale),
|
||||||
|
PPM (color), PAM (arbitrary), XV thumbnail (RGB332, read-only).
|
||||||
|
|
||||||
|
:Author:
|
||||||
|
`Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/>`_
|
||||||
|
|
||||||
|
:Organization:
|
||||||
|
Laboratory for Fluorescence Dynamics, University of California, Irvine
|
||||||
|
|
||||||
|
:Version: 2013.01.18
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
* `CPython 2.7, 3.2 or 3.3 <http://www.python.org>`_
|
||||||
|
* `Numpy 1.7 <http://www.numpy.org>`_
|
||||||
|
* `Matplotlib 1.2 <http://www.matplotlib.org>`_ (optional for plotting)
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
>>> im1 = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16)
|
||||||
|
>>> imsave('_tmp.pgm', im1)
|
||||||
|
>>> im2 = imread('_tmp.pgm')
|
||||||
|
>>> assert numpy.all(im1 == im2)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import division, print_function
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import math
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
import numpy
|
||||||
|
|
||||||
|
__version__ = '2013.01.18'
|
||||||
|
__docformat__ = 'restructuredtext en'
|
||||||
|
__all__ = ['imread', 'imsave', 'NetpbmFile']
|
||||||
|
|
||||||
|
|
||||||
|
def imread(filename, *args, **kwargs):
|
||||||
|
"""Return image data from Netpbm file as numpy array.
|
||||||
|
|
||||||
|
`args` and `kwargs` are arguments to NetpbmFile.asarray().
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
>>> image = imread('_tmp.pgm')
|
||||||
|
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
netpbm = NetpbmFile(filename)
|
||||||
|
image = netpbm.asarray()
|
||||||
|
finally:
|
||||||
|
netpbm.close()
|
||||||
|
return image
|
||||||
|
|
||||||
|
|
||||||
|
def imsave(filename, data, maxval=None, pam=False):
|
||||||
|
"""Write image data to Netpbm file.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
>>> image = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16)
|
||||||
|
>>> imsave('_tmp.pgm', image)
|
||||||
|
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
netpbm = NetpbmFile(data, maxval=maxval)
|
||||||
|
netpbm.write(filename, pam=pam)
|
||||||
|
finally:
|
||||||
|
netpbm.close()
|
||||||
|
|
||||||
|
|
||||||
|
class NetpbmFile(object):
|
||||||
|
"""Read and write Netpbm PAM, PBM, PGM, PPM, files."""
|
||||||
|
|
||||||
|
_types = {b'P1': b'BLACKANDWHITE', b'P2': b'GRAYSCALE', b'P3': b'RGB',
|
||||||
|
b'P4': b'BLACKANDWHITE', b'P5': b'GRAYSCALE', b'P6': b'RGB',
|
||||||
|
b'P7 332': b'RGB', b'P7': b'RGB_ALPHA'}
|
||||||
|
|
||||||
|
def __init__(self, arg=None, **kwargs):
|
||||||
|
"""Initialize instance from filename, open file, or numpy array."""
|
||||||
|
for attr in ('header', 'magicnum', 'width', 'height', 'maxval',
|
||||||
|
'depth', 'tupltypes', '_filename', '_fh', '_data'):
|
||||||
|
setattr(self, attr, None)
|
||||||
|
if arg is None:
|
||||||
|
self._fromdata([], **kwargs)
|
||||||
|
elif isinstance(arg, basestring):
|
||||||
|
self._fh = open(arg, 'rb')
|
||||||
|
self._filename = arg
|
||||||
|
self._fromfile(self._fh, **kwargs)
|
||||||
|
elif hasattr(arg, 'seek'):
|
||||||
|
self._fromfile(arg, **kwargs)
|
||||||
|
self._fh = arg
|
||||||
|
else:
|
||||||
|
self._fromdata(arg, **kwargs)
|
||||||
|
|
||||||
|
def asarray(self, copy=True, cache=False, **kwargs):
|
||||||
|
"""Return image data from file as numpy array."""
|
||||||
|
data = self._data
|
||||||
|
if data is None:
|
||||||
|
data = self._read_data(self._fh, **kwargs)
|
||||||
|
if cache:
|
||||||
|
self._data = data
|
||||||
|
else:
|
||||||
|
return data
|
||||||
|
return deepcopy(data) if copy else data
|
||||||
|
|
||||||
|
def write(self, arg, **kwargs):
|
||||||
|
"""Write instance to file."""
|
||||||
|
if hasattr(arg, 'seek'):
|
||||||
|
self._tofile(arg, **kwargs)
|
||||||
|
else:
|
||||||
|
with open(arg, 'wb') as fid:
|
||||||
|
self._tofile(fid, **kwargs)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""Close open file. Future asarray calls might fail."""
|
||||||
|
if self._filename and self._fh:
|
||||||
|
self._fh.close()
|
||||||
|
self._fh = None
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def _fromfile(self, fh):
|
||||||
|
"""Initialize instance from open file."""
|
||||||
|
fh.seek(0)
|
||||||
|
data = fh.read(4096)
|
||||||
|
if (len(data) < 7) or not (b'0' < data[1:2] < b'8'):
|
||||||
|
raise ValueError("Not a Netpbm file:\n%s" % data[:32])
|
||||||
|
try:
|
||||||
|
self._read_pam_header(data)
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
self._read_pnm_header(data)
|
||||||
|
except Exception:
|
||||||
|
raise ValueError("Not a Netpbm file:\n%s" % data[:32])
|
||||||
|
|
||||||
|
def _read_pam_header(self, data):
|
||||||
|
"""Read PAM header and initialize instance."""
|
||||||
|
regroups = re.search(
|
||||||
|
b"(^P7[\n\r]+(?:(?:[\n\r]+)|(?:#.*)|"
|
||||||
|
b"(HEIGHT\s+\d+)|(WIDTH\s+\d+)|(DEPTH\s+\d+)|(MAXVAL\s+\d+)|"
|
||||||
|
b"(?:TUPLTYPE\s+\w+))*ENDHDR\n)", data).groups()
|
||||||
|
self.header = regroups[0]
|
||||||
|
self.magicnum = b'P7'
|
||||||
|
for group in regroups[1:]:
|
||||||
|
key, value = group.split()
|
||||||
|
setattr(self, unicode(key).lower(), int(value))
|
||||||
|
matches = re.findall(b"(TUPLTYPE\s+\w+)", self.header)
|
||||||
|
self.tupltypes = [s.split(None, 1)[1] for s in matches]
|
||||||
|
|
||||||
|
def _read_pnm_header(self, data):
|
||||||
|
"""Read PNM header and initialize instance."""
|
||||||
|
bpm = data[1:2] in b"14"
|
||||||
|
regroups = re.search(b"".join((
|
||||||
|
b"(^(P[123456]|P7 332)\s+(?:#.*[\r\n])*",
|
||||||
|
b"\s*(\d+)\s+(?:#.*[\r\n])*",
|
||||||
|
b"\s*(\d+)\s+(?:#.*[\r\n])*" * (not bpm),
|
||||||
|
b"\s*(\d+)\s(?:\s*#.*[\r\n]\s)*)")), data).groups() + (1, ) * bpm
|
||||||
|
self.header = regroups[0]
|
||||||
|
self.magicnum = regroups[1]
|
||||||
|
self.width = int(regroups[2])
|
||||||
|
self.height = int(regroups[3])
|
||||||
|
self.maxval = int(regroups[4])
|
||||||
|
self.depth = 3 if self.magicnum in b"P3P6P7 332" else 1
|
||||||
|
self.tupltypes = [self._types[self.magicnum]]
|
||||||
|
|
||||||
|
def _read_data(self, fh, byteorder='>'):
|
||||||
|
"""Return image data from open file as numpy array."""
|
||||||
|
fh.seek(len(self.header))
|
||||||
|
data = fh.read()
|
||||||
|
dtype = 'u1' if self.maxval < 256 else byteorder + 'u2'
|
||||||
|
depth = 1 if self.magicnum == b"P7 332" else self.depth
|
||||||
|
shape = [-1, self.height, self.width, depth]
|
||||||
|
size = numpy.prod(shape[1:])
|
||||||
|
if self.magicnum in b"P1P2P3":
|
||||||
|
data = numpy.array(data.split(None, size)[:size], dtype)
|
||||||
|
data = data.reshape(shape)
|
||||||
|
elif self.maxval == 1:
|
||||||
|
shape[2] = int(math.ceil(self.width / 8))
|
||||||
|
data = numpy.frombuffer(data, dtype).reshape(shape)
|
||||||
|
data = numpy.unpackbits(data, axis=-2)[:, :, :self.width, :]
|
||||||
|
else:
|
||||||
|
data = numpy.frombuffer(data, dtype)
|
||||||
|
data = data[:size * (data.size // size)].reshape(shape)
|
||||||
|
if data.shape[0] < 2:
|
||||||
|
data = data.reshape(data.shape[1:])
|
||||||
|
if data.shape[-1] < 2:
|
||||||
|
data = data.reshape(data.shape[:-1])
|
||||||
|
if self.magicnum == b"P7 332":
|
||||||
|
rgb332 = numpy.array(list(numpy.ndindex(8, 8, 4)), numpy.uint8)
|
||||||
|
rgb332 *= [36, 36, 85]
|
||||||
|
data = numpy.take(rgb332, data, axis=0)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def _fromdata(self, data, maxval=None):
|
||||||
|
"""Initialize instance from numpy array."""
|
||||||
|
data = numpy.array(data, ndmin=2, copy=True)
|
||||||
|
if data.dtype.kind not in "uib":
|
||||||
|
raise ValueError("not an integer type: %s" % data.dtype)
|
||||||
|
if data.dtype.kind == 'i' and numpy.min(data) < 0:
|
||||||
|
raise ValueError("data out of range: %i" % numpy.min(data))
|
||||||
|
if maxval is None:
|
||||||
|
maxval = numpy.max(data)
|
||||||
|
maxval = 255 if maxval < 256 else 65535
|
||||||
|
if maxval < 0 or maxval > 65535:
|
||||||
|
raise ValueError("data out of range: %i" % maxval)
|
||||||
|
data = data.astype('u1' if maxval < 256 else '>u2')
|
||||||
|
self._data = data
|
||||||
|
if data.ndim > 2 and data.shape[-1] in (3, 4):
|
||||||
|
self.depth = data.shape[-1]
|
||||||
|
self.width = data.shape[-2]
|
||||||
|
self.height = data.shape[-3]
|
||||||
|
self.magicnum = b'P7' if self.depth == 4 else b'P6'
|
||||||
|
else:
|
||||||
|
self.depth = 1
|
||||||
|
self.width = data.shape[-1]
|
||||||
|
self.height = data.shape[-2]
|
||||||
|
self.magicnum = b'P5' if maxval > 1 else b'P4'
|
||||||
|
self.maxval = maxval
|
||||||
|
self.tupltypes = [self._types[self.magicnum]]
|
||||||
|
self.header = self._header()
|
||||||
|
|
||||||
|
def _tofile(self, fh, pam=False):
|
||||||
|
"""Write Netbm file."""
|
||||||
|
fh.seek(0)
|
||||||
|
fh.write(self._header(pam))
|
||||||
|
data = self.asarray(copy=False)
|
||||||
|
if self.maxval == 1:
|
||||||
|
data = numpy.packbits(data, axis=-1)
|
||||||
|
data.tofile(fh)
|
||||||
|
|
||||||
|
def _header(self, pam=False):
|
||||||
|
"""Return file header as byte string."""
|
||||||
|
if pam or self.magicnum == b'P7':
|
||||||
|
header = "\n".join((
|
||||||
|
"P7",
|
||||||
|
"HEIGHT %i" % self.height,
|
||||||
|
"WIDTH %i" % self.width,
|
||||||
|
"DEPTH %i" % self.depth,
|
||||||
|
"MAXVAL %i" % self.maxval,
|
||||||
|
"\n".join("TUPLTYPE %s" % unicode(i) for i in self.tupltypes),
|
||||||
|
"ENDHDR\n"))
|
||||||
|
elif self.maxval == 1:
|
||||||
|
header = "P4 %i %i\n" % (self.width, self.height)
|
||||||
|
elif self.depth == 1:
|
||||||
|
header = "P5 %i %i %i\n" % (self.width, self.height, self.maxval)
|
||||||
|
else:
|
||||||
|
header = "P6 %i %i %i\n" % (self.width, self.height, self.maxval)
|
||||||
|
if sys.version_info[0] > 2:
|
||||||
|
header = bytes(header, 'ascii')
|
||||||
|
return header
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return information about instance."""
|
||||||
|
return unicode(self.header)
|
||||||
|
|
||||||
|
|
||||||
|
if sys.version_info[0] > 2:
|
||||||
|
basestring = str
|
||||||
|
unicode = lambda x: str(x, 'ascii')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Show images specified on command line or all images in current directory
|
||||||
|
from glob import glob
|
||||||
|
from matplotlib import pyplot
|
||||||
|
files = sys.argv[1:] if len(sys.argv) > 1 else glob('*.p*m')
|
||||||
|
for fname in files:
|
||||||
|
try:
|
||||||
|
pam = NetpbmFile(fname)
|
||||||
|
img = pam.asarray(copy=False)
|
||||||
|
if False:
|
||||||
|
pam.write('_tmp.pgm.out', pam=True)
|
||||||
|
img2 = imread('_tmp.pgm.out')
|
||||||
|
assert numpy.all(img == img2)
|
||||||
|
imsave('_tmp.pgm.out', img)
|
||||||
|
img2 = imread('_tmp.pgm.out')
|
||||||
|
assert numpy.all(img == img2)
|
||||||
|
pam.close()
|
||||||
|
except ValueError as e:
|
||||||
|
print(fname, e)
|
||||||
|
continue
|
||||||
|
_shape = img.shape
|
||||||
|
if img.ndim > 3 or (img.ndim > 2 and img.shape[-1] not in (3, 4)):
|
||||||
|
img = img[0]
|
||||||
|
cmap = 'gray' if pam.maxval > 1 else 'binary'
|
||||||
|
pyplot.imshow(img, cmap, interpolation='nearest')
|
||||||
|
pyplot.title("%s %s %s %s" % (fname, unicode(pam.magicnum),
|
||||||
|
_shape, img.dtype))
|
||||||
|
pyplot.show()
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from sympy import Function, S, oo, I, cos, sin, asin, log, erf,pi,exp
|
from sympy import Function, S, oo, I, cos, sin, asin, log, erf, pi, exp, sqrt, sign
|
||||||
|
|
||||||
|
|
||||||
class ln_diff_erf(Function):
|
class ln_diff_erf(Function):
|
||||||
|
|
@ -10,7 +10,7 @@ class ln_diff_erf(Function):
|
||||||
return -2*exp(-x1**2)/(sqrt(pi)*(erf(x0)-erf(x1)))
|
return -2*exp(-x1**2)/(sqrt(pi)*(erf(x0)-erf(x1)))
|
||||||
elif argindex == 1:
|
elif argindex == 1:
|
||||||
x0, x1 = self.args
|
x0, x1 = self.args
|
||||||
return 2*exp(-x0**2)/(sqrt(pi)*(erf(x0)-erf(x1)))
|
return 2.*exp(-x0**2)/(sqrt(pi)*(erf(x0)-erf(x1)))
|
||||||
else:
|
else:
|
||||||
raise ArgumentIndexError(self, argindex)
|
raise ArgumentIndexError(self, argindex)
|
||||||
|
|
||||||
|
|
@ -19,12 +19,209 @@ class ln_diff_erf(Function):
|
||||||
if x0.is_Number and x1.is_Number:
|
if x0.is_Number and x1.is_Number:
|
||||||
return log(erf(x0)-erf(x1))
|
return log(erf(x0)-erf(x1))
|
||||||
|
|
||||||
class sim_h(Function):
|
class dh_dd_i(Function):
|
||||||
nargs = 5
|
nargs = 5
|
||||||
|
@classmethod
|
||||||
|
def eval(cls, t, tprime, d_i, d_j, l):
|
||||||
|
if (t.is_Number
|
||||||
|
and tprime.is_Number
|
||||||
|
and d_i.is_Number
|
||||||
|
and d_j.is_Number
|
||||||
|
and l.is_Number):
|
||||||
|
|
||||||
|
diff_t = (t-tprime)
|
||||||
|
l2 = l*l
|
||||||
|
h = h(t, tprime, d_i, d_j, l)
|
||||||
|
half_l_di = 0.5*l*d_i
|
||||||
|
arg_1 = half_l_di + tprime/l
|
||||||
|
arg_2 = half_l_di - (t-tprime)/l
|
||||||
|
ln_part_1 = ln_diff_erf(arg_1, arg_2)
|
||||||
|
arg_1 = half_l_di
|
||||||
|
arg_2 = half_l_di - t/l
|
||||||
|
sign_val = sign(t/l)
|
||||||
|
ln_part_2 = ln_diff_erf(half_l_di, half_l_di - t/l)
|
||||||
|
|
||||||
|
base = ((0.5*d_i*l2*(d_i+d_j)-1)*h
|
||||||
|
+ (-diff_t*sign_val*exp(half_l_di*half_l_di
|
||||||
|
-d_i*diff_t
|
||||||
|
+ln_part_1)
|
||||||
|
+t*sign_val*exp(half_l_di*half_l_di
|
||||||
|
-d_i*t-d_j*tprime
|
||||||
|
+ln_part_2))
|
||||||
|
+ l/sqrt(pi)*(-exp(-diff_t*diff_t/l2)
|
||||||
|
+exp(-tprime*tprime/l2-d_i*t)
|
||||||
|
+exp(-t*t/l2-d_j*tprime)
|
||||||
|
-exp(-(d_i*t + d_j*tprime))))
|
||||||
|
return base/(d_i+d_j)
|
||||||
|
|
||||||
|
class dh_dd_j(Function):
|
||||||
|
nargs = 5
|
||||||
|
@classmethod
|
||||||
|
def eval(cls, t, tprime, d_i, d_j, l):
|
||||||
|
if (t.is_Number
|
||||||
|
and tprime.is_Number
|
||||||
|
and d_i.is_Number
|
||||||
|
and d_j.is_Number
|
||||||
|
and l.is_Number):
|
||||||
|
diff_t = (t-tprime)
|
||||||
|
l2 = l*l
|
||||||
|
half_l_di = 0.5*l*d_i
|
||||||
|
h = h(t, tprime, d_i, d_j, l)
|
||||||
|
arg_1 = half_l_di + tprime/l
|
||||||
|
arg_2 = half_l_di - (t-tprime)/l
|
||||||
|
ln_part_1 = ln_diff_erf(arg_1, arg_2)
|
||||||
|
arg_1 = half_l_di
|
||||||
|
arg_2 = half_l_di - t/l
|
||||||
|
sign_val = sign(t/l)
|
||||||
|
ln_part_2 = ln_diff_erf(half_l_di, half_l_di - t/l)
|
||||||
|
sign_val = sign(t/l)
|
||||||
|
base = tprime*sign_val*exp(half_l_di*half_l_di-(d_i*t+d_j*tprime)+ln_part_2)-h
|
||||||
|
return base/(d_i+d_j)
|
||||||
|
|
||||||
|
class dh_dl(Function):
|
||||||
|
nargs = 5
|
||||||
|
@classmethod
|
||||||
|
def eval(cls, t, tprime, d_i, d_j, l):
|
||||||
|
if (t.is_Number
|
||||||
|
and tprime.is_Number
|
||||||
|
and d_i.is_Number
|
||||||
|
and d_j.is_Number
|
||||||
|
and l.is_Number):
|
||||||
|
|
||||||
|
diff_t = (t-tprime)
|
||||||
|
l2 = l*l
|
||||||
|
h = h(t, tprime, d_i, d_j, l)
|
||||||
|
return 0.5*d_i*d_i*l*h + 2./(sqrt(pi)*(d_i+d_j))*((-diff_t/l2-d_i/2.)*exp(-diff_t*diff_t/l2)+(-tprime/l2+d_i/2.)*exp(-tprime*tprime/l2-d_i*t)-(-t/l2-d_i/2.)*exp(-t*t/l2-d_j*tprime)-d_i/2.*exp(-(d_i*t+d_j*tprime)))
|
||||||
|
|
||||||
|
class dh_dt(Function):
|
||||||
|
nargs = 5
|
||||||
|
@classmethod
|
||||||
|
def eval(cls, t, tprime, d_i, d_j, l):
|
||||||
|
if (t.is_Number
|
||||||
|
and tprime.is_Number
|
||||||
|
and d_i.is_Number
|
||||||
|
and d_j.is_Number
|
||||||
|
and l.is_Number):
|
||||||
|
if (t is S.NaN
|
||||||
|
or tprime is S.NaN
|
||||||
|
or d_i is S.NaN
|
||||||
|
or d_j is S.NaN
|
||||||
|
or l is S.NaN):
|
||||||
|
return S.NaN
|
||||||
|
else:
|
||||||
|
half_l_di = 0.5*l*d_i
|
||||||
|
arg_1 = half_l_di + tprime/l
|
||||||
|
arg_2 = half_l_di - (t-tprime)/l
|
||||||
|
ln_part_1 = ln_diff_erf(arg_1, arg_2)
|
||||||
|
arg_1 = half_l_di
|
||||||
|
arg_2 = half_l_di - t/l
|
||||||
|
sign_val = sign(t/l)
|
||||||
|
ln_part_2 = ln_diff_erf(half_l_di, half_l_di - t/l)
|
||||||
|
|
||||||
|
|
||||||
|
return (sign_val*exp(half_l_di*half_l_di
|
||||||
|
- d_i*(t-tprime)
|
||||||
|
+ ln_part_1
|
||||||
|
- log(d_i + d_j))
|
||||||
|
- sign_val*exp(half_l_di*half_l_di
|
||||||
|
- d_i*t - d_j*tprime
|
||||||
|
+ ln_part_2
|
||||||
|
- log(d_i + d_j))).diff(t)
|
||||||
|
|
||||||
|
class dh_dtprime(Function):
|
||||||
|
nargs = 5
|
||||||
|
@classmethod
|
||||||
|
def eval(cls, t, tprime, d_i, d_j, l):
|
||||||
|
if (t.is_Number
|
||||||
|
and tprime.is_Number
|
||||||
|
and d_i.is_Number
|
||||||
|
and d_j.is_Number
|
||||||
|
and l.is_Number):
|
||||||
|
if (t is S.NaN
|
||||||
|
or tprime is S.NaN
|
||||||
|
or d_i is S.NaN
|
||||||
|
or d_j is S.NaN
|
||||||
|
or l is S.NaN):
|
||||||
|
return S.NaN
|
||||||
|
else:
|
||||||
|
half_l_di = 0.5*l*d_i
|
||||||
|
arg_1 = half_l_di + tprime/l
|
||||||
|
arg_2 = half_l_di - (t-tprime)/l
|
||||||
|
ln_part_1 = ln_diff_erf(arg_1, arg_2)
|
||||||
|
arg_1 = half_l_di
|
||||||
|
arg_2 = half_l_di - t/l
|
||||||
|
sign_val = sign(t/l)
|
||||||
|
ln_part_2 = ln_diff_erf(half_l_di, half_l_di - t/l)
|
||||||
|
|
||||||
|
|
||||||
|
return (sign_val*exp(half_l_di*half_l_di
|
||||||
|
- d_i*(t-tprime)
|
||||||
|
+ ln_part_1
|
||||||
|
- log(d_i + d_j))
|
||||||
|
- sign_val*exp(half_l_di*half_l_di
|
||||||
|
- d_i*t - d_j*tprime
|
||||||
|
+ ln_part_2
|
||||||
|
- log(d_i + d_j))).diff(tprime)
|
||||||
|
|
||||||
|
|
||||||
|
class h(Function):
|
||||||
|
nargs = 5
|
||||||
|
def fdiff(self, argindex=5):
|
||||||
|
t, tprime, d_i, d_j, l = self.args
|
||||||
|
if argindex == 1:
|
||||||
|
return dh_dt(t, tprime, d_i, d_j, l)
|
||||||
|
elif argindex == 2:
|
||||||
|
return dh_dtprime(t, tprime, d_i, d_j, l)
|
||||||
|
elif argindex == 3:
|
||||||
|
return dh_dd_i(t, tprime, d_i, d_j, l)
|
||||||
|
elif argindex == 4:
|
||||||
|
return dh_dd_j(t, tprime, d_i, d_j, l)
|
||||||
|
elif argindex == 5:
|
||||||
|
return dh_dl(t, tprime, d_i, d_j, l)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def eval(cls, t, tprime, d_i, d_j, l):
|
def eval(cls, t, tprime, d_i, d_j, l):
|
||||||
return exp((d_j/2*l)**2)/(d_i+d_j)*(exp(-d_j*(tprime - t))*(erf((tprime-t)/l - d_j/2*l) + erf(t/l + d_j/2*l)) - exp(-(d_j*tprime + d_i))*(erf(tprime/l - d_j/2*l) + erf(d_j/2*l)))
|
# putting in the is_Number stuff forces it to look for a fdiff method for derivative. If it's left out, then when asking for self.diff, it just does the diff on the eval symbolic terms directly. We want to avoid that because we are looking to ensure everything is numerically stable. Maybe it's because of the if statement that this happens?
|
||||||
|
if (t.is_Number
|
||||||
|
and tprime.is_Number
|
||||||
|
and d_i.is_Number
|
||||||
|
and d_j.is_Number
|
||||||
|
and l.is_Number):
|
||||||
|
if (t is S.NaN
|
||||||
|
or tprime is S.NaN
|
||||||
|
or d_i is S.NaN
|
||||||
|
or d_j is S.NaN
|
||||||
|
or l is S.NaN):
|
||||||
|
return S.NaN
|
||||||
|
else:
|
||||||
|
half_l_di = 0.5*l*d_i
|
||||||
|
arg_1 = half_l_di + tprime/l
|
||||||
|
arg_2 = half_l_di - (t-tprime)/l
|
||||||
|
ln_part_1 = ln_diff_erf(arg_1, arg_2)
|
||||||
|
arg_1 = half_l_di
|
||||||
|
arg_2 = half_l_di - t/l
|
||||||
|
sign_val = sign(t/l)
|
||||||
|
ln_part_2 = ln_diff_erf(half_l_di, half_l_di - t/l)
|
||||||
|
|
||||||
|
|
||||||
|
return (sign_val*exp(half_l_di*half_l_di
|
||||||
|
- d_i*(t-tprime)
|
||||||
|
+ ln_part_1
|
||||||
|
- log(d_i + d_j))
|
||||||
|
- sign_val*exp(half_l_di*half_l_di
|
||||||
|
- d_i*t - d_j*tprime
|
||||||
|
+ ln_part_2
|
||||||
|
- log(d_i + d_j)))
|
||||||
|
|
||||||
|
|
||||||
|
# return (exp((d_j/2.*l)**2)/(d_i+d_j)
|
||||||
|
# *(exp(-d_j*(tprime - t))
|
||||||
|
# *(erf((tprime-t)/l - d_j/2.*l)
|
||||||
|
# + erf(t/l + d_j/2.*l))
|
||||||
|
# - exp(-(d_j*tprime + d_i))
|
||||||
|
# *(erf(tprime/l - d_j/2.*l)
|
||||||
|
# + erf(d_j/2.*l))))
|
||||||
|
|
||||||
class erfc(Function):
|
class erfc(Function):
|
||||||
nargs = 1
|
nargs = 1
|
||||||
|
|
@ -40,52 +237,3 @@ class erfcx(Function):
|
||||||
def eval(cls, arg):
|
def eval(cls, arg):
|
||||||
return erfc(arg)*exp(arg*arg)
|
return erfc(arg)*exp(arg*arg)
|
||||||
|
|
||||||
class sinc_grad(Function):
|
|
||||||
nargs = 1
|
|
||||||
|
|
||||||
def fdiff(self, argindex=1):
|
|
||||||
if argindex==1:
|
|
||||||
# Strictly speaking this should be computed separately, as it won't work when x=0. See http://calculus.subwiki.org/wiki/Sinc_function
|
|
||||||
return ((2-x*x)*sin(self.args[0]) - 2*x*cos(x))/(x*x*x)
|
|
||||||
else:
|
|
||||||
raise ArgumentIndexError(self, argindex)
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def eval(cls, x):
|
|
||||||
if x.is_Number:
|
|
||||||
if x is S.NaN:
|
|
||||||
return S.NaN
|
|
||||||
elif x is S.Zero:
|
|
||||||
return S.Zero
|
|
||||||
else:
|
|
||||||
return (x*cos(x) - sin(x))/(x*x)
|
|
||||||
|
|
||||||
class sinc(Function):
|
|
||||||
|
|
||||||
nargs = 1
|
|
||||||
|
|
||||||
def fdiff(self, argindex=1):
|
|
||||||
if argindex==1:
|
|
||||||
return sinc_grad(self.args[0])
|
|
||||||
else:
|
|
||||||
raise ArgumentIndexError(self, argindex)
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def eval(cls, arg):
|
|
||||||
if arg.is_Number:
|
|
||||||
if arg is S.NaN:
|
|
||||||
return S.NaN
|
|
||||||
elif arg is S.Zero:
|
|
||||||
return S.One
|
|
||||||
else:
|
|
||||||
return sin(arg)/arg
|
|
||||||
|
|
||||||
if arg.func is asin:
|
|
||||||
x = arg.args[0]
|
|
||||||
return x / arg
|
|
||||||
|
|
||||||
def _eval_is_real(self):
|
|
||||||
return self.args[0].is_real
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,24 +13,32 @@ def std_norm_cdf(x):
|
||||||
Cumulative standard Gaussian distribution
|
Cumulative standard Gaussian distribution
|
||||||
Based on Abramowitz, M. and Stegun, I. (1970)
|
Based on Abramowitz, M. and Stegun, I. (1970)
|
||||||
"""
|
"""
|
||||||
|
#Generalize for many x
|
||||||
|
x = np.asarray(x).copy()
|
||||||
|
cdf_x = np.zeros_like(x)
|
||||||
|
N = x.size
|
||||||
support_code = "#include <math.h>"
|
support_code = "#include <math.h>"
|
||||||
code = """
|
code = """
|
||||||
|
|
||||||
double sign = 1.0;
|
double sign, t, erf;
|
||||||
if (x < 0.0){
|
for (int i=0; i<N; i++){
|
||||||
|
sign = 1.0;
|
||||||
|
if (x[i] < 0.0){
|
||||||
sign = -1.0;
|
sign = -1.0;
|
||||||
x = -x;
|
x[i] = -x[i];
|
||||||
}
|
}
|
||||||
x = x/sqrt(2.0);
|
x[i] = x[i]/sqrt(2.0);
|
||||||
|
|
||||||
double t = 1.0/(1.0 + 0.3275911*x);
|
t = 1.0/(1.0 + 0.3275911*x[i]);
|
||||||
|
|
||||||
double erf = 1. - exp(-x*x)*t*(0.254829592 + t*(-0.284496736 + t*(1.421413741 + t*(-1.453152027 + t*(1.061405429)))));
|
erf = 1. - exp(-x[i]*x[i])*t*(0.254829592 + t*(-0.284496736 + t*(1.421413741 + t*(-1.453152027 + t*(1.061405429)))));
|
||||||
|
|
||||||
return_val = 0.5*(1.0 + sign*erf);
|
//return_val = 0.5*(1.0 + sign*erf);
|
||||||
|
cdf_x[i] = 0.5*(1.0 + sign*erf);
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
x = float(x)
|
weave.inline(code, arg_names=['x', 'cdf_x', 'N'], support_code=support_code)
|
||||||
return weave.inline(code,arg_names=['x'],support_code=support_code)
|
return cdf_x
|
||||||
|
|
||||||
def inv_std_norm_cdf(x):
|
def inv_std_norm_cdf(x):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -246,17 +246,36 @@ class lvm_dimselect(lvm):
|
||||||
|
|
||||||
|
|
||||||
class image_show(matplotlib_show):
|
class image_show(matplotlib_show):
|
||||||
"""Show a data vector as an image."""
|
"""Show a data vector as an image. This visualizer rehapes the output vector and displays it as an image.
|
||||||
def __init__(self, vals, axes=None, dimensions=(16,16), transpose=False, invert=False, scale=False, palette=[], presetMean = 0., presetSTD = -1., selectImage=0):
|
|
||||||
|
:param vals: the values of the output to display.
|
||||||
|
:type vals: ndarray
|
||||||
|
:param axes: the axes to show the output on.
|
||||||
|
:type vals: axes handle
|
||||||
|
:param dimensions: the dimensions that the image needs to be transposed to for display.
|
||||||
|
:type dimensions: tuple
|
||||||
|
:param transpose: whether to transpose the image before display.
|
||||||
|
:type bool: default is False.
|
||||||
|
:param order: whether array is in Fortan ordering ('F') or Python ordering ('C'). Default is python ('C').
|
||||||
|
:type order: string
|
||||||
|
:param invert: whether to invert the pixels or not (default False).
|
||||||
|
:type invert: bool
|
||||||
|
:param palette: a palette to use for the image.
|
||||||
|
:param preset_mean: the preset mean of a scaled image.
|
||||||
|
:type preset_mean: double
|
||||||
|
:param preset_std: the preset standard deviation of a scaled image.
|
||||||
|
:type preset_std: double"""
|
||||||
|
def __init__(self, vals, axes=None, dimensions=(16,16), transpose=False, order='C', invert=False, scale=False, palette=[], preset_mean = 0., preset_std = -1., select_image=0):
|
||||||
matplotlib_show.__init__(self, vals, axes)
|
matplotlib_show.__init__(self, vals, axes)
|
||||||
self.dimensions = dimensions
|
self.dimensions = dimensions
|
||||||
self.transpose = transpose
|
self.transpose = transpose
|
||||||
|
self.order = order
|
||||||
self.invert = invert
|
self.invert = invert
|
||||||
self.scale = scale
|
self.scale = scale
|
||||||
self.palette = palette
|
self.palette = palette
|
||||||
self.presetMean = presetMean
|
self.preset_mean = preset_mean
|
||||||
self.presetSTD = presetSTD
|
self.preset_std = preset_std
|
||||||
self.selectImage = selectImage # This is used when the y vector contains multiple images concatenated.
|
self.select_image = select_image # This is used when the y vector contains multiple images concatenated.
|
||||||
|
|
||||||
self.set_image(self.vals)
|
self.set_image(self.vals)
|
||||||
if not self.palette == []: # Can just show the image (self.set_image() took care of setting the palette)
|
if not self.palette == []: # Can just show the image (self.set_image() took care of setting the palette)
|
||||||
|
|
@ -272,22 +291,22 @@ class image_show(matplotlib_show):
|
||||||
|
|
||||||
def set_image(self, vals):
|
def set_image(self, vals):
|
||||||
dim = self.dimensions[0] * self.dimensions[1]
|
dim = self.dimensions[0] * self.dimensions[1]
|
||||||
nImg = np.sqrt(vals[0,].size/dim)
|
num_images = np.sqrt(vals[0,].size/dim)
|
||||||
if nImg > 1 and nImg.is_integer(): # Show a mosaic of images
|
if num_images > 1 and num_images.is_integer(): # Show a mosaic of images
|
||||||
nImg = np.int(nImg)
|
num_images = np.int(num_images)
|
||||||
self.vals = np.zeros((self.dimensions[0]*nImg, self.dimensions[1]*nImg))
|
self.vals = np.zeros((self.dimensions[0]*num_images, self.dimensions[1]*num_images))
|
||||||
for iR in range(nImg):
|
for iR in range(num_images):
|
||||||
for iC in range(nImg):
|
for iC in range(num_images):
|
||||||
currImgId = iR*nImg + iC
|
cur_img_id = iR*num_images + iC
|
||||||
currImg = np.reshape(vals[0,dim*currImgId+np.array(range(dim))], self.dimensions, order='F')
|
cur_img = np.reshape(vals[0,dim*cur_img_id+np.array(range(dim))], self.dimensions, order=self.order)
|
||||||
firstRow = iR*self.dimensions[0]
|
first_row = iR*self.dimensions[0]
|
||||||
lastRow = (iR+1)*self.dimensions[0]
|
last_row = (iR+1)*self.dimensions[0]
|
||||||
firstCol = iC*self.dimensions[1]
|
first_col = iC*self.dimensions[1]
|
||||||
lastCol = (iC+1)*self.dimensions[1]
|
last_col = (iC+1)*self.dimensions[1]
|
||||||
self.vals[firstRow:lastRow, firstCol:lastCol] = currImg
|
self.vals[first_row:last_row, first_col:last_col] = cur_img
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.vals = np.reshape(vals[0,dim*self.selectImage+np.array(range(dim))], self.dimensions, order='F')
|
self.vals = np.reshape(vals[0,dim*self.select_image+np.array(range(dim))], self.dimensions, order=self.order)
|
||||||
if self.transpose:
|
if self.transpose:
|
||||||
self.vals = self.vals.T
|
self.vals = self.vals.T
|
||||||
# if not self.scale:
|
# if not self.scale:
|
||||||
|
|
@ -296,8 +315,8 @@ class image_show(matplotlib_show):
|
||||||
self.vals = -self.vals
|
self.vals = -self.vals
|
||||||
|
|
||||||
# un-normalizing, for visualisation purposes:
|
# un-normalizing, for visualisation purposes:
|
||||||
if self.presetSTD >= 0: # The Mean is assumed to be in the range (0,255)
|
if self.preset_std >= 0: # The Mean is assumed to be in the range (0,255)
|
||||||
self.vals = self.vals*self.presetSTD + self.presetMean
|
self.vals = self.vals*self.preset_std + self.preset_mean
|
||||||
# Clipping the values:
|
# Clipping the values:
|
||||||
self.vals[self.vals < 0] = 0
|
self.vals[self.vals < 0] = 0
|
||||||
self.vals[self.vals > 255] = 255
|
self.vals[self.vals > 255] = 255
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ class TanhWarpingFunction_d(WarpingFunction):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
mpsi = psi.coSpy()
|
mpsi = psi.copy()
|
||||||
d = psi[-1]
|
d = psi[-1]
|
||||||
mpsi = mpsi[:self.num_parameters-1].reshape(self.n_terms, 3)
|
mpsi = mpsi[:self.num_parameters-1].reshape(self.n_terms, 3)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,5 @@ include *.txt
|
||||||
recursive-include doc *.txt
|
recursive-include doc *.txt
|
||||||
include *.md
|
include *.md
|
||||||
recursive-include doc *.md
|
recursive-include doc *.md
|
||||||
|
include *.cfg
|
||||||
|
recursive-include doc *.cfg
|
||||||
|
|
|
||||||
38
README.md
38
README.md
|
|
@ -9,6 +9,44 @@ A Gaussian processes framework in Python.
|
||||||
|
|
||||||
Continuous integration status: 
|
Continuous integration status: 
|
||||||
|
|
||||||
|
Getting started
|
||||||
|
===============
|
||||||
|
Installing with pip
|
||||||
|
-------------------
|
||||||
|
The simplest way to install GPy is using pip. ubuntu users can do:
|
||||||
|
|
||||||
|
sudo apt-get install python-pip
|
||||||
|
pip install gpy
|
||||||
|
|
||||||
|
If you'd like to install from source, or want to contribute to the project (e.g. by sending pull requests via github), read on.
|
||||||
|
|
||||||
|
Ubuntu
|
||||||
|
------
|
||||||
|
For the most part, the developers are using ubuntu. To install the required packages:
|
||||||
|
|
||||||
|
sudo apt-get install python-numpy python-scipy python-matplotlib
|
||||||
|
|
||||||
|
clone this git repository and add it to your path:
|
||||||
|
|
||||||
|
git clone git@github.com:SheffieldML/GPy.git ~/SheffieldML
|
||||||
|
echo 'PYTHONPATH=$PYTHONPATH:~/SheffieldML' >> ~/.bashrc
|
||||||
|
|
||||||
|
|
||||||
|
Windows
|
||||||
|
-------
|
||||||
|
On windows, we recommend the . We've also had luck with . git clone or unzip the source to a suitable directory, and add an approptiate PYTHONPATH environment variable.
|
||||||
|
|
||||||
|
On windows 7 (and possibly earlier versions) there's a bug in scipy version 0.13 which tries to write very long filenames. Reverting to scipy 0.12 seems to do the trick:
|
||||||
|
|
||||||
|
conda install scipy=0.12
|
||||||
|
|
||||||
|
OSX
|
||||||
|
---
|
||||||
|
Everything appears to work out-of-the box using  on osx Mavericks. Download/clone GPy, and then add GPy to your PYTHONPATH
|
||||||
|
|
||||||
|
git clone git@github.com:SheffieldML/GPy.git ~/SheffieldML
|
||||||
|
echo 'PYTHONPATH=$PYTHONPATH:~/SheffieldML' >> ~/.profile
|
||||||
|
|
||||||
|
|
||||||
Compiling documentation:
|
Compiling documentation:
|
||||||
========================
|
========================
|
||||||
|
|
|
||||||
|
|
@ -1,102 +1,107 @@
|
||||||
GPy.core package
|
core Package
|
||||||
================
|
============
|
||||||
|
|
||||||
Submodules
|
:mod:`core` Package
|
||||||
----------
|
-------------------
|
||||||
|
|
||||||
GPy.core.domains module
|
.. automodule:: GPy.core
|
||||||
-----------------------
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
:mod:`domains` Module
|
||||||
|
---------------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.domains
|
.. automodule:: GPy.core.domains
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.core.fitc module
|
:mod:`fitc` Module
|
||||||
--------------------
|
------------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.fitc
|
.. automodule:: GPy.core.fitc
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.core.gp module
|
:mod:`gp` Module
|
||||||
------------------
|
----------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.gp
|
.. automodule:: GPy.core.gp
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.core.gp_base module
|
:mod:`gp_base` Module
|
||||||
-----------------------
|
---------------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.gp_base
|
.. automodule:: GPy.core.gp_base
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.core.mapping module
|
:mod:`mapping` Module
|
||||||
-----------------------
|
---------------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.mapping
|
.. automodule:: GPy.core.mapping
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.core.model module
|
:mod:`model` Module
|
||||||
---------------------
|
-------------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.model
|
.. automodule:: GPy.core.model
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.core.parameterized module
|
:mod:`parameterized` Module
|
||||||
-----------------------------
|
---------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.parameterized
|
.. automodule:: GPy.core.parameterized
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.core.priors module
|
:mod:`priors` Module
|
||||||
----------------------
|
--------------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.priors
|
.. automodule:: GPy.core.priors
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.core.sparse_gp module
|
:mod:`sparse_gp` Module
|
||||||
-------------------------
|
-----------------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.sparse_gp
|
.. automodule:: GPy.core.sparse_gp
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.core.svigp module
|
:mod:`svigp` Module
|
||||||
---------------------
|
-------------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.svigp
|
.. automodule:: GPy.core.svigp
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.core.transformations module
|
:mod:`transformations` Module
|
||||||
-------------------------------
|
-----------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.core.transformations
|
.. automodule:: GPy.core.transformations
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
:mod:`variational` Module
|
||||||
|
-------------------------
|
||||||
|
|
||||||
Module contents
|
.. automodule:: GPy.core.variational
|
||||||
---------------
|
|
||||||
|
|
||||||
.. automodule:: GPy.core
|
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,59 @@
|
||||||
GPy.examples package
|
examples Package
|
||||||
====================
|
================
|
||||||
|
|
||||||
Submodules
|
:mod:`examples` Package
|
||||||
----------
|
-----------------------
|
||||||
|
|
||||||
GPy.examples.classification module
|
.. automodule:: GPy.examples
|
||||||
----------------------------------
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
:mod:`classification` Module
|
||||||
|
----------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.examples.classification
|
.. automodule:: GPy.examples.classification
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.examples.dimensionality_reduction module
|
:mod:`dimensionality_reduction` Module
|
||||||
--------------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.examples.dimensionality_reduction
|
.. automodule:: GPy.examples.dimensionality_reduction
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.examples.regression module
|
:mod:`laplace_approximations` Module
|
||||||
------------------------------
|
------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: GPy.examples.laplace_approximations
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
:mod:`regression` Module
|
||||||
|
------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.examples.regression
|
.. automodule:: GPy.examples.regression
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.examples.stochastic module
|
:mod:`stochastic` Module
|
||||||
------------------------------
|
------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.examples.stochastic
|
.. automodule:: GPy.examples.stochastic
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.examples.tutorials module
|
:mod:`tutorials` Module
|
||||||
-----------------------------
|
-----------------------
|
||||||
|
|
||||||
.. automodule:: GPy.examples.tutorials
|
.. automodule:: GPy.examples.tutorials
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
|
||||||
Module contents
|
|
||||||
---------------
|
|
||||||
|
|
||||||
.. automodule:: GPy.examples
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,51 @@
|
||||||
GPy.inference package
|
inference Package
|
||||||
=====================
|
=================
|
||||||
|
|
||||||
Submodules
|
:mod:`conjugate_gradient_descent` Module
|
||||||
----------
|
----------------------------------------
|
||||||
|
|
||||||
GPy.inference.conjugate_gradient_descent module
|
|
||||||
-----------------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: GPy.inference.conjugate_gradient_descent
|
.. automodule:: GPy.inference.conjugate_gradient_descent
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.inference.gradient_descent_update_rules module
|
:mod:`gradient_descent_update_rules` Module
|
||||||
--------------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.inference.gradient_descent_update_rules
|
.. automodule:: GPy.inference.gradient_descent_update_rules
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.inference.optimization module
|
:mod:`optimization` Module
|
||||||
---------------------------------
|
--------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.inference.optimization
|
.. automodule:: GPy.inference.optimization
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.inference.samplers module
|
:mod:`samplers` Module
|
||||||
-----------------------------
|
----------------------
|
||||||
|
|
||||||
.. automodule:: GPy.inference.samplers
|
.. automodule:: GPy.inference.samplers
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.inference.scg module
|
:mod:`scg` Module
|
||||||
------------------------
|
-----------------
|
||||||
|
|
||||||
.. automodule:: GPy.inference.scg
|
.. automodule:: GPy.inference.scg
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.inference.sgd module
|
:mod:`sgd` Module
|
||||||
------------------------
|
-----------------
|
||||||
|
|
||||||
.. automodule:: GPy.inference.sgd
|
.. automodule:: GPy.inference.sgd
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
|
||||||
Module contents
|
|
||||||
---------------
|
|
||||||
|
|
||||||
.. automodule:: GPy.inference
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
|
||||||
|
|
@ -1,246 +1,275 @@
|
||||||
GPy.kern.parts package
|
parts Package
|
||||||
======================
|
=============
|
||||||
|
|
||||||
Submodules
|
:mod:`parts` Package
|
||||||
----------
|
--------------------
|
||||||
|
|
||||||
GPy.kern.parts.Brownian module
|
.. automodule:: GPy.kern.parts
|
||||||
------------------------------
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
:mod:`Brownian` Module
|
||||||
|
----------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.Brownian
|
.. automodule:: GPy.kern.parts.Brownian
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.Matern32 module
|
:mod:`Matern32` Module
|
||||||
------------------------------
|
----------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.Matern32
|
.. automodule:: GPy.kern.parts.Matern32
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.Matern52 module
|
:mod:`Matern52` Module
|
||||||
------------------------------
|
----------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.Matern52
|
.. automodule:: GPy.kern.parts.Matern52
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.bias module
|
:mod:`ODE_1` Module
|
||||||
--------------------------
|
-------------------
|
||||||
|
|
||||||
|
.. automodule:: GPy.kern.parts.ODE_1
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
:mod:`ODE_UY` Module
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. automodule:: GPy.kern.parts.ODE_UY
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
:mod:`bias` Module
|
||||||
|
------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.bias
|
.. automodule:: GPy.kern.parts.bias
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.coregionalize module
|
:mod:`coregionalize` Module
|
||||||
-----------------------------------
|
---------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.coregionalize
|
.. automodule:: GPy.kern.parts.coregionalize
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.exponential module
|
:mod:`eq_ode1` Module
|
||||||
---------------------------------
|
---------------------
|
||||||
|
|
||||||
|
.. automodule:: GPy.kern.parts.eq_ode1
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
:mod:`exponential` Module
|
||||||
|
-------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.exponential
|
.. automodule:: GPy.kern.parts.exponential
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.finite_dimensional module
|
:mod:`finite_dimensional` Module
|
||||||
----------------------------------------
|
--------------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.finite_dimensional
|
.. automodule:: GPy.kern.parts.finite_dimensional
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.fixed module
|
:mod:`fixed` Module
|
||||||
---------------------------
|
-------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.fixed
|
.. automodule:: GPy.kern.parts.fixed
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.gibbs module
|
:mod:`gibbs` Module
|
||||||
---------------------------
|
-------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.gibbs
|
.. automodule:: GPy.kern.parts.gibbs
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.hetero module
|
:mod:`hetero` Module
|
||||||
----------------------------
|
--------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.hetero
|
.. automodule:: GPy.kern.parts.hetero
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.hierarchical module
|
:mod:`hierarchical` Module
|
||||||
----------------------------------
|
--------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.hierarchical
|
.. automodule:: GPy.kern.parts.hierarchical
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.independent_outputs module
|
:mod:`independent_outputs` Module
|
||||||
-----------------------------------------
|
---------------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.independent_outputs
|
.. automodule:: GPy.kern.parts.independent_outputs
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.kernpart module
|
:mod:`kernpart` Module
|
||||||
------------------------------
|
----------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.kernpart
|
.. automodule:: GPy.kern.parts.kernpart
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.linear module
|
:mod:`linear` Module
|
||||||
----------------------------
|
--------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.linear
|
.. automodule:: GPy.kern.parts.linear
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.mlp module
|
:mod:`mlp` Module
|
||||||
-------------------------
|
-----------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.mlp
|
.. automodule:: GPy.kern.parts.mlp
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.periodic_Matern32 module
|
:mod:`periodic_Matern32` Module
|
||||||
---------------------------------------
|
-------------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.periodic_Matern32
|
.. automodule:: GPy.kern.parts.periodic_Matern32
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.periodic_Matern52 module
|
:mod:`periodic_Matern52` Module
|
||||||
---------------------------------------
|
-------------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.periodic_Matern52
|
.. automodule:: GPy.kern.parts.periodic_Matern52
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.periodic_exponential module
|
:mod:`periodic_exponential` Module
|
||||||
------------------------------------------
|
----------------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.periodic_exponential
|
.. automodule:: GPy.kern.parts.periodic_exponential
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.poly module
|
:mod:`poly` Module
|
||||||
--------------------------
|
------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.poly
|
.. automodule:: GPy.kern.parts.poly
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.prod module
|
:mod:`prod` Module
|
||||||
--------------------------
|
------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.prod
|
.. automodule:: GPy.kern.parts.prod
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.prod_orthogonal module
|
:mod:`prod_orthogonal` Module
|
||||||
-------------------------------------
|
-----------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.prod_orthogonal
|
.. automodule:: GPy.kern.parts.prod_orthogonal
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.rational_quadratic module
|
:mod:`rational_quadratic` Module
|
||||||
----------------------------------------
|
--------------------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.rational_quadratic
|
.. automodule:: GPy.kern.parts.rational_quadratic
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.rbf module
|
:mod:`rbf` Module
|
||||||
-------------------------
|
-----------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.rbf
|
.. automodule:: GPy.kern.parts.rbf
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.rbf_inv module
|
:mod:`rbf_inv` Module
|
||||||
-----------------------------
|
---------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.rbf_inv
|
.. automodule:: GPy.kern.parts.rbf_inv
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.rbfcos module
|
:mod:`rbfcos` Module
|
||||||
----------------------------
|
--------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.rbfcos
|
.. automodule:: GPy.kern.parts.rbfcos
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.spline module
|
:mod:`spline` Module
|
||||||
----------------------------
|
--------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.spline
|
.. automodule:: GPy.kern.parts.spline
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.symmetric module
|
:mod:`symmetric` Module
|
||||||
-------------------------------
|
-----------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.symmetric
|
.. automodule:: GPy.kern.parts.symmetric
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.sympykern module
|
:mod:`sympy_helpers` Module
|
||||||
-------------------------------
|
---------------------------
|
||||||
|
|
||||||
|
.. automodule:: GPy.kern.parts.sympy_helpers
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
:mod:`sympykern` Module
|
||||||
|
-----------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.sympykern
|
.. automodule:: GPy.kern.parts.sympykern
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
GPy.kern.parts.white module
|
:mod:`white` Module
|
||||||
---------------------------
|
-------------------
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts.white
|
.. automodule:: GPy.kern.parts.white
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
|
||||||
Module contents
|
|
||||||
---------------
|
|
||||||
|
|
||||||
.. automodule:: GPy.kern.parts
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue