code: def EvalInputReceiver(  # pylint: disable=invalid-name
      features: types.TensorTypeMaybeDict,
      labels: Optional[types.TensorTypeMaybeDict],
      receiver_tensors: types.TensorTypeMaybeDict,
      input_refs: Optional[types.TensorType] = None,
      iterator_initializer: Optional[str] = None,
  ) -> EvalInputReceiverType:
      """Returns an appropriate receiver for eval_input_receiver_fn.
  
      This is a wrapper around TensorFlow's InputReceiver that adds additional
      entries and prefixes to the input tensors so that features and labels can be
      discovered at evaluation time. It also wraps the features and labels tensors
      in identity to workaround TensorFlow issue #17568.
  
      The resulting signature_def.inputs will have the following form:
        inputs/<input>     - placeholders that are used for input processing (i.e
                             receiver_tensors). If receiver_tensors is a tensor and
                             not a dict, then this will just be named 'inputs'.
        input_refs         - reference to input_refs tensor (see below).
        features/<feature> - references to tensors passed in features. If features
                             is a tensor and not a dict, then this will just be
                             named 'features'.
        labels/<label>     - references to tensors passed in labels. If labels is
                             a tensor and not a dict, then this will just be named
                             'labels'.
  
      Args:
        features: A `Tensor`, `SparseTensor`, or dict of string to `Tensor` or
          `SparseTensor`, specifying the features to be passed to the model.
        labels: A `Tensor`, `SparseTensor`, or dict of string to `Tensor` or
          `SparseTensor`, specifying the labels to be passed to the model. If your
          model is an unsupervised model whose `model_fn` does not accept a `labels`
          argument, you may pass None instead.
        receiver_tensors: A dict of string to `Tensor` containing exactly key named
          'examples', which maps to the single input node that the receiver expects
          to be fed by default. Typically this is a placeholder expecting serialized
          `tf.Example` protos.
        input_refs: Optional (unless iterator_initializer used). A 1-D integer
          `Tensor` that is batch-aligned with `features` and `labels` which is an
          index into receiver_tensors['examples'] indicating where this slice of
          features / labels came from. If not provided, defaults to range(0,
          len(receiver_tensors['examples'])).
        iterator_initializer: Optional name of tf.compat.v1.data.Iterator
          initializer used when the inputs are fed using an iterator. This is
          intended to be used by models that cannot handle a single large input due
          to memory resource constraints. For example, a model that takes a
          tf.train.SequenceExample record as input but only processes smaller
          batches of examples within the overall sequence at a time. The caller is
          responsible for setting the input_refs appropriately (i.e. all examples
          belonging to the same tf.train.Sequence should have the same input_ref).
  
      Raises:
        ValueError: receiver_tensors did not contain exactly one key named
          "examples" or iterator_initializer used without input_refs.
      """
      if list(receiver_tensors) != ["examples"]:
          raise ValueError(
              "receiver_tensors must contain exactly one key named "
              "examples."
          )
  
      if input_refs is None:
          if iterator_initializer is not None:
              raise ValueError(
                  "input_refs is required if iterator_initializer is used"
              )
          input_refs = tf.range(
              tf.size(input=list(receiver_tensors.values())[0])
          )
  
      updated_receiver_tensors = {}
  
      def add_tensors(prefix, tensor_or_dict):
          if isinstance(tensor_or_dict, dict):
              for key in tensor_or_dict:
                  updated_receiver_tensors[
                      prefix + "/" + key
                  ] = tensor_or_dict[key]
          else:
              updated_receiver_tensors[prefix] = tensor_or_dict
  
      add_tensors(
          constants.SIGNATURE_DEF_INPUTS_PREFIX, receiver_tensors
      )
      add_tensors(constants.FEATURES_NAME, features)
      if labels is not None:
          add_tensors(constants.LABELS_NAME, labels)
      updated_receiver_tensors[
          constants.SIGNATURE_DEF_INPUT_REFS_KEY
      ] = input_refs
      if iterator_initializer:
          updated_receiver_tensors[
              constants.SIGNATURE_DEF_ITERATOR_INITIALIZER_KEY
          ] = tf.constant(iterator_initializer)
      updated_receiver_tensors[
          constants.SIGNATURE_DEF_TFMA_VERSION_KEY
      ] = tf.constant(version.VERSION)
  
      # TODO(b/119308261): Remove once all evaluator binaries have been updated.
      _add_tfma_collections(features, labels, input_refs)
      util.add_build_data_collection()
  
      # Workaround for TensorFlow issue #17568. Note that we pass the
      # identity-wrapped features and labels to model_fn, but we have to feed
      # the non-identity wrapped Tensors during evaluation.
      #
      # Also note that we can't wrap predictions, so metrics that have control
      # dependencies on predictions will cause the predictions to be recomputed
      # during their evaluation.
      wrapped_features = (
          util.wrap_tensor_or_dict_of_tensors_in_identity(features)
      )
      if labels is not None:
          wrapped_labels = (
              util.wrap_tensor_or_dict_of_tensors_in_identity(labels)
          )
          return export_lib.SupervisedInputReceiver(
              features=wrapped_features,
              labels=wrapped_labels,
              receiver_tensors=updated_receiver_tensors,
          )
      else:
          return export_lib.UnsupervisedInputReceiver(
              features=wrapped_features,
              receiver_tensors=updated_receiver_tensors,
          )
  
file_path: model-analysis/tensorflow_model_analysis/eval_saved_model/export.py
imports: from typing import Any, Callable, Dict, Optional, Union
  import tensorflow
  from tensorflow import estimator
  from tensorflow_model_analysis import version
  from tensorflow_model_analysis.api import types
  from tensorflow_model_analysis.eval_saved_model import constants
  from tensorflow_model_analysis.eval_saved_model import encoding
  from tensorflow_model_analysis.eval_saved_model import util
  from tensorflow_model_analysis.utils import util
  from tensorflow.python.estimator.export import export
label_desc: Use image node_id 1 for calling a global function with example usage: EvalInputReceiver(features, labels, receiver_tensors, input_refs, iterator_initializer) and returns: export_lib, export_lib