code: def testWithBinaryClassificationMultiOutput(self, add_custom_metrics):
      # If custom metrics are used, then model.evaluate is called.
      export_dir = self._createBinaryClassificationModel(
          sequential=False,
          output_names=("output_1", "output_2"),
          add_custom_metrics=add_custom_metrics,
      )
      eval_shared_model = self.createTestEvalSharedModel(
          eval_saved_model_path=export_dir
      )
      computation = (
          keras_util.metric_computations_using_keras_saved_model(
              "", eval_shared_model.model_loader, None
          )[0]
      )
  
      inputs = [
          metric_types.StandardMetricInputs(
              labels={
                  "output_1": np.array([0.0]),
                  "output_2": np.array([0.0]),
              },
              predictions={
                  "output_1": np.array([1.0]),
                  "output_2": np.array([0.0]),
              },
              example_weights={
                  "output_1": np.array([0.5]),
                  "output_2": np.array([0.1]),
              },
              features={
                  "output_1": np.array([1.0]),
                  "output_2": np.array([0.0]),
              },
          ),
          metric_types.StandardMetricInputs(
              labels={
                  "output_1": np.array([1.0]),
                  "output_2": np.array([1.0]),
              },
              predictions={
                  "output_1": np.array([0.7]),
                  "output_2": np.array([0.3]),
              },
              example_weights={
                  "output_1": np.array([0.7]),
                  "output_2": np.array([0.4]),
              },
              features={
                  "output_1": np.array([0.7]),
                  "output_2": np.array([0.3]),
              },
          ),
          metric_types.StandardMetricInputs(
              labels={
                  "output_1": np.array([0.0]),
                  "output_2": np.array([1.0]),
              },
              predictions={
                  "output_1": np.array([0.5]),
                  "output_2": np.array([0.8]),
              },
              example_weights={
                  "output_1": np.array([0.9]),
                  "output_2": np.array([0.7]),
              },
              features={
                  "output_1": np.array([0.5]),
                  "output_2": np.array([0.8]),
              },
          ),
      ]
  
      expected_values = {
          "output_1": {
              "auc": 0.5,
              "auc_pr": 0.30685,
              "precision": 0.5,
              "recall": 1.0,
              "true_positives": 1.0,
              "false_positives": 1.0,
              "true_negatives": 1.0,
              "false_negatives": 0.0,
              "specificity_at_sensitivity": 0.5,
              "sensitivity_at_specificity": 1.0,
              "weighted_auc": 0.64286,
              "weighted_auc_pr": 0.37467,
              "weighted_precision": 0.5833333,
              "weighted_recall": 1.0,
              "weighted_true_positives": 0.7,
              "weighted_false_positives": 0.5,
              "weighted_true_negatives": 0.9,
              "weighted_false_negatives": 0.0,
              "weighted_specificity_at_sensitivity": 0.642857,
              "weighted_sensitivity_at_specificity": 1.0,
              "loss": 2.861993,
          },
          "output_2": {
              "auc": 1.0,
              "auc_pr": 1.0,
              "precision": 1.0,
              "recall": 0.5,
              "true_positives": 1.0,
              "false_positives": 0.0,
              "true_negatives": 1.0,
              "false_negatives": 1.0,
              "specificity_at_sensitivity": 1.0,
              "sensitivity_at_specificity": 1.0,
              "weighted_auc": 1.0,
              "weighted_auc_pr": 1.0,
              "weighted_precision": 1.0,
              "weighted_recall": 0.6363636,
              "weighted_true_positives": 0.7,
              "weighted_false_positives": 0.0,
              "weighted_true_negatives": 0.1,
              "weighted_false_negatives": 0.4,
              "weighted_specificity_at_sensitivity": 1.0,
              "weighted_sensitivity_at_specificity": 1.0,
              "loss": 0.21259646,
          },
          "": {"loss": 2.861993 + 0.21259646},
      }
      if add_custom_metrics:
          # Loss is different due to rounding errors from tf.Example conversion.
          expected_values["output_1"]["loss"] = 2.8327076
          expected_values["output_2"]["loss"] = 0.21259646
          expected_values[""]["loss"] = 2.8327076 + 0.21259646
          expected_values[""]["custom_output_1"] = 1.0 + 0.7 + 0.5
          expected_values[""]["custom_output_2"] = 0.0 + 0.3 + 0.8
  
      with beam.Pipeline() as pipeline:
          # pylint: disable=no-value-for-parameter
          result = (
              pipeline
              | "Create" >> beam.Create(inputs)
              | "AddSlice" >> beam.Map(lambda x: ((), x))
              | "ComputeMetric"
              >> beam.CombinePerKey(computation.combiner)
          )
  
          # pylint: enable=no-value-for-parameter
  
          def check_result(got):
              try:
                  self.assertLen(got, 1)
                  got_slice_key, got_metrics = got[0]
                  self.assertEqual(got_slice_key, ())
                  expected = {}
                  for (
                      output_name,
                      per_output_values,
                  ) in expected_values.items():
                      for name, value in per_output_values.items():
                          key = metric_types.MetricKey(
                              name=name,
                              output_name=output_name,
                              example_weighted=None,
                          )
                          expected[key] = value
                  self.assertDictElementsAlmostEqual(
                      got_metrics, expected
                  )
  
              except AssertionError as err:
                  raise util.BeamAssertException(err)
  
          util.assert_that(result, check_result, label="result")
  
imports: import tempfile
  import unittest
  from absl.testing import parameterized
  import apache_beam
  from apache_beam.testing import util
  import numpy
  import tensorflow
  from tensorflow_model_analysis.eval_saved_model import testutil
  from tensorflow_model_analysis.evaluators import keras_util
  from tensorflow_model_analysis.metrics import metric_types
label_desc: Use image node_id 8 for calling the KerasSavedModelUtilTest obj's underlying member method code with example usage: obj.testWithBinaryClassificationMultiOutput(add_custom_metrics) without return types