Merge branch 'devel' of github.com:SheffieldML/GPy into devel

This commit is contained in:
Ricardo 2014-05-30 16:23:51 +01:00
commit 6877b21fad
2 changed files with 46 additions and 40 deletions

View file

@ -76,14 +76,14 @@ class Observable(object):
def add_observer(self, observer, callble, priority=0):
"""
Add an observer `observer` with the callback `callble`
Add an observer `observer` with the callback `callble`
and priority `priority` to this observers list.
"""
self.observers.add(priority, observer, callble)
def remove_observer(self, observer, callble=None):
"""
Either (if callble is None) remove all callables,
Either (if callble is None) remove all callables,
which were added alongside observer,
or remove callable `callble` which was added alongside
the observer `observer`.
@ -201,12 +201,12 @@ class Pickleable(object):
#===========================================================================
def copy(self, memo=None, which=None):
"""
Returns a (deep) copy of the current parameter handle.
Returns a (deep) copy of the current parameter handle.
All connections to parents of the copy will be cut.
:param dict memo: memo for deepcopy
:param Parameterized which: parameterized object which started the copy process [default: self]
:param Parameterized which: parameterized object which started the copy process [default: self]
"""
#raise NotImplementedError, "Copy is not yet implemented, TODO: Observable hierarchy"
if memo is None:
@ -247,7 +247,7 @@ class Pickleable(object):
if k not in ignore_list:
dc[k] = v
return dc
def __setstate__(self, state):
self.__dict__.update(state)
from lists_and_dicts import ObserverList
@ -640,24 +640,24 @@ class OptimizationHandlable(Indexable):
#===========================================================================
# Optimizer copy
#===========================================================================
#===========================================================================
@property
def optimizer_array(self):
"""
Array for the optimizer to work on.
This array always lives in the space for the optimizer.
Thus, it is untransformed, going from Transformations.
Setting this array, will make sure the transformed parameters for this model
will be set accordingly. It has to be set with an array, retrieved from
this method, as e.g. fixing will resize the array.
this method, as e.g. fixing will resize the array.
The optimizer should only interfere with this array, such that transofrmations
are secured.
"""
if self.__dict__.get('_optimizer_copy_', None) is None or self.size != self._optimizer_copy_.size:
self._optimizer_copy_ = np.empty(self.size)
if not self._optimizer_copy_transformed:
self._optimizer_copy_.flat = self.param_array.flat
[np.put(self._optimizer_copy_, ind, c.finv(self.param_array[ind])) for c, ind in self.constraints.iteritems() if c != __fixed__]
@ -668,32 +668,32 @@ class OptimizationHandlable(Indexable):
elif self._has_fixes():
return self._optimizer_copy_[self._fixes_]
self._optimizer_copy_transformed = True
return self._optimizer_copy_
@optimizer_array.setter
def optimizer_array(self, p):
"""
Make sure the optimizer copy does not get touched, thus, we only want to
Make sure the optimizer copy does not get touched, thus, we only want to
set the values *inside* not the array itself.
Also we want to update param_array in here.
"""
f = None
if self.has_parent() and self.constraints[__fixed__].size != 0:
f = np.ones(self.size).astype(bool)
f[self.constraints[__fixed__]] = FIXED
elif self._has_fixes():
elif self._has_fixes():
f = self._fixes_
if f is None:
self.param_array.flat = p
[np.put(self.param_array, ind, c.f(self.param_array.flat[ind]))
[np.put(self.param_array, ind, c.f(self.param_array.flat[ind]))
for c, ind in self.constraints.iteritems() if c != __fixed__]
else:
self.param_array.flat[f] = p
[np.put(self.param_array, ind[f[ind]], c.f(self.param_array.flat[ind[f[ind]]]))
[np.put(self.param_array, ind[f[ind]], c.f(self.param_array.flat[ind[f[ind]]]))
for c, ind in self.constraints.iteritems() if c != __fixed__]
self._optimizer_copy_transformed = False
self._trigger_params_changed()
@ -709,13 +709,13 @@ class OptimizationHandlable(Indexable):
# elif self._has_fixes():
# return p[self._fixes_]
# return p
#
#
def _set_params_transformed(self, p):
raise DeprecationWarning, "_get|set_params{_optimizer_copy_transformed} is deprecated, use self.optimizer array insetad!"
# """
# Set parameters p, but make sure they get transformed before setting.
# This means, the optimizer sees p, whereas the model sees transformed(p),
# This means, the optimizer sees p, whereas the model sees transformed(p),
# such that, the parameters the model sees are in the right domain.
# """
# if not(p is self.param_array):
@ -725,7 +725,7 @@ class OptimizationHandlable(Indexable):
# self.param_array.flat[fixes] = p
# elif self._has_fixes(): self.param_array.flat[self._fixes_] = p
# else: self.param_array.flat = p
# [np.put(self.param_array, ind, c.f(self.param_array.flat[ind]))
# [np.put(self.param_array, ind, c.f(self.param_array.flat[ind]))
# for c, ind in self.constraints.iteritems() if c != __fixed__]
# self._trigger_params_changed()
@ -885,7 +885,7 @@ class Parameterizable(OptimizationHandlable):
def traverse(self, visit, *args, **kwargs):
"""
Traverse the hierarchy performing visit(self, *args, **kwargs)
Traverse the hierarchy performing visit(self, *args, **kwargs)
at every node passed by downwards. This function includes self!
See "visitor pattern" in literature. This is implemented in pre-order fashion.
@ -992,7 +992,7 @@ class Parameterizable(OptimizationHandlable):
def _setup_observers(self):
"""
Setup the default observers
1: parameters_changed_notify
2: pass through to parent, if present
"""

View file

@ -13,7 +13,7 @@ class DiffGenomeKern(Kern):
self.idx_p = idx_p
self.index_dim=index_dim
self.kern = SplitKern(kernel,Xp, index_dim=index_dim)
super(DiffGenomeKern, self).__init__(input_dim=kernel.input_dim+1, name=name)
super(DiffGenomeKern, self).__init__(input_dim=kernel.input_dim+1, active_dims=None, name=name)
self.add_parameter(self.kern)
def K(self, X, X2=None):
@ -21,10 +21,12 @@ class DiffGenomeKern(Kern):
K = self.kern.K(X,X2)
slices = index_to_slices(X[:,self.index_dim])
idx_start = slices[1][0]
idx_start = slices[1][0].start
idx_end = idx_start+self.idx_p
K_c = K[idx_start:idx_end,idx_start:idx_end].copy()
K[idx_start:idx_end,:] = K[:self.idx_p,:]
K[:,idx_start:idx_end] = K[:,self.idx_p]
K[:,idx_start:idx_end] = K[:,:self.idx_p]
K[idx_start:idx_end,idx_start:idx_end] = K_c
return K
@ -32,7 +34,7 @@ class DiffGenomeKern(Kern):
Kdiag = self.kern.Kdiag(X)
slices = index_to_slices(X[:,self.index_dim])
idx_start = slices[1][0]
idx_start = slices[1][0].start
idx_end = idx_start+self.idx_p
Kdiag[idx_start:idx_end] = Kdiag[:self.idx_p]
@ -41,25 +43,27 @@ class DiffGenomeKern(Kern):
def update_gradients_full(self,dL_dK,X,X2=None):
assert X2==None
slices = index_to_slices(X[:,self.index_dim])
idx_start = slices[1][0]
idx_start = slices[1][0].start
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()
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()
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()
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()
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()
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()
self.kern.update_gradients_full(dL_dK, X)
self.kern.gradient += grad_p1+grad_p2+grad_p3-grad_n1-grad_n2-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):
pass
@ -90,7 +94,7 @@ class SplitKern(CombinationKernel):
assert len(slices2)<=2, 'The Split kernel only support two different indices'
target = np.zeros((X.shape[0], X2.shape[0]))
# 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:
[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:
@ -113,17 +117,19 @@ class SplitKern(CombinationKernel):
target[:] += self.kern.gradient
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]
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[1], slices[0])]
else:
assert dL_dK.shape==(X.shape[0],X2.shape[0])
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:
[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:
[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
def update_gradients_diag(self, dL_dKdiag, X):