class_docstr: Base class for batched multi-output GPyTorch models with independent outputs.
  
  This model should be used when the same training data is used for all outputs.
  Outputs are modeled independently by using a different batch for each output.
  
  :meta private:
class_docstr_tok: ["Base","class","for","batched","multi-output","GPyTorch","models","with","independent","outputs",".","This","model","should","be","used","when","the","same","training","data","is","used","for","all","outputs",".","Outputs","are","modeled","independently","by","using","a","different","batch","for","each","output",".",":","meta","private",":"]
docstr: Subset the model along the output dimension.
  
  Args:
      idcs: The output indices to subset the model to.
  
  Returns:
      The current model, subset to the specified output indices.
docstr_tok: ["Subset","the","model","along","the","output","dimension",".","Args",":","idcs",":","The","output","indices","to","subset","the","model","to",".","Returns",":","The","current","model",",","subset","to","the","specified","output","indices","."]
code: def subset_output(
      self, idcs: List[int]
  ) -> BatchedMultiOutputGPyTorchModel:
      r"""Subset the model along the output dimension.
  
      Args:
          idcs: The output indices to subset the model to.
  
      Returns:
          The current model, subset to the specified output indices.
      """
      try:
          subset_batch_dict = self._subset_batch_dict
      except AttributeError:
          raise NotImplementedError(
              "subset_output requires the model to define a `_subset_dict` attribute"
          )
  
      m = len(idcs)
      new_model = deepcopy(self)
  
      subset_everything = self.num_outputs == m and idcs == list(
          range(m)
      )
      if subset_everything:
          return new_model
  
      tidxr = torch.tensor(idcs, device=new_model.train_targets.device)
      idxr = tidxr if m > 1 else idcs[0]
      new_tail_bs = torch.Size([m]) if m > 1 else torch.Size()
  
      new_model._num_outputs = m
      new_model._aug_batch_shape = (
          new_model._aug_batch_shape[:-1] + new_tail_bs
      )
      new_model.train_inputs = tuple(
          ti[..., idxr, :, :] for ti in new_model.train_inputs
      )
      new_model.train_targets = new_model.train_targets[..., idxr, :]
  
      # adjust batch shapes of parameters/buffers if necessary
      for full_name, p in itertools.chain(
          new_model.named_parameters(), new_model.named_buffers()
      ):
          if full_name in subset_batch_dict:
              idx = subset_batch_dict[full_name]
              new_data = p.index_select(dim=idx, index=tidxr)
              if m == 1:
                  new_data = new_data.squeeze(idx)
              p.data = new_data
          mod_name = full_name.split(".")[:-1]
          mod_batch_shape(new_model, mod_name, m if m > 1 else 0)
  
      # subset outcome transform if present
      try:
          subset_octf = new_model.outcome_transform.subset_output(
              idcs=idcs
          )
          new_model.outcome_transform = subset_octf
      except AttributeError:
          pass
  
      # Subset fixed noise likelihood if present.
      if isinstance(self.likelihood, FixedNoiseGaussianLikelihood):
          full_noise = new_model.likelihood.noise_covar.noise
          new_noise = full_noise[
              ..., idcs if len(idcs) > 1 else idcs[0], :
          ]
          new_model.likelihood.noise_covar.noise = new_noise
  
      return new_model
  
imports: from __future__ import annotations
  import itertools
  import warnings
  from abc import ABC
  from copy import deepcopy
  from typing import Any, List, Optional, Tuple, TYPE_CHECKING, Union
  import torch
  from botorch.acquisition.objective import PosteriorTransform
  from botorch.exceptions.errors import BotorchTensorDimensionError, InputDataError
  from botorch.exceptions.warnings import _get_single_precision_warning, BotorchTensorDimensionWarning
  from botorch.models.model import Model, ModelList
  from botorch.models.utils import _make_X_full, add_output_dim, gpt_posterior_settings, mod_batch_shape, multioutput_to_batch_mode_transform
  from botorch.posteriors.fully_bayesian import GaussianMixturePosterior
  from botorch.posteriors.gpytorch import GPyTorchPosterior
  from botorch.utils.multitask import separate_mtmvn
  from botorch.utils.transforms import is_ensemble
  from gpytorch.distributions import MultitaskMultivariateNormal, MultivariateNormal
  from gpytorch.likelihoods.gaussian_likelihood import FixedNoiseGaussianLikelihood
  from linear_operator.operators import BlockDiagLinearOperator, CatLinearOperator
  from torch import Tensor
label_desc: Use image node_id 7 for calling the BatchedMultiOutputGPyTorchModel obj's underlying member method code with example usage: obj.subset_output(idcs) and returns: new_model, new_model