Gráficos y métricas de análisis del modelo de Tensorflow

Descripción general

TFMA admite las siguientes métricas y gráficos:

  • Métricas estándar de Keras ( tf.keras.metrics.* )
    • Tenga en cuenta que no necesita un modelo de Keras para utilizar las métricas de Keras. Las métricas se calculan fuera del gráfico en la viga utilizando las clases de métricas directamente.
  • Gráficos y métricas estándar de TFMA ( tfma.metrics.* )

  • Métricas keras personalizadas (métricas derivadas de tf.keras.metrics.Metric )

  • Métricas TFMA personalizadas (métricas derivadas de tfma.metrics.Metric ) utilizando combinadores de vigas personalizados o métricas derivadas de otras métricas).

TFMA también proporciona soporte integrado para convertir métricas de clasificación binaria para usar con problemas de múltiples clases/múltiples etiquetas:

  • Binarización basada en ID de clase, K superior, etc.
  • Métricas agregadas basadas en micropromediados, macropromediados, etc.

TFMA también proporciona soporte integrado para métricas basadas en consultas/clasificaciones donde los ejemplos se agrupan automáticamente por una clave de consulta en la canalización.

Combinados, hay más de 50 métricas y gráficos estándar disponibles para una variedad de problemas que incluyen regresión, clasificación binaria, clasificación de múltiples clases/múltiples etiquetas, clasificación, etc.

Configuración

Hay dos formas de configurar métricas en TFMA: (1) usando tfma.MetricsSpec o (2) creando instancias de las tf.keras.metrics.* y/o tfma.metrics.* en Python y usando tfma.metrics.specs_from_metrics para convertirlos en una lista de tfma.MetricsSpec .

Las siguientes secciones describen configuraciones de ejemplo para diferentes tipos de problemas de aprendizaje automático.

Métricas de regresión

El siguiente es un ejemplo de configuración para un problema de regresión. Consulte los módulos tf.keras.metrics.* y tfma.metrics.* para conocer posibles métricas adicionales admitidas.

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    metrics { class_name: "ExampleCount" }
    metrics { class_name: "MeanSquaredError" }
    metrics { class_name: "Accuracy" }
    metrics { class_name: "MeanLabel" }
    metrics { class_name: "MeanPrediction" }
    metrics { class_name: "Calibration" }
    metrics {
      class_name: "CalibrationPlot"
      config: '"min_value": 0, "max_value": 10'
    }
  }
""", tfma.EvalConfig()).metrics_specs

Esta misma configuración se puede crear usando el siguiente código Python:

metrics = [
    tfma.metrics.ExampleCount(name='example_count'),
    tf.keras.metrics.MeanSquaredError(name='mse'),
    tf.keras.metrics.Accuracy(name='accuracy'),
    tfma.metrics.MeanLabel(name='mean_label'),
    tfma.metrics.MeanPrediction(name='mean_prediction'),
    tfma.metrics.Calibration(name='calibration'),
    tfma.metrics.CalibrationPlot(
        name='calibration', min_value=0, max_value=10)
]
metrics_specs = tfma.metrics.specs_from_metrics(metrics)

Tenga en cuenta que esta configuración también está disponible llamando tfma.metrics.default_regression_specs .

Métricas de clasificación binaria

A continuación se muestra un ejemplo de configuración para un problema de clasificación binaria. Consulte los módulos tf.keras.metrics.* y tfma.metrics.* para conocer posibles métricas adicionales admitidas.

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    metrics { class_name: "ExampleCount" }
    metrics { class_name: "BinaryCrossentropy" }
    metrics { class_name: "BinaryAccuracy" }
    metrics { class_name: "AUC" }
    metrics { class_name: "AUCPrecisionRecall" }
    metrics { class_name: "MeanLabel" }
    metrics { class_name: "MeanPrediction" }
    metrics { class_name: "Calibration" }
    metrics { class_name: "ConfusionMatrixPlot" }
    metrics { class_name: "CalibrationPlot" }
  }
""", tfma.EvalConfig()).metrics_specs

Esta misma configuración se puede crear usando el siguiente código Python:

