Tensorflow 为什么tf.function跟踪层两次?

Tensorflow 为什么tf.function跟踪层两次?,tensorflow,keras,tensorflow2.0,tf.keras,Tensorflow,Keras,Tensorflow2.0,Tf.keras,示例代码如下所示: import tensorflow as tf # tf-2.4 or tf-2.x from datetime import datetime # Define a layer with an eager side effect class EagerLayer(tf.keras.layers.Layer): def __init__(self, **kwargs): super(EagerLayer, self).__init__(**kwargs)

示例代码如下所示:

import tensorflow as tf     # tf-2.4 or tf-2.x
from datetime import datetime

# Define a layer with an eager side effect
class EagerLayer(tf.keras.layers.Layer):
  def __init__(self, **kwargs):
    super(EagerLayer, self).__init__(**kwargs)
    # Do some kind of initialization here
    self.dense = tf.keras.layers.Dense(32)

  def call(self, inputs):
    print("\nCurrently running eagerly", str(datetime.now()))
    return self.dense(inputs)

input_data = tf.random.uniform([60, 28, 28])
layer = EagerLayer()
tf_func_layer = tf.function(layer)
print("=============")
_ = tf_func_layer(input_data)
输出是

=============

Currently running eagerly 2020-12-16 20:46:38.482592

Currently running eagerly 2020-12-16 20:46:38.503605
打印副作用显示两次,这意味着该功能被跟踪两次

我只是想知道为什么该层被跟踪了两次


可以找到一个colab笔记本。

打开verbose会得到以下输出~

=============
INFO:tensorflow:Converted call: <__main__.EagerLayer object at 0x7fbf6e34b860>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: {}

INFO:tensorflow:Converted call: <built-in function hasattr>
    args: (<__main__.EagerLayer object at 0x7fbf6e34b860>, '_thread_local')
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._split_out_first_arg of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: ((<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,), {})
    kwargs: None

INFO:tensorflow:Converted call: <function flatten at 0x7fbf86ceb598>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: None

INFO:tensorflow:Converted call: <function _in_functional_construction_mode at 0x7fbf82850840>
    args: (<__main__.EagerLayer object at 0x7fbf6e34b860>, <tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>, (), {}, [<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>])
    kwargs: None

INFO:tensorflow:Converted call: <function call_context at 0x7fbf8276bf28>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <built-in function any>
    args: (<generator object outer_factory.<locals>.inner_factory.<locals>.tf____call__.<locals>.else_body_10.<locals>.<genexpr> at 0x7fbf6e07d4c0>,)
    kwargs: None

INFO:tensorflow:Converted call: <built-in function isinstance>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>, (<class 'tensorflow.python.ops.numpy_ops.np_arrays.ndarray'>, <class 'numpy.ndarray'>, <class 'float'>, <class 'int'>))
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._get_input_masks of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>, [<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>], (), {})
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._set_training_mode of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: ((), {}, <tensorflow.python.keras.engine.base_layer_utils.CallContext object at 0x7fbf79a7c860>)
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._clear_losses of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <function executing_eagerly at 0x7fbf86cb58c8>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._maybe_cast_inputs of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>, [<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>])
    kwargs: None

INFO:tensorflow:Converted call: <function assert_input_compatibility at 0x7fbf8276f2f0>
    args: (None, <tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>, 'eager_layer_7')
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._name_scope of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._autographed_call of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._maybe_build of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: None

INFO:tensorflow:Converted call: <function EagerLayer.call at 0x7fbf6ccc1bf8>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: {}

INFO:tensorflow:Converted call: <bound method EagerLayer.call of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: {}

INFO:tensorflow:Converted call: <built-in method now of type object at 0xa33e60>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <class 'str'>
    args: (datetime.datetime(2020, 12, 31, 15, 15, 24, 101021),)
    kwargs: None


Currently running eagerly 2020-12-31 15:15:24.101021
INFO:tensorflow:Converted call: <tensorflow.python.keras.layers.core.Dense object at 0x7fbf6cccb198>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._set_save_spec of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: None

INFO:tensorflow:Converted call: <__main__.EagerLayer object at 0x7fbf6e34b860>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: {}

INFO:tensorflow:Converted call: <built-in function hasattr>
    args: (<__main__.EagerLayer object at 0x7fbf6e34b860>, '_thread_local')
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._split_out_first_arg of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: ((<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,), {})
    kwargs: None

INFO:tensorflow:Converted call: <function flatten at 0x7fbf86ceb598>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: None

INFO:tensorflow:Converted call: <function _in_functional_construction_mode at 0x7fbf82850840>
    args: (<__main__.EagerLayer object at 0x7fbf6e34b860>, <tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>, (), {}, [<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>])
    kwargs: None

INFO:tensorflow:Converted call: <function call_context at 0x7fbf8276bf28>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <built-in function any>
    args: (<generator object outer_factory.<locals>.inner_factory.<locals>.tf____call__.<locals>.else_body_10.<locals>.<genexpr> at 0x7fbf6e3615c8>,)
    kwargs: None

INFO:tensorflow:Converted call: <built-in function isinstance>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>, (<class 'tensorflow.python.ops.numpy_ops.np_arrays.ndarray'>, <class 'numpy.ndarray'>, <class 'float'>, <class 'int'>))
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._get_input_masks of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>, [<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>], (), {})
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._set_training_mode of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: ((), {}, <tensorflow.python.keras.engine.base_layer_utils.CallContext object at 0x7fbf79a7c860>)
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._clear_losses of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <function executing_eagerly at 0x7fbf86cb58c8>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._maybe_cast_inputs of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>, [<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>])
    kwargs: None

INFO:tensorflow:Converted call: <function assert_input_compatibility at 0x7fbf8276f2f0>
    args: (None, <tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>, 'eager_layer_7')
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._name_scope of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <bound method Layer._autographed_call of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <function EagerLayer.call at 0x7fbf6ccfcd08>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: {}

INFO:tensorflow:Converted call: <bound method EagerLayer.call of <__main__.EagerLayer object at 0x7fbf6e34b860>>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: {}

INFO:tensorflow:Converted call: <built-in method now of type object at 0xa33e60>
    args: ()
    kwargs: None

INFO:tensorflow:Converted call: <class 'str'>
    args: (datetime.datetime(2020, 12, 31, 15, 15, 24, 153569),)
    kwargs: None


Currently running eagerly 2020-12-31 15:15:24.153569
INFO:tensorflow:Converted call: <tensorflow.python.keras.layers.core.Dense object at 0x7fbf6cccb198>
    args: (<tf.Tensor 'self:0' shape=(60, 28, 28) dtype=float32>,)
    kwargs: None
=============
信息:tensorflow:转换呼叫:
args:(,)
kwargs:{}
信息:tensorflow:转换呼叫:
参数:(,“\u线程\u本地”)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:((,),{})
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,(),{},[])
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,)
夸尔斯:没有
信息:tensorflow:转换呼叫:
参数:(,(,,)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,[],(),{})
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:((),{},)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
参数:(,[])
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(无,'eager_layer_7')
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,)
kwargs:{}
信息:tensorflow:转换呼叫:
args:(,)
kwargs:{}
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(datetime.datetime(2020,12,31,15,15,24101021),)
夸尔斯:没有
目前正在急切运行2020-12-31 15:15:24.101021
信息:tensorflow:转换呼叫:
args:(,)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,)
kwargs:{}
信息:tensorflow:转换呼叫:
参数:(,“\u线程\u本地”)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:((,),{})
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,(),{},[])
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,)
夸尔斯:没有
信息:tensorflow:转换呼叫:
参数:(,(,,)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,[],(),{})
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:((),{},)
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
参数:(,[])
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(无,'eager_layer_7')
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(,)
kwargs:{}
信息:tensorflow:转换呼叫:
args:(,)
kwargs:{}
信息:tensorflow:转换呼叫:
args:()
夸尔斯:没有
信息:tensorflow:转换呼叫:
args:(datetime.datetime(2020,12,31,15,15,24153569),)
夸尔斯:没有
目前正在热播2020-12-31 15:15:24.153569
信息:tensorflow:转换呼叫:
args:(,)
夸尔斯:没有

我假设它调用两次的原因是为了运行set\u save\u spec,但仍然不确定…

也提到了这一点,但没有解释
现在,调用fit并查看函数是否被跟踪(两次),然后渴望的效果将不再运行。
您应该使用
tf.keras.Model
而不是
tf.keras.layers.Layer
…@DachuanZhao我们可以使用
tf.keras.Model
tf.keras.layers.Layer
。此外,它们都被跟踪两次。第一次跟踪发生在创建图形时(即,在调用
tf.function(layer)
)。第二个跟踪是对
tf\u func\u layer
@SusmitAgrawal的实际调用。调用
tf。函数(layer)
不打印任何内容。