このページは Cloud Translation API によって翻訳されました。
Switch to English

tf.summaryの使用法をTF 2.0に移行する

TensorFlow.orgで見る Google Colabで実行 GitHubでソースを表示
import tensorflow as tf

TensorFlow 2.0には、 tf.summaryで視覚化するための要約データを書き込むために使用されるtf.summary APIに対する重要な変更が含まれてtf.summaryます。

変更点

tf.summary APIを2つのサブAPIと考えると便利です。

  • 個々の要約を記録するための一連の操作summary.scalar()summary.histogram()summary.image()summary.audio() 、およびsummary.text() -モデルコードからインラインで呼び出されます。
  • これらの個々の要約を収集し、それらを特別にフォーマットされたログファイル(TensorBoardが読み取って視覚化を生成する)に書き込むロジックを記述します。

TF 1.x

2つの半分は手動で一緒に配線する必要がありましたFileWriter.add_summary(output, step) Session.run()を介してサマリーop出力をフェッチし、 FileWriter.add_summary(output, step)を呼び出しSession.run()v1.summary.merge_all() opは、グラフコレクションを使用してすべての要約op出力を集約することでこれを容易にしましたが、このアプローチは熱心な実行と制御フローに対して依然として不十分であり、特にTF 2.0には適していません。

TF 2.X

2つの半分は緊密に統合されており、個々のtf.summary opsは実行時にすぐにデータを書き込みます。モデルコードからAPIを使用することは今でもおなじみのはずですが、グラフモードとの互換性を保ちながら、熱心に実行できるようになりました。 APIの両方の半分を統合することは、 summary.FileWriterがTensorFlow実行コンテキストの一部になり、 tf.summary opsから直接アクセスされるtf.summaryなることをtf.summaryます。そのため、ライターの設定が異なるように見えます。

熱心な実行、TF 2.0のデフォルトでの使用例:

writer = tf.summary.create_file_writer("/tmp/mylogs/eager")

with writer.as_default():
  for step in range(100):
    # other model code would go here
    tf.summary.scalar("my_metric", 0.5, step=step)
    writer.flush()
ls /tmp/mylogs/eager
events.out.tfevents.1599908770.kokoro-gcp-ubuntu-prod-1849198075.22428.5.v2

tf.functionグラフ実行での使用例:

writer = tf.summary.create_file_writer("/tmp/mylogs/tf_function")

@tf.function
def my_func(step):
  with writer.as_default():
    # other model code would go here
    tf.summary.scalar("my_metric", 0.5, step=step)

for step in tf.range(100, dtype=tf.int64):
  my_func(step)
  writer.flush()
ls /tmp/mylogs/tf_function
events.out.tfevents.1599908771.kokoro-gcp-ubuntu-prod-1849198075.22428.1013.v2

レガシーTF 1.xグラフ実行での使用例:

g = tf.compat.v1.Graph()
with g.as_default():
  step = tf.Variable(0, dtype=tf.int64)
  step_update = step.assign_add(1)
  writer = tf.summary.create_file_writer("/tmp/mylogs/session")
  with writer.as_default():
    tf.summary.scalar("my_metric", 0.5, step=step)
  all_summary_ops = tf.compat.v1.summary.all_v2_summary_ops()
  writer_flush = writer.flush()


with tf.compat.v1.Session(graph=g) as sess:
  sess.run([writer.init(), step.initializer])

  for i in range(100):
    sess.run(all_summary_ops)
    sess.run(step_update)
    sess.run(writer_flush)  
ls /tmp/mylogs/session
events.out.tfevents.1599908771.kokoro-gcp-ubuntu-prod-1849198075.22428.1446.v2

コードを変換する

