Métriques et tracés d'analyse du modèle Tensorflow

Aperçu

TFMA prend en charge les métriques et les tracés suivants :

  • Métriques keras standard ( tf.keras.metrics.* )
    • Notez que vous n'avez pas besoin d'un modèle keras pour utiliser les métriques keras. Les métriques sont calculées en dehors du graphique dans Beam en utilisant directement les classes de métriques.
  • Métriques et tracés TFMA standard ( tfma.metrics.* )

  • Métriques keras personnalisées (métriques dérivées de tf.keras.metrics.Metric )

  • Métriques TFMA personnalisées (métriques dérivées de tfma.metrics.Metric ) utilisant des combinateurs de faisceaux personnalisés ou des métriques dérivées d'autres métriques).

TFMA fournit également une prise en charge intégrée pour la conversion des métriques de classification binaire à utiliser avec des problèmes multi-classes/multi-étiquettes :

  • Binarisation basée sur l'ID de classe, le top K, etc.
  • Métriques agrégées basées sur une micro-moyenne, une macro-moyenne, etc.

TFMA fournit également une prise en charge intégrée des métriques basées sur les requêtes/classements, où les exemples sont automatiquement regroupés par clé de requête dans le pipeline.

Au total, il existe plus de 50 métriques et graphiques standard disponibles pour une variété de problèmes, notamment la régression, la classification binaire, la classification multi-classes/multi-étiquettes, le classement, etc.

Configuration

Il existe deux manières de configurer les métriques dans TFMA : (1) en utilisant tfma.MetricsSpec ou (2) en créant des instances de tf.keras.metrics.* et/ou tfma.metrics.* en python et en utilisant tfma.metrics.specs_from_metrics pour les convertir en une liste de tfma.MetricsSpec .

Les sections suivantes décrivent des exemples de configurations pour différents types de problèmes d'apprentissage automatique.

Métriques de régression

Ce qui suit est un exemple de configuration pour un problème de régression. Consultez les modules tf.keras.metrics.* et tfma.metrics.* pour connaître les éventuelles métriques supplémentaires prises en charge.

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

Cette même configuration peut être créée à l'aide du code python suivant :

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)

Notez que cette configuration est également disponible en appelant tfma.metrics.default_regression_specs .

Métriques de classification binaire

Ce qui suit est un exemple de configuration pour un problème de classification binaire. Consultez les modules tf.keras.metrics.* et tfma.metrics.* pour connaître les éventuelles métriques supplémentaires prises en charge.

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

Cette même configuration peut être créée à l'aide du code python suivant :

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)

Notez que cette configuration est également disponible en appelant tfma.metrics.default_binary_classification_specs .

Métriques de classification multi-classes/multi-étiquettes

Ce qui suit est un exemple de configuration pour un problème de classification multi-classe. Consultez les modules tf.keras.metrics.* et tfma.metrics.* pour connaître les éventuelles métriques supplémentaires prises en charge.

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

Cette même configuration peut être créée à l'aide du code python suivant :

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)

Notez que cette configuration est également disponible en appelant tfma.metrics.default_multi_class_classification_specs .

Métriques binarisées multi-classes/multi-étiquettes

Les métriques multi-classes/multi-étiquettes peuvent être binarisées pour produire des métriques par classe, par top_k, etc. à l'aide de tfma.BinarizationOptions . Par exemple:

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

Cette même configuration peut être créée à l'aide du code python suivant :

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étriques globales multiclasses/multi-étiquettes

Les métriques multi-classes/multi-étiquettes peuvent être agrégées pour produire une valeur agrégée unique pour une métrique de classification binaire à l'aide tfma.AggregationOptions .

Notez que les paramètres d'agrégation sont indépendants des paramètres de binarisation, vous pouvez donc utiliser à la fois tfma.AggregationOptions et tfma.BinarizationOptions .

Micromoyenne

La micro-moyenne peut être effectuée à l'aide de l'option micro_average dans tfma.AggregationOptions . Par exemple:

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

Cette même configuration peut être créée à l'aide du code python suivant :

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))

La micro-moyenne prend également en charge le paramètre top_k où seules les valeurs k supérieures sont utilisées dans le calcul. Par exemple:

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

Cette même configuration peut être créée à l'aide du code python suivant :

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 / Moyenne macro pondérée

La moyenne des macros peut être effectuée à l'aide des options macro_average ou weighted_macro_average dans tfma.AggregationOptions . À moins que les paramètres top_k ne soient utilisés, la macro nécessite de définir les class_weights afin de savoir pour quelles classes calculer la moyenne. Si un class_weight n’est pas fourni, alors 0,0 est supposé. Par exemple:

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

Cette même configuration peut être créée à l'aide du code python suivant :

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)}))

Comme la micro-moyenne, la macro-moyenne prend également en charge la définition top_k où seules les valeurs k supérieures sont utilisées dans le calcul. Par exemple:

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

Cette même configuration peut être créée à l'aide du code python suivant :

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étriques basées sur les requêtes/classements

Les métriques basées sur les requêtes/classements sont activées en spécifiant l'option query_key dans les spécifications des métriques. Par exemple:

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

Cette même configuration peut être créée à l'aide du code python suivant :

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étriques d'évaluation multimodèles

TFMA prend en charge l'évaluation de plusieurs modèles en même temps. Lorsqu’une évaluation multimodèle est effectuée, les métriques seront calculées pour chaque modèle. Par exemple:

from google.protobuf import text_format

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

Si les métriques doivent être calculées pour un sous-ensemble de modèles, définissez model_names dans metric_specs . Par exemple:

from google.protobuf import text_format

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

L'API specs_from_metrics prend également en charge la transmission des noms de modèles :

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

Mesures de comparaison de modèles

TFMA prend en charge l'évaluation des métriques de comparaison d'un modèle candidat par rapport à un modèle de référence. Un moyen simple de configurer la paire de modèles candidats et de référence consiste à transmettre un eval_shared_model avec les noms de modèles appropriés (tfma.BASELINE_KEY et 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")

Les métriques de comparaison sont calculées automatiquement pour toutes les métriques différenciables (actuellement uniquement les métriques de valeur scalaire telles que la précision et l'AUC).

Métriques du modèle multi-sorties

TFMA prend en charge l'évaluation des métriques sur des modèles qui ont des sorties différentes. Les modèles à sorties multiples stockent leurs prédictions de sortie sous la forme d'un dictionnaire saisi par nom de sortie. Lorsque des modèles multi-sorties sont utilisés, les noms des sorties associées à un ensemble de métriques doivent être spécifiés dans la section output_names de MetricsSpec. Par exemple:

from google.protobuf import text_format

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

L'API specs_from_metrics prend également en charge la transmission des noms de sortie :

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

Personnalisation des paramètres de métrique

TFMA permet de personnaliser les paramètres utilisés avec différentes métriques. Par exemple, vous souhaiterez peut-être modifier le nom, définir des seuils, etc. Cela se fait en ajoutant une section config à la configuration de la métrique. La configuration est spécifiée à l'aide de la version de chaîne JSON des paramètres qui seraient transmis à la méthode metrics __init__ (pour faciliter l'utilisation, les crochets « { » et « » de début et de fin peuvent être omis). Par exemple:

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

Cette personnalisation est bien entendu également prise en charge directement :

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

Sorties

Le résultat d’une évaluation de métrique est une série de clés/valeurs de métrique et/ou de clés/valeurs de tracé basées sur la configuration utilisée.

Clés métriques

Les MetricKeys sont définis à l’aide d’un type de clé structuré. Cette clé identifie de manière unique chacun des aspects suivants d'une métrique :

  • Nom de la métrique ( auc , mean_label , etc.)
  • Nom du modèle (utilisé uniquement en cas d'évaluation multi-modèle)
  • Nom de la sortie (utilisé uniquement si les modèles multi-sorties sont évalués)
  • Sous-clé (par exemple, ID de classe si le modèle multi-classes est binarisé)

Valeur métrique

Les MetricValues ​​sont définies à l'aide d'un proto qui encapsule les différents types de valeurs pris en charge par les différentes métriques (par exemple double , ConfusionMatrixAtThresholds , etc.).

Vous trouverez ci-dessous les types de valeurs de métriques pris en charge :

  • double_value - Un wrapper pour un type double.
  • bytes_value - Une valeur en octets.
  • bounded_value - Représente une valeur réelle qui pourrait être une estimation ponctuelle, éventuellement avec des limites approximatives. Possède les propriétés value , lower_bound et upper_bound .
  • value_at_cutoffs - Valeur aux seuils (par exemple précision@K, rappel@K). Possède values de propriété, chacune ayant des propriétés cutoff et value .
  • confusion_matrix_at_thresholds - Matrice de confusion aux seuils. Possède matrices de propriétés, chacune possédant des propriétés pour les valeurs de matrice threshold , precision , recall et de confusion telles que false_negatives .
  • array_value - Pour les métriques qui renvoient un tableau de valeurs.

Clés de tracé

Les PlotKeys sont similaires aux clés métriques, sauf que pour des raisons historiques, toutes les valeurs des tracés sont stockées dans un seul proto, de sorte que la clé de tracé n'a pas de nom.

Valeurs du tracé

Tous les tracés pris en charge sont stockés dans un seul proto appelé PlotData .

Résultat d'évaluation

Le retour d'une exécution d'évaluation est un tfma.EvalResult . Cet enregistrement contient slicing_metrics qui codent la clé de métrique sous la forme d'un dictionnaire à plusieurs niveaux où les niveaux correspondent respectivement au nom de sortie, à l'ID de classe, au nom de la métrique et à la valeur de la métrique. Ceci est destiné à être utilisé pour l’affichage de l’interface utilisateur dans un ordinateur portable Jupiter. Si l'accès aux données sous-jacentes est nécessaire, le fichier de résultats metrics doit être utilisé à la place (voir metrics_for_slice.proto ).

Personnalisation

En plus des métriques personnalisées ajoutées dans le cadre d'un keras enregistré (ou d'un ancien EvalSavedModel). Il existe deux manières de personnaliser les métriques dans la post-sauvegarde TFMA : (1) en définissant une classe de métriques keras personnalisée et (2) en définissant une classe de métriques TFMA personnalisée soutenue par un combinateur de faisceaux.

Dans les deux cas, les métriques sont configurées en spécifiant le nom de la classe de métriques et le module associé. Par exemple:

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étriques Keras personnalisées

Pour créer une métrique keras personnalisée, les utilisateurs doivent étendre tf.keras.metrics.Metric avec leur implémentation, puis s'assurer que le module de la métrique est disponible au moment de l'évaluation.

Notez que pour les métriques ajoutées après l'enregistrement du modèle, TFMA prend uniquement en charge les métriques qui prennent l'étiquette (c'est-à-dire y_true), la prédiction (y_pred) et l'exemple de poids (sample_weight) comme paramètres de la méthode update_state .

Exemple de métrique Keras

Voici un exemple de métrique keras personnalisée :

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étriques TFMA personnalisées

Pour créer une métrique TFMA personnalisée, les utilisateurs doivent étendre tfma.metrics.Metric avec leur implémentation, puis s'assurer que le module de la métrique est disponible au moment de l'évaluation.

Métrique

Une implémentation tfma.metrics.Metric est composée d'un ensemble de kwargs qui définissent la configuration des métriques ainsi que d'une fonction permettant de créer les calculs (éventuellement multiples) nécessaires pour calculer la valeur des métriques. Deux principaux types de calcul peuvent être utilisés : tfma.metrics.MetricComputation et tfma.metrics.DerivedMetricComputation , décrits dans les sections ci-dessous. La fonction qui crée ces calculs recevra les paramètres suivants en entrée :

  • eval_config: tfam.EvalConfig
    • La configuration d'évaluation transmise à l'évaluateur (utile pour rechercher les paramètres de spécifications du modèle tels que la clé de prédiction à utiliser, etc.).
  • model_names: List[Text]
    • Liste des noms de modèles pour lesquels calculer les métriques (Aucun si modèle unique)
  • output_names: List[Text] .
    • Liste des noms de sortie pour lesquels calculer les métriques (Aucun si modèle unique)
  • sub_keys: List[tfma.SubKey] .
    • Liste des sous-clés (ID de classe, top K, etc.) pour lesquelles calculer les métriques (ou Aucune)
  • aggregation_type: tfma.AggregationType
    • Type d'agrégation si vous calculez une métrique d'agrégation.
  • class_weights: Dict[int, float] .
    • Pondérations de classe à utiliser lors du calcul d’une métrique d’agrégation.
  • query_key: Text
    • Clé de requête utilisée lors du calcul d’une métrique basée sur une requête/un classement.

Si une métrique n'est pas associée à un ou plusieurs de ces paramètres, elle peut alors laisser ces paramètres en dehors de sa définition de signature.

Si une métrique est calculée de la même manière pour chaque modèle, sortie et sous-clé, alors l'utilitaire tfma.metrics.merge_per_key_computations peut être utilisé pour effectuer les mêmes calculs pour chacune de ces entrées séparément.

Calcul métrique

Un MetricComputation est composé d'une combinaison de preprocessors et d'un combiner . Les preprocessors sont une liste de preprocessor , qui est un beam.DoFn qui prend les extraits en entrée et génère l'état initial qui sera utilisé par le combineur (voir l'architecture pour plus d'informations sur ce que sont les extraits). Tous les préprocesseurs seront exécutés séquentiellement dans l'ordre de la liste. Si les preprocessors sont vides, le combinateur recevra les StandardMetricInputs (les entrées métriques standard contiennent des étiquettes, des prédictions et des example_weights). Le combiner est un beam.CombineFn qui prend un tuple de (slice key, sortie du préprocesseur) comme entrée et génère un tuple de (slice_key, metric results dict) comme résultat.

Notez que le découpage se produit entre les preprocessors et combiner .

Notez que si un calcul de métrique souhaite utiliser les deux entrées de métrique standard, mais l'augmenter avec quelques-unes des fonctionnalités des extraits features , alors le FeaturePreprocessor spécial peut être utilisé pour fusionner les fonctionnalités demandées à partir de plusieurs combinateurs en un seul. valeur StandardMetricsInputs partagée qui est transmise à tous les combinateurs (les combinateurs sont responsables de lire les fonctionnalités qui les intéressent et d’ignorer le reste).

Exemple

Voici un exemple très simple de définition de métrique TFMA pour calculer l'ExempleCount :

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}

Calcul métrique dérivé

Un DerivedMetricComputation est constitué d'une fonction de résultat utilisée pour calculer des valeurs de métriques en fonction du résultat d'autres calculs de métriques. La fonction de résultat prend un dict de valeurs calculées comme entrée et génère un dict de résultats de métriques supplémentaires.

Notez qu'il est acceptable (recommandé) d'inclure les calculs dont dépend un calcul dérivé dans la liste des calculs créés par une métrique. Cela évite d'avoir à pré-créer et à transmettre des calculs partagés entre plusieurs métriques. L'évaluateur déduira automatiquement les calculs qui ont la même définition afin qu'un seul calcul soit réellement exécuté.

Exemple

Les métriques TJUR fournissent un bon exemple de métriques dérivées.