TLDR:それはあなたの機能と、あなたが本番か開発かによって異なります。tf.function
関数を簡単にデバッグしたい場合、またはオートグラフまたはtf.v1コードの互換性の制限に該当する場合は使用しないでください。Inside TensorFlowがセッションではなくオートグラフと関数について語るのを見ることを強くお勧めします。
以下では、理由を詳しく説明します。理由はすべて、Googleがオンラインで提供する情報から取得されます。
一般に、tf.function
デコレータは、TensorFlowグラフを実行する呼び出し可能関数として関数をコンパイルします。これは以下を伴います:
- 必要に応じて、オートグラフによるコードの変換(注釈付き関数から呼び出された関数を含む)
- 生成されたグラフコードのトレースと実行
この背後にある設計アイデアに関する詳細な情報があります。
関数を装飾することの利点 tf.function
一般的なメリット
- より高速な実行、特に関数が多数の小さな演算で構成される場合(ソース)
Pythonコードを含む関数の場合/ tf.function
デコレーションによるオートグラフの使用
AutoGraphを使用する場合tf.function
は、AutoGraphを直接呼び出すよりもを使用することを強くお勧めします。これには、自動制御の依存関係、一部のAPI、より多くのキャッシュ、および例外ヘルパー(ソース)に必要な理由が含まれます。
関数を装飾することの欠点 tf.function
一般的な欠点
- 関数がいくつかの高価な演算のみで構成されている場合、速度はそれほど向上しません(ソース)
Pythonコードを含む関数の場合/ tf.function
デコレーションによるオートグラフの使用
- 例外のキャッチなし(意欲的なモードで実行する必要があります。装飾された関数の外で)(ソース)
- デバッグはずっと難しい
- 隠れた副作用とTF制御フローによる制限
AutoGraphの制限に関する詳細情報が利用可能です。
tf.v1コードを持つ関数の場合
- で変数を複数回作成することは許可されていませんが
tf.function
、tf.v1コードが段階的に廃止されるため、これは変更される可能性があります(ソース)
tf.v2コードを持つ関数の場合
制限の例
変数を複数回作成する
v
次の例のように、変数を複数回作成することはできません。
@tf.function
def f(x):
v = tf.Variable(1)
return tf.add(x, v)
f(tf.constant(2))
# => ValueError: tf.function-decorated function tried to create variables on non-first call.
次のコードでは、これがself.v
1度だけ作成されるようにすることでこれを軽減しています。
class C(object):
def __init__(self):
self.v = None
@tf.function
def f(self, x):
if self.v is None:
self.v = tf.Variable(1)
return tf.add(x, self.v)
c = C()
print(c.f(tf.constant(2)))
# => tf.Tensor(3, shape=(), dtype=int32)
AutoGraphによってキャプチャされない隠れた副作用
self.a
この例ののような変更を非表示にすることはできません。クロスファンクション分析がまだ行われていないため、エラーが発生します(まだ)(ソース)。
class C(object):
def change_state(self):
self.a += 1
@tf.function
def f(self):
self.a = tf.constant(0)
if tf.constant(True):
self.change_state() # Mutation of self.a is hidden
tf.print(self.a)
x = C()
x.f()
# => InaccessibleTensorError: The tensor 'Tensor("add:0", shape=(), dtype=int32)' cannot be accessed here: it is defined in another function or code block. Use return values, explicit Python locals or TensorFlow collections to access it. Defined in: FuncGraph(name=cond_true_5, id=5477800528); accessed from: FuncGraph(name=f, id=5476093776).
明白な視界の変化は問題ありません:
class C(object):
@tf.function
def f(self):
self.a = tf.constant(0)
if tf.constant(True):
self.a += 1 # Mutation of self.a is in plain sight
tf.print(self.a)
x = C()
x.f()
# => 1
TF制御フローによる制限の例
elseの値をTF制御フローに定義する必要があるため、このifステートメントはエラーになります。
@tf.function
def f(a, b):
if tf.greater(a, b):
return tf.constant(1)
# If a <= b would return None
x = f(tf.constant(3), tf.constant(2))
# => ValueError: A value must also be returned from the else branch. If a value is returned from one branch of a conditional a value must be returned from all branches.
tensorflow0.1
、tensorflow0.2
、tensorflow0.3
、tensorflow0.4
、tensorflow0.5
など、などのそれぞれのためのタグこれらtf
のモジュールやクラス、その後。また、Pythonの標準モジュールとその関数およびクラスのそれぞれにタグを追加してみませんか?