Tensorflow 2 收到“警告:tensorflow:x 对 <function> 的最后 x 次调用触发了 tf.function 重新跟踪”。

Sim*_*ace 6 python machine-learning deep-learning keras tensorflow

我正在开发一个项目,使用Keras训练了一系列二元分类器,并使用Tensorflow作为后端引擎。我的输入数据是一系列图像,其中每个二元分类器必须对图像进行预测,稍后我将预测保存在 CSV 文件中。

我遇到的问题是,当我从第一个系列的二元分类器获得预测时,没有任何警告,但是当第五个或第六个二元分类器调用输入数据的预测方法时,收到以下警告:

警告:tensorflow:最近 5 次调用 <function Model.make_predict_function..predict_function at 0x2b280ff5c158> 触发了 tf.function 回溯。跟踪成本很高,并且跟踪次数过多可能是由于 (1) 在循环中重复创建 @tf.function,(2) 传递不同形状的张量,(3) 传递 Python 对象而不是张量。对于 (1),请在循环外部定义 @tf.function。对于(2),@tf.function具有experimental_relax_shapes=True选项,可以放宽参数形状,从而避免不必要的回溯。对于(3),请参阅 https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_argshttps://www.tensorflow.org/api_docs/python/tf/function了解更多详细信息。

为了回答括号中的每一点,我的答案如下:

  1. 预测方法在 for 循环调用。
  2. 我不传递张量,而是传递灰度图像的NumPy 数组列表,所有这些数组的宽度和高度大小都相同。唯一可以更改的是批量大小,因为列表只能包含 1 个图像或多个图像。
  3. 正如我在第 2 点中所写,我传递了一个 NumPy 数组列表。

我调试了我的程序,发现调用预测方法时总是会出现此警告。总结我编写的代码如下:

import cv2 as cv
import tensorflow as tf
from tensorflow.keras.models import load_model
# Load the models
binary_classifiers = [load_model(path) for path in path2models]
# Get the images
images = [#Load the images with OpenCV]
# Apply the resizing and reshapes on the images.
my_list = list()
for image in images:
    image_reworked = # Apply the resizing and reshaping on images
    my_list.append(image_reworked)

# Get the prediction from each model
# This is where I get the warning
predictions = [model.predict(x=my_list,verbose=0) for model in binary_classifiers]
Run Code Online (Sandbox Code Playgroud)

我尝试过的

我将一个函数定义为 tf.function 并将预测代码放入 tf.function 中,如下所示

@tf.function
def testing(models, faces):
    return [model.predict(x=faces,verbose=0) for model in models]
Run Code Online (Sandbox Code Playgroud)

但我最终收到以下错误:

运行时错误:检测到Model.predicttf.function. Model.predict 是管理自己的 .predict 的高级端点tf.function。请将呼叫移至Model.predict所有封闭的外部tf.function。请注意,您可以Model 直接在tf.functionlike:内调用张量model(x)

所以调用该方法predict基本上已经是一个tf.function了。因此,当我从该方法收到警告时,定义 tf.function 是没有用的。

我还检查了另外两个问题:

  1. Tensorflow 2:获取“警告:tensorflow:最近 9 次触发 tf.function 重新跟踪的调用中有 9 次。跟踪成本高昂”
  2. 加载多个保存的tensorflow/keras模型进行预测

但这两个问题都没有回答我关于如何避免此警告的问题。另外,我还检查了警告消息中的链接,但无法解决我的问题。

我想要的是

我只是想避免这个警告。虽然我仍在从模型中获得预测,但我注意到 python 程序在对图像列表进行预测时花费了太多时间。

我正在使用什么

  • Python 3.6.13
  • 张量流2.3.0

解决方案

经过一番尝试抑制该predict方法的警告后,我检查了 Tensorflow 的文档,并且在有关如何使用 Tensorflow 的第一个教程之一中解释说,默认情况下,Tensorflow 以 eager 模式执行,这对于测试很有用并调试网络模型。由于我已经多次测试了我的模型,因此只需要通过编写以下 Python 行代码来禁用 eager 模式:

tf.compat.v1.disable_eager_execution()

现在警告不再出现。

小智 4

为了社区的利益在这里提供解决方案

经过一番尝试抑制该predict方法的警告后,我检查了 Tensorflow 的文档,并且在有关如何使用 Tensorflow 的第一个教程之一中解释说,默认情况下,Tensorflow 以 eager 模式执行,这对于测试很有用并调试网络模型。由于我已经多次测试了我的模型,因此只需要通过编写以下 Python 行代码来禁用 eager 模式:

tf.compat.v1.disable_eager_execution()
Run Code Online (Sandbox Code Playgroud)

现在警告不再出现。(摘自西蒙娜)

tf.compat.v1.disable_eager_execution()只能在创建任何图、操作或张量之前调用。它可以在程序开始时用于从TensorFlow 1.x到 的迁移项目2.x

更多细节可以参考Eager execution