GPRegression working, gradients still todo

This commit is contained in:
Max Zwiessele 2013-10-22 16:16:54 +01:00
parent 9a70f27010
commit 27724fd456
3 changed files with 33 additions and 21 deletions

View file

@ -311,7 +311,7 @@ class Model(Parameterized):
the objective cannot be computed.
:param x: the parameters of the model.
:parameter type: np.array
:type x: np.array
"""
try:
self._set_params_transformed(x)
@ -329,7 +329,7 @@ class Model(Parameterized):
Compute the objective function of the model and the gradient of the model at the point given by x.
:param x: the point at which gradients are to be computed.
:type np.array:
:type x: np.array
"""
try:

View file

@ -45,7 +45,7 @@ class Param(numpy.ndarray):
obj._name_ = name
obj._parent_ = None
obj._parent_index_ = None
obj._updates_parent_ = None
obj._gradient_parent_ = None
obj._gradient_ = gradient
obj._current_slice_ = (slice(obj.shape[0]),)
obj._realshape_ = obj.shape
@ -72,7 +72,7 @@ class Param(numpy.ndarray):
self._realndim_ = getattr(obj, '_realndim_', None)
self._updated_ = getattr(obj, '_updated_', None)
self._original_ = getattr(obj, '_original_', None)
self._updates_parent_ = getattr(obj, '_updates_parent_', None)
self._gradient_parent_ = getattr(obj, '_gradient_parent_', None)
def __array_wrap__(self, out_arr, context=None):
return out_arr.view(numpy.ndarray)
@ -85,7 +85,7 @@ class Param(numpy.ndarray):
(self._name_,
self._parent_,
self._parent_index_,
self._updates_parent_,
self._gradient_parent_,
self._gradient_,
self._current_slice_,
self._realshape_,
@ -107,7 +107,7 @@ class Param(numpy.ndarray):
self._realshape_ = state.pop()
self._current_slice_ = state.pop()
self._gradient_ = state.pop()
self._updates_parent_ = state.pop()
self._gradient_parent_ = state.pop()
self._parent_index_ = state.pop()
self._parent_ = state.pop()
self._name_ = state.pop()
@ -174,7 +174,7 @@ class Param(numpy.ndarray):
self._parent_._get_original(self).__setitem__(self._current_slice_, transform.initialize(self), update=False)
self._parent_._add_constrain(self, transform, warning)
if update:
self._updates_parent_.parameters_changed()
self._parent_.parameters_changed()
def constrain_positive(self, warning=True):
"""
:param warning: print a warning if re-constraining parameters.
@ -321,7 +321,7 @@ class Param(numpy.ndarray):
numpy.ndarray.__setitem__(self, s, val)
self._fire_changed()
if update:
self._updates_parent_.parameters_changed()
self._parent_.parameters_changed()
#===========================================================================
# Index Operations:
#===========================================================================
@ -467,7 +467,7 @@ class ParamConcatenation(object):
[numpy.place(p, ind[ps], vals[ps]) and p._fire_changed()
for p, ps in zip(self.params, self._param_slices_)]
if update:
self.params[0]._updates_parent_.parameters_changed()
self.params[0]._parent_.parameters_changed()
def _vals(self):
return numpy.hstack([p._get_params() for p in self.params])
#===========================================================================
@ -489,8 +489,8 @@ class ParamConcatenation(object):
def constrain_bounded(self, lower, upper, warning=True):
[param.constrain_bounded(lower, upper, warning) for param in self.params]
constrain_bounded.__doc__ = Param.constrain_bounded.__doc__
def unconstrain(self, constraints=None):
[param.unconstrain(constraints) for param in self.params]
def unconstrain(self, *constraints):
[param.unconstrain(*constraints) for param in self.params]
unconstrain.__doc__ = Param.unconstrain.__doc__
def unconstrain_negative(self):
[param.unconstrain_negative() for param in self.params]

View file

@ -12,6 +12,7 @@ import transformations
import itertools
from re import compile, _pattern_type
import re
from GPy.util.misc import fast_array_equal
#===============================================================================
# Printing:
@ -81,7 +82,7 @@ class Parameterized(object):
#===========================================================================
# Parameter connection for model creation:
#===========================================================================
def set_as_parameter(self, name, array, gradient, index=None, highest_parent=None):
def set_as_parameter(self, name, array, gradient, index=None, gradient_parent=None):
"""
:param name: name of the parameter (in print and plots), can be callable without parameters
:type name: str, callable
@ -91,7 +92,7 @@ class Parameterized(object):
:type gradient: callable
:param index: (optional) index of the parameter when printing
(:param highest_parent: connect these parameters to this class, but tell
(:param gradient_parent: connect these parameters to this class, but tell
updates to highest_parent, this is needed when parameterized classes
contain parameterized classes, but want to access the parameters
of their children)
@ -107,7 +108,7 @@ class Parameterized(object):
self._parameters_.append(Param(name, array, gradient))
else:
self._parameters_.insert(index, Param(name, array, gradient))
self._connect_parameters(highest_parent=highest_parent)
self._connect_parameters(gradient_parent=gradient_parent)
def set_as_parameters(self, *parameters, **kwargs):
"""
:param parameters: the parameters to add
@ -115,13 +116,13 @@ class Parameterized(object):
Add all parameters to this parameter class, you can insert parameters
at any given point using the :py:func:`list.insert` syntax
at any given index using the :py:func:`list.insert` syntax
"""
if kwargs.get('index',None) is None:
self._parameters_.extend(parameters)
else:
self._parameters_.insert(kwargs['index'], parameters)
self._connect_parameters(highest_parent=kwargs.get('highest_parent', self))
self._connect_parameters(gradient_parent=kwargs.get('gradient_parent', self))
# def remove_parameter(self, *names_params_indices):
# """
# :param names_params_indices: mix of parameter_names, parameter objects, or indices
@ -137,7 +138,7 @@ class Parameterized(object):
def parameters_changed(self):
# will be called as soon as paramters have changed
pass
def _connect_parameters(self, highest_parent=None):
def _connect_parameters(self, gradient_parent=None):
# connect parameterlist to this parameterized object
# This just sets up the right connection for the params objects
# to be used as parameters
@ -147,11 +148,20 @@ class Parameterized(object):
sizes = numpy.cumsum([0] + self._parameter_sizes_)
self._parameter_size_ = sizes[-1]
self._param_slices_ = [slice(start, stop) for start,stop in zip(sizes, sizes[1:])]
for i, p in enumerate(self._parameters_):
i = 0
for p in self._parameters_:
#if p._parent_ is None:
p._parent_ = self
p._parent_index_ = i
p._updates_parent_ = highest_parent or self
i += 1
p._gradient_parent_ = gradient_parent or p._gradient_parent_ or self
not_unique = []
# for k,v in self.__dict__.iteritems():
# try:
# if fast_array_equal(v,p):
# self.__dict__[k] = p
# except: # parameter comparison, just for convenience
# pass
if p.name in self.__dict__:
if p.base is self.__dict__[p.name] or p is self.__dict__[p.name]:
self.__dict__[p.name] = p
@ -218,7 +228,6 @@ class Parameterized(object):
#===========================================================================
def _get_param_names_transformed(self):
return numpy.array([p.name+str(i) for p in self._parameters_ for i in p._indices()])[self._fixes_][0]
def _get_params(self):
# don't overwrite this anymore!
return numpy.hstack([x._get_params() for x in self._parameters_])#numpy.fromiter(itertools.chain(*itertools.imap(lambda x: x._get_params(), self._parameters_)), dtype=numpy.float64, count=sum(self._parameter_sizes_))
@ -233,6 +242,7 @@ class Parameterized(object):
return p[self._fixes_]
return p
def _set_params_transformed(self, p):
p = p.copy()
if self._fixes_ is not None: tmp = self._get_params(); tmp[self._fixes_] = p; p = tmp; del tmp
[numpy.put(p, ind, c.f(p[ind])) for c,ind in self._constraints_.iteritems() if c != __fixed__]
self._set_params(p)
@ -338,13 +348,15 @@ class Parameterized(object):
print "Warning: re-constraining parameters:\n{}".format(param._short())
return rav_i
def _remove_constrain(self, param, *transforms, **kwargs):
if transforms is ():
if not transforms:
transforms = self._constraints_.properties()
removed_indices = numpy.array([]).astype(int)
if "index" in kwargs: index = kwargs['index']
else: index = self._raveled_index_for(param)
for constr in transforms:
removed = self._constraints_.remove(constr, index)
if constr is __fixed__:
self._set_unfixed(removed)
removed_indices = numpy.union1d(removed_indices, removed)
return removed_indices
# convienience for iterating over items