From 901628a30ce144e0fe6c5a1565e17d4f42dc6159 Mon Sep 17 00:00:00 2001 From: Zhenwen Dai Date: Fri, 4 Sep 2015 12:33:38 +0100 Subject: [PATCH] fall back to the old psicomp interfacegit status! --- GPy/kern/_src/kern.py | 15 +++------ GPy/kern/_src/kernel_slice_operations.py | 12 +++---- GPy/kern/_src/psi_comp/__init__.py | 25 ++++++--------- GPy/kern/_src/psi_comp/linear_psi_comp.py | 2 +- GPy/kern/_src/psi_comp/rbf_psi_comp.py | 38 +++++++---------------- GPy/kern/_src/rbf.py | 15 ++++----- 6 files changed, 37 insertions(+), 70 deletions(-) diff --git a/GPy/kern/_src/kern.py b/GPy/kern/_src/kern.py index 0b74f144..ff5d49d3 100644 --- a/GPy/kern/_src/kern.py +++ b/GPy/kern/_src/kern.py @@ -103,8 +103,7 @@ class Kern(Parameterized): """Set the gradients of all parameters when doing full (N) inference.""" raise NotImplementedError - def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, - psi0=None, psi1=None, psi2=None): + def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): """ Set the gradients of all parameters when doing inference with uncertain inputs, using expectations of the kernel. @@ -115,8 +114,7 @@ class Kern(Parameterized): dL_dpsi1 * dpsi1_d{theta_i} + dL_dpsi2 * dpsi2_d{theta_i} """ - dtheta = self.psicomp.psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, - psi0=psi0, psi1=psi1, psi2=psi2)[0] + dtheta = self.psicomp.psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[0] self.gradient[:] = dtheta def gradients_Z_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, @@ -125,17 +123,14 @@ class Kern(Parameterized): Returns the derivative of the objective wrt Z, using the chain rule through the expectation variables. """ - return self.psicomp.psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, - psi0=psi0, psi1=psi1, psi2=psi2)[1] + return self.psicomp.psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[1] - def gradients_qX_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, - psi0=None, psi1=None, psi2=None, Lpsi0=None, Lpsi1=None, Lpsi2=None): + def gradients_qX_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): """ Compute the gradients wrt the parameters of the variational distruibution q(X), chain-ruling via the expectations of the kernel """ - return self.psicomp.psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, - psi0=psi0, psi1=psi1, psi2=psi2)[2:] + return self.psicomp.psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[2:] def plot(self, x=None, fignum=None, ax=None, title=None, plot_limits=None, resolution=None, **mpl_kwargs): """ diff --git a/GPy/kern/_src/kernel_slice_operations.py b/GPy/kern/_src/kernel_slice_operations.py index 1b14b363..de4aa629 100644 --- a/GPy/kern/_src/kernel_slice_operations.py +++ b/GPy/kern/_src/kernel_slice_operations.py @@ -137,11 +137,9 @@ def _slice_psi(f): def _slice_update_gradients_expectations(f): @wraps(f) - def wrap(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, - psi0=None, psi1=None, psi2=None, Lpsi0=None, Lpsi1=None, Lpsi2=None): + def wrap(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): with _Slice_wrap(self, Z, variational_posterior) as s: - ret = f(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, s.X, s.X2, - psi0=psi0, psi1=psi1, psi2=psi2, Lpsi0=Lpsi0, Lpsi1=Lpsi1, Lpsi2=Lpsi2) + ret = f(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, s.X, s.X2) return ret return wrap @@ -150,8 +148,7 @@ def _slice_gradients_Z_expectations(f): def wrap(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, psi0=None, psi1=None, psi2=None, Lpsi0=None, Lpsi1=None, Lpsi2=None): with _Slice_wrap(self, Z, variational_posterior) as s: - ret = s.handle_return_array(f(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, s.X, s.X2, - psi0=psi0, psi1=psi1, psi2=psi2, Lpsi0=Lpsi0, Lpsi1=Lpsi1, Lpsi2=Lpsi2)) + ret = s.handle_return_array(f(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, s.X, s.X2)) return ret return wrap @@ -160,8 +157,7 @@ def _slice_gradients_qX_expectations(f): def wrap(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, psi0=None, psi1=None, psi2=None, Lpsi0=None, Lpsi1=None, Lpsi2=None): with _Slice_wrap(self, variational_posterior, Z) as s: - ret = list(f(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, s.X2, s.X, - psi0=psi0, psi1=psi1, psi2=psi2, Lpsi0=Lpsi0, Lpsi1=Lpsi1, Lpsi2=Lpsi2)) + ret = list(f(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, s.X2, s.X)) r2 = ret[:2] ret[0] = s.handle_return_array(r2[0]) ret[1] = s.handle_return_array(r2[1]) diff --git a/GPy/kern/_src/psi_comp/__init__.py b/GPy/kern/_src/psi_comp/__init__.py index 088b514c..cfc67068 100644 --- a/GPy/kern/_src/psi_comp/__init__.py +++ b/GPy/kern/_src/psi_comp/__init__.py @@ -11,23 +11,19 @@ from . import linear_psi_comp from .gaussherm import PSICOMP_GH class PSICOMP_RBF(Pickleable): - @Cache_this(limit=10, ignore_args=(0,)) + @Cache_this(limit=2, ignore_args=(0,)) def psicomputations(self, variance, lengthscale, Z, variational_posterior, return_psi2_n=False): if isinstance(variational_posterior, variational.NormalPosterior): return rbf_psi_comp.psicomputations(variance, lengthscale, Z, variational_posterior, return_psi2_n=return_psi2_n) elif isinstance(variational_posterior, variational.SpikeAndSlabPosterior): - if return_psi2_n: - raise NotImplementedError('However this function seems to return it by default') return ssrbf_psi_comp.psicomputations(variance, lengthscale, Z, variational_posterior) else: raise ValueError("unknown distriubtion received for psi-statistics") - @Cache_this(limit=10, ignore_args=(0,1,2,3)) - def psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior, - psi0=None, psi1=None, psi2=None, Lpsi0=None, Lpsi1=None, Lpsi2=None): + @Cache_this(limit=2, ignore_args=(0,1,2,3)) + def psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior): if isinstance(variational_posterior, variational.NormalPosterior): - return rbf_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior, - psi0=psi0, psi1=psi1, psi2=psi2, Lpsi0=Lpsi0, Lpsi1=Lpsi1, Lpsi2=Lpsi2) + return rbf_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior) elif isinstance(variational_posterior, variational.SpikeAndSlabPosterior): return ssrbf_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior) else: @@ -38,10 +34,8 @@ class PSICOMP_RBF(Pickleable): class PSICOMP_Linear(Pickleable): - @Cache_this(limit=10, ignore_args=(0,)) - def psicomputations(self, variance, Z, variational_posterior, return_psi2_n=False): - if return_psi2_n: - raise NotImplementedError + @Cache_this(limit=2, ignore_args=(0,)) + def psicomputations(self, variance, Z, variational_posterior): if isinstance(variational_posterior, variational.NormalPosterior): return linear_psi_comp.psicomputations(variance, Z, variational_posterior) elif isinstance(variational_posterior, variational.SpikeAndSlabPosterior): @@ -49,10 +43,9 @@ class PSICOMP_Linear(Pickleable): else: raise ValueError("unknown distriubtion received for psi-statistics") - @Cache_this(limit=10, ignore_args=(0,1,2,3)) - def psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior, psi0=None, psi1=None, psi2=None): + @Cache_this(limit=2, ignore_args=(0,1,2,3)) + def psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior): if isinstance(variational_posterior, variational.NormalPosterior): - #Should pass psi in return linear_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior) elif isinstance(variational_posterior, variational.SpikeAndSlabPosterior): return sslinear_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior) @@ -60,4 +53,4 @@ class PSICOMP_Linear(Pickleable): raise ValueError("unknown distriubtion received for psi-statistics") def _setup_observers(self): - pass + pass \ No newline at end of file diff --git a/GPy/kern/_src/psi_comp/linear_psi_comp.py b/GPy/kern/_src/psi_comp/linear_psi_comp.py index a24b263a..f3262d3b 100644 --- a/GPy/kern/_src/psi_comp/linear_psi_comp.py +++ b/GPy/kern/_src/psi_comp/linear_psi_comp.py @@ -22,7 +22,7 @@ def psicomputations(variance, Z, variational_posterior, return_psi2_n=False): psi0 = (variance*(np.square(mu)+S)).sum(axis=1) psi1 = np.dot(mu,(variance*Z).T) - if return_psi2_n: + if not return_psi2_n: psi2 = np.dot(S.sum(axis=0)*np.square(variance)*Z,Z.T)+ tdot(psi1.T) else: raise NotImplementedError diff --git a/GPy/kern/_src/psi_comp/rbf_psi_comp.py b/GPy/kern/_src/psi_comp/rbf_psi_comp.py index 3fa2de94..892eb1a0 100644 --- a/GPy/kern/_src/psi_comp/rbf_psi_comp.py +++ b/GPy/kern/_src/psi_comp/rbf_psi_comp.py @@ -22,8 +22,7 @@ def psicomputations(variance, lengthscale, Z, variational_posterior, return_psi2 psi0[:] = variance psi1 = _psi1computations(variance, lengthscale, Z, mu, S) psi2 = _psi2computations(variance, lengthscale, Z, mu, S) - if not return_psi2_n: - psi2 = psi2.sum(axis=0) + if not return_psi2_n: psi2 = psi2.sum(axis=0) return psi0, psi1, psi2 def __psi1computations(variance, lengthscale, Z, mu, S): @@ -68,12 +67,11 @@ def __psi2computations(variance, lengthscale, Z, mu, S): _psi2 = variance*variance*np.exp(_psi2_logdenom[:,None,None]+_psi2_exp1[None,:,:]+_psi2_exp2) return _psi2 -def psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior, - psi0=None, psi1=None, psi2=None, Lpsi0=None, Lpsi1=None, Lpsi2=None): +def psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior): ARD = (len(lengthscale)!=1) - dvar_psi1, dl_psi1, dZ_psi1, dmu_psi1, dS_psi1 = _psi1compDer(dL_dpsi1, variance, lengthscale, Z, variational_posterior.mean, variational_posterior.variance, psi1=psi1, Lpsi1=Lpsi1) - dvar_psi2, dl_psi2, dZ_psi2, dmu_psi2, dS_psi2 = _psi2compDer(dL_dpsi2, variance, lengthscale, Z, variational_posterior.mean, variational_posterior.variance, psi2=psi2, Lpsi2=Lpsi2) + dvar_psi1, dl_psi1, dZ_psi1, dmu_psi1, dS_psi1 = _psi1compDer(dL_dpsi1, variance, lengthscale, Z, variational_posterior.mean, variational_posterior.variance) + dvar_psi2, dl_psi2, dZ_psi2, dmu_psi2, dS_psi2 = _psi2compDer(dL_dpsi2, variance, lengthscale, Z, variational_posterior.mean, variational_posterior.variance) dL_dvar = np.sum(dL_dpsi0) + dvar_psi1 + dvar_psi2 @@ -87,7 +85,7 @@ def psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscal return dL_dvar, dL_dlengscale, dL_dZ, dL_dmu, dL_dS -def __psi1compDer(dL_dpsi1, variance, lengthscale, Z, mu, S, psi1=None, Lpsi1=None): +def _psi1compDer(dL_dpsi1, variance, lengthscale, Z, mu, S): """ dL_dpsi1 - NxM Z - MxQ @@ -106,10 +104,8 @@ def __psi1compDer(dL_dpsi1, variance, lengthscale, Z, mu, S, psi1=None, Lpsi1=No lengthscale2 = np.square(lengthscale) - if psi1 is None: - psi1 = _psi1computations(variance, lengthscale, Z, mu, S) - if Lpsi1 is None: - Lpsi1 = dL_dpsi1*psi1 + _psi1 = _psi1computations(variance, lengthscale, Z, mu, S) + Lpsi1 = dL_dpsi1*_psi1 Zmu = Z[None,:,:]-mu[:,None,:] # NxMxQ denom = 1./(S+lengthscale2) Zmu2_denom = np.square(Zmu)*denom[:,None,:] #NxMxQ @@ -121,7 +117,7 @@ def __psi1compDer(dL_dpsi1, variance, lengthscale, Z, mu, S, psi1=None, Lpsi1=No return _dL_dvar, _dL_dl, _dL_dZ, _dL_dmu, _dL_dS -def __psi2compDer(dL_dpsi2, variance, lengthscale, Z, mu, S, psi2=None, Lpsi2=None): +def _psi2compDer(dL_dpsi2, variance, lengthscale, Z, mu, S): """ Z - MxQ mu - NxQ @@ -142,10 +138,8 @@ def __psi2compDer(dL_dpsi2, variance, lengthscale, Z, mu, S, psi2=None, Lpsi2=No denom = 1./(2*S+lengthscale2) denom2 = np.square(denom) - if psi2 is None: - psi2 = _psi2computations(variance, lengthscale, Z, mu, S) # NxMxM - if Lpsi2 is None: - Lpsi2 = dL_dpsi2*psi2 # dL_dpsi2 is MxM, using broadcast to multiply N out + _psi2 = _psi2computations(variance, lengthscale, Z, mu, S) # NxMxM + Lpsi2 = dL_dpsi2*_psi2 # dL_dpsi2 is MxM, using broadcast to multiply N out Lpsi2sum = np.einsum('nmo->n',Lpsi2) #N Lpsi2Z = np.einsum('nmo,oq->nq',Lpsi2,Z) #NxQ Lpsi2Z2 = np.einsum('nmo,oq,oq->nq',Lpsi2,Z,Z) #NxQ @@ -156,14 +150,8 @@ def __psi2compDer(dL_dpsi2, variance, lengthscale, Z, mu, S, psi2=None, Lpsi2=No _dL_dvar = Lpsi2sum.sum()*2/variance _dL_dmu = (-2*denom) * (mu*Lpsi2sum[:,None]-Lpsi2Zhat) _dL_dS = (2*np.square(denom))*(np.square(mu)*Lpsi2sum[:,None]-2*mu*Lpsi2Zhat+Lpsi2Zhat2) - denom*Lpsi2sum[:,None] - _dL_dZ1 = -np.einsum('nmo,oq->oq',Lpsi2,Z)/lengthscale2 - _dL_dZ2 = np.einsum('nmo,oq->mq',Lpsi2,Z)/lengthscale2 - _dL_dZ3 = 2*np.einsum('nmo,nq,nq->mq',Lpsi2,mu,denom) - _dL_dZ4 = - np.einsum('nmo,nq,mq->mq',Lpsi2,denom,Z) - _dL_dZ5 = - np.einsum('nmo,oq,nq->mq',Lpsi2,Z,denom) - _dL_dZ = _dL_dZ1 + _dL_dZ2 + _dL_dZ3 + _dL_dZ4 + _dL_dZ5 - #_dL_dZ = -np.einsum('nmo,oq->oq',Lpsi2,Z)/lengthscale2+np.einsum('nmo,oq->mq',Lpsi2,Z)/lengthscale2+ \ - #2*np.einsum('nmo,nq,nq->mq',Lpsi2,mu,denom) - np.einsum('nmo,nq,mq->mq',Lpsi2,denom,Z) - np.einsum('nmo,oq,nq->mq',Lpsi2,Z,denom) + _dL_dZ = -np.einsum('nmo,oq->oq',Lpsi2,Z)/lengthscale2+np.einsum('nmo,oq->mq',Lpsi2,Z)/lengthscale2+ \ + 2*np.einsum('nmo,nq,nq->mq',Lpsi2,mu,denom) - np.einsum('nmo,nq,mq->mq',Lpsi2,denom,Z) - np.einsum('nmo,oq,nq->mq',Lpsi2,Z,denom) _dL_dl = 2*lengthscale* ((S/lengthscale2*denom+np.square(mu*denom))*Lpsi2sum[:,None]+(Lpsi2Z2-Lpsi2Z2p)/(2*np.square(lengthscale2))- (2*mu*denom2)*Lpsi2Zhat+denom2*Lpsi2Zhat2).sum(axis=0) @@ -171,5 +159,3 @@ def __psi2compDer(dL_dpsi2, variance, lengthscale, Z, mu, S, psi2=None, Lpsi2=No _psi1computations = Cacher(__psi1computations, limit=5) _psi2computations = Cacher(__psi2computations, limit=5) -_psi1compDer = Cacher(__psi1compDer, limit=5) -_psi2compDer = Cacher(__psi2compDer, limit=5) diff --git a/GPy/kern/_src/rbf.py b/GPy/kern/_src/rbf.py index 08ef29fe..c422ead7 100644 --- a/GPy/kern/_src/rbf.py +++ b/GPy/kern/_src/rbf.py @@ -64,17 +64,14 @@ class RBF(Stationary): def psi2n(self, Z, variational_posterior): return self.psicomp.psicomputations(self.variance, self.lengthscale, Z, variational_posterior, return_psi2_n=True)[2] - def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, - psi0=None, psi1=None, psi2=None, Lpsi0=None, Lpsi1=None, Lpsi2=None): - dL_dvar, dL_dlengscale = self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variance, self.lengthscale, Z, variational_posterior, psi0=psi0, psi1=psi1, psi2=psi2, Lpsi0=Lpsi0, Lpsi1=Lpsi1, Lpsi2=Lpsi2)[:2] + def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + dL_dvar, dL_dlengscale = self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variance, self.lengthscale, Z, variational_posterior)[:2] self.variance.gradient = dL_dvar self.lengthscale.gradient = dL_dlengscale - def gradients_Z_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, - psi0=None, psi1=None, psi2=None, Lpsi0=None, Lpsi1=None, Lpsi2=None): - return self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variance, self.lengthscale, Z, variational_posterior, psi0=psi0, psi1=psi1, psi2=psi2, Lpsi0=Lpsi0, Lpsi1=Lpsi1, Lpsi2=Lpsi2)[2] + def gradients_Z_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + return self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variance, self.lengthscale, Z, variational_posterior)[2] - def gradients_qX_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior, - psi0=None, psi1=None, psi2=None, Lpsi0=None, Lpsi1=None, Lpsi2=None): - return self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variance, self.lengthscale, Z, variational_posterior, psi0=psi0, psi1=psi1, psi2=psi2, Lpsi0=Lpsi0, Lpsi1=Lpsi1, Lpsi2=Lpsi2)[3:] + def gradients_qX_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + return self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variance, self.lengthscale, Z, variational_posterior)[3:]