diff --git a/GPy/core/parameterization/parameter_core.py b/GPy/core/parameterization/parameter_core.py index 2a036378..f17f7d55 100644 --- a/GPy/core/parameterization/parameter_core.py +++ b/GPy/core/parameterization/parameter_core.py @@ -862,6 +862,25 @@ class Parameterizable(OptimizationHandlable): self._param_array_ = np.empty(self.size, dtype=np.float64) return self._param_array_ + @property + def unfixed_param_array(self): + """ + Array representing the parameters of this class. + There is only one copy of all parameters in memory, two during optimization. + + !WARNING!: setting the parameter array MUST always be done in memory: + m.param_array[:] = m_copy.param_array + """ + if self.__dict__.get('_param_array_', None) is None: + self._param_array_ = np.empty(self.size, dtype=np.float64) + + if self.constraints[__fixed__].size !=0: + fixes = np.ones(self.size).astype(bool) + fixes[self.constraints[__fixed__]] = FIXED + return self._param_array_[fixes] + else: + return self._param_array_ + @param_array.setter def param_array(self, arr): self._param_array_ = arr diff --git a/GPy/inference/optimization/__init__.py b/GPy/inference/optimization/__init__.py index 1a8f043b..1590568f 100644 --- a/GPy/inference/optimization/__init__.py +++ b/GPy/inference/optimization/__init__.py @@ -1,2 +1,3 @@ from scg import SCG from optimization import * +from hmc import HMC,HMC_shortcut diff --git a/GPy/inference/optimization/hmc.py b/GPy/inference/optimization/hmc.py new file mode 100644 index 00000000..8c65cdf0 --- /dev/null +++ b/GPy/inference/optimization/hmc.py @@ -0,0 +1,157 @@ +"""HMC implementation""" + +import numpy as np + + +class HMC: + def __init__(self,model,M=None,stepsize=1e-1): + self.model = model + self.stepsize = stepsize + self.p = np.empty_like(model.optimizer_array.copy()) + if M is None: + self.M = np.eye(self.p.size) + else: + self.M = M + self.Minv = np.linalg.inv(self.M) + + def sample(self, m_iters=1000, hmc_iters=20): + params = np.empty((m_iters,self.p.size)) + for i in xrange(m_iters): + self.p[:] = np.random.multivariate_normal(np.zeros(self.p.size),self.M) + H_old = self._computeH() + theta_old = self.model.optimizer_array.copy() + params[i] = self.model.unfixed_param_array + #Matropolis + self._update(hmc_iters) + H_new = self._computeH() + + if H_old>H_new: + k = 1. + else: + k = np.exp(H_old-H_new) + if np.random.rand()H_new: + k = 1. + else: + k = np.exp(H_old-H_new) + if np.random.rand()pos: + pos = -1 + i += pos + self.model.optimizer_array = theta_buf[hmc_iters] + self.p[:] = -p_buf[hmc_iters] + else: + pos_new = pos-hmc_iters+i + self.model.optimizer_array = theta_buf[hmc_iters+pos_new] + self.p[:] = -p_buf[hmc_iters+pos_new] + break + else: + Hlist = range(hmc_iters+pos,hmc_iters+pos+self.groupsize) +# print Hlist +# print self._testH(H_buf[Hlist]) + + if self._testH(H_buf[Hlist]): + pos += -1 + else: + # Reverse the trajectory for the 2nd time + r = (hmc_iters - i)%((reversal[0]-pos)*2) + if r>(reversal[0]-pos): + pos_new = 2*reversal[0] - r - pos + else: + pos_new = pos + r + self.model.optimizer_array = theta_buf[hmc_iters+pos_new] + self.p[:] = p_buf[hmc_iters+pos_new] # the sign of momentum might be wrong! +# print reversal[0],pos,pos_new +# print H_buf + break + + def _testH(self, Hlist): + Hstd = np.std(Hlist) +# print Hlist +# print Hstd + if Hstdself.Hstd_th[1]: + return False + else: + return True + + def _computeH(self,): + return self.model.objective_function()+self.p.size*np.log(2*np.pi)/2.+np.log(np.linalg.det(self.M))/2.+np.dot(self.p, np.dot(self.Minv,self.p[:,None]))/2. +