class_docstr: Learned preference objective constructed from a preference model.
  
  For input `samples`, it samples each individual sample again from the latent
  preference posterior distribution using `pref_model` and return the posterior mean.
  
  Example:
      >>> train_X = torch.rand(2, 2)
      >>> train_comps = torch.LongTensor([[0, 1]])
      >>> pref_model = PairwiseGP(train_X, train_comps)
      >>> learned_pref_obj = LearnedObjective(pref_model)
      >>> samples = sampler(posterior)
      >>> objective = learned_pref_obj(samples)
class_docstr_tok: ["Learned","preference","objective","constructed","from","a","preference","model",".","For","input","`","samples","`",",","it","samples","each","individual","sample","again","from","the","latent","preference","posterior","distribution","using","`","pref_model","`","and","return","the","posterior","mean",".","Example",":",">",">",">","train_X","=","torch.rand","(","2",",","2",")",">",">",">","train_comps","=","torch.LongTensor","(","[","[","0",",","1","]","]",")",">",">",">","pref_model","=","PairwiseGP","(","train_X",",","train_comps",")",">",">",">","learned_pref_obj","=","LearnedObjective","(","pref_model",")",">",">",">","samples","=","sampler","(","posterior",")",">",">",">","objective","=","learned_pref_obj","(","samples",")"]
docstr: Sample each element of samples.
  
  Args:
      samples: A `sample_size x batch_shape x q x d`-dim Tensors of
          samples from a model posterior.
  
  Returns:
      A `(sample_size * num_samples) x batch_shape x q`-dim Tensor of
      objective values sampled from utility posterior using `pref_model`.
code: def forward(
      self, samples: Tensor, X: Optional[Tensor] = None
  ) -> Tensor:
      r"""Sample each element of samples.
  
      Args:
          samples: A `sample_size x batch_shape x q x d`-dim Tensors of
              samples from a model posterior.
  
      Returns:
          A `(sample_size * num_samples) x batch_shape x q`-dim Tensor of
          objective values sampled from utility posterior using `pref_model`.
      """
      if samples.dtype != torch.float64 and any(
          d == torch.float64 for d in self.pref_model.dtypes_of_buffers
      ):
          warnings.warn(
              LEARNED_OBJECTIVE_PREF_MODEL_MIXED_DTYPE_WARN,
              InputDataWarning,
              stacklevel=2,
          )
          samples = samples.to(torch.float64)
  
      if samples.ndim < 3:
          raise ValueError("samples should have at least 3 dimensions.")
  
      posterior = self.pref_model.posterior(samples)
      if isinstance(self.pref_model, DeterministicModel):
          # return preference posterior mean
          return posterior.mean.squeeze(-1)
      else:
          # return preference posterior augmented samples
          samples = self.sampler(posterior).squeeze(-1)
          return samples.reshape(-1, *samples.shape[2:])
  
imports: from __future__ import annotations
  import inspect
  import warnings
  from abc import ABC, abstractmethod
  from typing import Callable, List, Optional, TYPE_CHECKING, Union
  import torch
  from botorch.exceptions.errors import BotorchTensorDimensionError, UnsupportedError
  from botorch.exceptions.warnings import InputDataWarning
  from botorch.models.model import Model
  from botorch.models.transforms.outcome import Standardize
  from botorch.posteriors.gpytorch import GPyTorchPosterior, scalarize_posterior
  from botorch.sampling import IIDNormalSampler
  from botorch.utils import apply_constraints
  from gpytorch.distributions import MultitaskMultivariateNormal, MultivariateNormal
  from linear_operator.operators.dense_linear_operator import to_linear_operator
  from torch import Tensor
  from torch.nn import Module
  from botorch.models.deterministic import DeterministicModel
label_desc: Use image node_id 2 for calling the LearnedObjective obj's underlying member method code with example usage: obj.forward(samples, X) and returns: posterior, samples