class_docstr: A stateless base class for Gaussian process models, that is, those of the
  form
  
  .. math::
     :nowrap:
  
     \begin{align}
         \theta        & \sim p(\theta) \\
         f             & \sim \mathcal{GP}(m(x), k(x, x'; \theta)) \\
         f_i           & = f(x_i) \\
         y_i \,|\, f_i & \sim p(y_i|f_i)
     \end{align}
  
  This class mostly adds functionality for predictions. To use it, inheriting
  classes must define a predict_f function, which computes the means and
  variances of the latent function.
  
  These predictions are then pushed through the likelihood to obtain means
  and variances of held out data, self.predict_y.
  
  The predictions can also be used to compute the (log) density of held-out
  data via self.predict_log_density.
  
  It is also possible to draw samples from the latent GPs using
  self.predict_f_samples.
  
  If you are new to GPflow, see our :doc:`../../../../getting_started` for examples on how to use
  a model.
  
  :param kernel: Covariance function. $k$ above.
  :param likelihood: The likelihood of $y_i$, given $f_i$.
  :param mean_function: Mean of $f$.
  :param num_latent_gps: The number of latent GPs - the output dimension of $f$.
code: def __init__(
      self,
      kernel: Kernel,
      likelihood: Likelihood,
      mean_function: Optional[MeanFunction] = None,
      num_latent_gps: Optional[int] = None,
  ):
      super().__init__()
      assert (
          num_latent_gps is not None
      ), "GPModel requires specification of num_latent_gps"
      self.num_latent_gps = num_latent_gps
      if mean_function is None:
          mean_function = Zero()
      self.mean_function = mean_function
      self.kernel = kernel
      self.likelihood = likelihood
  
imports: import abc
  from typing import Any, Optional
  import tensorflow
  from check_shapes import check_shapes
  from ..base import InputData, MeanAndVariance, Module, RegressionData
  from ..conditionals.util import sample_mvn
  from ..kernels import Kernel, MultioutputKernel
  from ..likelihoods import Likelihood, SwitchedLikelihood
  from ..mean_functions import MeanFunction, Zero
  from ..utilities import assert_params_false, to_default_float
label_desc: Use image node_id 1 to create a new GPModel object from inherited base classes: BayesianModel with example: obj = GPModel(kernel, likelihood, mean_function, num_latent_gps)