From 3aedf63966e4c8b6f6734d08e116afdfa8ac5d79 Mon Sep 17 00:00:00 2001 From: Max Zwiessele Date: Mon, 12 Jan 2015 11:36:53 +0000 Subject: [PATCH] [natural gradients] added natural gradients, usable but not analysed --- GPy/core/parameterization/parameter_core.py | 11 +++++++++++ GPy/core/parameterization/transformations.py | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/GPy/core/parameterization/parameter_core.py b/GPy/core/parameterization/parameter_core.py index 6add95b0..a15d8d53 100644 --- a/GPy/core/parameterization/parameter_core.py +++ b/GPy/core/parameterization/parameter_core.py @@ -683,6 +683,17 @@ class OptimizationHandlable(Indexable): [np.put(g, i, c.gradfactor(self.param_array[i], g[i])) for c, i in self.constraints.iteritems() if c != __fixed__] if self._has_fixes(): return g[self._fixes_] return g + + def _transform_gradients_non_natural(self, g): + """ + Transform the gradients by multiplying the gradient factor for each + constraint to it. + """ + self._highest_parent_.tie.collate_gradient() + [np.put(g, i, c.gradfactor_non_natural(self.param_array[i], g[i])) for c, i in self.constraints.iteritems() if c != __fixed__] + if self._has_fixes(): return g[self._fixes_] + return g + @property def num_params(self): diff --git a/GPy/core/parameterization/transformations.py b/GPy/core/parameterization/transformations.py index 235b9d1c..be08f870 100644 --- a/GPy/core/parameterization/transformations.py +++ b/GPy/core/parameterization/transformations.py @@ -42,6 +42,8 @@ class Transformation(object): \frac{\frac{\partial L}{\partial f}\left(\left.\partial f(x)}{\partial x}\right|_{x=f^{-1}(f)\right)} """ raise NotImplementedError + def gradfactor_non_natural(self, model_param, dL_dmodel_param): + return self.gradfactor(model_param, dL_dmodel_param) def initialize(self, f): """ produce a sensible initial value for f(x)""" raise NotImplementedError @@ -98,6 +100,7 @@ class NormalTheta(Transformation): # that the values are ok # Before: theta[self.var_indices] = np.abs(-.5/theta[self.var_indices]) + #theta[self.var_indices] = np.exp(-.5/theta[self.var_indices]) theta[self.mu_indices] *= theta[self.var_indices] return theta # which is now {mu, var} @@ -106,6 +109,7 @@ class NormalTheta(Transformation): varp = muvar[self.var_indices] muvar[self.mu_indices] /= varp muvar[self.var_indices] = -.5/varp + #muvar[self.var_indices] = -.5/np.log(varp) return muvar # which is now {theta1, theta2} @@ -250,6 +254,19 @@ class NormalNaturalThroughTheta(NormalTheta): #======================================================================= return dmuvar # which is now the gradient multiplicator + def gradfactor_non_natural(self, muvar, dmuvar): + mu = muvar[self.mu_indices] + var = muvar[self.var_indices] + #======================================================================= + # theta gradients + # This works and the gradient checks! + dmuvar[self.mu_indices] *= var + dmuvar[self.var_indices] *= 2*(var)**2 + dmuvar[self.var_indices] += 2*dmuvar[self.mu_indices]*mu + #======================================================================= + + return dmuvar # which is now the gradient multiplicator for {theta1, theta2} + def __str__(self): return "natgrad"