既存のtf.summary使用法をTF 2.0 APIに変換することは確実に自動化できないため、 tf_upgrade_v2スクリプトは単にすべてをtf.compat.v1.summary書き換えます。 TF 2.0に移行するには、次のようにコードを調整する必要があります。

  1. .as_default()を使用するには、 .as_default()を介して設定されたデフォルトのライターが存在する必要があります

    • これは、熱心に操作を実行するか、グラフ構築で操作を使用することを意味します
    • デフォルトのライターがない場合、サマリー操作はサイレントノーオペレーションになります
    • デフォルトのライターは(まだ) @tf.function実行境界を越えて伝播しません-それらは関数がトレースされたときにのみ検出されます-したがって、ベストプラクティスは、関数本体内でwriter.as_default()を呼び出し、ライターオブジェクトが@tf.functionが使用されている限り存在し続けます
  2. 「step」値は、 step引数を介して各opに渡される必要があります

    • TensorBoardでは、データを時系列としてレンダリングするためにステップ値が必要です
    • TF 1.xからのグローバルステップが削除されているため、明示的な受け渡しが必要です。そのため、各オペレーションは、読み取る必要のあるステップ変数を知っている必要があります。
    • ボイラープレートを減らすために、デフォルトのステップ値を登録するための実験的なサポートはtf.summary.experimental.set_step()として利用できますが、これは予告なしに変更される可能性がある暫定的な機能です
  3. 個々のサマリー操作の関数シグネチャが変更されました

    • 戻り値はブール値になりました(要約が実際に作成されたかどうかを示します)
    • 2番目のパラメーター名(使用されている場合)がtensorからdata変更されました
    • collectionsパラメータは削除されました。コレクションはTF 1.xのみです
    • familyパラメータは削除されました。 tf.name_scope()使用するだけです
  4. 【レガシーグラフモード/セッション実行ユーザーのみ】

    • 最初にv1.Session.run(writer.init())ライターを初期化します

    • v1.summary.all_v2_summary_ops()を使用して、現在のグラフのすべてのTF 2.0サマリー操作を取得します。たとえば、 Session.run()介して実行しSession.run()

    • v1.Session.run(writer.flush())ライターをフラッシュし、 close()でも同様に

TF 1.xコードが代わりにtf.contrib.summary APIを使用していたtf.contrib.summary 、それはTF 2.0 APIに非常に似ているため、 tf_upgrade_v2スクリプトは移行手順のほとんどを自動化します(完全に使用できない場合は警告またはエラーを出力します)移行済み)。ほとんどの場合、API呼び出しをtf.compat.v2.summary書き換えるだけです。あなたが唯一のTFとの互換性が必要な場合2.0+あなたがドロップすることができcompat.v2し、同じようにそれを参照tf.summary

追加のヒント

上記の重要な領域に加えて、いくつかの補助的な側面も変更されました。

  • 条件付き記録(「100ステップごとに記録」など)の外観が新しくなりました

    • opsと関連するコードを制御するには、それらを通常のifステートメント(eagerモードで動作し、 @tf.functionを介し@tf.function )またはtf.cond
    • 要約のみを制御するには、新しいtf.summary.record_if()コンテキストマネージャを使用して、選択したブール条件を渡します
    • これらはTF 1.xパターンを置き換えます:
if condition:
  writer.add_summary()
  • tf.compat.v1.Graph直接記述しtf.compat.v1.Graph -代わりにトレース関数を使用

    • TF 2.0でのグラフの実行は、明示的なグラフの代わりに@tf.functionを使用します
    • TF 2.0では、新しいトレーススタイルAPI tf.summary.trace_on()およびtf.summary.trace_export()を使用して、実行された関数グラフを記録します
  • tf.summary.FileWriterCacheを使用したtf.summary.FileWriterCacheごとのグローバルライターキャッシュはtf.summary.FileWriterCache

    • ユーザーは独自のライターオブジェクトのキャッシング/共有を実装するか、個別のライターを使用する必要があります(後者のTensorBoardサポートは進行中です )。
  • イベントファイルのバイナリ表現が変更されました

    • TensorBoard 1.xはすでに新しい形式をサポートしています。この違いは、イベントファイルからサマリーデータを手動で解析しているユーザーにのみ影響します
    • サマリーデータはテンソルバイトとして保存されるようになりました。あなたはそれをnumpyに変換するためにtf.make_ndarray(event.summary.value[0].tensor)を使用することができます