code: def batch_cross_validation(
      model_cls: Type[GPyTorchModel],
      mll_cls: Type[MarginalLogLikelihood],
      cv_folds: CVFolds,
      fit_args: Optional[Dict[str, Any]] = None,
      observation_noise: bool = False,
  ) -> CVResults:
      r"""Perform cross validation by using gpytorch batch mode.
  
      Args:
          model_cls: A GPyTorchModel class. This class must initialize the likelihood
              internally. Note: Multi-task GPs are not currently supported.
          mll_cls: A MarginalLogLikelihood class.
          cv_folds: A CVFolds tuple.
          fit_args: Arguments passed along to fit_gpytorch_mll.
  
      Returns:
          A CVResults tuple with the following fields
  
          - model: GPyTorchModel for batched cross validation
          - posterior: GPyTorchPosterior where the mean has shape `n x 1 x m` or
            `batch_shape x n x 1 x m`
          - observed_Y: A `n x 1 x m` or `batch_shape x n x 1 x m` tensor of observations.
          - observed_Yvar: A `n x 1 x m` or `batch_shape x n x 1 x m` tensor of observed
            measurement noise.
  
      Example:
          >>> train_X = torch.rand(10, 1)
          >>> train_Y = torch.sin(6 * train_X) + 0.2 * torch.rand_like(train_X)
          >>> cv_folds = gen_loo_cv_folds(train_X, train_Y)
          >>> cv_results = batch_cross_validation(
          >>>     SingleTaskGP,
          >>>     ExactMarginalLogLikelihood,
          >>>     cv_folds,
          >>> )
  
      WARNING: This function is currently very memory inefficient, use it only
          for problems of small size.
      """
      fit_args = fit_args or {}
      kwargs = {
          "train_X": cv_folds.train_X,
          "train_Y": cv_folds.train_Y,
          "train_Yvar": cv_folds.train_Yvar,
      }
      model_cv = model_cls(**_filter_kwargs(model_cls, **kwargs))
      mll_cv = mll_cls(model_cv.likelihood, model_cv)
      mll_cv.to(cv_folds.train_X)
      mll_cv = fit_gpytorch_mll(mll_cv, **fit_args)
  
      # Evaluate on the hold-out set in batch mode
      with torch.no_grad():
          posterior = model_cv.posterior(
              cv_folds.test_X, observation_noise=observation_noise
          )
  
      return CVResults(
          model=model_cv,
          posterior=posterior,
          observed_Y=cv_folds.test_Y,
          observed_Yvar=cv_folds.test_Yvar,
      )
  
file_path: botorch/botorch/cross_validation.py
imports: from __future__ import annotations
  from typing import Any, Dict, NamedTuple, Optional, Type
  import torch
  from botorch.fit import fit_gpytorch_mll
  from botorch.models.gpytorch import GPyTorchModel
  from botorch.optim.utils import _filter_kwargs
  from botorch.posteriors.gpytorch import GPyTorchPosterior
  from gpytorch.mlls.marginal_log_likelihood import MarginalLogLikelihood
  from torch import Tensor
label_desc: Use image node_id 2 for calling a global function with example usage: batch_cross_validation(model_cls, mll_cls, cv_folds, fit_args, observation_noise) and returns: CVResults