Confusion about keras Model: __call__ vs. call vs. predict methods

Viewed 7748

I have realized that I do not quite understand the difference between calling either the __call__, call, or predict method of a Keras' model.

For example, we have a trained keras model. After calling the code:

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

I expected that y_pred_1, y_pred_2, and y_pred_3 are all the same. But it turned out that they are not the same.

Could you please explain to me the difference?

4 Answers

Just to complement the answer as I was also searching for this. When you need to specify the training flag of the model for the inference phase, such as, model(X_new, training=False) when you have a batch normalization layer, for example, both predict and predict_on_batch already do that when they are executed.

So, model(X_new, training=False) and model.predict_on_batch(X_new) are equivalent.

The difference between predict and predict_on_batch is that the latter runs over a single batch, and the former runs over a dataset that is splitted into batches and the results merged to produce the final numpy array of predictions.

Beyond the difference mentioned by @Dmitry Kabanov, the functions generate different types of output, __call__ generates a Tensor, and predict and predict_on_batch generate numpy.ndarray, and according to the documentation, __call__ is faster than the predict function for small scale inputs, i.e., which fit in one batch.

Adding to @Dmitry Kabanov, they are similar yet they aren't exactly the same thing. If you care about performance, need to look in to critical differences between them.

model.predict model(x)
loops over the data in batches which means means that predict() calls can scale to very large arrays. happens in-memory and doesn't scale
not differentiable differentiable
use this if you just need the output value use this when you need to retrieve the gradients
Output is NumPy value Output is a Tensor
use this if you have batches of data to be predicted use this for small dataset
relatively slower for small data relatively faster for small data

Please check more detailed explanation in Keras FAQs

UPDATE 2021-12-18. Please see the answer by @TFer2 below for a much better and fuller answer.


My own old answer that spots only difference in data types (tf.Tensor vs np.ndarray)

My bad, it was a mistake in my code.

It turned out that there is no essential difference between these three methods.

The only difference is that call accepts only tensors, while the other two methods also accept NumPy arrays.

Here is a toy code showing that three methods are the same:

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))

I think there is a difference when you use one of those specific layers: DropOut() and BatchNormalization(). Indeed, those layers act differently whether they are used in train mode or test/evaluation mode.

The difference between call() and predict() is that call() is giving a prediction with training mode and predict() with testing mode. The difference between those two is that the prediction won't be the same every time you are using call() contrary to predict(). Train and test mode are similar to the train and test modes of the Pytorch library.

Related