指標とオプティマイザを移行する

TensorFlow.org で表示 Google Colab で実行 GitHub でソースを表示 ノートブックをダウンロード

TF1 では、tf.metrics はすべての指標関数の API 名前空間です。各指標は、labelprediction を入力パラメータとして取り、対応する指標テンソルを結果として返す関数です。TF2 では、tf.keras.metrics にすべての指標関数とオブジェクトが含まれています。Metric オブジェクトを tf.keras.Model および tf.keras.layers.layer で使用して、指標値を計算できます。

セットアップ

いくつかの必要な TensorFlow インポートから始めましょう。

import tensorflow as tf
import tensorflow.compat.v1 as tf1
2022-12-14 22:13:32.624361: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory
2022-12-14 22:13:32.624482: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory
2022-12-14 22:13:32.624493: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.

デモ用にいくつかの簡単なデータを準備します。

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: Estimator を使用した tf.compat.v1.metrics

TF1 では、指標は eval_metric_ops として EstimatorSpec に追加でき、演算は tf.metrics で定義されたすべての指標関数を介して生成されます。例に従って、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.math.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: /tmpfs/tmp/tmp23fn1_x6
INFO:tensorflow:Using config: {'_model_dir': '/tmpfs/tmp/tmp23fn1_x6', '_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.9/site-packages/tensorflow/python/training/training_util.py:396: 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.9/site-packages/tensorflow/python/training/adagrad.py:138: 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 /tmpfs/tmp/tmp23fn1_x6/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 2.6736233, step = 0
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 3...
INFO:tensorflow:Saving checkpoints for 3 into /tmpfs/tmp/tmp23fn1_x6/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 3...
INFO:tensorflow:Loss for final step: 0.008751018.
<tensorflow_estimator.python.estimator.estimator.Estimator at 0x7f281028d310>
estimator.evaluate(_eval_input_fn)
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2022-12-14T22:13:38
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmpfs/tmp/tmp23fn1_x6/model.ckpt-3
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Inference Time : 0.25721s
INFO:tensorflow:Finished evaluation at 2022-12-14-22:13:38
INFO:tensorflow:Saving dict for global step 3: accuracy = 0.6666667, global_step = 3, loss = 2.0419586
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 3: /tmpfs/tmp/tmp23fn1_x6/model.ckpt-3
{'accuracy': 0.6666667, 'loss': 2.0419586, 'global_step': 3}

また、指標は 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': '/tmpfs/tmp/tmp23fn1_x6', '_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 2022-12-14T22:13:38
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmpfs/tmp/tmp23fn1_x6/model.ckpt-3
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Inference Time : 0.16179s
INFO:tensorflow:Finished evaluation at 2022-12-14-22:13:38
INFO:tensorflow:Saving dict for global step 3: accuracy = 0.6666667, global_step = 3, loss = 2.0419586, mean_squared_error = 0.33333334
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 3: /tmpfs/tmp/tmp23fn1_x6/model.ckpt-3
{'accuracy': 0.6666667,
 'loss': 2.0419586,
 'mean_squared_error': 0.33333334,
 'global_step': 3}

TF2: tf.keras.Model を使用した Keras メトリクス API

TF2 では、tf.keras.metrics にすべての指標クラスと関数が含まれています。これらは OOP スタイルで設計されており、他の tf.keras API と密接に統合されています。すべての指標は tf.keras.metrics 名前空間で見つけることができ、通常は tf.compat.v1.metricstf.keras.metrics の間に直接マッピングがあります。

次の例では、指標が model.compile() メソッドに追加されています。ユーザーは、ラベルと予測テンソルを指定せずに、指標インスタンスを作成するだけで済みます。Keras モデルは、モデルの出力とラベルを指標オブジェクトにルーティングします。

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.math.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 4ms/step - loss: 0.3333 - accuracy: 0.6667
{'loss': 0.3333333432674408, 'accuracy': 0.6666666865348816}

Eager execution を有効にすると、tf.keras.metrics.Metric インスタンスを直接使用して、numpy データまたは Eager テンソルを評価できます。tf.keras.metrics.Metric オブジェクトはステートフルコンテナーです。指標値は metric.update_state(y_true, y_pred) で更新でき、結果は 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

tf.keras.metrics.Metric の詳細については、tf.keras.metrics.Metric の API ドキュメントと移行ガイドを参照してください。

TF1.x オプティマイザの Keras オプティマイザへの移行

Adam オプティマイザ勾配降下オプティマイザなどの tf.compat.v1.train 内のオプティマイザは、tf.keras.optimizers 内に同等のものをもちます。

以下の表は、これらのレガシーオプティマイザを Keras の同等のものに変換する方法をまとめたものです。追加の手順(デフォルトの学習率の更新など)が必要でない限り、TF1.x バージョンを TF2 バージョンに直接置き換えることができます。

オプティマイザを変換すると、古いチェックポイントの互換性が失われる可能性があることに注意してください。

TF1.x TF2 追加の手順
`tf.v1.train.GradientDescentOptimizer` tf.keras.optimizers.SGD なし
`tf.v1.train.MomentumOptimizer` tf.keras.optimizers.SGD `momentum` 引数を含む
`tf.v1.train.AdamOptimizer` tf.keras.optimizers.Adam `beta1` および `beta2` 引数の名前を `beta_1` および `beta_2` に変更する
`tf.v1.train.RMSPropOptimizer` tf.keras.optimizers.RMSprop `decay` 引数の名前を `rho` に変更する
`tf.v1.train.AdadeltaOptimizer` tf.keras.optimizers.Adadelta なし
`tf.v1.train.AdagradOptimizer` tf.keras.optimizers.Adagrad なし
`tf.v1.train.FtrlOptimizer` tf.keras.optimizers.Ftrl `accum_name` および `linear_name` 引数を削除する
`tf.contrib.AdamaxOptimizer` tf.keras.optimizers.Adamax `beta1` および `beta2` 引数の名前を `beta_1` および `beta_2` に変更する
`tf.contrib.Nadam` tf.keras.optimizers.Nadam `beta1` および `beta2` 引数の名前を `beta_1` および `beta_2` に変更する

注意: TF2 では、すべてのイプシロン(数値安定定数)のデフォルトが 1e-8 ではなく 1e-7 になりました。ほとんどの場合、この違いは無視できます。