【问题标题】:Why does tf.executing_eagerly() return False in TensorFlow 2?为什么 tf.executing_eagerly() 在 TensorFlow 2 中返回 False?
【发布时间】:2020-08-04 21:42:05
【问题描述】:

让我解释一下我的设置。我正在使用 TensorFlow 2.1、TF 附带的 Keras 版本和 TensorFlow Probability 0.9。

我有一个函数get_model,它使用 Keras 和自定义层创建(使用函数式 API)并返回一个模型。在这些自定义层A__init__方法中,我调用了一个方法A.m,它执行了语句print(tf.executing_eagerly()),但是它返回了False。为什么?

更准确地说,这是我的大致设置

def get_model():
    inp = Input(...)
    x = A(...)(inp) 
    x = A(...)(x)
    ...
    model = Model(inp, out)
    model.compile(...)
    return model

class A(tfp.layers.DenseFlipout): # TensorFlow Probability
    def __init__(...):
        self.m()

    def m(self): 
        print(tf.executing_eagerly()) # Prints False

tf.executing_eagerly 的文档说

默认情况下启用急切执行,并且此 API 在大多数情况下返回 True。但是,此 API 在以下用例中可能会返回 False。

  • tf.function 内部执行,除非之前在 tf.init_scopetf.config.experimental_run_functions_eagerly(True) 下调用。
  • tf.dataset 的转换函数内部执行。
  • tf.compat.v1.disable_eager_execution() 被调用。

但这些情况不是我的情况,所以 tf.executing_eagerly() 在我的情况下应该返回 True,但不是。为什么?

这是一个说明问题的简单完整示例(在 TF 2.1 中)。

import tensorflow as tf


class MyLayer(tf.keras.layers.Layer):
    def call(self, inputs):
        tf.print("tf.executing_eagerly() =", tf.executing_eagerly())
        return inputs


def get_model():
    inp = tf.keras.layers.Input(shape=(1,))
    out = MyLayer(8)(inp)
    model = tf.keras.Model(inputs=inp, outputs=out)
    model.summary()
    return model


def train():
    model = get_model()
    model.compile(optimizer="adam", loss="mae")
    x_train = [2, 3, 4, 1, 2, 6]
    y_train = [1, 0, 1, 0, 1, 1]
    model.fit(x_train, y_train)


if __name__ == '__main__':
    train()

这个例子打印tf.executing_eagerly() = False

the related Github issue

【问题讨论】:

    标签: python tensorflow keras tensorflow2.0 tensorflow-probability


    【解决方案1】:

    据我所知,当自定义图层的输入是符号输入时,该图层将以图形(非急切)模式执行。但是,如果您对自定义层的输入是一个急切张量(如以下示例 #1 中所示,则自定义层将以急切模式执行。因此您的模型的输出 tf.executing_eagerly() = False 是预期的。

    示例 #1

    from tensorflow.keras import layers
    
    
    class Linear(layers.Layer):
    
      def __init__(self, units=32, input_dim=32):
        super(Linear, self).__init__()
        w_init = tf.random_normal_initializer()
        self.w = tf.Variable(initial_value=w_init(shape=(input_dim, units),
                                                  dtype='float32'),
                             trainable=True)
        b_init = tf.zeros_initializer()
        self.b = tf.Variable(initial_value=b_init(shape=(units,),
                                                  dtype='float32'),
                             trainable=True)
    
      def call(self, inputs):
        print("tf.executing_eagerly() =", tf.executing_eagerly())
        return tf.matmul(inputs, self.w) + self.b
    
    x = tf.ones((1, 2)) # returns tf.executing_eagerly() = True
    #x = tf.keras.layers.Input(shape=(2,)) #tf.executing_eagerly() = False
    linear_layer = Linear(4, 2)
    y = linear_layer(x)
    print(y) 
    #output in graph mode: Tensor("linear_9/Identity:0", shape=(None, 4), dtype=float32)
    #output in Eager mode: tf.Tensor([[-0.03011466  0.02563028  0.01234017  0.02272708]], shape=(1, 4), dtype=float32)
    

    这是另一个使用自定义层的 Keras 功能 API 示例(与您类似)。该模型以图形模式执行并打印tf.executing_eagerly() = False,就像您的情况一样。

    from tensorflow import keras
    from tensorflow.keras import layers
    class CustomDense(layers.Layer):
      def __init__(self, units=32):
        super(CustomDense, self).__init__()
        self.units = units
    
      def build(self, input_shape):
        self.w = self.add_weight(shape=(input_shape[-1], self.units),
                                 initializer='random_normal',
                                 trainable=True)
        self.b = self.add_weight(shape=(self.units,),
                                 initializer='random_normal',
                                 trainable=True)
    
      def call(self, inputs):
        print("tf.executing_eagerly() =", tf.executing_eagerly())
        return tf.matmul(inputs, self.w) + self.b
    
    
    inputs = keras.Input((4,))
    outputs = CustomDense(10)(inputs)
    
    model = keras.Model(inputs, outputs) 
    

    【讨论】:

      猜你喜欢
      • 2018-01-31
      • 1970-01-01
      • 2011-08-21
      • 2023-01-16
      • 2013-09-18
      • 1970-01-01
      • 1970-01-01
      • 2019-01-09
      • 2019-12-07
      相关资源
      最近更新 更多