icub-client
svi_ratio.py
Go to the documentation of this file.
1 
3 
4 
5 #from .posterior import Posterior
6 from GPy.util.linalg import jitchol, backsub_both_sides, tdot, dtrtrs, dtrtri,pdinv
7 from GPy.util import diag
8 from GPy.core.parameterization.variational import VariationalPosterior
9 import numpy as np
10 from GPy.inference.latent_function_inference import LatentFunctionInference
11 from GPy.inference.latent_function_inference.posterior import Posterior
12 log_2_pi = np.log(2*np.pi)
13 
14 try:
15  from mpi4py import MPI
16 except:
17  pass
18 
19 
20 class SVI_Ratio(LatentFunctionInference):
21  """
22  Inference the marginal likelihood through \frac{p(y,y*)}{p(y)}
23  """
24  const_jitter = 1e-6
25  def __init__(self, mpi_comm=None):
26 
27  self.mpi_comm = mpi_comm
28 
29  def get_trYYT(self, Y):
30  return np.sum(np.square(Y))
31 
32  def get_YYTfactor(self, Y):
33  N, D = Y.shape
34  if (N>=D):
35  return Y.view(np.ndarray)
36  else:
37  return jitchol(tdot(Y))
38 
39  def gatherPsiStat(self, kern, X, Z, Y, beta, uncertain_inputs, D, missing_data):
40 
41  assert beta.size == 1
42 
43  if uncertain_inputs:
44  psi0 = kern.psi0(Z, X)
45  psi1 = kern.psi1(Z, X)*beta
46  psi2 = kern.psi2(Z, X)*beta if not missing_data else kern.psi2n(Z, X)*beta
47  else:
48  psi0 = kern.Kdiag(X)
49  psi1 = kern.K(X, Z)
50  if missing_data:
51  psi2 = psi1[:,None,:]*psi1[:,:,None]*beta
52  else:
53  psi2 = tdot(psi1.T)*beta
54  psi1 = psi1*beta
55 
56  if isinstance(Y, VariationalPosterior):
57  m, s = Y.mean, Y.variance
58  psi1Y = np.dot(m.T,psi1) # DxM
59  YRY = (np.square(m).sum()+s.sum())*beta
60  psi0 = (D*psi0).sum()*beta
61  elif missing_data:
62  psi1Y = np.dot((Y).T,psi1) # DxM
63  trYYT = self.get_trYYT(Y)
64  YRY = trYYT*beta
65  psi0 = (psi0*D).sum()*beta
66  else:
67  psi1Y = np.dot(Y.T,psi1) # DxM
68  trYYT = self.get_trYYT(Y)
69  YRY = trYYT*beta
70  psi0 = (psi0*D).sum()*beta
71 
72  return psi0, psi2, YRY, psi1, psi1Y
73 
74  def inference(self, kern, X, Z, likelihood, Y, qU):
75  """
76  The SVI-VarDTC inference
77  """
78 
79  if isinstance(Y, np.ndarray) and np.any(np.isnan(Y)):
80  missing_data = True
81  N, M, Q = Y.shape[0], Z.shape[0], Z.shape[1]
82  Ds = Y.shape[1] - (np.isnan(Y)*1).sum(1)
83  Ymask = 1-np.isnan(Y)*1
84  Y_masked = np.zeros_like(Y)
85  Y_masked[Ymask==1] = Y[Ymask==1]
86  ND = Ymask.sum()
87  else:
88  missing_data = False
89  N, D, M, Q = Y.shape[0], Y.shape[1], Z.shape[0], Z.shape[1]
90  ND = N*D
91 
92  uncertain_inputs = isinstance(X, VariationalPosterior)
93  uncertain_outputs = isinstance(Y, VariationalPosterior)
94 
95  beta = 1./np.fmax(likelihood.variance, 1e-6)
96 
97  psi0, psi2, YRY, psi1, psi1Y = self.gatherPsiStat(kern, X, Z, Y if not missing_data else Y_masked, beta, uncertain_inputs, D if not missing_data else Ds, missing_data)
98 
99  #======================================================================
100  # Compute Common Components
101  #======================================================================
102 
103  mu, S = qU.mean, qU.covariance
104  mupsi1Y = mu.dot(psi1Y)
105 
106  Kmm = kern.K(Z).copy()
107  diag.add(Kmm, self.const_jitter)
108  Lm = jitchol(Kmm)
109 
110  if missing_data:
111  S_mu = S[None,:,:]+mu.T[:,:,None]*mu.T[:,None,:]
112  NS_mu = S_mu.T.dot(Ymask.T).T
113  LmInv = dtrtri(Lm)
114 
115  LmInvPsi2LmInvT = np.swapaxes(psi2.dot(LmInv.T),1,2).dot(LmInv.T)
116  LmInvSmuLmInvT = np.swapaxes(NS_mu.dot(LmInv.T),1,2).dot(LmInv.T)
117 
118  B = mupsi1Y+ mupsi1Y.T +(Ds[:,None,None]*psi2).sum(0)
119  tmp = backsub_both_sides(Lm, B,'right')
120 
121  logL = -ND*log_2_pi/2. +ND*np.log(beta)/2. - psi0/2. - YRY/2. \
122  -(LmInvSmuLmInvT*LmInvPsi2LmInvT).sum()/2. +np.trace(tmp)/2.
123  else:
124  S_mu = S*D+tdot(mu)
125  if uncertain_inputs:
126  LmInvPsi2LmInvT = backsub_both_sides(Lm, psi2, 'right')
127  else:
128  LmInvPsi2LmInvT = tdot(dtrtrs(Lm, psi1.T)[0])/beta #tdot(psi1.dot(LmInv.T).T) /beta
129  LmInvSmuLmInvT = backsub_both_sides(Lm, S_mu, 'right')
130 
131  B = mupsi1Y+ mupsi1Y.T +D*psi2
132  tmp = backsub_both_sides(Lm, B,'right')
133 
134  logL = -ND*log_2_pi/2. +ND*np.log(beta)/2. - psi0/2. - YRY/2. \
135  -(LmInvSmuLmInvT*LmInvPsi2LmInvT).sum()/2. +np.trace(tmp)/2.
136 
137  #======================================================================
138  # Compute dL_dKmm
139  #======================================================================
140 
141  dL_dKmm = np.eye(M)
142 
143  #======================================================================
144  # Compute dL_dthetaL for uncertian input and non-heter noise
145  #======================================================================
146 
147  dL_dthetaL = None #(YRY*beta + beta*output_dim*psi0 - num_data*output_dim*beta)/2. - beta*(dL_dpsi2R*psi2).sum() - beta*np.trace(LLinvPsi1TYYTPsi1LLinvT)
148 
149  #======================================================================
150  # Compute dL_dpsi
151  #======================================================================
152 
153  if missing_data:
154  dL_dpsi0 = -Ds * (beta * np.ones((N,)))/2.
155  else:
156  dL_dpsi0 = -D * (beta * np.ones((N,)))/2.
157 
158  if uncertain_outputs:
159  Ym,Ys = Y.mean, Y.variance
160  dL_dpsi1 = dtrtrs(Lm, dtrtrs(Lm, Ym.dot(mu.T).T)[0], trans=1)[0].T*beta
161  else:
162  if missing_data:
163  dL_dpsi1 = dtrtrs(Lm, dtrtrs(Lm, (Y_masked).dot(mu.T).T)[0], trans=1)[0].T*beta
164  else:
165  dL_dpsi1 = dtrtrs(Lm, dtrtrs(Lm, Y.dot(mu.T).T)[0], trans=1)[0].T*beta
166 
167  if uncertain_inputs:
168  if missing_data:
169  dL_dpsi2 = np.swapaxes((Ds[:,None,None]*np.eye(M)[None,:,:]-LmInvSmuLmInvT).dot(LmInv),1,2).dot(LmInv)*beta/2.
170  else:
171  dL_dpsi2 = beta*backsub_both_sides(Lm, D*np.eye(M)-LmInvSmuLmInvT, 'left')/2.
172  else:
173  dL_dpsi1 += beta*psi1.dot(dL_dpsi2+dL_dpsi2.T)
174  dL_dpsi2 = None
175 
176  if uncertain_inputs:
177  grad_dict = {'dL_dKmm': dL_dKmm,
178  'dL_dpsi0':dL_dpsi0,
179  'dL_dpsi1':dL_dpsi1,
180  'dL_dpsi2':dL_dpsi2,
181  'dL_dthetaL':dL_dthetaL}
182  else:
183  grad_dict = {'dL_dKmm': dL_dKmm,
184  'dL_dKdiag':dL_dpsi0,
185  'dL_dKnm':dL_dpsi1,
186  'dL_dthetaL':dL_dthetaL}
187 
188  if uncertain_outputs:
189  Ym = Y.mean
190  grad_dict['dL_dYmean'] = -Ym*beta+ dtrtrs(Lm,psi1.T)[0].T.dot(dtrtrs(Lm,mu)[0])
191  grad_dict['dL_dYvar'] = beta/-2.
192 
193  return logL, grad_dict
194 
195 
196 
def gatherPsiStat(self, kern, X, Z, Y, beta, uncertain_inputs, D, missing_data)
Definition: svi_ratio.py:39
Inference the marginal likelihood through {p(y,y*)}{p(y)}.
Definition: svi_ratio.py:23
def inference(self, kern, X, Z, likelihood, Y, qU)
The SVI-VarDTC inference.
Definition: svi_ratio.py:77
def __init__(self, mpi_comm=None)
Definition: svi_ratio.py:25