metrics = [
    tfma.metrics.ExampleCount(name='example_count'),
    tf.keras.metrics.BinaryCrossentropy(name='binary_crossentropy'),
    tf.keras.metrics.BinaryAccuracy(name='accuracy'),
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    tf.keras.metrics.AUC(
        name='auc_precision_recall', curve='PR', num_thresholds=10000),
    tf.keras.metrics.Precision(name='precision'),
    tf.keras.metrics.Recall(name='recall'),
    tfma.metrics.MeanLabel(name='mean_label'),
    tfma.metrics.MeanPrediction(name='mean_prediction'),
    tfma.metrics.Calibration(name='calibration'),
    tfma.metrics.ConfusionMatrixPlot(name='confusion_matrix_plot'),
    tfma.metrics.CalibrationPlot(name='calibration_plot')
]
metrics_specs = tfma.metrics.specs_from_metrics(metrics)

Tenga en cuenta que esta configuración también está disponible llamando tfma.metrics.default_binary_classification_specs .

Métricas de clasificación de múltiples clases/múltiples etiquetas

A continuación se muestra un ejemplo de configuración para un problema de clasificación de clases múltiples. Consulte los módulos tf.keras.metrics.* y tfma.metrics.* para conocer posibles métricas adicionales admitidas.

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    metrics { class_name: "ExampleCount" }
    metrics { class_name: "SparseCategoricalCrossentropy" }
    metrics { class_name: "SparseCategoricalAccuracy" }
    metrics { class_name: "Precision" config: '"top_k": 1' }
    metrics { class_name: "Precision" config: '"top_k": 3' }
    metrics { class_name: "Recall" config: '"top_k": 1' }
    metrics { class_name: "Recall" config: '"top_k": 3' }
    metrics { class_name: "MultiClassConfusionMatrixPlot" }
  }
""", tfma.EvalConfig()).metrics_specs

Esta misma configuración se puede crear usando el siguiente código Python:

metrics = [
    tfma.metrics.ExampleCount(name='example_count'),
    tf.keras.metrics.SparseCategoricalCrossentropy(
        name='sparse_categorical_crossentropy'),
    tf.keras.metrics.SparseCategoricalAccuracy(name='accuracy'),
    tf.keras.metrics.Precision(name='precision', top_k=1),
    tf.keras.metrics.Precision(name='precision', top_k=3),
    tf.keras.metrics.Recall(name='recall', top_k=1),
    tf.keras.metrics.Recall(name='recall', top_k=3),
    tfma.metrics.MultiClassConfusionMatrixPlot(
        name='multi_class_confusion_matrix_plot'),
]
metrics_specs = tfma.metrics.specs_from_metrics(metrics)

Tenga en cuenta que esta configuración también está disponible llamando tfma.metrics.default_multi_class_classification_specs .

Métricas binarizadas de múltiples clases/múltiples etiquetas

Las métricas de múltiples clases/múltiples etiquetas se pueden binarizar para producir métricas por clase, por top_k, etc. usando tfma.BinarizationOptions . Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    binarize: { class_ids: { values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] } }
    // Metrics to binarize
    metrics { class_name: "AUC" }
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Esta misma configuración se puede crear usando el siguiente código Python:

metrics = [
    // Metrics to binarize
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics, binarize=tfma.BinarizationOptions(
        class_ids={'values': [0,1,2,3,4,5,6,7,8,9]}))

Métricas agregadas de múltiples clases/múltiples etiquetas

Las métricas de múltiples clases/múltiples etiquetas se pueden agregar para producir un único valor agregado para una métrica de clasificación binaria mediante tfma.AggregationOptions .

Tenga en cuenta que la configuración de agregación es independiente de la configuración de binarización, por lo que puede usar tfma.AggregationOptions y tfma.BinarizationOptions al mismo tiempo.

Micropromedio

El micropromediado se puede realizar utilizando la opción micro_average dentro de tfma.AggregationOptions . Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    aggregate: { micro_average: true }
    // Metrics to aggregate
    metrics { class_name: "AUC" }
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Esta misma configuración se puede crear usando el siguiente código Python:

metrics = [
    // Metrics to aggregate
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics, aggregate=tfma.AggregationOptions(micro_average=True))

El micropromediado también admite la configuración de top_k donde solo se utilizan los valores k superiores en el cálculo. Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    aggregate: {
      micro_average: true
      top_k_list: { values: [1, 3] }
    }
    // Metrics to aggregate
    metrics { class_name: "AUC" }
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Esta misma configuración se puede crear usando el siguiente código Python:

metrics = [
    // Metrics to aggregate
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics,
    aggregate=tfma.AggregationOptions(micro_average=True,
                                      top_k_list={'values': [1, 3]}))

Macro / Promedio macro ponderado

El promedio de macros se puede realizar utilizando las opciones macro_average weighted_macro_average dentro de tfma.AggregationOptions . A menos que se utilice la configuración top_k , la macro requiere configurar class_weights para saber para qué clases calcular el promedio. Si no se proporciona class_weight , se supone 0,0. Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    aggregate: {
      macro_average: true
      class_weights: { key: 0 value: 1.0 }
      class_weights: { key: 1 value: 1.0 }
      class_weights: { key: 2 value: 1.0 }
      class_weights: { key: 3 value: 1.0 }
      class_weights: { key: 4 value: 1.0 }
      class_weights: { key: 5 value: 1.0 }
      class_weights: { key: 6 value: 1.0 }
      class_weights: { key: 7 value: 1.0 }
      class_weights: { key: 8 value: 1.0 }
      class_weights: { key: 9 value: 1.0 }
    }
    // Metrics to aggregate
    metrics { class_name: "AUC" }
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Esta misma configuración se puede crear usando el siguiente código Python:

metrics = [
    // Metrics to aggregate
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics,
    aggregate=tfma.AggregationOptions(
        macro_average=True, class_weights={i: 1.0 for i in range(10)}))

Al igual que el micropromedio, el macropromediado también admite la configuración de top_k donde solo se utilizan los valores k superiores en el cálculo. Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    aggregate: {
      macro_average: true
      top_k_list: { values: [1, 3] }
    }
    // Metrics to aggregate
    metrics { class_name: "AUC" }
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Esta misma configuración se puede crear usando el siguiente código Python:

metrics = [
    // Metrics to aggregate
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics,
    aggregate=tfma.AggregationOptions(macro_average=True,
                                      top_k_list={'values': [1, 3]}))

Métricas basadas en consultas/clasificaciones

Las métricas basadas en consultas/clasificaciones se habilitan especificando la opción query_key en las especificaciones de métricas. Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    query_key: "doc_id"
    metrics {
      class_name: "NDCG"
      config: '"gain_key": "gain", "top_k_list": [1, 2]'
    }
    metrics { class_name: "MinLabelPosition" }
  }
""", tfma.EvalConfig()).metrics_specs

Esta misma configuración se puede crear usando el siguiente código Python:

metrics = [
    tfma.metrics.NDCG(name='ndcg', gain_key='gain', top_k_list=[1, 2]),
    tfma.metrics.MinLabelPosition(name='min_label_position')
]
metrics_specs = tfma.metrics.specs_from_metrics(metrics, query_key='doc_id')

Métricas de evaluación multimodelo

TFMA admite la evaluación de múltiples modelos al mismo tiempo. Cuando se realiza una evaluación de múltiples modelos, se calcularán métricas para cada modelo. Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    # no model_names means all models
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Si es necesario calcular métricas para un subconjunto de modelos, establezca model_names en metric_specs . Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    model_names: ["my-model1"]
    ...
  }
""", tfma.EvalConfig()).metrics_specs

La API specs_from_metrics también admite el paso de nombres de modelos:

metrics = [
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics, model_names=['my-model1'])

Métricas de comparación de modelos

TFMA admite la evaluación de métricas de comparación para un modelo candidato con respecto a un modelo de referencia. Una forma sencilla de configurar el par de modelo candidato y de referencia es pasar un eval_shared_model con los nombres de modelo adecuados (tfma.BASELINE_KEY y tfma.CANDIDATE_KEY):


eval_config = text_format.Parse("""
  model_specs {
    # ... model_spec without names ...
  }
  metrics_spec {
    # ... metrics ...
  }
""", tfma.EvalConfig())

eval_shared_models = [
  tfma.default_eval_shared_model(
      model_name=tfma.CANDIDATE_KEY,
      eval_saved_model_path='/path/to/saved/candidate/model',
      eval_config=eval_config),
  tfma.default_eval_shared_model(
      model_name=tfma.BASELINE_KEY,
      eval_saved_model_path='/path/to/saved/baseline/model',
      eval_config=eval_config),
]

eval_result = tfma.run_model_analysis(
    eval_shared_models,
    eval_config=eval_config,
    # This assumes your data is a TFRecords file containing records in the
    # tf.train.Example format.
    data_location="/path/to/file/containing/tfrecords",
    output_path="/path/for/output")

Las métricas de comparación se calculan automáticamente para todas las métricas diferenciables (actualmente solo métricas de valores escalares como precisión y AUC).

Métricas del modelo de múltiples salidas

TFMA apoya la evaluación de métricas en modelos que tienen diferentes resultados. Los modelos de salidas múltiples almacenan sus predicciones de salida en forma de un diccionario codificado por nombre de salida. Cuando se utilizan modelos de múltiples salidas, los nombres de las salidas asociadas con un conjunto de métricas se deben especificar en la sección output_names de MetricsSpec. Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    output_names: ["my-output"]
    ...
  }
""", tfma.EvalConfig()).metrics_specs

La API specs_from_metrics también admite pasar nombres de salida:

metrics = [
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics, output_names=['my-output'])

Personalización de la configuración de métricas

TFMA permite personalizar las configuraciones que se utilizan con diferentes métricas. Por ejemplo, es posible que desee cambiar el nombre, establecer umbrales, etc. Esto se hace agregando una sección config a la configuración métrica. La configuración se especifica utilizando la versión de cadena JSON de los parámetros que se pasarían al método __init__ de métricas (para facilitar el uso, se pueden omitir los corchetes iniciales y finales '{' y '}'). Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    metrics {
      class_name: "ConfusionMatrixAtThresholds"
      config: '"thresholds": [0.3, 0.5, 0.8]'
    }
  }
""", tfma.MetricsSpec()).metrics_specs

Por supuesto, esta personalización también se admite directamente:

metrics = [
   tfma.metrics.ConfusionMatrixAtThresholds(thresholds=[0.3, 0.5, 0.8]),
]
metrics_specs = tfma.metrics.specs_from_metrics(metrics)

Salidas

El resultado de una evaluación de métricas es una serie de claves/valores de métricas y/o claves/valores de trazado según la configuración utilizada.

Claves métricas

Las MetricKeys se definen mediante un tipo de clave estructurada. Esta clave identifica de forma única cada uno de los siguientes aspectos de una métrica:

  • Nombre de la métrica ( auc , mean_label , etc.)
  • Nombre del modelo (solo se usa si se realiza una evaluación de múltiples modelos)
  • Nombre de salida (solo se usa si se evalúan modelos de múltiples salidas)
  • Subclave (por ejemplo, ID de clase si el modelo multiclase está binarizado)

Valor de métrica

Los MetricValues ​​se definen utilizando un protocolo que encapsula los diferentes tipos de valores admitidos por las diferentes métricas (por ejemplo, double , ConfusionMatrixAtThresholds , etc.).

A continuación se muestran los tipos de valores de métricas admitidos:

  • double_value : un contenedor para un tipo doble.
  • bytes_value : un valor en bytes.
  • bounded_value : representa un valor real que podría ser una estimación puntual, opcionalmente con límites aproximados de algún tipo. Tiene propiedades value , lower_bound y upper_bound .
  • value_at_cutoffs : valor en los límites (por ejemplo, precisión@K, recuperación@K). Tiene values de propiedad, cada uno de los cuales tiene propiedades cutoff y value .
  • confusion_matrix_at_thresholds : matriz de confusión en los umbrales. Tiene matrices de propiedades, cada una de las cuales tiene propiedades para valores de matriz threshold , precision , recall y confusión, como false_negatives .
  • array_value : para métricas que devuelven una matriz de valores.

Claves de la trama

Las PlotKeys son similares a las claves métricas excepto que, por razones históricas, todos los valores de los gráficos se almacenan en un solo protocolo, por lo que la clave del gráfico no tiene nombre.

Valores de trazado

Todos los gráficos admitidos se almacenan en un único protocolo llamado PlotData .

Resultado de evaluación

El resultado de una ejecución de evaluación es un tfma.EvalResult . Este registro contiene slicing_metrics que codifica la clave de métrica como un dictado de varios niveles donde los niveles corresponden al nombre de salida, ID de clase, nombre de métrica y valor de métrica, respectivamente. Está diseñado para usarse para la visualización de la interfaz de usuario en una computadora portátil Jupiter. Si es necesario acceder a los datos subyacentes, se debe utilizar el archivo de resultados metrics (consulte metrics_for_slice.proto ).

Personalización

Además de las métricas personalizadas que se agregan como parte de un keras guardado (o EvalSavedModel heredado). Hay dos formas de personalizar las métricas en el guardado posterior de TFMA: (1) definiendo una clase de métrica keras personalizada y (2) definiendo una clase de métrica TFMA personalizada respaldada por un combinador de haces.

En ambos casos, las métricas se configuran especificando el nombre de la clase de métrica y el módulo asociado. Por ejemplo:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    metrics { class_name: "MyMetric" module: "my.module"}
  }
""", tfma.EvalConfig()).metrics_specs

Métricas personalizadas de Keras

Para crear una métrica keras personalizada, los usuarios deben extender tf.keras.metrics.Metric con su implementación y luego asegurarse de que el módulo de la métrica esté disponible en el momento de la evaluación.

Tenga en cuenta que para las métricas agregadas después de guardar el modelo, TFMA solo admite métricas que toman la etiqueta (es decir, y_true), la predicción (y_pred) y el peso de ejemplo (sample_weight) como parámetros para el método update_state .

Ejemplo de métrica de Keras

El siguiente es un ejemplo de una métrica de Keras personalizada:

class MyMetric(tf.keras.metrics.Mean):

  def __init__(self, name='my_metric', dtype=None):
    super(MyMetric, self).__init__(name=name, dtype=dtype)

  def update_state(self, y_true, y_pred, sample_weight=None):
    return super(MyMetric, self).update_state(
        y_pred, sample_weight=sample_weight)

Métricas TFMA personalizadas

Para crear una métrica TFMA personalizada, los usuarios deben extender tfma.metrics.Metric con su implementación y luego asegurarse de que el módulo de la métrica esté disponible en el momento de la evaluación.

Métrico

Una implementación de tfma.metrics.Metric se compone de un conjunto de kwargs que definen la configuración de las métricas junto con una función para crear los cálculos (posiblemente múltiples) necesarios para calcular el valor de las métricas. Hay dos tipos de cálculo principales que se pueden utilizar: tfma.metrics.MetricComputation y tfma.metrics.DerivedMetricComputation que se describen en las secciones siguientes. A la función que crea estos cálculos se le pasarán los siguientes parámetros como entrada:

  • eval_config: tfam.EvalConfig
    • La configuración de evaluación pasada al evaluador (útil para buscar configuraciones de especificaciones del modelo, como la clave de predicción a usar, etc.).
  • model_names: List[Text]
    • Lista de nombres de modelos para calcular métricas (Ninguno si es un modelo único)
  • output_names: List[Text] .
    • Lista de nombres de salida para calcular métricas (Ninguno si es un modelo único)
  • sub_keys: List[tfma.SubKey] .
    • Lista de subclaves (ID de clase, K superior, etc.) para calcular métricas (o Ninguna)
  • aggregation_type: tfma.AggregationType
    • Tipo de agregación si se calcula una métrica de agregación.
  • class_weights: Dict[int, float] .
    • Ponderaciones de clase que se utilizarán si se calcula una métrica de agregación.
  • query_key: Text
    • Clave de consulta utilizada si se calcula una métrica basada en consultas/clasificación.

Si una métrica no está asociada con una o más de estas configuraciones, entonces puede dejar esos parámetros fuera de su definición de firma.

Si una métrica se calcula de la misma manera para cada modelo, salida y subclave, entonces la utilidad tfma.metrics.merge_per_key_computations se puede utilizar para realizar los mismos cálculos para cada una de estas entradas por separado.

Computación métrica

Una MetricComputation se compone de una combinación de preprocessors y un combiner . Los preprocessors son una lista de preprocessor , que es un beam.DoFn que toma extractos como entrada y genera el estado inicial que utilizará el combinador (consulte la arquitectura para obtener más información sobre qué son los extractos). Todos los preprocesadores se ejecutarán secuencialmente en el orden de la lista. Si los preprocessors están vacíos, al combinador se le pasarán StandardMetricInputs (las entradas métricas estándar contienen etiquetas, predicciones y pesos de ejemplo). El combiner es un beam.CombineFn que toma una tupla de (clave de segmento, salida del preprocesador) como entrada y genera una tupla de (clave_de segmento, dictado de resultados de métricas) como resultado.

