mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-04-29 14:56:24 +02:00
basic vardtc working
This commit is contained in:
parent
ac2d28e2fd
commit
8eaa0bbf8a
1 changed files with 17 additions and 32 deletions
|
|
@ -62,20 +62,9 @@ class VarDTC(LatentFunctionInference):
|
||||||
return Y * prec # TODO chache this, and make it effective
|
return Y * prec # TODO chache this, and make it effective
|
||||||
|
|
||||||
def inference(self, kern, X, Z, likelihood, Y, Y_metadata=None):
|
def inference(self, kern, X, Z, likelihood, Y, Y_metadata=None):
|
||||||
if isinstance(X, VariationalPosterior):
|
|
||||||
uncertain_inputs = True
|
|
||||||
psi0 = kern.psi0(Z, X)
|
|
||||||
psi1 = kern.psi1(Z, X)
|
|
||||||
psi2 = kern.psi2(Z, X)
|
|
||||||
else:
|
|
||||||
uncertain_inputs = False
|
|
||||||
psi0 = kern.Kdiag(X)
|
|
||||||
psi1 = kern.K(X, Z)
|
|
||||||
psi2 = None
|
|
||||||
|
|
||||||
#see whether we're using variational uncertain inputs
|
|
||||||
|
|
||||||
_, output_dim = Y.shape
|
_, output_dim = Y.shape
|
||||||
|
uncertain_inputs = isinstance(X, VariationalPosterior)
|
||||||
|
|
||||||
#see whether we've got a different noise variance for each datum
|
#see whether we've got a different noise variance for each datum
|
||||||
beta = 1./np.fmax(likelihood.gaussian_variance(Y_metadata), 1e-6)
|
beta = 1./np.fmax(likelihood.gaussian_variance(Y_metadata), 1e-6)
|
||||||
|
|
@ -96,23 +85,21 @@ class VarDTC(LatentFunctionInference):
|
||||||
diag.add(Kmm, self.const_jitter)
|
diag.add(Kmm, self.const_jitter)
|
||||||
Lm = jitchol(Kmm)
|
Lm = jitchol(Kmm)
|
||||||
|
|
||||||
# The rather complex computations of A
|
|
||||||
|
# The rather complex computations of A, and the psi stats
|
||||||
if uncertain_inputs:
|
if uncertain_inputs:
|
||||||
|
psi0 = kern.psi0(Z, X)
|
||||||
|
psi1 = kern.psi1(Z, X)
|
||||||
if het_noise:
|
if het_noise:
|
||||||
psi2_beta = psi2 * (beta.flatten().reshape(num_data, 1, 1)).sum(0)
|
psi2_beta = np.sum([kern.psi2(Z,X[i:i+1,:]) * beta_i for i,beta_i in enumerate(beta)],0)
|
||||||
else:
|
else:
|
||||||
psi2_beta = psi2.sum(0) * beta
|
psi2_beta = kern.psi2(Z,X) * beta
|
||||||
#if 0:
|
|
||||||
# evals, evecs = linalg.eigh(psi2_beta)
|
|
||||||
# clipped_evals = np.clip(evals, 0., 1e6) # TODO: make clipping configurable
|
|
||||||
# if not np.array_equal(evals, clipped_evals):
|
|
||||||
# pass # print evals
|
|
||||||
# tmp = evecs * np.sqrt(clipped_evals)
|
|
||||||
# tmp = tmp.T
|
|
||||||
# no backsubstitution because of bound explosion on tr(A) if not...
|
|
||||||
LmInv = dtrtri(Lm)
|
LmInv = dtrtri(Lm)
|
||||||
A = LmInv.dot(psi2_beta.dot(LmInv.T))
|
A = LmInv.dot(psi2_beta.dot(LmInv.T))
|
||||||
else:
|
else:
|
||||||
|
psi0 = kern.Kdiag(X)
|
||||||
|
psi1 = kern.K(X, Z)
|
||||||
|
psi2 = None
|
||||||
if het_noise:
|
if het_noise:
|
||||||
tmp = psi1 * (np.sqrt(beta.reshape(num_data, 1)))
|
tmp = psi1 * (np.sqrt(beta.reshape(num_data, 1)))
|
||||||
else:
|
else:
|
||||||
|
|
@ -149,7 +136,7 @@ class VarDTC(LatentFunctionInference):
|
||||||
log_marginal = _compute_log_marginal_likelihood(likelihood, num_data, output_dim, beta, het_noise,
|
log_marginal = _compute_log_marginal_likelihood(likelihood, num_data, output_dim, beta, het_noise,
|
||||||
psi0, A, LB, trYYT, data_fit, VVT_factor)
|
psi0, A, LB, trYYT, data_fit, VVT_factor)
|
||||||
|
|
||||||
#put the gradients in the right places
|
#noise derivatives
|
||||||
dL_dR = _compute_dL_dR(likelihood,
|
dL_dR = _compute_dL_dR(likelihood,
|
||||||
het_noise, uncertain_inputs, LB,
|
het_noise, uncertain_inputs, LB,
|
||||||
_LBi_Lmi_psi1Vf, DBi_plus_BiPBi, Lm, A,
|
_LBi_Lmi_psi1Vf, DBi_plus_BiPBi, Lm, A,
|
||||||
|
|
@ -158,6 +145,7 @@ class VarDTC(LatentFunctionInference):
|
||||||
|
|
||||||
dL_dthetaL = likelihood.exact_inference_gradients(dL_dR,Y_metadata)
|
dL_dthetaL = likelihood.exact_inference_gradients(dL_dR,Y_metadata)
|
||||||
|
|
||||||
|
#put the gradients in the right places
|
||||||
if uncertain_inputs:
|
if uncertain_inputs:
|
||||||
grad_dict = {'dL_dKmm': dL_dKmm,
|
grad_dict = {'dL_dKmm': dL_dKmm,
|
||||||
'dL_dpsi0':dL_dpsi0,
|
'dL_dpsi0':dL_dpsi0,
|
||||||
|
|
@ -409,10 +397,7 @@ def _compute_dL_dpsi(num_inducing, num_data, output_dim, beta, Lm, VVT_factor, C
|
||||||
dL_dpsi2 = None
|
dL_dpsi2 = None
|
||||||
else:
|
else:
|
||||||
dL_dpsi2 = beta * dL_dpsi2_beta
|
dL_dpsi2 = beta * dL_dpsi2_beta
|
||||||
if uncertain_inputs:
|
if not uncertain_inputs:
|
||||||
# repeat for each of the N psi_2 matrices
|
|
||||||
dL_dpsi2 = np.repeat(dL_dpsi2[None, :, :], num_data, axis=0)
|
|
||||||
else:
|
|
||||||
# subsume back into psi1 (==Kmn)
|
# subsume back into psi1 (==Kmn)
|
||||||
dL_dpsi1 += 2.*np.dot(psi1, dL_dpsi2)
|
dL_dpsi1 += 2.*np.dot(psi1, dL_dpsi2)
|
||||||
dL_dpsi2 = None
|
dL_dpsi2 = None
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue