mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-05-09 03:52:39 +02:00
gradcheck fixes are not easy
This commit is contained in:
parent
c78ddde6de
commit
9af4c34f90
4 changed files with 42 additions and 29 deletions
|
|
@ -411,12 +411,21 @@ class Model(Parameterized):
|
||||||
f2 = self.objective_function(x - dx)
|
f2 = self.objective_function(x - dx)
|
||||||
gradient = self.objective_function_gradients(x)
|
gradient = self.objective_function_gradients(x)
|
||||||
|
|
||||||
param_list = self._raveled_index_for(target_param)
|
if target_param is None:
|
||||||
|
transformed_index = range(len(x))
|
||||||
|
else:
|
||||||
|
transformed_index = self._raveled_index_for(target_param)
|
||||||
if self._has_fixes():
|
if self._has_fixes():
|
||||||
param_list = np.intersect1d(np.r_[:self.size][self._fixes_], param_list, True)
|
indices = np.r_[:self.size]
|
||||||
|
which = (transformed_index[:,None]==indices[self._fixes_]).nonzero()[0]
|
||||||
|
indices -= (~self._fixes_).cumsum()
|
||||||
|
transformed_index = indices[which]
|
||||||
|
|
||||||
|
if transformed_index.size == 0:
|
||||||
|
print "No free parameters to check"
|
||||||
|
return
|
||||||
|
|
||||||
|
gradient = gradient[transformed_index]
|
||||||
numerical_gradient = (f1 - f2) / (2 * dx)
|
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)))
|
||||||
|
|
||||||
|
|
@ -439,40 +448,46 @@ class Model(Parameterized):
|
||||||
separator = '-' * len(header_string[0])
|
separator = '-' * len(header_string[0])
|
||||||
print '\n'.join([header_string[0], separator])
|
print '\n'.join([header_string[0], separator])
|
||||||
if target_param is None:
|
if target_param is None:
|
||||||
param_list = range(len(x))
|
param_index = range(len(x))
|
||||||
|
transformed_index = param_index
|
||||||
else:
|
else:
|
||||||
param_list = self._raveled_index_for(target_param)
|
param_index = self._raveled_index_for(target_param)
|
||||||
if self._has_fixes():
|
if self._has_fixes():
|
||||||
param_list = np.intersect1d(np.r_[:self.size][self._fixes_], param_list, True)
|
indices = np.r_[:self.size]
|
||||||
|
which = (param_index[:,None]==indices[self._fixes_][None,:]).nonzero()
|
||||||
|
transformed_index = (indices-(~self._fixes_).cumsum())[which[1]]
|
||||||
|
param_index = indices[which[0]]
|
||||||
|
print param_index, transformed_index
|
||||||
|
else:
|
||||||
|
transformed_index = param_index
|
||||||
|
|
||||||
if param_list.size == 0:
|
if param_index.size == 0:
|
||||||
print "No free parameters to check"
|
print "No free parameters to check"
|
||||||
return
|
return
|
||||||
|
|
||||||
gradient = self.objective_function_gradients(x)
|
gradient = self.objective_function_gradients(x)
|
||||||
np.where(gradient == 0, 1e-312, gradient)
|
np.where(gradient == 0, 1e-312, gradient)
|
||||||
ret = True
|
ret = True
|
||||||
for i, ind in enumerate(param_list):
|
for nind, xind in itertools.izip(param_index, transformed_index):
|
||||||
xx = x.copy()
|
xx = x.copy()
|
||||||
xx[ind] += step
|
xx[xind] += step
|
||||||
f1 = self.objective_function(xx)
|
f1 = self.objective_function(xx)
|
||||||
xx[ind] -= 2.*step
|
xx[xind] -= 2.*step
|
||||||
f2 = self.objective_function(xx)
|
f2 = self.objective_function(xx)
|
||||||
print ind
|
|
||||||
numerical_gradient = (f1 - f2) / (2 * step)
|
numerical_gradient = (f1 - f2) / (2 * step)
|
||||||
ratio = (f1 - f2) / (2 * step * gradient[ind])
|
ratio = (f1 - f2) / (2 * step * gradient[xind])
|
||||||
difference = np.abs((f1 - f2) / 2 / step - gradient[ind])
|
difference = np.abs((f1 - f2) / 2 / step - gradient[xind])
|
||||||
|
|
||||||
if (np.abs(1. - ratio) < tolerance) or np.abs(difference) < tolerance:
|
if (np.abs(1. - ratio) < tolerance) or np.abs(difference) < tolerance:
|
||||||
formatted_name = "\033[92m {0} \033[0m".format(names[ind])
|
formatted_name = "\033[92m {0} \033[0m".format(names[nind])
|
||||||
ret &= True
|
ret &= True
|
||||||
else:
|
else:
|
||||||
formatted_name = "\033[91m {0} \033[0m".format(names[ind])
|
formatted_name = "\033[91m {0} \033[0m".format(names[nind])
|
||||||
ret &= False
|
ret &= False
|
||||||
|
|
||||||
r = '%.6f' % float(ratio)
|
r = '%.6f' % float(ratio)
|
||||||
d = '%.6f' % float(difference)
|
d = '%.6f' % float(difference)
|
||||||
g = '%.6f' % gradient[ind]
|
g = '%.6f' % gradient[xind]
|
||||||
ng = '%.6f' % float(numerical_gradient)
|
ng = '%.6f' % float(numerical_gradient)
|
||||||
grad_string = "{0:<{c0}}|{1:^{c1}}|{2:^{c2}}|{3:^{c3}}|{4:^{c4}}".format(formatted_name, r, d, g, ng, c0=cols[0] + 9, c1=cols[1], c2=cols[2], c3=cols[3], c4=cols[4])
|
grad_string = "{0:<{c0}}|{1:^{c1}}|{2:^{c2}}|{3:^{c3}}|{4:^{c4}}".format(formatted_name, r, d, g, ng, c0=cols[0] + 9, c1=cols[1], c2=cols[2], c3=cols[3], c4=cols[4])
|
||||||
print grad_string
|
print grad_string
|
||||||
|
|
|
||||||
|
|
@ -348,7 +348,7 @@ class Param(ObservableArray, Constrainable, Gradcheckable, Indexable, Parameteri
|
||||||
def _description_str(self):
|
def _description_str(self):
|
||||||
if self.size <= 1: return ["%f" % self]
|
if self.size <= 1: return ["%f" % self]
|
||||||
else: return [str(self.shape)]
|
else: return [str(self.shape)]
|
||||||
def _parameter_names(self, add_name):
|
def parameter_names(self, add_name=False):
|
||||||
return [self.name]
|
return [self.name]
|
||||||
@property
|
@property
|
||||||
def flattened_parameters(self):
|
def flattened_parameters(self):
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,10 @@ class Parameterizable(object):
|
||||||
from GPy.core.parameterization.array_core import ParamList
|
from GPy.core.parameterization.array_core import ParamList
|
||||||
_parameters_ = ParamList()
|
_parameters_ = ParamList()
|
||||||
|
|
||||||
def parameter_names(self):
|
def parameter_names(self, add_name=False):
|
||||||
return [p.name for p in self._parameters_]
|
if add_name:
|
||||||
|
return [adjust_name_for_printing(self.name) + "." + xi for x in self._parameters_ for xi in x.parameter_names(add_name=True)]
|
||||||
|
return [xi for x in self._parameters_ for xi in x.parameter_names(add_name=True)]
|
||||||
|
|
||||||
def parameters_changed(self):
|
def parameters_changed(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -209,7 +211,7 @@ class Constrainable(Nameable, Indexable, Parameterizable):
|
||||||
reconstrained = self.unconstrain()
|
reconstrained = self.unconstrain()
|
||||||
self.constraints.add(transform, self._raveled_index())
|
self.constraints.add(transform, self._raveled_index())
|
||||||
if warning and reconstrained.size > 0:
|
if warning and reconstrained.size > 0:
|
||||||
print "WARNING: reconstraining parameters {}".format(self.parameter_names)
|
print "WARNING: reconstraining parameters {}".format(self.parameter_names() or self.name)
|
||||||
if update:
|
if update:
|
||||||
self._highest_parent_.parameters_changed()
|
self._highest_parent_.parameters_changed()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -434,11 +434,7 @@ class Parameterized(Constrainable, Pickleable, Observable, Gradcheckable):
|
||||||
return self._direct_parent_.hirarchy_name() + adjust_name_for_printing(self.name)
|
return self._direct_parent_.hirarchy_name() + adjust_name_for_printing(self.name)
|
||||||
else:
|
else:
|
||||||
return adjust_name_for_printing(self.name)
|
return adjust_name_for_printing(self.name)
|
||||||
def _parameter_names(self, add_name=False):
|
#parameter_names = property(parameter_names, doc="Names for all parameters handled by this parameterization object -- will add hirarchy name entries for printing")
|
||||||
if add_name:
|
|
||||||
return [adjust_name_for_printing(self.name) + "." + xi for x in self._parameters_ for xi in x._parameter_names(add_name=True)]
|
|
||||||
return [xi for x in self._parameters_ for xi in x._parameter_names(add_name=True)]
|
|
||||||
parameter_names = property(_parameter_names, doc="Names for all parameters handled by this parameterization object -- will add hirarchy name entries for printing")
|
|
||||||
def _collect_gradient(self, target):
|
def _collect_gradient(self, target):
|
||||||
[p._collect_gradient(target[s]) for p, s in itertools.izip(self._parameters_, self._param_slices_)]
|
[p._collect_gradient(target[s]) for p, s in itertools.izip(self._parameters_, self._param_slices_)]
|
||||||
@property
|
@property
|
||||||
|
|
@ -468,7 +464,7 @@ class Parameterized(Constrainable, Pickleable, Observable, Gradcheckable):
|
||||||
|
|
||||||
name = adjust_name_for_printing(self.name) + "."
|
name = adjust_name_for_printing(self.name) + "."
|
||||||
constrs = self._constraints_str; ts = self._ties_str
|
constrs = self._constraints_str; ts = self._ties_str
|
||||||
desc = self._description_str; names = self.parameter_names
|
desc = self._description_str; names = self.parameter_names()
|
||||||
nl = max([len(str(x)) for x in names + [name]])
|
nl = max([len(str(x)) for x in names + [name]])
|
||||||
sl = max([len(str(x)) for x in desc + ["Value"]])
|
sl = max([len(str(x)) for x in desc + ["Value"]])
|
||||||
cl = max([len(str(x)) if x else 0 for x in constrs + ["Constraint"]])
|
cl = max([len(str(x)) if x else 0 for x in constrs + ["Constraint"]])
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue