关于 keras 模型的困惑:__call__ vs. call vs. predict 方法

Dmi*_*nov 14 keras tensorflow

我已经意识到,我不太明白调用要么之间的差别__call__call或者predict一个Keras'模式的方法。

例如,我们有一个经过训练的 keras 模型。调用代码后:

# After training.
y_pred_1 = model(X_new)
y_pred_2 = model.call(X_new)
y_pred_3 = model.predict(X_new)
Run Code Online (Sandbox Code Playgroud)

我预计y_pred_1, y_pred_2, 和y_pred_3都是一样的。但事实证明,它们并不相同。

你能向我解释一下区别吗?

小智 29

添加@Dmitry Kabanov,它们很相似,但并不完全相同。如果您关心性能,则需要研究它们之间的关键差异。

模型.预测 型号(x)
批量循环数据,这意味着 Predict() 调用可以扩展到非常大的数组。 发生在内存中并且无法扩展
不可微分 可微的
如果您只需要输出值,请使用它 当你需要检索梯度时使用这个
输出是 NumPy 值 输出是一个张量
如果您有批量数据需要预测,请使用此选项 将其用于小数据集
小数据相对较慢 小数据相对较快

请查看Keras FAQs中更详细的解释


Dmi*_*nov 7

更新 2021 年 12 月 18 日。请参阅下面@TFer2 的答案,以获得更好、更全面的答案。


我自己的旧答案仅发现数据类型的差异(tf.Tensor vs np.ndarray)

我的错,这是我的代码中的一个错误。

事实证明,这三种方法没有本质区别。

唯一的区别是call仅接受张量,而其他两种方法也接受 NumPy 数组。

这是一个玩具代码,显示三种方法是相同的:

import numpy as np
import tensorflow as tf


model = tf.keras.Sequential(
    [
        tf.keras.layers.InputLayer(input_shape=(2, )),
        tf.keras.layers.Dense(2),
    ]
)
model.compile(loss='mse')

W = model.trainable_variables[0]
W.assign(np.array([[1.0, 0.0], [0.0, 1.0]]).T)

input = np.array([[1.0, 2.0], [3.0, 4.0], ], dtype=np.float32)

print("__call__:")
print(model(input))

print("Call:")
print(model.call(tf.convert_to_tensor(input)))

print("Predict:")
print(model.predict(input))
Run Code Online (Sandbox Code Playgroud)


K. *_*dan 6

只是为了补充答案,因为我也在寻找这个。当你需要指定模型的推断相如的训练标志,model(X_new, training=False)当你有一个批标准化层,例如,无论是predictpredict_on_batch已经做执行时他们。

所以,model(X_new, training=False)model.predict_on_batch(X_new)是等价的。

predict和之间的区别在于,predict_on_batch后者在单个批次上运行,而前者在一个数据集上运行,该数据集被拆分为多个批次,并将结果合并以生成最终的 numpy 预测数组。

超出由@Dmitry卡巴诺夫提到的差异,则这些功能产生不同类型的输出, __call__产生一个张量,以及predictpredict_on_batch产生numpy.ndarray,并 根据该文档__call__比快predict于小规模的输入,即,其适合于在一个批处理功能。