mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-05-27 14:25:16 +02:00
fixes now hierarchical, maybe need to be restructured as lookup from constraints
This commit is contained in:
parent
79ba989b31
commit
24b43c490c
3 changed files with 62 additions and 33 deletions
|
|
@ -226,7 +226,7 @@ class Param(OptimizationHandlable, ObsAr):
|
||||||
# Constrainable
|
# Constrainable
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
def _ensure_fixes(self):
|
def _ensure_fixes(self):
|
||||||
self._fixes_ = numpy.ones(self._realsize_, dtype=bool)
|
if not self._has_fixes(): self._fixes_ = numpy.ones(self._realsize_, dtype=bool)
|
||||||
|
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
# Convenience
|
# Convenience
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ Observable Pattern for patameterization
|
||||||
from transformations import Transformation, Logexp, NegativeLogexp, Logistic, __fixed__, FIXED, UNFIXED
|
from transformations import Transformation, Logexp, NegativeLogexp, Logistic, __fixed__, FIXED, UNFIXED
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
__updated__ = '2014-03-17'
|
__updated__ = '2014-03-18'
|
||||||
|
|
||||||
class HierarchyError(Exception):
|
class HierarchyError(Exception):
|
||||||
"""
|
"""
|
||||||
|
|
@ -377,7 +377,7 @@ class Constrainable(Nameable, Indexable):
|
||||||
# Ensure that the fixes array is set:
|
# Ensure that the fixes array is set:
|
||||||
# Parameterized: ones(self.size)
|
# Parameterized: ones(self.size)
|
||||||
# Param: ones(self._realsize_
|
# Param: ones(self._realsize_
|
||||||
self._fixes_ = np.ones(self.size, dtype=bool)
|
if not self._has_fixes(): self._fixes_ = np.ones(self.size, dtype=bool)
|
||||||
|
|
||||||
def _set_fixed(self, index):
|
def _set_fixed(self, index):
|
||||||
self._ensure_fixes()
|
self._ensure_fixes()
|
||||||
|
|
@ -398,7 +398,7 @@ class Constrainable(Nameable, Indexable):
|
||||||
self._fixes_ = None
|
self._fixes_ = None
|
||||||
|
|
||||||
def _has_fixes(self):
|
def _has_fixes(self):
|
||||||
return hasattr(self, "_fixes_") and self._fixes_ is not None
|
return hasattr(self, "_fixes_") and self._fixes_ is not None and self._fixes_.size == self.size
|
||||||
|
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
# Prior Operations
|
# Prior Operations
|
||||||
|
|
@ -576,14 +576,22 @@ class OptimizationHandlable(Constrainable):
|
||||||
# transformed parameters (apply transformation rules)
|
# transformed parameters (apply transformation rules)
|
||||||
p = self._param_array_.copy()
|
p = self._param_array_.copy()
|
||||||
[np.put(p, ind, c.finv(p[ind])) for c, ind in self.constraints.iteritems() if c != __fixed__]
|
[np.put(p, ind, c.finv(p[ind])) for c, ind in self.constraints.iteritems() if c != __fixed__]
|
||||||
if self._has_fixes():
|
if self.has_parent() and self.constraints[__fixed__].size != 0:
|
||||||
|
fixes = np.ones(self.size).astype(bool)
|
||||||
|
fixes[self.constraints[__fixed__]] = FIXED
|
||||||
|
return p[fixes]
|
||||||
|
elif self._has_fixes():
|
||||||
return p[self._fixes_]
|
return p[self._fixes_]
|
||||||
return p
|
return p
|
||||||
|
|
||||||
def _set_params_transformed(self, p):
|
def _set_params_transformed(self, p):
|
||||||
if p is self._param_array_:
|
if p is self._param_array_:
|
||||||
p = p.copy()
|
p = p.copy()
|
||||||
if self._has_fixes(): self._param_array_[self._fixes_] = p
|
if self.has_parent() and self.constraints[__fixed__].size != 0:
|
||||||
|
fixes = np.ones(self.size).astype(bool)
|
||||||
|
fixes[self.constraints[__fixed__]] = FIXED
|
||||||
|
self._param_array_[fixes] = p
|
||||||
|
elif self._has_fixes(): self._param_array_[self._fixes_] = p
|
||||||
else: self._param_array_[:] = p
|
else: self._param_array_[:] = p
|
||||||
self.untransform()
|
self.untransform()
|
||||||
self._trigger_params_changed()
|
self._trigger_params_changed()
|
||||||
|
|
@ -770,11 +778,11 @@ class Parameterizable(OptimizationHandlable):
|
||||||
Add all parameters to this param class, you can insert parameters
|
Add all parameters to this param class, you can insert parameters
|
||||||
at any given index using the :func:`list.insert` syntax
|
at any given index using the :func:`list.insert` syntax
|
||||||
"""
|
"""
|
||||||
# if param.has_parent():
|
|
||||||
# raise AttributeError, "parameter {} already in another model, create new object (or copy) for adding".format(param._short())
|
|
||||||
if param in self._parameters_ and index is not None:
|
if param in self._parameters_ and index is not None:
|
||||||
self.remove_parameter(param)
|
self.remove_parameter(param)
|
||||||
self.add_parameter(param, index)
|
self.add_parameter(param, index)
|
||||||
|
elif param.has_parent():
|
||||||
|
raise HierarchyError, "parameter {} already in another model ({}), create new object (or copy) for adding".format(param._short(), param._highest_parent_._short())
|
||||||
elif param not in self._parameters_:
|
elif param not in self._parameters_:
|
||||||
if param.has_parent():
|
if param.has_parent():
|
||||||
parent = param._parent_
|
parent = param._parent_
|
||||||
|
|
@ -798,13 +806,19 @@ class Parameterizable(OptimizationHandlable):
|
||||||
|
|
||||||
param.add_observer(self, self._pass_through_notify_observers, -np.inf)
|
param.add_observer(self, self._pass_through_notify_observers, -np.inf)
|
||||||
|
|
||||||
self.size += param.size
|
parent = self
|
||||||
|
while parent is not None:
|
||||||
|
parent.size += param.size
|
||||||
|
parent = parent._parent_
|
||||||
|
|
||||||
|
self._connect_parameters()
|
||||||
|
|
||||||
|
self._highest_parent_._connect_parameters(ignore_added_names=_ignore_added_names)
|
||||||
|
self._highest_parent_._notify_parent_change()
|
||||||
|
self._highest_parent_._connect_fixes()
|
||||||
|
|
||||||
self._connect_parameters(ignore_added_names=_ignore_added_names)
|
|
||||||
self._notify_parent_change()
|
|
||||||
self._connect_fixes()
|
|
||||||
else:
|
else:
|
||||||
raise RuntimeError, """Parameter exists already added and no copy made"""
|
raise HierarchyError, """Parameter exists already and no copy made"""
|
||||||
|
|
||||||
|
|
||||||
def add_parameters(self, *parameters):
|
def add_parameters(self, *parameters):
|
||||||
|
|
@ -830,17 +844,18 @@ class Parameterizable(OptimizationHandlable):
|
||||||
param.remove_observer(self, self._pass_through_notify_observers)
|
param.remove_observer(self, self._pass_through_notify_observers)
|
||||||
self.constraints.shift_left(start, param.size)
|
self.constraints.shift_left(start, param.size)
|
||||||
|
|
||||||
self._connect_fixes()
|
|
||||||
self._connect_parameters()
|
self._connect_parameters()
|
||||||
self._notify_parent_change()
|
self._notify_parent_change()
|
||||||
|
|
||||||
parent = self._parent_
|
parent = self._parent_
|
||||||
while parent is not None:
|
while parent is not None:
|
||||||
parent._connect_fixes()
|
parent.size -= param.size
|
||||||
parent._connect_parameters()
|
|
||||||
parent._notify_parent_change()
|
|
||||||
parent = parent._parent_
|
parent = parent._parent_
|
||||||
|
|
||||||
|
self._highest_parent_._connect_parameters()
|
||||||
|
self._highest_parent_._connect_fixes()
|
||||||
|
self._highest_parent_._notify_parent_change()
|
||||||
|
|
||||||
def _connect_parameters(self, ignore_added_names=False):
|
def _connect_parameters(self, ignore_added_names=False):
|
||||||
# connect parameterlist to this parameterized object
|
# connect parameterlist to this parameterized object
|
||||||
# This just sets up the right connection for the params objects
|
# This just sets up the right connection for the params objects
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,9 @@ class ParameterizedTest(unittest.TestCase):
|
||||||
self.param = Param('param', np.random.rand(25,2), Logistic(0, 1))
|
self.param = Param('param', np.random.rand(25,2), Logistic(0, 1))
|
||||||
|
|
||||||
self.test1 = GPy.core.Parameterized("test model")
|
self.test1 = GPy.core.Parameterized("test model")
|
||||||
self.test1.add_parameter(self.white)
|
self.test1.kern = self.rbf+self.white
|
||||||
self.test1.add_parameter(self.rbf, 0)
|
self.test1.add_parameter(self.test1.kern)
|
||||||
self.test1.add_parameter(self.param)
|
self.test1.add_parameter(self.param, 0)
|
||||||
|
|
||||||
x = np.linspace(-2,6,4)[:,None]
|
x = np.linspace(-2,6,4)[:,None]
|
||||||
y = np.sin(x)
|
y = np.sin(x)
|
||||||
|
|
@ -45,22 +45,24 @@ class ParameterizedTest(unittest.TestCase):
|
||||||
def test_add_parameter(self):
|
def test_add_parameter(self):
|
||||||
self.assertEquals(self.rbf._parent_index_, 0)
|
self.assertEquals(self.rbf._parent_index_, 0)
|
||||||
self.assertEquals(self.white._parent_index_, 1)
|
self.assertEquals(self.white._parent_index_, 1)
|
||||||
|
self.assertEquals(self.param._parent_index_, 0)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_fixes(self):
|
def test_fixes(self):
|
||||||
self.white.fix(warning=False)
|
self.white.fix(warning=False)
|
||||||
self.test1.remove_parameter(self.test1.param)
|
self.test1.remove_parameter(self.param)
|
||||||
self.assertTrue(self.test1._has_fixes())
|
self.assertTrue(self.test1._has_fixes())
|
||||||
from GPy.core.parameterization.transformations import FIXED, UNFIXED
|
from GPy.core.parameterization.transformations import FIXED, UNFIXED
|
||||||
self.assertListEqual(self.test1._fixes_.tolist(),[UNFIXED,UNFIXED,FIXED])
|
self.assertListEqual(self.test1._fixes_.tolist(),[UNFIXED,UNFIXED,FIXED])
|
||||||
|
self.test1.kern.add_parameter(self.white, 0)
|
||||||
self.test1.add_parameter(self.white, 0)
|
|
||||||
self.assertListEqual(self.test1._fixes_.tolist(),[FIXED,UNFIXED,UNFIXED])
|
self.assertListEqual(self.test1._fixes_.tolist(),[FIXED,UNFIXED,UNFIXED])
|
||||||
|
self.test1.kern.rbf.fix()
|
||||||
|
self.assertListEqual(self.test1._fixes_.tolist(),[FIXED]*3)
|
||||||
|
|
||||||
def test_remove_parameter(self):
|
def test_remove_parameter(self):
|
||||||
from GPy.core.parameterization.transformations import FIXED, UNFIXED, __fixed__, Logexp
|
from GPy.core.parameterization.transformations import FIXED, UNFIXED, __fixed__, Logexp
|
||||||
self.white.fix()
|
self.white.fix()
|
||||||
self.test1.remove_parameter(self.white)
|
self.test1.kern.remove_parameter(self.white)
|
||||||
self.assertIs(self.test1._fixes_,None)
|
self.assertIs(self.test1._fixes_,None)
|
||||||
|
|
||||||
self.assertListEqual(self.white._fixes_.tolist(), [FIXED])
|
self.assertListEqual(self.white._fixes_.tolist(), [FIXED])
|
||||||
|
|
@ -81,7 +83,12 @@ class ParameterizedTest(unittest.TestCase):
|
||||||
self.assertListEqual(self.white._fixes_.tolist(), [FIXED])
|
self.assertListEqual(self.white._fixes_.tolist(), [FIXED])
|
||||||
self.assertIs(self.test1.constraints, self.rbf.constraints._param_index_ops)
|
self.assertIs(self.test1.constraints, self.rbf.constraints._param_index_ops)
|
||||||
self.assertIs(self.test1.constraints, self.param.constraints._param_index_ops)
|
self.assertIs(self.test1.constraints, self.param.constraints._param_index_ops)
|
||||||
self.assertListEqual(self.test1.constraints[Logexp()].tolist(), [0,1])
|
self.assertListEqual(self.test1.constraints[Logexp()].tolist(), range(self.param.size, self.param.size+self.rbf.size))
|
||||||
|
|
||||||
|
def test_remove_parameter_param_array_grad_array(self):
|
||||||
|
val = self.test1.kern._param_array_.copy()
|
||||||
|
self.test1.kern.remove_parameter(self.white)
|
||||||
|
self.assertListEqual(self.test1.kern._param_array_.tolist(), val[:2].tolist())
|
||||||
|
|
||||||
def test_add_parameter_already_in_hirarchy(self):
|
def test_add_parameter_already_in_hirarchy(self):
|
||||||
self.assertRaises(HierarchyError, self.test1.add_parameter, self.white._parameters_[0])
|
self.assertRaises(HierarchyError, self.test1.add_parameter, self.white._parameters_[0])
|
||||||
|
|
@ -91,28 +98,35 @@ class ParameterizedTest(unittest.TestCase):
|
||||||
self.assertIs(self.test1.constraints, self.rbf.constraints._param_index_ops)
|
self.assertIs(self.test1.constraints, self.rbf.constraints._param_index_ops)
|
||||||
self.assertListEqual(self.rbf.constraints.indices()[0].tolist(), range(2))
|
self.assertListEqual(self.rbf.constraints.indices()[0].tolist(), range(2))
|
||||||
from GPy.core.parameterization.transformations import Logexp
|
from GPy.core.parameterization.transformations import Logexp
|
||||||
kern = self.rbf+self.white
|
kern = self.test1.kern
|
||||||
|
self.test1.remove_parameter(kern)
|
||||||
self.assertListEqual(kern.constraints[Logexp()].tolist(), range(3))
|
self.assertListEqual(kern.constraints[Logexp()].tolist(), range(3))
|
||||||
|
|
||||||
def test_constraints(self):
|
def test_constraints(self):
|
||||||
self.rbf.constrain(GPy.transformations.Square(), False)
|
self.rbf.constrain(GPy.transformations.Square(), False)
|
||||||
self.assertListEqual(self.test1.constraints[GPy.transformations.Square()].tolist(), range(2))
|
self.assertListEqual(self.test1.constraints[GPy.transformations.Square()].tolist(), range(self.param.size, self.param.size+self.rbf.size))
|
||||||
self.assertListEqual(self.test1.constraints[GPy.transformations.Logexp()].tolist(), [2])
|
self.assertListEqual(self.test1.constraints[GPy.transformations.Logexp()].tolist(), [self.param.size+self.rbf.size])
|
||||||
|
|
||||||
self.test1.remove_parameter(self.rbf)
|
self.test1.kern.remove_parameter(self.rbf)
|
||||||
self.assertListEqual(self.test1.constraints[GPy.transformations.Square()].tolist(), [])
|
self.assertListEqual(self.test1.constraints[GPy.transformations.Square()].tolist(), [])
|
||||||
|
|
||||||
def test_constraints_views(self):
|
def test_constraints_views(self):
|
||||||
self.assertEqual(self.white.constraints._offset, 2)
|
self.assertEqual(self.white.constraints._offset, self.param.size+self.rbf.size)
|
||||||
self.assertEqual(self.rbf.constraints._offset, 0)
|
self.assertEqual(self.rbf.constraints._offset, self.param.size)
|
||||||
self.assertEqual(self.param.constraints._offset, 3)
|
self.assertEqual(self.param.constraints._offset, 0)
|
||||||
|
|
||||||
def test_fixing_randomize(self):
|
def test_fixing_randomize(self):
|
||||||
self.white.fix(warning=True)
|
self.white.fix(warning=True)
|
||||||
val = float(self.test1.white.variance)
|
val = float(self.white.variance)
|
||||||
self.test1.randomize()
|
self.test1.randomize()
|
||||||
self.assertEqual(val, self.white.variance)
|
self.assertEqual(val, self.white.variance)
|
||||||
|
|
||||||
|
def test_fixing_randomize_parameter_handling(self):
|
||||||
|
self.rbf.fix(warning=True)
|
||||||
|
val = float(self.rbf.variance)
|
||||||
|
self.test1.kern.randomize()
|
||||||
|
self.assertEqual(val, self.rbf.variance)
|
||||||
|
|
||||||
def test_fixing_optimize(self):
|
def test_fixing_optimize(self):
|
||||||
self.testmodel.kern.lengthscale.fix()
|
self.testmodel.kern.lengthscale.fix()
|
||||||
val = float(self.testmodel.kern.lengthscale)
|
val = float(self.testmodel.kern.lengthscale)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue