mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-05-21 14:05:14 +02:00
active_dims as extra parameter for kernels, it tells which input dimensions to work on
This commit is contained in:
parent
328e0124c7
commit
efcce6d0af
12 changed files with 73 additions and 59 deletions
|
|
@ -9,7 +9,9 @@ from kern import CombinationKernel
|
|||
class Add(CombinationKernel):
|
||||
"""
|
||||
Add given list of kernels together.
|
||||
propagates gradients thorugh.
|
||||
propagates gradients through.
|
||||
|
||||
This kernel will take over the active dims of it's subkernels passed in.
|
||||
"""
|
||||
def __init__(self, subkerns, name='add'):
|
||||
super(Add, self).__init__(subkerns, name)
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ class Brownian(Kern):
|
|||
:param variance:
|
||||
:type variance: float
|
||||
"""
|
||||
def __init__(self, input_dim=1, variance=1., name='Brownian'):
|
||||
def __init__(self, input_dim=1, variance=1., active_dims=None, name='Brownian'):
|
||||
assert input_dim==1, "Brownian motion in 1D only"
|
||||
super(Brownian, self).__init__(input_dim, name)
|
||||
super(Brownian, self).__init__(input_dim, active_dims, name)
|
||||
|
||||
self.variance = Param('variance', variance, Logexp())
|
||||
self.add_parameters(self.variance)
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ class Coregionalize(Kern):
|
|||
|
||||
.. note: see coregionalization examples in GPy.examples.regression for some usage.
|
||||
"""
|
||||
def __init__(self, input_dim, output_dim, rank=1, W=None, kappa=None, name='coregion'):
|
||||
super(Coregionalize, self).__init__(input_dim, name=name)
|
||||
def __init__(self, input_dim, output_dim, rank=1, W=None, kappa=None, active_dims=None, name='coregion'):
|
||||
super(Coregionalize, self).__init__(input_dim, active_dims, name=name)
|
||||
self.output_dim = output_dim
|
||||
self.rank = rank
|
||||
if self.rank>output_dim:
|
||||
|
|
|
|||
|
|
@ -16,26 +16,24 @@ class Kern(Parameterized):
|
|||
__metaclass__ = KernCallsViaSlicerMeta
|
||||
#===========================================================================
|
||||
_debug=False
|
||||
def __init__(self, input_dim, name, *a, **kw):
|
||||
def __init__(self, input_dim, active_dims, name, *a, **kw):
|
||||
"""
|
||||
The base class for a kernel: a positive definite function
|
||||
which forms of a covariance function (kernel).
|
||||
|
||||
:param input_dim: the number of input dimensions to the function
|
||||
:type input_dim: int
|
||||
:param int input_dim: the number of input dimensions to the function
|
||||
:param array-like|slice active_dims: list of indices on which dimensions this kernel works on
|
||||
|
||||
Do not instantiate.
|
||||
"""
|
||||
super(Kern, self).__init__(name=name, *a, **kw)
|
||||
if isinstance(input_dim, int):
|
||||
self.active_dims = np.r_[0:input_dim]
|
||||
self.input_dim = input_dim
|
||||
else:
|
||||
self.active_dims = np.r_[input_dim]
|
||||
self.input_dim = len(self.active_dims)
|
||||
self.active_dims = active_dims or slice(0, input_dim)
|
||||
self.input_dim = input_dim
|
||||
assert isinstance(self.active_dims, (slice, list, tuple, np.ndarray)), 'active_dims needs to be an array-like or slice object over dimensions, {} given'.format(self.active_dims.__class__)
|
||||
assert self.active_dims.size == self.input_dim, "input_dim {} does not match len(active_dim) {}".format(self.input_dim, self.active_dims.size)
|
||||
self._sliced_X = 0
|
||||
|
||||
@Cache_this(limit=10)#, ignore_args = (0,))
|
||||
@Cache_this(limit=10)
|
||||
def _slice_X(self, X):
|
||||
return X[:, self.active_dims]
|
||||
|
||||
|
|
@ -69,9 +67,7 @@ class Kern(Parameterized):
|
|||
def update_gradients_full(self, dL_dK, X, X2):
|
||||
"""Set the gradients of all parameters when doing full (N) inference."""
|
||||
raise NotImplementedError
|
||||
def update_gradients_diag(self, dL_dKdiag, X):
|
||||
"""Set the gradients for all parameters for the derivative of the diagonal of the covariance w.r.t the kernel parameters."""
|
||||
raise NotImplementedError
|
||||
|
||||
def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior):
|
||||
"""
|
||||
Set the gradients of all parameters when doing inference with
|
||||
|
|
@ -193,13 +189,29 @@ class Kern(Parameterized):
|
|||
super(Kern, self)._setstate(state)
|
||||
|
||||
class CombinationKernel(Kern):
|
||||
def __init__(self, kernels, name):
|
||||
"""
|
||||
Abstract super class for combination kernels.
|
||||
A combination kernel combines (a list of) kernels and works on those.
|
||||
Examples are the HierarchicalKernel or Add and Prod kernels.
|
||||
"""
|
||||
def __init__(self, kernels, name, extra_dims=[]):
|
||||
"""
|
||||
Abstract super class for combination kernels.
|
||||
A combination kernel combines (a list of) kernels and works on those.
|
||||
Examples are the HierarchicalKernel or Add and Prod kernels.
|
||||
|
||||
:param list kernels: List of kernels to combine (can be only one element)
|
||||
:param str name: name of the combination kernel
|
||||
:param array-like|slice extra_dims: if needed extra dimensions for the combination kernel to work on
|
||||
"""
|
||||
assert all([isinstance(k, Kern) for k in kernels])
|
||||
import itertools
|
||||
# make sure the active dimensions of all underlying kernels are covered:
|
||||
ma = reduce(lambda a,b: max(a, max(b)), (x.active_dims for x in kernels), 0)
|
||||
ma = reduce(lambda a,b: max(a, b.stop if isinstance(b, slice) else max(b)), itertools.chain((x.active_dims for x in kernels), [extra_dims]), 0)
|
||||
input_dim = np.r_[0:ma+1]
|
||||
# initialize the kernel with the full input_dim
|
||||
super(CombinationKernel, self).__init__(input_dim, name)
|
||||
self.extra_dims = extra_dims
|
||||
self.add_parameters(*kernels)
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ class Linear(Kern):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, input_dim, variances=None, ARD=False, name='linear'):
|
||||
super(Linear, self).__init__(input_dim, name)
|
||||
def __init__(self, input_dim, variances=None, ARD=False, active_dims=None, name='linear'):
|
||||
super(Linear, self).__init__(input_dim, active_dims, name)
|
||||
self.ARD = ARD
|
||||
if not ARD:
|
||||
if variances is not None:
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ class MLP(Kern):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, input_dim, variance=1., weight_variance=1., bias_variance=100., name='mlp'):
|
||||
super(MLP, self).__init__(input_dim, name)
|
||||
def __init__(self, input_dim, variance=1., weight_variance=1., bias_variance=100., active_dims=None, name='mlp'):
|
||||
super(MLP, self).__init__(input_dim, active_dims, name)
|
||||
self.variance = Param('variance', variance, Logexp())
|
||||
self.weight_variance = Param('weight_variance', weight_variance, Logexp())
|
||||
self.bias_variance = Param('bias_variance', bias_variance, Logexp())
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from ...core.parameterization.param import Param
|
|||
from ...core.parameterization.transformations import Logexp
|
||||
|
||||
class Periodic(Kern):
|
||||
def __init__(self, input_dim, variance, lengthscale, period, n_freq, lower, upper, name):
|
||||
def __init__(self, input_dim, variance, lengthscale, period, n_freq, lower, upper, active_dims, name):
|
||||
"""
|
||||
:type input_dim: int
|
||||
:param variance: the variance of the Matern kernel
|
||||
|
|
@ -25,7 +25,7 @@ class Periodic(Kern):
|
|||
"""
|
||||
|
||||
assert input_dim==1, "Periodic kernels are only defined for input_dim=1"
|
||||
super(Periodic, self).__init__(input_dim, name)
|
||||
super(Periodic, self).__init__(input_dim, active_dims, name)
|
||||
self.input_dim = input_dim
|
||||
self.lower,self.upper = lower, upper
|
||||
self.n_freq = n_freq
|
||||
|
|
@ -77,8 +77,8 @@ class PeriodicExponential(Periodic):
|
|||
Only defined for input_dim=1.
|
||||
"""
|
||||
|
||||
def __init__(self, input_dim=1, variance=1., lengthscale=1., period=2.*np.pi, n_freq=10, lower=0., upper=4*np.pi, name='periodic_exponential'):
|
||||
super(PeriodicExponential, self).__init__(input_dim, variance, lengthscale, period, n_freq, lower, upper, name)
|
||||
def __init__(self, input_dim=1, variance=1., lengthscale=1., period=2.*np.pi, n_freq=10, lower=0., upper=4*np.pi, active_dims=None, name='periodic_exponential'):
|
||||
super(PeriodicExponential, self).__init__(input_dim, variance, lengthscale, period, n_freq, lower, upper, active_dims, name)
|
||||
|
||||
def parameters_changed(self):
|
||||
self.a = [1./self.lengthscale, 1.]
|
||||
|
|
@ -187,8 +187,8 @@ class PeriodicMatern32(Periodic):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, input_dim=1, variance=1., lengthscale=1., period=2.*np.pi, n_freq=10, lower=0., upper=4*np.pi, name='periodic_Matern32'):
|
||||
super(PeriodicMatern32, self).__init__(input_dim, variance, lengthscale, period, n_freq, lower, upper, name)
|
||||
def __init__(self, input_dim=1, variance=1., lengthscale=1., period=2.*np.pi, n_freq=10, lower=0., upper=4*np.pi, active_dims=None, name='periodic_Matern32'):
|
||||
super(PeriodicMatern32, self).__init__(input_dim, variance, lengthscale, period, n_freq, lower, upper, active_dims, name)
|
||||
def parameters_changed(self):
|
||||
self.a = [3./self.lengthscale**2, 2*np.sqrt(3)/self.lengthscale, 1.]
|
||||
self.b = [1,self.lengthscale**2/3]
|
||||
|
|
@ -300,8 +300,8 @@ class PeriodicMatern52(Periodic):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, input_dim=1, variance=1., lengthscale=1., period=2.*np.pi, n_freq=10, lower=0., upper=4*np.pi, name='periodic_Matern52'):
|
||||
super(PeriodicMatern52, self).__init__(input_dim, variance, lengthscale, period, n_freq, lower, upper, name)
|
||||
def __init__(self, input_dim=1, variance=1., lengthscale=1., period=2.*np.pi, n_freq=10, lower=0., upper=4*np.pi, active_dims=None, name='periodic_Matern52'):
|
||||
super(PeriodicMatern52, self).__init__(input_dim, variance, lengthscale, period, n_freq, lower, upper, active_dims, name)
|
||||
|
||||
def parameters_changed(self):
|
||||
self.a = [5*np.sqrt(5)/self.lengthscale**3, 15./self.lengthscale**2,3*np.sqrt(5)/self.lengthscale, 1.]
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ class RBF(Stationary):
|
|||
k(r) = \sigma^2 \exp \\bigg(- \\frac{1}{2} r^2 \\bigg)
|
||||
|
||||
"""
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, name='rbf'):
|
||||
super(RBF, self).__init__(input_dim, variance, lengthscale, ARD, name)
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='rbf'):
|
||||
super(RBF, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name)
|
||||
self.weave_options = {}
|
||||
|
||||
def K_of_r(self, r):
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ class SSRBF(Stationary):
|
|||
.. Note: this object implements both the ARD and 'spherical' version of the function
|
||||
"""
|
||||
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=True, name='SSRBF'):
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=True, active_dims=None, name='SSRBF'):
|
||||
assert ARD==True, "Not Implemented!"
|
||||
super(SSRBF, self).__init__(input_dim, variance, lengthscale, ARD, name)
|
||||
super(SSRBF, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name)
|
||||
|
||||
def K_of_r(self, r):
|
||||
return self.variance * np.exp(-0.5 * r**2)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from ...core.parameterization.transformations import Logexp
|
|||
import numpy as np
|
||||
|
||||
class Static(Kern):
|
||||
def __init__(self, input_dim, variance, name):
|
||||
def __init__(self, input_dim, variance, active_dims, name):
|
||||
super(Static, self).__init__(input_dim, name)
|
||||
self.variance = Param('variance', variance, Logexp())
|
||||
self.add_parameters(self.variance)
|
||||
|
|
@ -43,8 +43,8 @@ class Static(Kern):
|
|||
|
||||
|
||||
class White(Static):
|
||||
def __init__(self, input_dim, variance=1., name='white'):
|
||||
super(White, self).__init__(input_dim, variance, name)
|
||||
def __init__(self, input_dim, variance=1., active_dims=None, name='white'):
|
||||
super(White, self).__init__(input_dim, variance, active_dims, name)
|
||||
|
||||
def K(self, X, X2=None):
|
||||
if X2 is None:
|
||||
|
|
@ -66,8 +66,8 @@ class White(Static):
|
|||
|
||||
|
||||
class Bias(Static):
|
||||
def __init__(self, input_dim, variance=1., name='bias'):
|
||||
super(Bias, self).__init__(input_dim, variance, name)
|
||||
def __init__(self, input_dim, variance=1., active_dims=None, name='bias'):
|
||||
super(Bias, self).__init__(input_dim, variance, active_dims, name)
|
||||
|
||||
def K(self, X, X2=None):
|
||||
shape = (X.shape[0], X.shape[0] if X2 is None else X2.shape[0])
|
||||
|
|
@ -90,14 +90,14 @@ class Bias(Static):
|
|||
self.variance.gradient = dL_dpsi0.sum() + dL_dpsi1.sum() + 2.*self.variance*dL_dpsi2.sum()
|
||||
|
||||
class Fixed(Static):
|
||||
def __init__(self, input_dim, covariance_matrix, variance=1., name='fixed'):
|
||||
def __init__(self, input_dim, covariance_matrix, variance=1., active_dims=None, name='fixed'):
|
||||
"""
|
||||
:param input_dim: the number of input dimensions
|
||||
:type input_dim: int
|
||||
:param variance: the variance of the kernel
|
||||
:type variance: float
|
||||
"""
|
||||
super(Bias, self).__init__(input_dim, variance, name)
|
||||
super(Bias, self).__init__(input_dim, variance, active_dims, name)
|
||||
self.fixed_K = covariance_matrix
|
||||
def K(self, X, X2):
|
||||
return self.variance * self.fixed_K
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ class Stationary(Kern):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, input_dim, variance, lengthscale, ARD, name):
|
||||
super(Stationary, self).__init__(input_dim, name)
|
||||
def __init__(self, input_dim, variance, lengthscale, ARD, active_dims, name):
|
||||
super(Stationary, self).__init__(input_dim, active_dims, name)
|
||||
self.ARD = ARD
|
||||
if not ARD:
|
||||
if lengthscale is None:
|
||||
|
|
@ -186,8 +186,8 @@ class Stationary(Kern):
|
|||
return np.ones(self.input_dim)/self.lengthscale
|
||||
|
||||
class Exponential(Stationary):
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, name='Exponential'):
|
||||
super(Exponential, self).__init__(input_dim, variance, lengthscale, ARD, name)
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='Exponential'):
|
||||
super(Exponential, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name)
|
||||
|
||||
def K_of_r(self, r):
|
||||
return self.variance * np.exp(-0.5 * r)
|
||||
|
|
@ -205,8 +205,8 @@ class Matern32(Stationary):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, name='Mat32'):
|
||||
super(Matern32, self).__init__(input_dim, variance, lengthscale, ARD, name)
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='Mat32'):
|
||||
super(Matern32, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name)
|
||||
|
||||
def K_of_r(self, r):
|
||||
return self.variance * (1. + np.sqrt(3.) * r) * np.exp(-np.sqrt(3.) * r)
|
||||
|
|
@ -249,8 +249,8 @@ class Matern52(Stationary):
|
|||
|
||||
k(r) = \sigma^2 (1 + \sqrt{5} r + \\frac53 r^2) \exp(- \sqrt{5} r)
|
||||
"""
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, name='Mat52'):
|
||||
super(Matern52, self).__init__(input_dim, variance, lengthscale, ARD, name)
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='Mat52'):
|
||||
super(Matern52, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name)
|
||||
|
||||
def K_of_r(self, r):
|
||||
return self.variance*(1+np.sqrt(5.)*r+5./3*r**2)*np.exp(-np.sqrt(5.)*r)
|
||||
|
|
@ -291,8 +291,8 @@ class Matern52(Stationary):
|
|||
|
||||
|
||||
class ExpQuad(Stationary):
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, name='ExpQuad'):
|
||||
super(ExpQuad, self).__init__(input_dim, variance, lengthscale, ARD, name)
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='ExpQuad'):
|
||||
super(ExpQuad, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name)
|
||||
|
||||
def K_of_r(self, r):
|
||||
return self.variance * np.exp(-0.5 * r**2)
|
||||
|
|
@ -301,8 +301,8 @@ class ExpQuad(Stationary):
|
|||
return -r*self.K_of_r(r)
|
||||
|
||||
class Cosine(Stationary):
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, name='Cosine'):
|
||||
super(Cosine, self).__init__(input_dim, variance, lengthscale, ARD, name)
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='Cosine'):
|
||||
super(Cosine, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name)
|
||||
|
||||
def K_of_r(self, r):
|
||||
return self.variance * np.cos(r)
|
||||
|
|
@ -322,8 +322,8 @@ class RatQuad(Stationary):
|
|||
"""
|
||||
|
||||
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, power=2., ARD=False, name='ExpQuad'):
|
||||
super(RatQuad, self).__init__(input_dim, variance, lengthscale, ARD, name)
|
||||
def __init__(self, input_dim, variance=1., lengthscale=None, power=2., ARD=False, active_dims=None, name='ExpQuad'):
|
||||
super(RatQuad, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name)
|
||||
self.power = Param('power', power, Logexp())
|
||||
self.add_parameters(self.power)
|
||||
|
||||
|
|
|
|||
|
|
@ -26,13 +26,13 @@ class Sympykern(Kern):
|
|||
- to handle multiple inputs, call them x_1, z_1, etc
|
||||
- to handle multpile correlated outputs, you'll need to add parameters with an index, such as lengthscale_i and lengthscale_j.
|
||||
"""
|
||||
def __init__(self, input_dim, k=None, output_dim=1, name=None, param=None):
|
||||
def __init__(self, input_dim, k=None, output_dim=1, name=None, param=None, active_dims=None):
|
||||
|
||||
if name is None:
|
||||
name='sympykern'
|
||||
if k is None:
|
||||
raise ValueError, "You must provide an argument for the covariance function."
|
||||
super(Sympykern, self).__init__(input_dim, name)
|
||||
super(Sympykern, self).__init__(input_dim, active_dims, name)
|
||||
|
||||
self._sp_k = k
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue