关于Keras模型的困惑:__call__ vs.调用与预测方法

kqlmhetl  于 2023-08-06  发布在  其他
关注(0)|答案(5)|浏览(110)

我意识到我不太理解调用Keras模型的__call__callpredict方法之间的区别。
例如,我们有一个经过训练的Keras模型。调用代码后:

# After training.
y_pred_1 = model(X_new)
y_pred_2 = model.call(X_new)
y_pred_3 = model.predict(X_new)

字符串
我希望y_pred_1y_pred_2y_pred_3都是相同的。但事实证明,它们并不相同。
你能给我解释一下区别吗?

hsgswve4

hsgswve41#

再加上@Dmitry Kabanov,它们是相似的,但它们并不完全相同。如果您关心性能,则需要查看它们之间的关键差异。
| model(x)| model(x) |
| --| ------------ |
| 发生在内存中,无法扩展| happens in-memory and doesn't scale |
| 可微的| differentiable |
| 在需要检索渐变时使用此选项| use this when you need to retrieve the gradients |
| 输出是Tensor| Output is a Tensor |
| 将此用于小型数据集| use this for small dataset |
| 对于小数据来说相对更快| relatively faster for small data |
请在Keras常见问题解答中查看更详细的说明

b4lqfgs4

b4lqfgs42#

只是为了补充答案,因为我也在寻找这个。当你需要为推理阶段指定模型的训练标志时,例如,当你有一个批处理规范化层时,predictpredict_on_batch在执行时已经这样做了。
因此,model(X_new, training=False)model.predict_on_batch(X_new)是等价的。
predictpredict_on_batch之间的区别在于,后者在单个批次上运行,而前者在拆分成批次的数据集上运行,并将结果合并以产生最终的numpy预测数组。
除了@Dmitry Kabanov提到的差异之外,这些函数生成不同类型的输出,__call__生成Tensor,predictpredict_on_batch生成numpy.ndarray,根据文档,__call__predict函数更快,适用于小规模输入,即适合一个批次。

brc7rcf0

brc7rcf03#

更新2021-12-18.请看下面@TFer2的回答,以获得更好更全面的答案。

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

我的错,我的代码出错了。
事实证明,这三种方法之间没有本质区别。
唯一的区别是call只接受Tensor,而其他两个方法也接受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))

字符串

d8tt03nd

d8tt03nd4#

我认为当你使用其中一个特定的层时会有区别:DropOut()BatchNormalization()中的至少一个。实际上,这些层无论在训练模式还是测试/评估模式中使用,其作用都不同。
call()predict()之间的区别在于call()在训练模式下给出预测,而predict()在测试模式下给出预测。这两者之间的区别在于,每次使用call()predict()时,预测结果都不会相同。训练和测试模式类似于Pytorch库的训练和测试模式。

l7mqbcuq

l7mqbcuq5#

我对keras_cv RetinaNet模型也有同样的疑问。从我所看到的,有更多的差异之间调用和预测这个模型。

call()返回两个Tensor:

{'box': <tf.Tensor: shape=(1, 9441, 4), dtype=float32, numpy= array([ ... ], dtype=float32)>, 'classification': <tf.Tensor: shape=(1, 9441, 2), dtype=float32, numpy= array([...], dtype=float32)>}

字符串
predict()执行非max-suppression和其他一些pos-processing,并返回4个numpy数组:

{'boxes': array([[[ 37.201706,  81.78369 ,  62.617325, 136.692   ], ... ]], dtype=float32),
 'confidence': array([ [ 0.9999949   ...  ]], dtype=float32),
 'classes': array([[ 0, ... ]]),
 'num_detections': array([1], dtype=int32)
 }

相关问题