[kernel] combination kernel and hierarchical independent gradient updates

This commit is contained in:
Max Zwiessele 2016-04-01 09:45:39 +01:00
parent 8ad14681ee
commit ff9a6f9c26
2 changed files with 17 additions and 11 deletions

View file

@ -56,7 +56,10 @@ class IndependentOutputs(CombinationKernel):
self.single_kern = False
self.kern = kernels
super(IndependentOutputs, self).__init__(kernels=kernels, extra_dims=[index_dim], name=name)
self.index_dim = index_dim
# 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
def K(self,X ,X2=None):
slices = index_to_slices(X[:,self.index_dim])
@ -103,13 +106,10 @@ class IndependentOutputs(CombinationKernel):
target = np.zeros(X.shape)
kerns = itertools.repeat(self.kern) if self.single_kern else self.kern
if X2 is None:
# TODO: make use of index_to_slices
# FIXME: Broken as X is already sliced out
# print("Warning, gradients_X may not be working, I believe X has already been sliced out by the slicer!")
values = np.unique(X[:,self.index_dim])
slices = [X[:,self.index_dim]==i for i in values]
[target.__setitem__(s, kern.gradients_X(dL_dK[s,s],X[s],None))
for kern, s in zip(kerns, slices)]
for kern, s in zip(kerns, slices):
target[s] += kern.gradients_X(dL_dK[s, :][:, s],X[s], None)
#slices = index_to_slices(X[:,self.index_dim])
#[[np.add(target[s], kern.gradients_X(dL_dK[s,s], X[s]), out=target[s])
# for s in slices_i] for kern, slices_i in zip(kerns, slices)]
@ -121,8 +121,8 @@ class IndependentOutputs(CombinationKernel):
values = np.unique(X[:,self.index_dim])
slices = [X[:,self.index_dim]==i for i in values]
slices2 = [X2[:,self.index_dim]==i for i in values]
[target.__setitem__(s, kern.gradients_X(dL_dK[s, :][:, s2],X[s],X2[s2]))
for kern, s, s2 in zip(kerns, slices, slices2)]
for kern, s, s2 in zip(kerns, slices, slices2):
target[s] += kern.gradients_X(dL_dK[s, :][:, s2],X[s],X2[s2])
# TODO: make work with index_to_slices
#slices = index_to_slices(X[:,self.index_dim])
#slices2 = index_to_slices(X2[:,self.index_dim])
@ -133,7 +133,9 @@ class IndependentOutputs(CombinationKernel):
slices = index_to_slices(X[:,self.index_dim])
kerns = itertools.repeat(self.kern) if self.single_kern else self.kern
target = np.zeros(X.shape)
[[target.__setitem__(s, kern.gradients_X_diag(dL_dKdiag[s],X[s])) for s in slices_i] for kern, slices_i in zip(kerns, slices)]
for kern, slices_i in zip(kerns, slices):
for s in slices_i:
target[s] += kern.gradients_X_diag(dL_dKdiag[s],X[s])
return target
def update_gradients_diag(self, dL_dKdiag, X):

View file

@ -402,7 +402,7 @@ class KernelTestsNonContinuous(unittest.TestCase):
np.testing.assert_array_equal(kern.active_dims, [-1,0,1,2])
np.testing.assert_array_equal(kern._all_dims_active, [0,1,2,-1])
@skip('Gradients for independend outputs with different X do not work correctly')
#@skip('Gradients for independend outputs with different X do not work correctly')
def testIndependendGradients(self):
k = GPy.kern.RBF(self.D, active_dims=range(self.D))
kern = GPy.kern.IndependentOutputs(k, -1, 'ind_single')
@ -418,7 +418,7 @@ class KernelTestsNonContinuous(unittest.TestCase):
np.testing.assert_array_equal(kern.active_dims, [-1,0,2])
np.testing.assert_array_equal(kern._all_dims_active, [0,1,2,-1])
@skip('Gradients for independend outputs with different X do not work correctly')
#@skip('Gradients for independend outputs with different X do not work correctly')
def test_Hierarchical_gradients(self):
k = [GPy.kern.RBF(2, active_dims=[0,2], name='rbf1'), GPy.kern.RBF(2, active_dims=[0,2], name='rbf2')]
kern = GPy.kern.IndependentOutputs(k, -1, name='ind_split')
@ -431,6 +431,10 @@ class KernelTestsNonContinuous(unittest.TestCase):
X2 = self.X2[self.X2[:,-1]!=2]
self.assertTrue(check_kernel_gradient_functions(kern, X=X, X2=X2, verbose=verbose, fixed_X_dims=-1))
def test_Coregionalize(self):
kern = GPy.kern.Coregionalize(1, output_dim=3, active_dims=[-1])
self.assertTrue(check_kernel_gradient_functions(kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1))
@unittest.skipIf(not config.getboolean('cython', 'working'),"Cython modules have not been built on this machine")
class Coregionalize_cython_test(unittest.TestCase):
"""