mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-04-28 06:16:24 +02:00
domain and trtansformations namespace prettyfying
This commit is contained in:
parent
780daac03e
commit
2018368d8d
5 changed files with 36 additions and 41 deletions
|
|
@ -6,21 +6,21 @@ Created on 4 Jun 2013
|
||||||
(Hyper-)Parameter domains defined for :py:mod:`~GPy.core.priors` and :py:mod:`~GPy.kern`.
|
(Hyper-)Parameter domains defined for :py:mod:`~GPy.core.priors` and :py:mod:`~GPy.kern`.
|
||||||
These domains specify the legitimate realm of the parameters to live in.
|
These domains specify the legitimate realm of the parameters to live in.
|
||||||
|
|
||||||
:const:`~GPy.core.domains.REAL` :
|
:const:`~GPy.core.domains._REAL` :
|
||||||
real domain, all values in the real numbers are allowed
|
real domain, all values in the real numbers are allowed
|
||||||
|
|
||||||
:const:`~GPy.core.domains.POSITIVE`:
|
:const:`~GPy.core.domains._POSITIVE`:
|
||||||
positive domain, only positive real values are allowed
|
positive domain, only positive real values are allowed
|
||||||
|
|
||||||
:const:`~GPy.core.domains.NEGATIVE`:
|
:const:`~GPy.core.domains._NEGATIVE`:
|
||||||
same as :const:`~GPy.core.domains.POSITIVE`, but only negative values are allowed
|
same as :const:`~GPy.core.domains._POSITIVE`, but only negative values are allowed
|
||||||
|
|
||||||
:const:`~GPy.core.domains.BOUNDED`:
|
:const:`~GPy.core.domains._BOUNDED`:
|
||||||
only values within the bounded range are allowed,
|
only values within the bounded range are allowed,
|
||||||
the bounds are specified withing the object with the bounded range
|
the bounds are specified withing the object with the bounded range
|
||||||
'''
|
'''
|
||||||
|
|
||||||
REAL = 'real'
|
_REAL = 'real'
|
||||||
POSITIVE = "positive"
|
_POSITIVE = "positive"
|
||||||
NEGATIVE = 'negative'
|
_NEGATIVE = 'negative'
|
||||||
BOUNDED = 'bounded'
|
_BOUNDED = 'bounded'
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ from GPy.util.misc import opt_wrapper
|
||||||
from parameterized import Parameterized
|
from parameterized import Parameterized
|
||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from GPy.core.domains import POSITIVE, REAL
|
from GPy.core.domains import _POSITIVE, _REAL
|
||||||
from numpy.linalg.linalg import LinAlgError
|
from numpy.linalg.linalg import LinAlgError
|
||||||
# import numdifftools as ndt
|
# import numdifftools as ndt
|
||||||
|
|
||||||
|
|
@ -93,8 +93,8 @@ class Model(Parameterized):
|
||||||
|
|
||||||
# check constraints are okay
|
# check constraints are okay
|
||||||
|
|
||||||
if what.domain is POSITIVE:
|
if what.domain is _POSITIVE:
|
||||||
constrained_positive_indices = [i for i, t in zip(self.constrained_indices, self.constraints) if t.domain is POSITIVE]
|
constrained_positive_indices = [i for i, t in zip(self.constrained_indices, self.constraints) if t.domain is _POSITIVE]
|
||||||
if len(constrained_positive_indices):
|
if len(constrained_positive_indices):
|
||||||
constrained_positive_indices = np.hstack(constrained_positive_indices)
|
constrained_positive_indices = np.hstack(constrained_positive_indices)
|
||||||
else:
|
else:
|
||||||
|
|
@ -107,7 +107,7 @@ class Model(Parameterized):
|
||||||
print '\n'.join([n for i, n in enumerate(self._get_param_names()) if i in unconst])
|
print '\n'.join([n for i, n in enumerate(self._get_param_names()) if i in unconst])
|
||||||
print '\n'
|
print '\n'
|
||||||
self.constrain_positive(unconst)
|
self.constrain_positive(unconst)
|
||||||
elif what.domain is REAL:
|
elif what.domain is _REAL:
|
||||||
assert not np.any(which[:, None] == self.all_constrained_indices()), "constraint and prior incompatible"
|
assert not np.any(which[:, None] == self.all_constrained_indices()), "constraint and prior incompatible"
|
||||||
else:
|
else:
|
||||||
raise ValueError, "prior not recognised"
|
raise ValueError, "prior not recognised"
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class Parameterized(object):
|
||||||
- m.name regular expression matches all parameters beginning with name
|
- m.name regular expression matches all parameters beginning with name
|
||||||
- m['name'] regular expression matches all parameters with name
|
- m['name'] regular expression matches all parameters with name
|
||||||
|
|
||||||
Handling of constraining, fixing and tieing parameters together:
|
Handling of constraining, fixing and tieing parameters:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -74,28 +74,23 @@ class Parameterized(object):
|
||||||
self.__dict__[p.name] = p
|
self.__dict__[p.name] = p
|
||||||
|
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
# Optimization handling:
|
# Optimization handles:
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return numpy.hstack([x._get_params() for x in self._params])#numpy.fromiter(itertools.chain(*itertools.imap(lambda x: x._get_params(), self._params)), dtype=numpy.float64, count=sum(self.parameter_sizes))
|
return numpy.hstack([x._get_params() for x in self._params])#numpy.fromiter(itertools.chain(*itertools.imap(lambda x: x._get_params(), self._params)), dtype=numpy.float64, count=sum(self.parameter_sizes))
|
||||||
|
|
||||||
def _set_params(self, params):
|
def _set_params(self, params):
|
||||||
[p._set_params(params[s]) for p,s in itertools.izip(self._params,self._param_slices)]
|
[p._set_params(params[s]) for p,s in itertools.izip(self._params,self._param_slices)]
|
||||||
|
|
||||||
def _get_params_transformed(self):
|
def _get_params_transformed(self):
|
||||||
p = self._get_params()
|
p = self._get_params()
|
||||||
[numpy.put(p, ind, c.finv(p[ind])) for c,ind in self._constraints.iteritems() if c is not __fixed__]
|
[numpy.put(p, ind, c.finv(p[ind])) for c,ind in self._constraints.iteritems() if c is not __fixed__]
|
||||||
if self._ties_fixes is not None:
|
if self._ties_fixes is not None:
|
||||||
return p[self._ties_fixes]
|
return p[self._ties_fixes]
|
||||||
return p
|
return p
|
||||||
|
|
||||||
def _set_params_transformed(self, p):
|
def _set_params_transformed(self, p):
|
||||||
if self._ties_fixes is not None: tmp = self._get_params(); tmp[self._ties_fixes] = p; p = tmp; del tmp
|
if self._ties_fixes is not None: tmp = self._get_params(); tmp[self._ties_fixes] = p; p = tmp; del tmp
|
||||||
[numpy.put(p, ind, c.f(p[ind])) for c,ind in self._constraints.iteritems() if c is not __fixed__]
|
[numpy.put(p, ind, c.f(p[ind])) for c,ind in self._constraints.iteritems() if c is not __fixed__]
|
||||||
[numpy.put(p, f, p[t]) for f,t in self._ties.iter_from_to_indices()]
|
[numpy.put(p, f, p[t]) for f,t in self._ties.iter_from_to_indices()]
|
||||||
self._set_params(p)
|
self._set_params(p)
|
||||||
|
|
||||||
def _handle_ties(self):
|
def _handle_ties(self):
|
||||||
if not self._init:
|
if not self._init:
|
||||||
self._set_params_transformed(self._get_params_transformed())
|
self._set_params_transformed(self._get_params_transformed())
|
||||||
|
|
@ -466,7 +461,7 @@ class ParamConcatenation(object):
|
||||||
return "\n".join(map(repr,self.params))
|
return "\n".join(map(repr,self.params))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
X = numpy.random.randn(3,3,2)
|
X = numpy.random.randn(4,2)
|
||||||
p = Param("q_mean", X)
|
p = Param("q_mean", X)
|
||||||
p1 = Param("q_variance", numpy.random.rand(*p.shape))
|
p1 = Param("q_variance", numpy.random.rand(*p.shape))
|
||||||
p2 = Param("Y", numpy.random.randn(p.shape[0],1))
|
p2 = Param("Y", numpy.random.randn(p.shape[0],1))
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import numpy as np
|
||||||
import pylab as pb
|
import pylab as pb
|
||||||
from scipy.special import gammaln, digamma
|
from scipy.special import gammaln, digamma
|
||||||
from ..util.linalg import pdinv
|
from ..util.linalg import pdinv
|
||||||
from GPy.core.domains import REAL, POSITIVE
|
from GPy.core.domains import _REAL, _POSITIVE
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
class Prior:
|
class Prior:
|
||||||
|
|
@ -32,7 +32,7 @@ class Gaussian(Prior):
|
||||||
.. Note:: Bishop 2006 notation is used throughout the code
|
.. Note:: Bishop 2006 notation is used throughout the code
|
||||||
|
|
||||||
"""
|
"""
|
||||||
domain = REAL
|
domain = _REAL
|
||||||
def __init__(self, mu, sigma):
|
def __init__(self, mu, sigma):
|
||||||
self.mu = float(mu)
|
self.mu = float(mu)
|
||||||
self.sigma = float(sigma)
|
self.sigma = float(sigma)
|
||||||
|
|
@ -62,7 +62,7 @@ class LogGaussian(Prior):
|
||||||
.. Note:: Bishop 2006 notation is used throughout the code
|
.. Note:: Bishop 2006 notation is used throughout the code
|
||||||
|
|
||||||
"""
|
"""
|
||||||
domain = POSITIVE
|
domain = _POSITIVE
|
||||||
def __init__(self, mu, sigma):
|
def __init__(self, mu, sigma):
|
||||||
self.mu = float(mu)
|
self.mu = float(mu)
|
||||||
self.sigma = float(sigma)
|
self.sigma = float(sigma)
|
||||||
|
|
@ -92,7 +92,7 @@ class MultivariateGaussian:
|
||||||
.. Note:: Bishop 2006 notation is used throughout the code
|
.. Note:: Bishop 2006 notation is used throughout the code
|
||||||
|
|
||||||
"""
|
"""
|
||||||
domain = REAL
|
domain = _REAL
|
||||||
def __init__(self, mu, var):
|
def __init__(self, mu, var):
|
||||||
self.mu = np.array(mu).flatten()
|
self.mu = np.array(mu).flatten()
|
||||||
self.var = np.array(var)
|
self.var = np.array(var)
|
||||||
|
|
@ -147,7 +147,7 @@ class Gamma(Prior):
|
||||||
.. Note:: Bishop 2006 notation is used throughout the code
|
.. Note:: Bishop 2006 notation is used throughout the code
|
||||||
|
|
||||||
"""
|
"""
|
||||||
domain = POSITIVE
|
domain = _POSITIVE
|
||||||
def __init__(self, a, b):
|
def __init__(self, a, b):
|
||||||
self.a = float(a)
|
self.a = float(a)
|
||||||
self.b = float(b)
|
self.b = float(b)
|
||||||
|
|
@ -198,7 +198,7 @@ class inverse_gamma(Prior):
|
||||||
.. Note:: Bishop 2006 notation is used throughout the code
|
.. Note:: Bishop 2006 notation is used throughout the code
|
||||||
|
|
||||||
"""
|
"""
|
||||||
domain = POSITIVE
|
domain = _POSITIVE
|
||||||
def __init__(self, a, b):
|
def __init__(self, a, b):
|
||||||
self.a = float(a)
|
self.a = float(a)
|
||||||
self.b = float(b)
|
self.b = float(b)
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from GPy.core.domains import POSITIVE, NEGATIVE, BOUNDED
|
from GPy.core.domains import _POSITIVE,_NEGATIVE, _BOUNDED
|
||||||
import sys
|
import sys
|
||||||
import weakref
|
import weakref
|
||||||
lim_val = -np.log(sys.float_info.epsilon)
|
_lim_val = -np.log(sys.float_info.epsilon)
|
||||||
|
|
||||||
class Transformation(object):
|
class Transformation(object):
|
||||||
domain = None
|
domain = None
|
||||||
|
|
@ -29,13 +29,13 @@ class Transformation(object):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
class Logexp(Transformation):
|
class Logexp(Transformation):
|
||||||
domain = POSITIVE
|
domain = _POSITIVE
|
||||||
def f(self, x):
|
def f(self, x):
|
||||||
return np.where(x>lim_val, x, np.log(1. + np.exp(x)))
|
return np.where(x>_lim_val, x, np.log(1. + np.exp(x)))
|
||||||
def finv(self, f):
|
def finv(self, f):
|
||||||
return np.where(f>lim_val, f, np.log(np.exp(f) - 1.))
|
return np.where(f>_lim_val, f, np.log(np.exp(f) - 1.))
|
||||||
def gradfactor(self, f):
|
def gradfactor(self, f):
|
||||||
return np.where(f>lim_val, 1., 1 - np.exp(-f))
|
return np.where(f>_lim_val, 1., 1 - np.exp(-f))
|
||||||
def initialize(self, f):
|
def initialize(self, f):
|
||||||
if np.any(f < 0.):
|
if np.any(f < 0.):
|
||||||
print "Warning: changing parameters to satisfy constraints"
|
print "Warning: changing parameters to satisfy constraints"
|
||||||
|
|
@ -44,7 +44,7 @@ class Logexp(Transformation):
|
||||||
return '+ve'
|
return '+ve'
|
||||||
|
|
||||||
class NegativeLogexp(Transformation):
|
class NegativeLogexp(Transformation):
|
||||||
domain = NEGATIVE
|
domain = _NEGATIVE
|
||||||
logexp = Logexp()
|
logexp = Logexp()
|
||||||
def f(self, x):
|
def f(self, x):
|
||||||
return -self.logexp.f(x) # np.log(1. + np.exp(x))
|
return -self.logexp.f(x) # np.log(1. + np.exp(x))
|
||||||
|
|
@ -62,7 +62,7 @@ class LogexpClipped(Logexp):
|
||||||
min_bound = 1e-10
|
min_bound = 1e-10
|
||||||
log_max_bound = np.log(max_bound)
|
log_max_bound = np.log(max_bound)
|
||||||
log_min_bound = np.log(min_bound)
|
log_min_bound = np.log(min_bound)
|
||||||
domain = POSITIVE
|
domain = _POSITIVE
|
||||||
_instances = []
|
_instances = []
|
||||||
def __new__(cls, lower=1e-6, *args, **kwargs):
|
def __new__(cls, lower=1e-6, *args, **kwargs):
|
||||||
if cls._instances:
|
if cls._instances:
|
||||||
|
|
@ -97,9 +97,9 @@ class LogexpClipped(Logexp):
|
||||||
|
|
||||||
class Exponent(Transformation):
|
class Exponent(Transformation):
|
||||||
# TODO: can't allow this to go to zero, need to set a lower bound. Similar with negative Exponent below. See old MATLAB code.
|
# TODO: can't allow this to go to zero, need to set a lower bound. Similar with negative Exponent below. See old MATLAB code.
|
||||||
domain = POSITIVE
|
domain = _POSITIVE
|
||||||
def f(self, x):
|
def f(self, x):
|
||||||
return np.where(x<lim_val, np.where(x>-lim_val, np.exp(x), np.exp(-lim_val)), np.exp(lim_val))
|
return np.where(x<_lim_val, np.where(x>-_lim_val, np.exp(x), np.exp(-_lim_val)), np.exp(_lim_val))
|
||||||
def finv(self, x):
|
def finv(self, x):
|
||||||
return np.log(x)
|
return np.log(x)
|
||||||
def gradfactor(self, f):
|
def gradfactor(self, f):
|
||||||
|
|
@ -112,7 +112,7 @@ class Exponent(Transformation):
|
||||||
return '+ve'
|
return '+ve'
|
||||||
|
|
||||||
class NegativeExponent(Exponent):
|
class NegativeExponent(Exponent):
|
||||||
domain = NEGATIVE
|
domain = _NEGATIVE
|
||||||
def f(self, x):
|
def f(self, x):
|
||||||
return -Exponent.f(x)
|
return -Exponent.f(x)
|
||||||
def finv(self, f):
|
def finv(self, f):
|
||||||
|
|
@ -125,7 +125,7 @@ class NegativeExponent(Exponent):
|
||||||
return '-ve'
|
return '-ve'
|
||||||
|
|
||||||
class Square(Transformation):
|
class Square(Transformation):
|
||||||
domain = POSITIVE
|
domain = _POSITIVE
|
||||||
def f(self, x):
|
def f(self, x):
|
||||||
return x ** 2
|
return x ** 2
|
||||||
def finv(self, x):
|
def finv(self, x):
|
||||||
|
|
@ -138,7 +138,7 @@ class Square(Transformation):
|
||||||
return '+sq'
|
return '+sq'
|
||||||
|
|
||||||
class Logistic(Transformation):
|
class Logistic(Transformation):
|
||||||
domain = BOUNDED
|
domain = _BOUNDED
|
||||||
_instances = []
|
_instances = []
|
||||||
def __new__(cls, lower=1e-6, upper=1e-6, *args, **kwargs):
|
def __new__(cls, lower=1e-6, upper=1e-6, *args, **kwargs):
|
||||||
if cls._instances:
|
if cls._instances:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue