mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-05-07 19:12:40 +02:00
expand_param and extract_param replaced with set_params_transformed and get_params_transformed
This commit is contained in:
parent
7350143dd0
commit
1674bc529b
8 changed files with 54 additions and 54 deletions
|
|
@ -115,7 +115,7 @@ class model(parameterised):
|
||||||
[np.put(ret,i,p.lnpdf_grad(xx)) for i,(p,xx) in enumerate(zip(self.priors,x)) if not p is None]
|
[np.put(ret,i,p.lnpdf_grad(xx)) for i,(p,xx) in enumerate(zip(self.priors,x)) if not p is None]
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def extract_gradients(self):
|
def _log_likelihood_gradients_transformed(self):
|
||||||
"""
|
"""
|
||||||
Use self.log_likelihood_gradients and self.prior_gradients to get the gradients of the model.
|
Use self.log_likelihood_gradients and self.prior_gradients to get the gradients of the model.
|
||||||
Adjust the gradient for constraints and ties, return.
|
Adjust the gradient for constraints and ties, return.
|
||||||
|
|
@ -138,14 +138,14 @@ class model(parameterised):
|
||||||
Make this draw from the prior if one exists, else draw from N(0,1)
|
Make this draw from the prior if one exists, else draw from N(0,1)
|
||||||
"""
|
"""
|
||||||
#first take care of all parameters (from N(0,1))
|
#first take care of all parameters (from N(0,1))
|
||||||
x = self.extract_param()
|
x = self._get_params_transformed()
|
||||||
x = np.random.randn(x.size)
|
x = np.random.randn(x.size)
|
||||||
self.expand_param(x)
|
self._set_params_transformed(x)
|
||||||
#now draw from prior where possible
|
#now draw from prior where possible
|
||||||
x = self._get_params()
|
x = self._get_params()
|
||||||
[np.put(x,i,p.rvs(1)) for i,p in enumerate(self.priors) if not p is None]
|
[np.put(x,i,p.rvs(1)) for i,p in enumerate(self.priors) if not p is None]
|
||||||
self._set_params(x)
|
self._set_params(x)
|
||||||
self.expand_param(self.extract_param())#makes sure all of the tied parameters get the same init (since there's only one prior object...)
|
self._set_params_transformed(self._get_params_transformed())#makes sure all of the tied parameters get the same init (since there's only one prior object...)
|
||||||
|
|
||||||
|
|
||||||
def optimize_restarts(self, Nrestarts=10, robust=False, verbose=True, **kwargs):
|
def optimize_restarts(self, Nrestarts=10, robust=False, verbose=True, **kwargs):
|
||||||
|
|
@ -165,7 +165,7 @@ class model(parameterised):
|
||||||
:verbose: whether to show informations about the current restart
|
:verbose: whether to show informations about the current restart
|
||||||
"""
|
"""
|
||||||
|
|
||||||
initial_parameters = self.extract_param()
|
initial_parameters = self._get_params_transformed()
|
||||||
for i in range(Nrestarts):
|
for i in range(Nrestarts):
|
||||||
try:
|
try:
|
||||||
self.randomize()
|
self.randomize()
|
||||||
|
|
@ -182,9 +182,9 @@ class model(parameterised):
|
||||||
raise e
|
raise e
|
||||||
if len(self.optimization_runs):
|
if len(self.optimization_runs):
|
||||||
i = np.argmax([o.f_opt for o in self.optimization_runs])
|
i = np.argmax([o.f_opt for o in self.optimization_runs])
|
||||||
self.expand_param(self.optimization_runs[i].x_opt)
|
self._set_params_transformed(self.optimization_runs[i].x_opt)
|
||||||
else:
|
else:
|
||||||
self.expand_param(initial_parameters)
|
self._set_params_transformed(initial_parameters)
|
||||||
|
|
||||||
def ensure_default_constraints(self,warn=False):
|
def ensure_default_constraints(self,warn=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -214,24 +214,24 @@ class model(parameterised):
|
||||||
optimizer = self.preferred_optimizer
|
optimizer = self.preferred_optimizer
|
||||||
|
|
||||||
def f(x):
|
def f(x):
|
||||||
self.expand_param(x)
|
self._set_params_transformed(x)
|
||||||
return -self.log_likelihood()-self.log_prior()
|
return -self.log_likelihood()-self.log_prior()
|
||||||
def fp(x):
|
def fp(x):
|
||||||
self.expand_param(x)
|
self._set_params_transformed(x)
|
||||||
return -self.extract_gradients()
|
return -self._log_likelihood_gradients_transformed()
|
||||||
def f_fp(x):
|
def f_fp(x):
|
||||||
self.expand_param(x)
|
self._set_params_transformed(x)
|
||||||
return -self.log_likelihood()-self.log_prior(),-self.extract_gradients()
|
return -self.log_likelihood()-self.log_prior(),-self._log_likelihood_gradients_transformed()
|
||||||
|
|
||||||
if start == None:
|
if start == None:
|
||||||
start = self.extract_param()
|
start = self._get_params_transformed()
|
||||||
|
|
||||||
optimizer = optimization.get_optimizer(optimizer)
|
optimizer = optimization.get_optimizer(optimizer)
|
||||||
opt = optimizer(start, model = self, **kwargs)
|
opt = optimizer(start, model = self, **kwargs)
|
||||||
opt.run(f_fp=f_fp, f=f, fp=fp)
|
opt.run(f_fp=f_fp, f=f, fp=fp)
|
||||||
self.optimization_runs.append(opt)
|
self.optimization_runs.append(opt)
|
||||||
|
|
||||||
self.expand_param(opt.x_opt)
|
self._set_params_transformed(opt.x_opt)
|
||||||
|
|
||||||
def optimize_SGD(self, momentum = 0.1, learning_rate = 0.01, iterations = 20, **kwargs):
|
def optimize_SGD(self, momentum = 0.1, learning_rate = 0.01, iterations = 20, **kwargs):
|
||||||
# assert self.Y.shape[1] > 1, "SGD only works with D > 1"
|
# assert self.Y.shape[1] > 1, "SGD only works with D > 1"
|
||||||
|
|
@ -292,18 +292,18 @@ class model(parameterised):
|
||||||
If the overall gradient fails, invividual components are tested.
|
If the overall gradient fails, invividual components are tested.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
x = self.extract_param().copy()
|
x = self._get_params_transformed().copy()
|
||||||
|
|
||||||
#choose a random direction to step in:
|
#choose a random direction to step in:
|
||||||
dx = step*np.sign(np.random.uniform(-1,1,x.size))
|
dx = step*np.sign(np.random.uniform(-1,1,x.size))
|
||||||
|
|
||||||
#evaulate around the point x
|
#evaulate around the point x
|
||||||
self.expand_param(x+dx)
|
self._set_params_transformed(x+dx)
|
||||||
f1,g1 = self.log_likelihood() + self.log_prior(), self.extract_gradients()
|
f1,g1 = self.log_likelihood() + self.log_prior(), self._log_likelihood_gradients_transformed()
|
||||||
self.expand_param(x-dx)
|
self._set_params_transformed(x-dx)
|
||||||
f2,g2 = self.log_likelihood() + self.log_prior(), self.extract_gradients()
|
f2,g2 = self.log_likelihood() + self.log_prior(), self._log_likelihood_gradients_transformed()
|
||||||
self.expand_param(x)
|
self._set_params_transformed(x)
|
||||||
gradient = self.extract_gradients()
|
gradient = self._log_likelihood_gradients_transformed()
|
||||||
|
|
||||||
numerical_gradient = (f1-f2)/(2*dx)
|
numerical_gradient = (f1-f2)/(2*dx)
|
||||||
ratio = (f1-f2)/(2*np.dot(dx,gradient))
|
ratio = (f1-f2)/(2*np.dot(dx,gradient))
|
||||||
|
|
@ -319,7 +319,7 @@ class model(parameterised):
|
||||||
print "Global check failed. Testing individual gradients\n"
|
print "Global check failed. Testing individual gradients\n"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
names = self.extract_param_names()
|
names = self._get_param_names_transformed()
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
names = ['Variable %i'%i for i in range(len(x))]
|
names = ['Variable %i'%i for i in range(len(x))]
|
||||||
|
|
||||||
|
|
@ -338,13 +338,13 @@ class model(parameterised):
|
||||||
for i in range(len(x)):
|
for i in range(len(x)):
|
||||||
xx = x.copy()
|
xx = x.copy()
|
||||||
xx[i] += step
|
xx[i] += step
|
||||||
self.expand_param(xx)
|
self._set_params_transformed(xx)
|
||||||
f1,g1 = self.log_likelihood() + self.log_prior(), self.extract_gradients()[i]
|
f1,g1 = self.log_likelihood() + self.log_prior(), self._log_likelihood_gradients_transformed()[i]
|
||||||
xx[i] -= 2.*step
|
xx[i] -= 2.*step
|
||||||
self.expand_param(xx)
|
self._set_params_transformed(xx)
|
||||||
f2,g2 = self.log_likelihood() + self.log_prior(), self.extract_gradients()[i]
|
f2,g2 = self.log_likelihood() + self.log_prior(), self._log_likelihood_gradients_transformed()[i]
|
||||||
self.expand_param(x)
|
self._set_params_transformed(x)
|
||||||
gradient = self.extract_gradients()[i]
|
gradient = self._log_likelihood_gradients_transformed()[i]
|
||||||
|
|
||||||
|
|
||||||
numerical_gradient = (f1-f2)/(2*step)
|
numerical_gradient = (f1-f2)/(2*step)
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ class parameterised(object):
|
||||||
if hasattr(self,'prior'):
|
if hasattr(self,'prior'):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.expand_param(self.extract_param())# sets tied parameters to single value
|
self._set_params_transformed(self._get_params_transformed())# sets tied parameters to single value
|
||||||
|
|
||||||
def untie_everything(self):
|
def untie_everything(self):
|
||||||
"""Unties all parameters by setting tied_indices to an empty list."""
|
"""Unties all parameters by setting tied_indices to an empty list."""
|
||||||
|
|
@ -216,9 +216,9 @@ class parameterised(object):
|
||||||
self.constrained_fixed_values.append(self._get_params()[self.constrained_fixed_indices[-1]])
|
self.constrained_fixed_values.append(self._get_params()[self.constrained_fixed_indices[-1]])
|
||||||
|
|
||||||
#self.constrained_fixed_values.append(value)
|
#self.constrained_fixed_values.append(value)
|
||||||
self.expand_param(self.extract_param())
|
self._set_params_transformed(self._get_params_transformed())
|
||||||
|
|
||||||
def extract_param(self):
|
def _get_params_transformed(self):
|
||||||
"""use self._get_params to get the 'true' parameters of the model, which are then tied, constrained and fixed"""
|
"""use self._get_params to get the 'true' parameters of the model, which are then tied, constrained and fixed"""
|
||||||
x = self._get_params()
|
x = self._get_params()
|
||||||
x[self.constrained_positive_indices] = np.log(x[self.constrained_positive_indices])
|
x[self.constrained_positive_indices] = np.log(x[self.constrained_positive_indices])
|
||||||
|
|
@ -232,7 +232,7 @@ class parameterised(object):
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
def expand_param(self,x):
|
def _set_params_transformed(self,x):
|
||||||
""" takes the vector x, which is then modified (by untying, reparameterising or inserting fixed values), and then call self._set_params"""
|
""" takes the vector x, which is then modified (by untying, reparameterising or inserting fixed values), and then call self._set_params"""
|
||||||
|
|
||||||
#work out how many places are fixed, and where they are. tricky logic!
|
#work out how many places are fixed, and where they are. tricky logic!
|
||||||
|
|
@ -259,10 +259,10 @@ class parameterised(object):
|
||||||
[np.put(xx,i,low+sigmoid(xx[i])*(high-low)) for i,low,high in zip(self.constrained_bounded_indices, self.constrained_bounded_lowers, self.constrained_bounded_uppers)]
|
[np.put(xx,i,low+sigmoid(xx[i])*(high-low)) for i,low,high in zip(self.constrained_bounded_indices, self.constrained_bounded_lowers, self.constrained_bounded_uppers)]
|
||||||
self._set_params(xx)
|
self._set_params(xx)
|
||||||
|
|
||||||
def extract_param_names(self):
|
def _get_param_names_transformed(self):
|
||||||
"""
|
"""
|
||||||
Returns the parameter names as propagated after constraining,
|
Returns the parameter names as propagated after constraining,
|
||||||
tying or fixing, i.e. a list of the same length as extract_param()
|
tying or fixing, i.e. a list of the same length as _get_params_transformed()
|
||||||
"""
|
"""
|
||||||
n = self._get_param_names()
|
n = self._get_param_names()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class Metropolis_Hastings:
|
||||||
def __init__(self,model,cov=None):
|
def __init__(self,model,cov=None):
|
||||||
"""Metropolis Hastings, with tunings according to Gelman et al. """
|
"""Metropolis Hastings, with tunings according to Gelman et al. """
|
||||||
self.model = model
|
self.model = model
|
||||||
current = self.model.extract_param()
|
current = self.model._get_params_transformed()
|
||||||
self.D = current.size
|
self.D = current.size
|
||||||
self.chains = []
|
self.chains = []
|
||||||
if cov is None:
|
if cov is None:
|
||||||
|
|
@ -32,19 +32,19 @@ class Metropolis_Hastings:
|
||||||
if start is None:
|
if start is None:
|
||||||
self.model.randomize()
|
self.model.randomize()
|
||||||
else:
|
else:
|
||||||
self.model.expand_param(start)
|
self.model._set_params_transformed(start)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def sample(self, Ntotal, Nburn, Nthin, tune=True, tune_throughout=False, tune_interval=400):
|
def sample(self, Ntotal, Nburn, Nthin, tune=True, tune_throughout=False, tune_interval=400):
|
||||||
current = self.model.extract_param()
|
current = self.model._get_params_transformed()
|
||||||
fcurrent = self.model.log_likelihood() + self.model.log_prior()
|
fcurrent = self.model.log_likelihood() + self.model.log_prior()
|
||||||
accepted = np.zeros(Ntotal,dtype=np.bool)
|
accepted = np.zeros(Ntotal,dtype=np.bool)
|
||||||
for it in range(Ntotal):
|
for it in range(Ntotal):
|
||||||
print "sample %d of %d\r"%(it,Ntotal),
|
print "sample %d of %d\r"%(it,Ntotal),
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
prop = np.random.multivariate_normal(current, self.cov*self.scale*self.scale)
|
prop = np.random.multivariate_normal(current, self.cov*self.scale*self.scale)
|
||||||
self.model.expand_param(prop)
|
self.model._set_params_transformed(prop)
|
||||||
fprop = self.model.log_likelihood() + self.model.log_prior()
|
fprop = self.model.log_likelihood() + self.model.log_prior()
|
||||||
|
|
||||||
if fprop>fcurrent:#sample accepted, going 'uphill'
|
if fprop>fcurrent:#sample accepted, going 'uphill'
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,10 @@ class GPLVM(GP_regression):
|
||||||
|
|
||||||
def _get_param_names(self):
|
def _get_param_names(self):
|
||||||
return (sum([['X_%i_%i'%(n,q) for n in range(self.N)] for q in range(self.Q)],[])
|
return (sum([['X_%i_%i'%(n,q) for n in range(self.N)] for q in range(self.Q)],[])
|
||||||
+ self.kern.extract_param_names())
|
+ self.kern._get_param_names_transformed())
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return np.hstack((self.X.flatten(), self.kern.extract_param()))
|
return np.hstack((self.X.flatten(), self.kern._get_params_transformed()))
|
||||||
|
|
||||||
def _set_params(self,x):
|
def _set_params(self,x):
|
||||||
self.X = x[:self.X.size].reshape(self.N,self.Q).copy()
|
self.X = x[:self.X.size].reshape(self.N,self.Q).copy()
|
||||||
|
|
|
||||||
|
|
@ -42,13 +42,13 @@ class GP_EP(model):
|
||||||
model.__init__(self)
|
model.__init__(self)
|
||||||
|
|
||||||
def _set_params(self,p):
|
def _set_params(self,p):
|
||||||
self.kernel.expand_param(p)
|
self.kernel._set_params_transformed(p)
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return self.kernel.extract_param()
|
return self.kernel._get_params_transformed()
|
||||||
|
|
||||||
def _get_param_names(self):
|
def _get_param_names(self):
|
||||||
return self.kernel.extract_param_names()
|
return self.kernel._get_param_names_transformed()
|
||||||
|
|
||||||
def approximate_likelihood(self):
|
def approximate_likelihood(self):
|
||||||
self.ep_approx = Full(self.K,self.likelihood,epsilon=self.epsilon_ep,powerep=[self.eta,self.delta])
|
self.ep_approx = Full(self.K,self.likelihood,epsilon=self.epsilon_ep,powerep=[self.eta,self.delta])
|
||||||
|
|
@ -150,8 +150,8 @@ class GP_EP(model):
|
||||||
log_likelihood_change = log_likelihood_new - self.log_likelihood_path[-1]
|
log_likelihood_change = log_likelihood_new - self.log_likelihood_path[-1]
|
||||||
if log_likelihood_change < 0:
|
if log_likelihood_change < 0:
|
||||||
print 'log_likelihood decrement'
|
print 'log_likelihood decrement'
|
||||||
self.kernel.expand_param(self.parameters_path[-1])
|
self.kernel._set_params_transformed(self.parameters_path[-1])
|
||||||
self.kernM.expand_param(self.parameters_path[-1])
|
self.kernM._set_params_transformed(self.parameters_path[-1])
|
||||||
else:
|
else:
|
||||||
self.approximate_likelihood()
|
self.approximate_likelihood()
|
||||||
self.log_likelihood_path.append(self.log_likelihood())
|
self.log_likelihood_path.append(self.log_likelihood())
|
||||||
|
|
|
||||||
|
|
@ -71,15 +71,15 @@ class GP_regression(model):
|
||||||
model.__init__(self)
|
model.__init__(self)
|
||||||
|
|
||||||
def _set_params(self,p):
|
def _set_params(self,p):
|
||||||
self.kern.expand_param(p)
|
self.kern._set_params_transformed(p)
|
||||||
self.K = self.kern.K(self.X,slices1=self.Xslices)
|
self.K = self.kern.K(self.X,slices1=self.Xslices)
|
||||||
self.Ki, self.L, self.Li, self.K_logdet = pdinv(self.K)
|
self.Ki, self.L, self.Li, self.K_logdet = pdinv(self.K)
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return self.kern.extract_param()
|
return self.kern._get_params_transformed()
|
||||||
|
|
||||||
def _get_param_names(self):
|
def _get_param_names(self):
|
||||||
return self.kern.extract_param_names()
|
return self.kern._get_params_names_transformed()
|
||||||
|
|
||||||
def _model_fit_term(self):
|
def _model_fit_term(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,14 @@ class generalized_FITC(model):
|
||||||
model.__init__(self)
|
model.__init__(self)
|
||||||
|
|
||||||
def _set_params(self,p):
|
def _set_params(self,p):
|
||||||
self.kernel.expand_param(p[0:-self.Z.size])
|
self.kernel._set_params_transformed(p[0:-self.Z.size])
|
||||||
self.Z = p[-self.Z.size:].reshape(self.M,self.D)
|
self.Z = p[-self.Z.size:].reshape(self.M,self.D)
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return np.hstack([self.kernel.extract_param(),self.Z.flatten()])
|
return np.hstack([self.kernel._get_params_transformed(),self.Z.flatten()])
|
||||||
|
|
||||||
def _get_param_names(self):
|
def _get_param_names(self):
|
||||||
return self.kernel.extract_param_names()+['iip_%i'%i for i in range(self.Z.size)]
|
return self.kernel._get_param_names_transformed()+['iip_%i'%i for i in range(self.Z.size)]
|
||||||
|
|
||||||
def approximate_likelihood(self):
|
def approximate_likelihood(self):
|
||||||
self.Kmm = self.kernel.K(self.Z)
|
self.Kmm = self.kernel.K(self.Z)
|
||||||
|
|
@ -227,7 +227,7 @@ class generalized_FITC(model):
|
||||||
log_likelihood_change = log_likelihood_new - self.log_likelihood_path[-1]
|
log_likelihood_change = log_likelihood_new - self.log_likelihood_path[-1]
|
||||||
if log_likelihood_change < 0:
|
if log_likelihood_change < 0:
|
||||||
print 'log_likelihood decrement'
|
print 'log_likelihood decrement'
|
||||||
self.kernel.expand_param(self.parameters_path[-1])
|
self.kernel._set_params_transformed(self.parameters_path[-1])
|
||||||
self.kernM = self.kernel.copy()
|
self.kernM = self.kernel.copy()
|
||||||
slef.kernM.expand_X(self.iducing_inputs_path[-1])
|
slef.kernM.expand_X(self.iducing_inputs_path[-1])
|
||||||
self.__init__(self.kernel,self.likelihood,kernM=self.kernM,powerep=[self.eta,self.delta],epsilon_ep = self.epsilon_ep, epsilon_em = self.epsilon_em)
|
self.__init__(self.kernel,self.likelihood,kernM=self.kernM,powerep=[self.eta,self.delta],epsilon_ep = self.epsilon_ep, epsilon_em = self.epsilon_em)
|
||||||
|
|
|
||||||
|
|
@ -107,10 +107,10 @@ class sparse_GP_regression(GP_regression):
|
||||||
self.dL_dKmm += np.dot(np.dot(self.G,self.beta*self.psi2) - np.dot(self.LBL_inv, self.psi1VVpsi1), self.Kmmi) + 0.5*self.G # dE
|
self.dL_dKmm += np.dot(np.dot(self.G,self.beta*self.psi2) - np.dot(self.LBL_inv, self.psi1VVpsi1), self.Kmmi) + 0.5*self.G # dE
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return np.hstack([self.Z.flatten(),self.beta,self.kern.extract_param()])
|
return np.hstack([self.Z.flatten(),self.beta,self.kern._get_params_transformed()])
|
||||||
|
|
||||||
def _get_param_names(self):
|
def _get_param_names(self):
|
||||||
return sum([['iip_%i_%i'%(i,j) for i in range(self.Z.shape[0])] for j in range(self.Z.shape[1])],[]) + ['noise_precision']+self.kern.extract_param_names()
|
return sum([['iip_%i_%i'%(i,j) for i in range(self.Z.shape[0])] for j in range(self.Z.shape[1])],[]) + ['noise_precision']+self.kern._get_param_names_transformed()
|
||||||
|
|
||||||
def log_likelihood(self):
|
def log_likelihood(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue