From 10c774e84ecc4f2bd234393b85e1464703f24305 Mon Sep 17 00:00:00 2001 From: Nicolo Fusi Date: Tue, 29 Jan 2013 16:10:12 +0000 Subject: [PATCH] new shape for psi2 --- GPy/kern/kern.py | 10 +++++----- GPy/kern/rbf_ARD.py | 16 ++++++++-------- GPy/models/sparse_GP_regression.py | 12 ++++++------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/GPy/kern/kern.py b/GPy/kern/kern.py index 0d5e80f0..6201df35 100644 --- a/GPy/kern/kern.py +++ b/GPy/kern/kern.py @@ -259,29 +259,29 @@ class kern(parameterised): :Z: np.ndarray of inducing inputs (M x Q) : mu, S: np.ndarrays of means and variacnes (each N x Q) :returns psi2: np.ndarray (N,M,M,Q) """ - target = np.zeros((Z.shape[0],Z.shape[0])) + target = np.zeros((mu.shape[0],Z.shape[0],Z.shape[0])) slices1, slices2 = self._process_slices(slices1,slices2) - [p.psi2(Z[s2,i_s],mu[s1,i_s],S[s1,i_s],target[s2,s2]) for p,i_s,s1,s2 in zip(self.parts,self.input_slices,slices1,slices2)] + [p.psi2(Z[s2,i_s],mu[s1,i_s],S[s1,i_s],target[s1,s2,s2]) for p,i_s,s1,s2 in zip(self.parts,self.input_slices,slices1,slices2)] return target def dpsi2_dtheta(self,partial,Z,mu,S,slices1=None,slices2=None): """Returns shape (N,M,M,Ntheta)""" slices1, slices2 = self._process_slices(slices1,slices2) target = np.zeros(self.Nparam) - [p.dpsi2_dtheta(partial[s2,s2],Z[s2,i_s],mu[s1,i_s],S[s1,i_s],target[ps]) for p,i_s,s1,s2,ps in zip(self.parts,self.input_slices,slices1,slices2,self.param_slices)] + [p.dpsi2_dtheta(partial[s1,s2,s2],Z[s2,i_s],mu[s1,i_s],S[s1,i_s],target[ps]) for p,i_s,s1,s2,ps in zip(self.parts,self.input_slices,slices1,slices2,self.param_slices)] return target def dpsi2_dZ(self,partial,Z,mu,S,slices1=None,slices2=None): slices1, slices2 = self._process_slices(slices1,slices2) target = np.zeros_like(Z) - [p.dpsi2_dZ(partial[s2,s2],Z[s2,i_s],mu[s1,i_s],S[s1,i_s],target[s2,i_s]) for p,i_s,s1,s2 in zip(self.parts,self.input_slices,slices1,slices2)] + [p.dpsi2_dZ(partial[s1,s2,s2],Z[s2,i_s],mu[s1,i_s],S[s1,i_s],target[s2,i_s]) for p,i_s,s1,s2 in zip(self.parts,self.input_slices,slices1,slices2)] return target def dpsi2_dmuS(self,partial,Z,mu,S,slices1=None,slices2=None): """return shapes are N,M,M,Q""" slices1, slices2 = self._process_slices(slices1,slices2) target_mu, target_S = np.zeros((2,mu.shape[0],mu.shape[1])) - [p.dpsi2_dmuS(partial[s2,s2],Z[s2,i_s],mu[s1,i_s],S[s1,i_s],target_mu[s1,i_s],target_S[s1,i_s]) for p,i_s,s1,s2 in zip(self.parts,self.input_slices,slices1,slices2)] + [p.dpsi2_dmuS(partial[s1,s2,s2],Z[s2,i_s],mu[s1,i_s],S[s1,i_s],target_mu[s1,i_s],target_S[s1,i_s]) for p,i_s,s1,s2 in zip(self.parts,self.input_slices,slices1,slices2)] #TODO: there are some extra terms to compute here! return target_mu, target_S diff --git a/GPy/kern/rbf_ARD.py b/GPy/kern/rbf_ARD.py index 79c6ff58..a29a2bc9 100644 --- a/GPy/kern/rbf_ARD.py +++ b/GPy/kern/rbf_ARD.py @@ -106,31 +106,31 @@ class rbf_ARD(kernpart): def psi2(self,Z,mu,S,target): self._psi_computations(Z,mu,S) - target += self._psi2.sum(0) #TODO: psi2 should be NxMxM (for het. noise) + target += self._psi2 def dpsi2_dtheta(self,partial,Z,mu,S,target): """Shape N,M,M,Ntheta""" self._psi_computations(Z,mu,S) - d_var = np.sum(2.*self._psi2/self.variance,0) + d_var = 2.*self._psi2/self.variance d_length = self._psi2[:,:,:,None]*(0.5*self._psi2_Zdist_sq*self._psi2_denom + 2.*self._psi2_mudist_sq + 2.*S[:,None,None,:]/self.lengthscales2)/(self.lengthscales*self._psi2_denom) - d_length = d_length.sum(0) + # d_length = d_length.sum(0) target[0] += np.sum(partial*d_var) - target[1:] += (d_length*partial[:,:,None]).sum(0).sum(0) + target[1:] += (d_length*partial[:,:,:,None]).sum(0).sum(0).sum(0) def dpsi2_dZ(self,partial,Z,mu,S,target): """Returns shape N,M,M,Q""" self._psi_computations(Z,mu,S) term1 = 0.5*self._psi2_Zdist/self.lengthscales2 # M, M, Q term2 = self._psi2_mudist/self._psi2_denom/self.lengthscales2 # N, M, M, Q - dZ = self._psi2[:,:,:,None] * (term1[None] + term2) - target += (partial[None,:,:,None]*dZ).sum(0).sum(0) + dZ = self._psi2[:,:,:,None] * (term1[None] + term2) + target += (partial[:,:,:,None]*dZ).sum(0).sum(0) def dpsi2_dmuS(self,partial,Z,mu,S,target_mu,target_S): """Think N,M,M,Q """ self._psi_computations(Z,mu,S) tmp = self._psi2[:,:,:,None]/self.lengthscales2/self._psi2_denom - target_mu += (partial[None,:,:,None]*-tmp*2.*self._psi2_mudist).sum(1).sum(1) - target_S += (partial[None,:,:,None]*tmp*(2.*self._psi2_mudist_sq-1)).sum(1).sum(1) + target_mu += (partial[:,:,:,None]*-tmp*2.*self._psi2_mudist).sum(1).sum(1) + target_S += (partial[:,:,:,None]*tmp*(2.*self._psi2_mudist_sq-1)).sum(1).sum(1) def _K_computations(self,X,X2): if not (np.all(X==self._X) and np.all(X2==self._X2)): diff --git a/GPy/models/sparse_GP_regression.py b/GPy/models/sparse_GP_regression.py index 8caf38b1..8ea99116 100644 --- a/GPy/models/sparse_GP_regression.py +++ b/GPy/models/sparse_GP_regression.py @@ -70,7 +70,7 @@ class sparse_GP_regression(GP_regression): self.psi0 = self.kern.psi0(self.Z,self.X, self.X_uncertainty).sum() self.psi1 = self.kern.psi1(self.Z,self.X, self.X_uncertainty).T self.psi2 = self.kern.psi2(self.Z,self.X, self.X_uncertainty) - self.psi2_beta_scaled = self.psi2*(self.beta/self.scale_factor**2) + self.psi2_beta_scaled = (self.psi2*(self.beta/self.scale_factor**2)).sum(0) else: self.psi0 = self.kern.Kdiag(self.X,slices=self.Xslices).sum() self.psi1 = self.kern.K(self.Z,self.X) @@ -98,9 +98,9 @@ class sparse_GP_regression(GP_regression): # Compute dL_dpsi self.dL_dpsi0 = - 0.5 * self.D * self.beta * np.ones(self.N) self.dL_dpsi1 = mdot(self.V, self.psi1V.T,self.C).T - self.dL_dpsi2 = 0.5 * self.beta * self.D * self.Kmmi # dB - self.dL_dpsi2 += - 0.5 * self.beta/sf2 * self.D * self.C # dC - self.dL_dpsi2 += - 0.5 * self.beta * self.E # dD + self.dL_dpsi2 = 0.5 * self.beta * self.D * self.Kmmi[None,:,:] # dB + self.dL_dpsi2 += - 0.5 * self.beta/sf2 * self.D * self.C[None,:,:] # dC + self.dL_dpsi2 += - 0.5 * self.beta * self.E[None,:,:] # dD # Compute dL_dKmm self.dL_dKmm = -0.5 * self.D * mdot(self.Lmi.T, self.A, self.Lmi)*sf2 # dB @@ -152,7 +152,7 @@ class sparse_GP_regression(GP_regression): dL_dtheta += self.kern.dpsi2_dtheta(self.dL_dpsi2,self.Z,self.X, self.X_uncertainty) # for multiple_beta, dL_dpsi2 will be a different shape else: #re-cast computations in psi2 back to psi1: - dL_dpsi1 = self.dL_dpsi1 + 2.*np.dot(self.dL_dpsi2,self.psi1) + dL_dpsi1 = self.dL_dpsi1 + 2.*np.dot(self.dL_dpsi2.sum(0),self.psi1) dL_dtheta += self.kern.dK_dtheta(dL_dpsi1,self.Z,self.X) dL_dtheta += self.kern.dKdiag_dtheta(self.dL_dpsi0, self.X) @@ -168,7 +168,7 @@ class sparse_GP_regression(GP_regression): dL_dZ += 2.*self.kern.dpsi2_dZ(self.dL_dpsi2,self.Z,self.X, self.X_uncertainty) # 'stripes' else: #re-cast computations in psi2 back to psi1: - dL_dpsi1 = self.dL_dpsi1 + 2.*np.dot(self.dL_dpsi2,self.psi1) + dL_dpsi1 = self.dL_dpsi1 + 2.*np.dot(self.dL_dpsi2.sum(0),self.psi1) dL_dZ += self.kern.dK_dX(dL_dpsi1,self.Z,self.X) return dL_dZ