【问题标题】:tf.function input parameterstf.function 输入参数
【发布时间】:2020-02-06 17:29:27
【问题描述】:

我在 tensorflow 2 中编写了一个函数,并使用 tf.keras 编写了一个模型。函数定义如下:

@tf.function
def mask_output(input_tensor,mask):
    if tf.math.count_nonzero(mask) > 0:
        output_tensor = tf.multiply(input_tensor, mask)
    else:
        output_tensor = input_tensor
    return output_tensor

我给它的两个参数是模型中的张量。但是,当我定义模型并在模型定义中调用该函数时,它会说:

{_SymbolicException}Eager Execution 函数的输入不能是 Keras 符号张量,但可以找到

[<tf.Tensor 'a_dense2/Identity:0' shape=(None, 12, 5) dtype=float32>, <tf.Tensor 'a_mask_input:0' shape=(None, 12, 5) dtype=float32>]

如何解决?为什么我不能用两个 keras 张量输入来调用那个函数?

【问题讨论】:

  • 嗨@Rui Guo,你能提供一个最小的可重现代码吗?

标签: python tensorflow keras


【解决方案1】:

如果在 Eager 模式下运行,TensorFlow 操作将检查输入是否为 tensorflow.python.framework.ops.EagerTensor 类型,并且 keras 操作被实现为 DAG。因此,如果 Eager 模式的输入是 tensorflow.python.framework.ops.Tensor,则会引发错误。

您可以通过使用tf.config.experimental_run_functions_eagerly(True) 明确告诉 tensorflow 在 keras 的渴望模式下运行来将输入类型更改为 EagerTensor。添加此语句应该可以解决您的问题。

例如,这个程序抛出你所面临的错误 -

重现错误的代码-

import numpy as np
import tensorflow as tf
print(tf.__version__)
from tensorflow.keras import layers, losses, models

def get_loss_fcn(w):
    def loss_fcn(y_true, y_pred):
        loss = w * losses.mse(y_true, y_pred)
        return loss
    return loss_fcn

data_x = np.random.rand(5, 4, 1)
data_w = np.random.rand(5, 4)
data_y = np.random.rand(5, 4, 1)

x = layers.Input([4, 1])
w = layers.Input([4])
y = layers.Activation('tanh')(x)
model = models.Model(inputs=[x, w], outputs=y)
loss = get_loss_fcn(model.input[1])

model.compile(loss=loss)
model.fit((data_x, data_w), data_y)

输出 -

2.2.0
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/execute.py in quick_execute(op_name, num_outputs, inputs, attrs, ctx, name)
     59     tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle, device_name, op_name,
---> 60                                         inputs, attrs, num_outputs)
     61   except core._NotOkStatusException as e:

TypeError: An op outside of the function building code is being passed
a "Graph" tensor. It is possible to have Graph tensors
leak out of the function building context by including a
tf.init_scope in your function building code.
For example, the following function will fail:
  @tf.function
  def has_init_scope():
    my_constant = tf.constant(1.)
    with tf.init_scope():
      added = my_constant * 2
The graph tensor has name: input_8:0

During handling of the above exception, another exception occurred:

_SymbolicException                        Traceback (most recent call last)
8 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/execute.py in quick_execute(op_name, num_outputs, inputs, attrs, ctx, name)
     72       raise core._SymbolicException(
     73           "Inputs to eager execution function cannot be Keras symbolic "
---> 74           "tensors, but found {}".format(keras_symbolic_tensors))
     75     raise e
     76   # pylint: enable=protected-access

_SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor 'input_8:0' shape=(None, 4) dtype=float32>]

解决方案 - 在程序顶部添加这个tf.config.experimental_run_functions_eagerly(True) 可以成功运行程序。在程序顶部添加tf.compat.v1.disable_eager_execution() 以禁用急切执行也会成功运行程序。

固定代码 -

import numpy as np
import tensorflow as tf
print(tf.__version__)
from tensorflow.keras import layers, losses, models

tf.config.experimental_run_functions_eagerly(True)

def get_loss_fcn(w):
    def loss_fcn(y_true, y_pred):
        loss = w * losses.mse(y_true, y_pred)
        return loss
    return loss_fcn

data_x = np.random.rand(5, 4, 1)
data_w = np.random.rand(5, 4)
data_y = np.random.rand(5, 4, 1)

x = layers.Input([4, 1])
w = layers.Input([4])
y = layers.Activation('tanh')(x)
model = models.Model(inputs=[x, w], outputs=y)
loss = get_loss_fcn(model.input[1])

model.compile(loss=loss)
model.fit((data_x, data_w), data_y)

print('Done.')

输出 -

2.2.0
1/1 [==============================] - 0s 1ms/step - loss: 0.0000e+00
Done.

希望这能回答您的问题。快乐学习。

【讨论】:

  • 感谢您的回答。我对这里的渴望模式感到困惑。默认情况下是否处于渴望模式?使用 tf.config.experimental_run_functions_eagerly(True),程序将以渴望模式运行,如果没有它不会?您的意思是错误来自提供不是 tensorflow.python.framework.ops.Tensor 或 tensorflow.python.framework.ops.EagerTensor 的函数输入吗? tensorflow.python.framework.ops.Tensor 和 tensorflow.python.framework.ops.EagerTensor 有什么区别?
  • 我修改了答案-“所以如果急切模式的输入是tensorflow.python.framework.ops.Tensor,那么这会引发错误”。错误是因为tensorflow.python.framework.ops.Tensor 而我们需要使用tf.config.experimental_run_functions_eagerly(True) 将其更改为tensorflow.python.framework.ops.EagerTensor。调用tf.config.experimental_run_functions_eagerly(True) 将使tf.function 的所有调用急切地运行,而不是作为跟踪图函数运行。
  • 据说当我使用tf.compat.v1.disable_eager_execution() 而不是tf.config.experimental_run_functions_eagerly(True) 时,我的程序也运行良好。在这种情况下,张量会以另一种方式转换。
猜你喜欢
  • 2020-08-07
  • 1970-01-01
  • 2016-05-28
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 2010-10-21
相关资源
最近更新 更多