mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-05-18 13:55:14 +02:00
Added Multioutput derivative kernel for adding derivatives easy and changed it to default kernel in multioutput gp model
This commit is contained in:
parent
0daad96da1
commit
9a6e645bc6
3 changed files with 84 additions and 3 deletions
|
|
@ -44,4 +44,5 @@ from .src.sde_static import sde_White, sde_Bias
|
||||||
from .src.sde_stationary import sde_RBF,sde_Exponential,sde_RatQuad
|
from .src.sde_stationary import sde_RBF,sde_Exponential,sde_RatQuad
|
||||||
from .src.sde_brownian import sde_Brownian
|
from .src.sde_brownian import sde_Brownian
|
||||||
from .src.multioutput_kern import MultioutputKern
|
from .src.multioutput_kern import MultioutputKern
|
||||||
|
from .src.multioutput_derivative_kern import MultioutputDerivativeKern
|
||||||
from .src.diff_kern import DiffKern
|
from .src.diff_kern import DiffKern
|
||||||
81
GPy/kern/src/multioutput_derivative_kern.py
Normal file
81
GPy/kern/src/multioutput_derivative_kern.py
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
from .kern import Kern, CombinationKernel
|
||||||
|
from .multioutput_kern import MultioutputKern, ZeroKern
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
class KernWrapper(Kern):
|
||||||
|
def __init__(self, fk, fug, fg, base_kern):
|
||||||
|
self.fk = fk
|
||||||
|
self.fug = fug
|
||||||
|
self.fg = fg
|
||||||
|
self.base_kern
|
||||||
|
super(KernWrapper, self).__init__(1, None, name='KernWrapper',useGPU=False)
|
||||||
|
|
||||||
|
def K(self, X, X2=None):
|
||||||
|
return self.fk(X,X2=X2)
|
||||||
|
|
||||||
|
def update_gradients_full(self,dL_dK, X, X2=None):
|
||||||
|
return self.fug(dK_dK, X, X2=X2)
|
||||||
|
|
||||||
|
def gradients_X(self,dL_dK, X, X2=None):
|
||||||
|
return self.fg(dL_dK, X, X2=X2)
|
||||||
|
|
||||||
|
def get_gradient(self):
|
||||||
|
return self.base_kern.gradient.copy()
|
||||||
|
|
||||||
|
def append_gradient(self, gradient):
|
||||||
|
self.base_kern.gradient += gradient
|
||||||
|
|
||||||
|
class MultioutputDerivativeKern(MultioutputKern):
|
||||||
|
"""
|
||||||
|
Multioutput derivative kernel is a meta class for combining different kernels for multioutput GPs.
|
||||||
|
Multioutput derivative kernel is only a thin wrapper for Multioutput kernel for user not having to define
|
||||||
|
cross covariances.
|
||||||
|
"""
|
||||||
|
def __init__(self, kernels, cross_covariances={}, name='MultioutputDerivativeKern'):
|
||||||
|
#kernels contains a list of kernels as input,
|
||||||
|
if not isinstance(kernels, list):
|
||||||
|
self.single_kern = True
|
||||||
|
self.kern = kernels
|
||||||
|
kernels = [kernels]
|
||||||
|
else:
|
||||||
|
self.single_kern = False
|
||||||
|
self.kern = kernels
|
||||||
|
# The combination kernel ALLWAYS puts the extra dimension last.
|
||||||
|
# Thus, the index dimension of this kernel is always the last dimension
|
||||||
|
# after slicing. This is why the index_dim is just the last column:
|
||||||
|
self.index_dim = -1
|
||||||
|
super(MultioutputKern, self).__init__(kernels=kernels, extra_dims=[self.index_dim], name=name, link_parameters=False)
|
||||||
|
|
||||||
|
nl = len(kernels)
|
||||||
|
|
||||||
|
#build covariance structure
|
||||||
|
covariance = [[None for i in range(nl)] for j in range(nl)]
|
||||||
|
linked = []
|
||||||
|
for i in range(0,nl):
|
||||||
|
unique=True
|
||||||
|
for j in range(0,nl):
|
||||||
|
if i==j or (kernels[i] is kernels[j]):
|
||||||
|
covariance[i][j] = {'kern': kernels[i],'K':kernels[i].K, 'update_gradients_full': kernels[i].update_gradients_full, 'gradients_X': kernels[i].gradients_X}
|
||||||
|
if i>j:
|
||||||
|
unique=False
|
||||||
|
elif cross_covariances.get((i,j)) is not None: #cross covariance is given
|
||||||
|
covariance[i][j] = cross_covariances.get((i,j))
|
||||||
|
elif kernels[i].name == 'diffKern' and kernels[i].base_kern == kernels[j]: # one is derivative of other
|
||||||
|
kern = KernWrapper(kernels[i].dK_dX_wrap,kernels[i].update_gradients_dK_dX,kernels[i].gradients_X, kernels[j])
|
||||||
|
covariance[i][j] = {'kern':kern, 'K': kern.K, 'update_gradients_full': kern.update_gradients_full, 'gradients_X': kern.gradients_X}
|
||||||
|
unique=False
|
||||||
|
elif kernels[j].name == 'diffKern' and kernels[j].base_kern == kernels[i]: # one is derivative of other
|
||||||
|
kern = KernWrapper(kernels[j].dK_dX2_wrap,kernels[j].update_gradients_dK_dX2,kernels[j].gradients_X2, kernels[i])
|
||||||
|
covariance[i][j] = {'kern':kern, 'K': kern.K, 'update_gradients_full': kern.update_gradients_full, 'gradients_X': kern.gradients_X}
|
||||||
|
elif kernels[i].name == 'diffKern' and kernels[j].name == 'diffKern' and kernels[i].base_kern == kernels[j].base_kern: #both are partial derivatives
|
||||||
|
kern = KernWrapper(partial(kernels[i].K, dimX2=kernels[j].dimension), partial(kernels[i].update_gradients_full, dimX2=kernels[j].dimension),None, kernels[i].base_kern)
|
||||||
|
covariance[i][j] = {'kern':kern, 'K': kern.K, 'update_gradients_full': kern.update_gradients_full, 'gradients_X': kern.gradients_X}
|
||||||
|
if i>j:
|
||||||
|
unique=False
|
||||||
|
else:
|
||||||
|
kern = ZeroKern()
|
||||||
|
covariance[i][j] = {'kern': kern, 'K': kern.K, 'update_gradients_full': kern.update_gradients_full, 'gradients_X': kern.gradients_X}
|
||||||
|
if unique is True:
|
||||||
|
linked.append(i)
|
||||||
|
self.covariance = covariance
|
||||||
|
self.link_parameters(*[kernels[i] for i in linked])
|
||||||
|
|
@ -42,7 +42,7 @@ class MultioutputGP(GP):
|
||||||
Ny = len(Y_list)
|
Ny = len(Y_list)
|
||||||
|
|
||||||
assert isinstance(kernel_list, list)
|
assert isinstance(kernel_list, list)
|
||||||
kernel = kern.MultioutputKern(kernels=kernel_list, cross_covariances=kernel_cross_covariances)
|
kernel = kern.MultioutputDerivativeKern(kernels=kernel_list, cross_covariances=kernel_cross_covariances)
|
||||||
|
|
||||||
assert isinstance(likelihood_list, list)
|
assert isinstance(likelihood_list, list)
|
||||||
likelihood = likelihoods.MultioutputLikelihood(likelihood_list)
|
likelihood = likelihoods.MultioutputLikelihood(likelihood_list)
|
||||||
|
|
@ -53,8 +53,7 @@ class MultioutputGP(GP):
|
||||||
else:
|
else:
|
||||||
inference_method = expectation_propagation.EP()
|
inference_method = expectation_propagation.EP()
|
||||||
|
|
||||||
super(MultioutputGP, self).__init__(X,Y,kernel,likelihood, Y_metadata={'output_index':self.output_index, 'trials':np.ones(self.output_index.shape)}, inference_method = inference_method)# expectation_propagation.MultioutputEP()) # expectation_propagation.EP())
|
super(MultioutputGP, self).__init__(X,Y,kernel,likelihood, Y_metadata={'output_index':self.output_index, 'trials':np.ones(self.output_index.shape)}, inference_method = inference_method)
|
||||||
#expectation_propagation.MultioutputEP())
|
|
||||||
|
|
||||||
def predict_noiseless(self, Xnew, full_cov=False, Y_metadata=None, kern=None):
|
def predict_noiseless(self, Xnew, full_cov=False, Y_metadata=None, kern=None):
|
||||||
if isinstance(Xnew, list):
|
if isinstance(Xnew, list):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue