Migrer les métriques et les optimiseurs

Voir sur TensorFlow.org Exécuter dans Google Colab Voir la source sur GitHub Télécharger le cahier

Dans TF1, tf.metrics est l'espace de noms de l'API pour toutes les fonctions de métrique. Chacune des métriques est une fonction qui prend l' label et prediction comme paramètres d'entrée et renvoie le tenseur de métrique correspondant comme résultat. Dans TF2, tf.keras.metrics contient toutes les fonctions et tous les objets métriques. L'objet Metric peut être utilisé avec tf.keras.Model et tf.keras.layers.layer pour calculer les valeurs métriques.

Installer

Commençons par quelques importations TensorFlow nécessaires,

import tensorflow as tf
import tensorflow.compat.v1 as tf1

et préparez quelques données simples pour la démonstration :

features = [[1., 1.5], [2., 2.5], [3., 3.5]]
labels = [0, 0, 1]
eval_features = [[4., 4.5], [5., 5.5], [6., 6.5]]
eval_labels = [0, 1, 1]

TF1 : tf.compat.v1.metrics avec estimateur

Dans TF1, les métriques peuvent être ajoutées à EstimatorSpec en tant que eval_metric_ops , et l'op est généré via toutes les fonctions de métrique définies dans tf.metrics . Vous pouvez suivre l'exemple pour voir comment utiliser tf.metrics.accuracy .

def _input_fn():
  return tf1.data.Dataset.from_tensor_slices((features, labels)).batch(1)

def _eval_input_fn():
  return tf1.data.Dataset.from_tensor_slices(
      (eval_features, eval_labels)).batch(1)

def _model_fn(features, labels, mode):
  logits = tf1.layers.Dense(2)(features)
  predictions = tf.argmax(input=logits, axis=1)
  loss = tf1.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits)
  optimizer = tf1.train.AdagradOptimizer(0.05)
  train_op = optimizer.minimize(loss, global_step=tf1.train.get_global_step())
  accuracy = tf1.metrics.accuracy(labels=labels, predictions=predictions)
  return tf1.estimator.EstimatorSpec(mode, 
                                     predictions=predictions,
                                     loss=loss, 
                                     train_op=train_op,
                                     eval_metric_ops={'accuracy': accuracy})

estimator = tf1.estimator.Estimator(model_fn=_model_fn)
estimator.train(_input_fn)
INFO:tensorflow:Using default config.
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpnfk2kv3b
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpnfk2kv3b', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/training/training_util.py:401: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/training/adagrad.py:143: calling Constant.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpnfk2kv3b/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 1.0451624, step = 0
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 3...
INFO:tensorflow:Saving checkpoints for 3 into /tmp/tmpnfk2kv3b/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 3...
INFO:tensorflow:Loss for final step: 0.54487616.
<tensorflow_estimator.python.estimator.estimator.Estimator at 0x7f894c163990>
estimator.evaluate(_eval_input_fn)
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2021-11-19T02:25:11
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpnfk2kv3b/model.ckpt-3
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Inference Time : 0.14330s
INFO:tensorflow:Finished evaluation at 2021-11-19-02:25:11
INFO:tensorflow:Saving dict for global step 3: accuracy = 0.6666667, global_step = 3, loss = 0.588699
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 3: /tmp/tmpnfk2kv3b/model.ckpt-3
{'accuracy': 0.6666667, 'loss': 0.588699, 'global_step': 3}

De plus, des métriques pourraient être ajoutées à l'estimateur directement via tf.estimator.add_metrics() .

def mean_squared_error(labels, predictions):
  labels = tf.cast(labels, predictions.dtype)
  return {"mean_squared_error": 
          tf1.metrics.mean_squared_error(labels=labels, predictions=predictions)}

estimator = tf1.estimator.add_metrics(estimator, mean_squared_error)
estimator.evaluate(_eval_input_fn)
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpnfk2kv3b', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2021-11-19T02:25:12
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpnfk2kv3b/model.ckpt-3
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Inference Time : 0.14966s
INFO:tensorflow:Finished evaluation at 2021-11-19-02:25:12
INFO:tensorflow:Saving dict for global step 3: accuracy = 0.6666667, global_step = 3, loss = 0.588699, mean_squared_error = 0.33333334
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 3: /tmp/tmpnfk2kv3b/model.ckpt-3
{'accuracy': 0.6666667,
 'loss': 0.588699,
 'mean_squared_error': 0.33333334,
 'global_step': 3}

