code: def _build_likelihood(self):
          r
  
          # Get prior KL.
          KL = gauss_kl(self.q_mu, self.q_sqrt)
  
          # Get conditionals
          K = self.kern.K(self.X) + tf.eye(self.num_data, dtype=settings.float_type) * \
              settings.numerics.jitter_level
          L = tf.cholesky(K)
  
          fmean = tf.matmul(L, self.q_mu) + self.mean_function(self.X)  # NN,ND->ND
  
          q_sqrt_dnn = tf.matrix_band_part(self.q_sqrt, -1, 0)  # D x N x N
  
          L_tiled = tf.tile(tf.expand_dims(L, 0), tf.stack([self.num_latent, 1, 1]))
  
          LTA = tf.matmul(L_tiled, q_sqrt_dnn)  # D x N x N
          fvar = tf.reduce_sum(tf.square(LTA), 2)
  
          fvar = tf.transpose(fvar)
  
          # Get variational expectations.
          var_exp = self.likelihood.variational_expectations(fmean, fvar, self.Y)
  
          return tf.reduce_sum(var_exp) - KL
docs: r"""
          This method computes the variational lower bound on the likelihood,
          which is:
  
              E_{q(F)} [ \log p(Y|F) ] - KL[ q(F) || p(F)]
  
          with
  
              q(\mathbf f) = N(\mathbf f \,|\, \boldsymbol \mu, \boldsymbol \Sigma)