Copyright 2018 The TensorFlow Authors.
Eager execution
TensorFlow の Eager Execution は、計算グラフの作成と評価を同時におこなう命令的なプログラミングを行うための環境です: オペレーションはあとで実行するための計算グラフでなく、具体的な計算結果の値を返します。 この方法を用いることにより、初心者にとって TensorFlow を始めやすくなり、またモデルのデバッグも行いやすくなります。 さらにコードの記述量も削減されます。 このガイドの内容を実行するためには、対話的インタープリタ python
を起動し、以下のコードサンプルを実行してください。
Eager execution は研究や実験のための柔軟な機械学習環境として、以下を提供します。
直感的なインタフェース— Python のデータ構造を使用して、コードを自然に記述することができます。小規模なモデルとデータに対してすばやく実験を繰り返すことができます。
より簡単なデバッグ— ops を直接呼び出すことで、実行中のモデルを調査したり、変更をテストすることができます。 Python 標準のデバッグツールを用いて即座にエラーのレポーティングができます。
自然な制御フロー— TensorFlow のグラフ制御フローの代わりに Python の制御フローを利用するため、動的なモデルの作成をシンプルに行うことができます。
Eager execution は TensorFlow のほとんどの演算と GPU アクセラレーションをサポートします。
注意: いくつかのモデルは Eager execution を有効化することでオーバヘッドが増える可能性があります。 パフォーマンス改善を行っていますが、問題が見つかった場合はバグを報告し、ベンチマークを提供してください。
セットアップと基本的な使い方
TensorFlow 2.0 では、 Eager Execution はデフォルトで有効化されます。
これで TensorFlow の演算を実行してみましょう。結果はすぐに返されます。
Eager Execution を有効化することで、 TensorFlow の挙動は変わります—TensorFlowは即座に式を評価して結果をPythonに返すようになります。 tf.Tensor
オブジェクトは計算グラフのノードへのシンボリックハンドルの代わりに具体的な値を参照します。 セッションの中で構築して実行する計算グラフが存在しないため、print()
やデバッガを使って容易に結果を調べることができます。 勾配計算を遮ることなくテンソル値を評価、出力、およびチェックすることができます。
Eager execution は、NumPy と一緒に使うことができます。NumPy の演算は、tf.Tensor
を引数として受け取ることができます。TensorFlow の tf.math
演算は Python オブジェクトと Numpy 配列を tf.Tensor
に変換します。tf.Tensor.numpy
メソッドはオブジェクトの値を NumPy の ndarray
形式で返します。
動的な制御フロー
Eager Execution の主要なメリットは、モデルを実行する際にホスト言語のすべての機能性が利用できることです。 たとえば、fizzbuzzが簡単に書けます:
この関数はテンソル値に依存する条件式を持ち、実行時にこれらの値を表示します。
Eager Execution による学習
勾配の計算
自動微分はニューラルネットワークの学習で利用されるバックプロパゲーションなどの機械学習アルゴリズムの実装を行う上で便利です。 Eager Executionでは、勾配計算をあとで行うためのオペレーションをトレースするためにtf.GradientTape
を利用します。
Eager execution では、トレーニングや勾配計算に、tf.GradientTape
を利用できます。これは特に、複雑なトレーニングループを実行するときに役立ちます。
各呼び出し中に異なるオペレーションが発生する可能性があるため、すべての forward-pass オペレーションは一つの「テープ」に記録されます。勾配を計算するには、テープを逆方向に再生してから破棄します。特定の tf.GradientTape
は一つのグラデーションしか計算できません。後続の呼び出しは実行時エラーをスローします。
モデルをトレーニングする
以下の example は標準的な MNIST の手書き数字を分類するマルチレイヤーモデルを作成します。Eager execution 環境にトレーニング対象のグラフを構築するオプティマイザとレイヤー API を実演しています。
トレーニングを行わなくても、Eager execution により、モデルを呼び出して出力を検査することができます。
keras モデルは組み込みで学習のループを回すメソッド fit
がありますが、よりカスタマイズが必要な場合もあるでしょう。 Eager Executionを用いて実装された学習ループのサンプルを以下に示します:
Note: モデルの状況を確認したいときは、 tf.debugging
にある assert 機能を利用してください。この機能は Eager Execution と Graph Execution のどちらでも利用できます。
変数とオプティマイザ
tf.Variable
オブジェクトは、トレーニング中にアクセスされるミュータブルな tf.Tensor
のような値を格納し、自動微分を簡単化しています。
tf.GradientTape
と共に tf.Variable
を使うことでモデルパラメータはよりカプセル化されます。たとえば、上の の自動微分の例は以下のように書き換えることができます:
たとえば、上記の自動微分の例は次のように書き直すことができます。
次に、以下を行います。
モデルを作成します。
モデルのパラメータに関する損失関数の導関数。
その導関数に基づいて変数を更新するストラテジー。
注意: 変数は、Python オブジェクトへの最後の参照が削除されるまで永続し、その後削除されます。
オブジェクトベースの保存
tf.keras.Model
には、チェックポイントを簡単に作成できる便利な save_weights
メソッドがあります。
tf.train.Checkpoint
を使うと、このプロセスを完全に制御できるようになります。
このセクションは、トレーニングチェックポイントに関するガイドを短縮したものです。
モデルを保存して読み込むために、 tf.train.Checkpoint
は隠れ変数なしにオブジェクトの内部状態を保存します。 モデル
、 オプティマイザ
、そしてグローバルステップの状態を記録するには、それらを tf.train.Checkpoint
に渡します。
注意: 多くのトレーニングループでは、変数は tf.train.Checkpoint.restore
が呼び出された後に作成されます。これらの変数は作成されてすぐに復元され、チェックポイントが完全に読み込まれたことを確認するためのアサーションが利用可能になります。詳しくは、トレーニングチェックポイントに関するガイドをご覧ください。
オブジェクト指向メトリクス
tfe.keras.metrics
はオブジェクトとして保存されます。新しいデータをコーラブルに渡してメトリクスを更新し、 tfe.keras.metrics.result
メソッドを使って結果を取得します。次に例を示します:
サマリーと TensorBoard
TensorBoard はモデルのトレーニングプロセスを理解、デバッグ、および最適化するための視覚化ツールです。プログラムを実行する間に書き込まれるサマリーイベントを使用します。
Eager execution で変数のサマリーを記録するには、tf.summary
を使用できます。たとえば、100 トレーニングステップごとに loss
のサマリーを 1 回記録するには、次のように記述できます。
高度な自動微分トピック
動的なモデル
tf.GradientTape
は動的モデルでも使うことができます。 以下の バックトラックライン検索 アルゴリズムの例は、複雑な制御フローにもかかわらず 勾配があり、微分可能であることを除いて、通常の NumPy コードのように見えます:
カスタム勾配
カスタム勾配は、勾配を上書きする簡単な方法です。 フォワード関数では、 入力、出力、または中間結果に関する勾配を定義します。たとえば、逆方向パスにおいて勾配のノルムを制限する簡単な方法は次のとおりです:
カスタム勾配は、一連の演算に対して数値的に安定した勾配を提供するために一般的に使用されます。
ここで、 log1pexp
関数はカスタム勾配を用いて解析的に単純化することができます。 以下の実装は、フォワードパスの間に計算された tf.exp(x)
の値を 再利用します—冗長な計算を排除することでより効率的になります:
パフォーマンス
Eager execution の間、計算は自動的に GPU にオフロードされます。計算を実行する場所を指定する場合は、tf.device('/gpu:0')
ブロック(または CPU を指定するブロック)に含めることができます。
tf.Tensor
オブジェクトはそのオブジェクトに対するオペレーションを実行するために別のデバイスにコピーすることができます:
ベンチマーク
GPUでの ResNet50 の学習のような、計算量の多いモデルの場合は、Eager Executionのパフォーマンスは tf.function
のパフォーマンスに匹敵します。 しかし、この2つの環境下のパフォーマンスの違いは計算量の少ないモデルではより大きくなり、小さなたくさんのオペレーションからなるモデルでホットコードパスを最適化するためにやるべきことがあります。
function の使用
Eager Execution は開発とデバッグをより対話的にしますが、 TensorFlow 1.x スタイルの Graph Execution は分散学習、パフォーマンスの最適化、そしてプロダクション環境へのデプロイの観点で利点があります。