TF2 : API Keras Metrics avec tf.keras.Model

Dans TF2, tf.keras.metrics contient toutes les classes et fonctions de métriques. Ils sont conçus dans un style OOP et s'intègrent étroitement avec d'autres API tf.keras . Toutes les métriques se trouvent dans l'espace de noms tf.keras.metrics , et il existe généralement un mappage direct entre tf.compat.v1.metrics et tf.keras.metrics .

Dans l'exemple suivant, les métriques sont ajoutées dans la méthode model.compile() . Les utilisateurs n'ont qu'à créer l'instance de métrique, sans spécifier l'étiquette et le tenseur de prédiction. Le modèle Keras acheminera la sortie du modèle et l'étiquette vers l'objet de métrique.

dataset = tf.data.Dataset.from_tensor_slices((features, labels)).batch(1)
eval_dataset = tf.data.Dataset.from_tensor_slices(
      (eval_features, eval_labels)).batch(1)

inputs = tf.keras.Input((2,))
logits = tf.keras.layers.Dense(2)(inputs)
predictions = tf.argmax(input=logits, axis=1)
model = tf.keras.models.Model(inputs, predictions)
optimizer = tf.keras.optimizers.Adagrad(learning_rate=0.05)

model.compile(optimizer, loss='mse', metrics=[tf.keras.metrics.Accuracy()])
model.evaluate(eval_dataset, return_dict=True)
3/3 [==============================] - 0s 2ms/step - loss: 0.3333 - accuracy: 0.6667
{'loss': 0.3333333432674408, 'accuracy': 0.6666666865348816}

Lorsque l'exécution hâtive est activée, les instances tf.keras.metrics.Metric peuvent être directement utilisées pour évaluer des données numpy ou des tenseurs hâtifs. Les objets tf.keras.metrics.Metric sont des conteneurs avec état. La valeur de la métrique peut être mise à jour via metric.update_state(y_true, y_pred) , et le résultat peut être récupéré par metrics.result() .

accuracy = tf.keras.metrics.Accuracy()

accuracy.update_state(y_true=[0, 0, 1, 1], y_pred=[0, 0, 0, 1])
accuracy.result().numpy()
0.75
accuracy.update_state(y_true=[0, 0, 1, 1], y_pred=[0, 0, 0, 0])
accuracy.update_state(y_true=[0, 0, 1, 1], y_pred=[1, 1, 0, 0])
accuracy.result().numpy()
0.41666666

Pour plus de détails sur tf.keras.metrics.Metric , veuillez consulter la documentation de l'API sur tf.keras.metrics.Metric , ainsi que le guide de migration .

Migrer les optimiseurs TF1.x vers les optimiseurs Keras

Les optimiseurs de tf.compat.v1.train , tels que l' optimiseur Adam et l' optimiseur de descente de gradient , ont des équivalents dans tf.keras.optimizers .

Le tableau ci-dessous résume comment vous pouvez convertir ces optimiseurs hérités en leurs équivalents Keras. Vous pouvez remplacer directement la version TF1.x par la version TF2 sauf si des étapes supplémentaires (telles que la mise à jour du taux d'apprentissage par défaut ) sont nécessaires.

Notez que la conversion de vos optimiseurs peut rendre les anciens points de contrôle incompatibles .

TF1.x TF2 Étapes supplémentaires
`tf.v1.train.GradientDescentOptimizer` tf.keras.optimizers.SGD Rien
`tf.v1.train.MomentumOptimizer` tf.keras.optimizers.SGD Inclure l'argument "momentum"
`tf.v1.train.AdamOptimizer` tf.keras.optimizers.Adam Renommez les arguments `beta1` et `beta2` en `beta_1` et `beta_2`
`tf.v1.train.RMSPropOptimizer` tf.keras.optimizers.RMSprop Renommez l'argument `decay` en `rho`
`tf.v1.train.AdadeltaOptimizer` tf.keras.optimizers.Adadelta Rien
`tf.v1.train.AdagradOptimizer` tf.keras.optimizers.Adagrad Rien
`tf.v1.train.FtrlOptimizer` tf.keras.optimizers.Ftrl Supprimez les arguments `accum_name` et `linear_name`
`tf.contrib.AdamaxOptimizer` tf.keras.optimizers.Adamax Renommez les arguments `beta1` et `beta2` en `beta_1` et `beta_2`
`tf.contrib.Nadam` tf.keras.optimizers.Nadam Renommez les arguments `beta1` et `beta2` en `beta_1` et `beta_2`