Tenga en cuenta que el corte ocurre entre los preprocessors y combiner .

Tenga en cuenta que si un cálculo métrico desea utilizar ambas entradas métricas estándar, pero aumentarlas con algunas de las características de los extractos features , entonces se puede usar el FeaturePreprocessor especial que fusionará las características solicitadas de múltiples combinadores en un solo Valor StandardMetricsInputs compartido que se pasa a todos los combinadores (los combinadores son responsables de leer las características que les interesan e ignorar el resto).

Ejemplo

El siguiente es un ejemplo muy simple de definición de métrica TFMA para calcular el EjemploCount:

class ExampleCount(tfma.metrics.Metric):

  def __init__(self, name: Text = 'example_count'):
    super(ExampleCount, self).__init__(_example_count, name=name)


def _example_count(
    name: Text = 'example_count') -> tfma.metrics.MetricComputations:
  key = tfma.metrics.MetricKey(name=name)
  return [
      tfma.metrics.MetricComputation(
          keys=[key],
          preprocessors=[_ExampleCountPreprocessor()],
          combiner=_ExampleCountCombiner(key))
  ]


class ExampleCountTest(tfma.test.testutil.TensorflowModelAnalysisTest):

  def testExampleCount(self):
    metric = ExampleCount()
    computations = metric.computations(example_weighted=False)
    computation = computations[0]

    with beam.Pipeline() as pipeline:
      result = (
          pipeline
          | 'Create' >> beam.Create([...])  # Add inputs
          | 'PreProcess' >> beam.ParDo(computation.preprocessors[0])
          | 'Process' >> beam.Map(tfma.metrics.to_standard_metric_inputs)
          | 'AddSlice' >> beam.Map(lambda x: ((), x))
          | 'ComputeMetric' >> beam.CombinePerKey(computation.combiner)
      )

      def check_result(got):
        try:
          self.assertLen(got, 1)
          got_slice_key, got_metrics = got[0]
          self.assertEqual(got_slice_key, ())
          key = computation.keys[0]
          self.assertIn(key, got_metrics)
          self.assertAlmostEqual(got_metrics[key], expected_value, places=5)
        except AssertionError as err:
          raise util.BeamAssertException(err)

      util.assert_that(result, check_result, label='result')

class _ExampleCountPreprocessor(beam.DoFn):

  def process(self, extracts: tfma.Extracts) -> Iterable[int]:
    yield 1


class _ExampleCountPreprocessorTest(unittest.TestCase):

  def testExampleCountPreprocessor(self):
    ...  # Init the test case here
    with beam.Pipeline() as pipeline:
      updated_pcoll = (
          pipeline
          | 'Create' >> beam.Create([...])  # Add inputs
          | 'Preprocess'
          >> beam.ParDo(
              _ExampleCountPreprocessor()
          )
      )

      beam_testing_util.assert_that(
          updated_pcoll,
          lambda result: ...,  # Assert the test case
      )


class _ExampleCountCombiner(beam.CombineFn):

  def __init__(self, metric_key: tfma.metrics.MetricKey):
    self._metric_key = metric_key

  def create_accumulator(self) -> int:
    return 0

  def add_input(self, accumulator: int, state: int) -> int:
    return accumulator + state

  def merge_accumulators(self, accumulators: Iterable[int]) -> int:
    accumulators = iter(accumulators)
    result = next(accumulator)
    for accumulator in accumulators:
      result += accumulator
    return result

  def extract_output(self,
                     accumulator: int) -> Dict[tfma.metrics.MetricKey, int]:
    return {self._metric_key: accumulator}

Computación métrica derivada

Un DerivedMetricComputation se compone de una función de resultado que se utiliza para calcular valores de métricas en función del resultado de otros cálculos de métricas. La función de resultado toma un dictado de valores calculados como entrada y genera un dictado de resultados métricos adicionales.

Tenga en cuenta que es aceptable (recomendado) incluir los cálculos de los que depende un cálculo derivado en la lista de cálculos creados por una métrica. Esto evita tener que crear previamente y pasar cálculos que se comparten entre varias métricas. El evaluador eliminará automáticamente la duplicación de los cálculos que tengan la misma definición, de modo que solo se ejecute un cálculo.

Ejemplo

Las métricas TJUR proporcionan un buen ejemplo de métricas derivadas.