mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-05-09 03:52:39 +02:00
global gradient test done and some parameterized fixes
This commit is contained in:
parent
eae3c28dc0
commit
20e02e63a9
7 changed files with 39 additions and 93 deletions
|
|
@ -226,6 +226,11 @@ class Model(Parameterized):
|
||||||
|
|
||||||
TODO: valid args
|
TODO: valid args
|
||||||
"""
|
"""
|
||||||
|
if self.is_fixed:
|
||||||
|
raise RuntimeError, "Cannot optimize, when everything is fixed"
|
||||||
|
if self.size == 0:
|
||||||
|
raise RuntimeError, "Model without parameters cannot be minimized"
|
||||||
|
|
||||||
if optimizer is None:
|
if optimizer is None:
|
||||||
optimizer = self.preferred_optimizer
|
optimizer = self.preferred_optimizer
|
||||||
|
|
||||||
|
|
@ -294,9 +299,8 @@ class Model(Parameterized):
|
||||||
dx = dx[transformed_index]
|
dx = dx[transformed_index]
|
||||||
gradient = gradient[transformed_index]
|
gradient = gradient[transformed_index]
|
||||||
|
|
||||||
numerical_gradient = (f1 - f2) / (2 * dx)
|
|
||||||
global_ratio = (f1 - f2) / (2 * np.dot(dx, np.where(gradient == 0, 1e-32, gradient)))
|
global_ratio = (f1 - f2) / (2 * np.dot(dx, np.where(gradient == 0, 1e-32, gradient)))
|
||||||
return (np.abs(1. - global_ratio) < tolerance) or (np.abs(gradient - numerical_gradient).mean() < tolerance)
|
return (np.abs(1. - global_ratio) < tolerance)
|
||||||
else:
|
else:
|
||||||
# check the gradient of each parameter individually, and do some pretty printing
|
# check the gradient of each parameter individually, and do some pretty printing
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,6 @@ __updated__ = '2013-12-16'
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from parameter_core import Observable
|
from parameter_core import Observable
|
||||||
|
|
||||||
class ParamList(list):
|
|
||||||
"""
|
|
||||||
List to store ndarray-likes in.
|
|
||||||
It will look for 'is' instead of calling __eq__ on each element.
|
|
||||||
"""
|
|
||||||
def __contains__(self, other):
|
|
||||||
for el in self:
|
|
||||||
if el is other:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
class ObservableArray(np.ndarray, Observable):
|
class ObservableArray(np.ndarray, Observable):
|
||||||
"""
|
"""
|
||||||
An ndarray which reports changes to its observers.
|
An ndarray which reports changes to its observers.
|
||||||
|
|
|
||||||
|
|
@ -5,47 +5,7 @@ Created on Oct 2, 2013
|
||||||
'''
|
'''
|
||||||
import numpy
|
import numpy
|
||||||
from numpy.lib.function_base import vectorize
|
from numpy.lib.function_base import vectorize
|
||||||
from param import Param
|
from lists_and_dicts import IntArrayDict
|
||||||
from collections import defaultdict
|
|
||||||
|
|
||||||
class ParamDict(defaultdict):
|
|
||||||
def __init__(self):
|
|
||||||
"""
|
|
||||||
Default will be self._default, if not set otherwise
|
|
||||||
"""
|
|
||||||
defaultdict.__init__(self, self.default_factory)
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
try:
|
|
||||||
return defaultdict.__getitem__(self, key)
|
|
||||||
except KeyError:
|
|
||||||
for a in self.iterkeys():
|
|
||||||
if numpy.all(a==key) and a._parent_index_==key._parent_index_:
|
|
||||||
return defaultdict.__getitem__(self, a)
|
|
||||||
raise
|
|
||||||
|
|
||||||
def __contains__(self, key):
|
|
||||||
if defaultdict.__contains__(self, key):
|
|
||||||
return True
|
|
||||||
for a in self.iterkeys():
|
|
||||||
if numpy.all(a==key) and a._parent_index_==key._parent_index_:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
|
||||||
if isinstance(key, Param):
|
|
||||||
for a in self.iterkeys():
|
|
||||||
if numpy.all(a==key) and a._parent_index_==key._parent_index_:
|
|
||||||
return super(ParamDict, self).__setitem__(a, value)
|
|
||||||
defaultdict.__setitem__(self, key, value)
|
|
||||||
|
|
||||||
class SetDict(ParamDict):
|
|
||||||
def default_factory(self):
|
|
||||||
return set()
|
|
||||||
|
|
||||||
class IntArrayDict(ParamDict):
|
|
||||||
def default_factory(self):
|
|
||||||
return numpy.int_([])
|
|
||||||
|
|
||||||
class ParameterIndexOperations(object):
|
class ParameterIndexOperations(object):
|
||||||
'''
|
'''
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,24 @@ Created on 27 Feb 2014
|
||||||
@author: maxz
|
@author: maxz
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class ParamList(list):
|
from collections import defaultdict
|
||||||
|
class DefaultArrayDict(defaultdict):
|
||||||
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
Default will be self._default, if not set otherwise
|
||||||
|
"""
|
||||||
|
defaultdict.__init__(self, self.default_factory)
|
||||||
|
|
||||||
|
class SetDict(DefaultArrayDict):
|
||||||
|
def default_factory(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
|
class IntArrayDict(DefaultArrayDict):
|
||||||
|
def default_factory(self):
|
||||||
|
import numpy as np
|
||||||
|
return np.int_([])
|
||||||
|
|
||||||
|
class ArrayList(list):
|
||||||
"""
|
"""
|
||||||
List to store ndarray-likes in.
|
List to store ndarray-likes in.
|
||||||
It will look for 'is' instead of calling __eq__ on each element.
|
It will look for 'is' instead of calling __eq__ on each element.
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class Param(OptimizationHandlable, ObservableArray, Gradcheckable):
|
||||||
obj._realsize_ = obj.size
|
obj._realsize_ = obj.size
|
||||||
obj._realndim_ = obj.ndim
|
obj._realndim_ = obj.ndim
|
||||||
obj._updated_ = False
|
obj._updated_ = False
|
||||||
from index_operations import SetDict
|
from lists_and_dicts import SetDict
|
||||||
obj._tied_to_me_ = SetDict()
|
obj._tied_to_me_ = SetDict()
|
||||||
obj._tied_to_ = []
|
obj._tied_to_ = []
|
||||||
obj._original_ = True
|
obj._original_ = True
|
||||||
|
|
@ -232,7 +232,8 @@ class Param(OptimizationHandlable, ObservableArray, Gradcheckable):
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
@property
|
@property
|
||||||
def is_fixed(self):
|
def is_fixed(self):
|
||||||
return self._highest_parent_._is_fixed(self)
|
from transformations import __fixed__
|
||||||
|
return self.constraints[__fixed__].size == self.size
|
||||||
#def round(self, decimals=0, out=None):
|
#def round(self, decimals=0, out=None):
|
||||||
# view = super(Param, self).round(decimals, out).view(Param)
|
# view = super(Param, self).round(decimals, out).view(Param)
|
||||||
# view.__array_finalize__(self)
|
# view.__array_finalize__(self)
|
||||||
|
|
@ -347,8 +348,8 @@ class ParamConcatenation(object):
|
||||||
See :py:class:`GPy.core.parameter.Param` for more details on constraining.
|
See :py:class:`GPy.core.parameter.Param` for more details on constraining.
|
||||||
"""
|
"""
|
||||||
# self.params = params
|
# self.params = params
|
||||||
from lists_and_dicts import ParamList
|
from lists_and_dicts import ArrayList
|
||||||
self.params = ParamList([])
|
self.params = ArrayList([])
|
||||||
for p in params:
|
for p in params:
|
||||||
for p in p.flattened_parameters:
|
for p in p.flattened_parameters:
|
||||||
if p not in self.params:
|
if p not in self.params:
|
||||||
|
|
|
||||||
|
|
@ -335,6 +335,7 @@ class Constrainable(Nameable, Indexable):
|
||||||
|
|
||||||
def _add_to_index_operations(self, which, reconstrained, transform, warning):
|
def _add_to_index_operations(self, which, reconstrained, transform, warning):
|
||||||
if warning and reconstrained.size > 0:
|
if warning and reconstrained.size > 0:
|
||||||
|
# TODO: figure out which parameters have changed and only print those
|
||||||
print "WARNING: reconstraining parameters {}".format(self.parameter_names() or self.name)
|
print "WARNING: reconstraining parameters {}".format(self.parameter_names() or self.name)
|
||||||
which.add(transform, self._raveled_index())
|
which.add(transform, self._raveled_index())
|
||||||
|
|
||||||
|
|
@ -419,8 +420,8 @@ import numpy as np
|
||||||
class Parameterizable(OptimizationHandlable):
|
class Parameterizable(OptimizationHandlable):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(Parameterizable, self).__init__(*args, **kwargs)
|
super(Parameterizable, self).__init__(*args, **kwargs)
|
||||||
from GPy.core.parameterization.lists_and_dicts import ParamList
|
from GPy.core.parameterization.lists_and_dicts import ArrayList
|
||||||
_parameters_ = ParamList()
|
_parameters_ = ArrayList()
|
||||||
self._added_names_ = set()
|
self._added_names_ = set()
|
||||||
|
|
||||||
def parameter_names(self, add_self=False, adjust_for_printing=False, recursive=True):
|
def parameter_names(self, add_self=False, adjust_for_printing=False, recursive=True):
|
||||||
|
|
@ -482,7 +483,7 @@ class Parameterizable(OptimizationHandlable):
|
||||||
"""Returns a (deep) copy of the current model"""
|
"""Returns a (deep) copy of the current model"""
|
||||||
import copy
|
import copy
|
||||||
from .index_operations import ParameterIndexOperations, ParameterIndexOperationsView
|
from .index_operations import ParameterIndexOperations, ParameterIndexOperationsView
|
||||||
from .lists_and_dicts import ParamList
|
from .lists_and_dicts import ArrayList
|
||||||
|
|
||||||
dc = dict()
|
dc = dict()
|
||||||
for k, v in self.__dict__.iteritems():
|
for k, v in self.__dict__.iteritems():
|
||||||
|
|
@ -496,7 +497,7 @@ class Parameterizable(OptimizationHandlable):
|
||||||
|
|
||||||
dc['_direct_parent_'] = None
|
dc['_direct_parent_'] = None
|
||||||
dc['_parent_index_'] = None
|
dc['_parent_index_'] = None
|
||||||
dc['_parameters_'] = ParamList()
|
dc['_parameters_'] = ArrayList()
|
||||||
dc['constraints'].clear()
|
dc['constraints'].clear()
|
||||||
dc['priors'].clear()
|
dc['priors'].clear()
|
||||||
dc['size'] = 0
|
dc['size'] = 0
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ from re import compile, _pattern_type
|
||||||
from param import ParamConcatenation
|
from param import ParamConcatenation
|
||||||
from parameter_core import Pickleable, Parameterizable, adjust_name_for_printing, Gradcheckable
|
from parameter_core import Pickleable, Parameterizable, adjust_name_for_printing, Gradcheckable
|
||||||
from transformations import __fixed__
|
from transformations import __fixed__
|
||||||
from array_core import ParamList
|
from lists_and_dicts import ArrayList
|
||||||
|
|
||||||
class Parameterized(Parameterizable, Pickleable, Gradcheckable):
|
class Parameterized(Parameterizable, Pickleable, Gradcheckable):
|
||||||
"""
|
"""
|
||||||
|
|
@ -56,7 +56,7 @@ class Parameterized(Parameterizable, Pickleable, Gradcheckable):
|
||||||
def __init__(self, name=None, *a, **kw):
|
def __init__(self, name=None, *a, **kw):
|
||||||
super(Parameterized, self).__init__(name=name, parent=None, parent_index=None, *a, **kw)
|
super(Parameterized, self).__init__(name=name, parent=None, parent_index=None, *a, **kw)
|
||||||
self._in_init_ = True
|
self._in_init_ = True
|
||||||
self._parameters_ = ParamList()
|
self._parameters_ = ArrayList()
|
||||||
self.size = sum(p.size for p in self._parameters_)
|
self.size = sum(p.size for p in self._parameters_)
|
||||||
self.add_observer(self, self._parameters_changed_notification, -100)
|
self.add_observer(self, self._parameters_changed_notification, -100)
|
||||||
if not self._has_fixes():
|
if not self._has_fixes():
|
||||||
|
|
@ -265,16 +265,6 @@ class Parameterized(Parameterizable, Pickleable, Gradcheckable):
|
||||||
if self._has_fixes(): return g[self._fixes_]
|
if self._has_fixes(): return g[self._fixes_]
|
||||||
return g
|
return g
|
||||||
|
|
||||||
#===========================================================================
|
|
||||||
# Indexable Handling
|
|
||||||
#===========================================================================
|
|
||||||
def _backtranslate_index(self, param, ind):
|
|
||||||
# translate an index in parameterized indexing into the index of param
|
|
||||||
ind = ind - self._offset_for(param)
|
|
||||||
ind = ind[ind >= 0]
|
|
||||||
internal_offset = param._internal_offset()
|
|
||||||
ind = ind[ind < param.size + internal_offset]
|
|
||||||
return ind
|
|
||||||
def _offset_for(self, param):
|
def _offset_for(self, param):
|
||||||
# get the offset in the parameterized index array for param
|
# get the offset in the parameterized index array for param
|
||||||
if param.has_parent():
|
if param.has_parent():
|
||||||
|
|
@ -300,35 +290,21 @@ class Parameterized(Parameterizable, Pickleable, Gradcheckable):
|
||||||
"""
|
"""
|
||||||
return numpy.r_[:self.size]
|
return numpy.r_[:self.size]
|
||||||
|
|
||||||
#===========================================================================
|
|
||||||
# Fixing parameters:
|
|
||||||
#===========================================================================
|
|
||||||
def _fixes_for(self, param):
|
|
||||||
if self._has_fixes():
|
|
||||||
return self._fixes_[self._raveled_index_for(param)]
|
|
||||||
return numpy.ones(self.size, dtype=bool)[self._raveled_index_for(param)]
|
|
||||||
|
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
# Convenience for fixed, tied checking of param:
|
# Convenience for fixed, tied checking of param:
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
def fixed_indices(self):
|
|
||||||
return np.array([x.is_fixed for x in self._parameters_])
|
|
||||||
def _is_fixed(self, param):
|
|
||||||
# returns if the whole param is fixed
|
|
||||||
if not self._has_fixes():
|
|
||||||
return False
|
|
||||||
return not self._fixes_[self._raveled_index_for(param)].any()
|
|
||||||
# return not self._fixes_[self._offset_for(param): self._offset_for(param)+param._realsize_].any()
|
|
||||||
@property
|
@property
|
||||||
def is_fixed(self):
|
def is_fixed(self):
|
||||||
for p in self._parameters_:
|
for p in self._parameters_:
|
||||||
if not p.is_fixed: return False
|
if not p.is_fixed: return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _get_original(self, param):
|
def _get_original(self, param):
|
||||||
# if advanced indexing is activated it happens that the array is a copy
|
# if advanced indexing is activated it happens that the array is a copy
|
||||||
# you can retrieve the original param through this method, by passing
|
# you can retrieve the original param through this method, by passing
|
||||||
# the copy here
|
# the copy here
|
||||||
return self._parameters_[param._parent_index_]
|
return self._parameters_[param._parent_index_]
|
||||||
|
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
# Get/set parameters:
|
# Get/set parameters:
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue