DiffGenomeKern bug fix

This commit is contained in:
Zhenwen Dai 2014-05-29 17:10:14 +01:00
parent ea1326c8c8
commit 4c538efb64

View file

@ -6,6 +6,7 @@ import numpy as np
from kern import Kern,CombinationKernel from kern import Kern,CombinationKernel
from .independent_outputs import index_to_slices from .independent_outputs import index_to_slices
import itertools import itertools
from .rbf import RBF
class DiffGenomeKern(Kern): class DiffGenomeKern(Kern):
@ -13,6 +14,7 @@ class DiffGenomeKern(Kern):
self.idx_p = idx_p self.idx_p = idx_p
self.index_dim=index_dim self.index_dim=index_dim
self.kern = SplitKern(kernel,Xp, index_dim=index_dim) self.kern = SplitKern(kernel,Xp, index_dim=index_dim)
# self.kern = RBF(1)
super(DiffGenomeKern, self).__init__(input_dim=kernel.input_dim+1, active_dims=None, name=name) super(DiffGenomeKern, self).__init__(input_dim=kernel.input_dim+1, active_dims=None, name=name)
self.add_parameter(self.kern) self.add_parameter(self.kern)
@ -46,22 +48,24 @@ class DiffGenomeKern(Kern):
idx_start = slices[1][0].start idx_start = slices[1][0].start
idx_end = idx_start+self.idx_p idx_end = idx_start+self.idx_p
self.kern.update_gradients_full(dL_dK, X[:self.idx_p],X) self.kern.update_gradients_full(dL_dK[idx_start:idx_end,:], X[:self.idx_p],X)
grad_p1 = self.kern.gradient.copy() grad_p1 = self.kern.gradient.copy()
self.kern.update_gradients_full(dL_dK, X, X[:self.idx_p]) self.kern.update_gradients_full(dL_dK[:,idx_start:idx_end], X, X[:self.idx_p])
grad_p2 = self.kern.gradient.copy() grad_p2 = self.kern.gradient.copy()
self.kern.update_gradients_full(dL_dK, X[:self.idx_p], X[:self.idx_p]) self.kern.update_gradients_full(dL_dK[idx_start:idx_end,idx_start:idx_end], X[:self.idx_p],X[idx_start:idx_end])
grad_p3 = self.kern.gradient.copy() grad_p3 = self.kern.gradient.copy()
self.kern.update_gradients_full(dL_dK[idx_start:idx_end,idx_start:idx_end], X[idx_start:idx_end], X[:self.idx_p])
grad_p4 = self.kern.gradient.copy()
self.kern.update_gradients_full(dL_dK, X[idx_start:idx_end],X) self.kern.update_gradients_full(dL_dK[idx_start:idx_end,:], X[idx_start:idx_end],X)
grad_n1 = self.kern.gradient.copy() grad_n1 = self.kern.gradient.copy()
self.kern.update_gradients_full(dL_dK, X, X[idx_start:idx_end]) self.kern.update_gradients_full(dL_dK[:,idx_start:idx_end], X, X[idx_start:idx_end])
grad_n2 = self.kern.gradient.copy() grad_n2 = self.kern.gradient.copy()
self.kern.update_gradients_full(dL_dK, X[idx_start:idx_end], X[idx_start:idx_end]) self.kern.update_gradients_full(dL_dK[idx_start:idx_end,idx_start:idx_end], X[idx_start:idx_end], X[idx_start:idx_end])
grad_n3 = self.kern.gradient.copy() grad_n3 = self.kern.gradient.copy()
self.kern.update_gradients_full(dL_dK, X) self.kern.update_gradients_full(dL_dK, X)
self.kern.gradient += grad_p1+grad_p2-2*grad_p3-grad_n1-grad_n2+2*grad_n3 self.kern.gradient += grad_p1+grad_p2-grad_p3-grad_p4-grad_n1-grad_n2+2*grad_n3
def update_gradients_diag(self, dL_dKdiag, X): def update_gradients_diag(self, dL_dKdiag, X):
pass pass
@ -92,7 +96,7 @@ class SplitKern(CombinationKernel):
assert len(slices2)<=2, 'The Split kernel only support two different indices' assert len(slices2)<=2, 'The Split kernel only support two different indices'
target = np.zeros((X.shape[0], X2.shape[0])) target = np.zeros((X.shape[0], X2.shape[0]))
# diagonal blocks # diagonal blocks
[[target.__setitem__((s,s2), self.kern.K(X[s,:],X2[s2,:])) for s,s2 in itertools.product(slices[i], slices2[i])] for i in xrange(min(len(slices),len(slices)))] [[target.__setitem__((s,s2), self.kern.K(X[s,:],X2[s2,:])) for s,s2 in itertools.product(slices[i], slices2[i])] for i in xrange(min(len(slices),len(slices2)))]
if len(slices)>1: if len(slices)>1:
[target.__setitem__((s,s2), self.kern_cross.K(X[s,:],X2[s2,:])) for s,s2 in itertools.product(slices[1], slices2[0])] [target.__setitem__((s,s2), self.kern_cross.K(X[s,:],X2[s2,:])) for s,s2 in itertools.product(slices[1], slices2[0])]
if len(slices2)>1: if len(slices2)>1:
@ -115,17 +119,19 @@ class SplitKern(CombinationKernel):
target[:] += self.kern.gradient target[:] += self.kern.gradient
if X2 is None: if X2 is None:
assert dL_dK.shape==(X.shape[0],X.shape[0])
[[collate_grads(dL_dK[s,ss], X[s], X[ss]) for s,ss in itertools.product(slices_i, slices_i)] for slices_i in slices] [[collate_grads(dL_dK[s,ss], X[s], X[ss]) for s,ss in itertools.product(slices_i, slices_i)] for slices_i in slices]
if len(slices)>1: if len(slices)>1:
[collate_grads(dL_dK[s,ss], X[s], X[ss], True) for s,ss in itertools.product(slices[0], slices[1])] [collate_grads(dL_dK[s,ss], X[s], X[ss], True) for s,ss in itertools.product(slices[0], slices[1])]
[collate_grads(dL_dK[s,ss], X[s], X[ss], True) for s,ss in itertools.product(slices[1], slices[0])] [collate_grads(dL_dK[s,ss], X[s], X[ss], True) for s,ss in itertools.product(slices[1], slices[0])]
else: else:
assert dL_dK.shape==(X.shape[0],X2.shape[0])
slices2 = index_to_slices(X2[:,self.index_dim]) slices2 = index_to_slices(X2[:,self.index_dim])
[[collate_grads(dL_dK[s,s2],X[s],X2[s2]) for s,s2 in itertools.product(slices[i], slices2[i])] for i in xrange(min(len(slices),len(slices)))] [[collate_grads(dL_dK[s,s2],X[s],X2[s2]) for s,s2 in itertools.product(slices[i], slices2[i])] for i in xrange(min(len(slices),len(slices2)))]
if len(slices)>1: if len(slices)>1:
[collate_grads(dL_dK[s,ss], X[s], X2[s2], True) for s,s2 in itertools.product(slices[1], slices2[0])] [collate_grads(dL_dK[s,s2], X[s], X2[s2], True) for s,s2 in itertools.product(slices[1], slices2[0])]
if len(slices2)>1: if len(slices2)>1:
[collate_grads(dL_dK[s,ss], X[s], X2[s2], True) for s,s2 in itertools.product(slices[0], slices2[1])] [collate_grads(dL_dK[s,s2], X[s], X2[s2], True) for s,s2 in itertools.product(slices[0], slices2[1])]
self.kern.gradient = target self.kern.gradient = target
def update_gradients_diag(self, dL_dKdiag, X): def update_gradients_diag(self, dL_dKdiag, X):