为什么tf.executing_eagerly()在TensorFlow 2中返回False? [英] Why does tf.executing_eagerly() return False in TensorFlow 2?

查看:1279
本文介绍了为什么tf.executing_eagerly()在TensorFlow 2中返回False?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我解释一下我的设置.我正在使用TensorFlow 2.1,TF随附的Keras版本和TensorFlow Probability 0.9.

Let me explain my set up. I am using TensorFlow 2.1, the Keras version shipped with TF, and TensorFlow Probability 0.9.

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

I have a function get_model that creates (with the functional API) and returns a model using Keras and custom layers. In the __init__ method of these custom layers A, I call a method A.m, which executes the statement print(tf.executing_eagerly()), but it returns False. Why?

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

To be more precise, this is roughly my setup

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.

Eager execution is enabled by default and this API returns True in most of cases. However, this API might return False in the following use cases.

  • 除非已在tf.init_scopetf.config.experimental_run_functions_eagerly(True)下调用,否则在tf.function内部执行.
  • tf.dataset的转换函数中执行.
  • tf.compat.v1.disable_eager_execution()被调用.
  • Executing inside tf.function, unless under tf.init_scope or tf.config.experimental_run_functions_eagerly(True) is previously called.
  • Executing inside a transformation function for tf.dataset.
  • tf.compat.v1.disable_eager_execution() is called.

但是这些情况不是我的情况,因此tf.executing_eagerly()应该返回True,但不是.为什么?

But these cases are not my case, so tf.executing_eagerly() should return True in my case, but no. Why?

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

Here's a simple complete example (in TF 2.1) that illustrates the problem.

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.

请参见相关的Github问题.

推荐答案

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

As far as I know, when an input to a custom layer is symbolic input, then the layer is executed in graph (non-eager) mode. However, if your input to the custom layer is an eager tensor (as in the following example #1, then the custom layer is executed in the eager mode. So your model's output tf.executing_eagerly() = False is expected.

示例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.

Here is another example with Keras functional API where custom layer was used (similar to you). This model is executed in graph mode and prints tf.executing_eagerly() = False as in your case.

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) 

这篇关于为什么tf.executing_eagerly()在TensorFlow 2中返回False?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