Skip to content Skip to sidebar Skip to footer

Why Do I Have To Call Model.predict(x) Instead Of Model(x)?

I have the following keras model: def model_1(vocab_size, output_dim, batch_input_dims, rnn_units, input_shape_LSTM, name='model_1'): model = Sequential(name=name) model.add(Embe

Solution 1:

From docs

This [predict] method is designed for performance in large scale inputs. For small amount of inputs that fit in one batch, directly using call is recommended for faster execution, e.g., model(x), or model(x, training=False)

If you are unfamiliar with python's magic functions, using my_object(x) is equivalent to writing my_object.__call__(x).

So, how does this quote apply to your case?

The model by extension is also a tf.keras.layer.Layer, that's why you can stack multiple models into higher level models. Because it is also a layer, when you call it like model(x), it is acting like a layer and just returns transformed inputs, nothing more. But when you call it like model.predict(x), it acts more like a model and gives you transformations in the way that is more useful when predicting with model.

Why does the exception occur?

Because the Embedding layer is expecting a tf.Tensor and calling the model with model(x) does not perform that conversion. You can do it manually with tf.constant([array]) and then it will work. Or, you could add the tf.keras.layers.Input layer at the start and it will also solve the problem.

Does this answer your question?

Solution 2:

I can't reproduce your code. You don't give the parameter values/input values and it's not clear what tensorflow functions you are trying to use. This is what I tried

import tensorflow as tf

defmodel_1(vocab_size, output_dim, batch_input_dims, rnn_units, input_shape_LSTM, name='model_1'):

    model = tf.keras.Sequential(name=name)

    model.add(tf.keras.layers.Embedding(input_dim=vocab_size+1, output_dim=output_dim, mask_zero=True, batch_input_shape=batch_input_dims))

    model.add(tf.keras.layers.LSTM(units=rnn_units, input_shape=input_shape_LSTM,
        stateful=True,
        return_sequences=True,
        recurrent_initializer='glorot_uniform',
        recurrent_activation='sigmoid'))

    model.add(tf.keras.layers.Dense(units=vocab_size))

    return model

model = model_1(100, 50, (32,5), 10, (32,50))

x = tf.convert_to_tensor( np.random.rand(32,5) )
y = tf.convert_to_tensor( np.random.rand(32,5))

test = model(x)

test2 = model.predict(x)

And it works as expected, with no errors (Note test and test2 are not going to be equal because you have stateful = True to the LSTM)

Solution 3:

you have taken input_shape argument in your lstm layer, which is an intermediate layer,

Try this

defmodel_1(vocab_size, output_dim, batch_input_dims, rnn_units, name='model_1'):

model = Sequential(name=name)

model.add(Embedding(input_dim=vocab_size+1, output_dim=output_dim, mask_zero=True, batch_input_shape=batch_input_dims))

model.add(LSTM(units=rnn_units, 
    stateful=True, 
    return_sequences=True, 
    recurrent_initializer='glorot_uniform',
    recurrent_activation='sigmoid'))

model.add(Dense(units=vocab_size))

return model

this is working for me, full working code here

Solution 4:

Thank you guys for all your answears! I found the problem and I'll share with you so maybe I't will be usefull also for others (and maybe you can also explain me!)

I've imported tensorflow and the following layers:

import tensorflow as tf
    from keras import Sequential
    from keras.layers import Embedding
    from keras.layers import Dense
    from keras.layers import Dropout
    from keras.layers import LSTM

# create and fit the model

rnn_units = 1024
output_dim = 256
batch_size = 32
vocab_size = unique_columns.shape[1]
batch_input_dims = [batch_size, None]
input_shape_LSTM = (X.shape[1], 1)
# X has shape (200, 200000) and it is a numpy.ndarray

Then, I've built two models. The first one with the imported layers:

def model_1(vocab_size, output_dim, batch_input_dims, rnn_units, input_shape_LSTM, name='LSTM_1'):
    
    model = Sequential(name=name)
    
    model.add(Embedding(input_dim=vocab_size+1, output_dim=output_dim, batch_input_shape=batch_input_dims))
    
    return model

And the second one with tf.keras.layers

def build_model(vocab_size, embedding_dim, rnn_units, batch_size, batch_input_dims, name='LSTM_2'):
    
    model = tf.keras.Sequential(name=name)
   
    model.add(tf.keras.layers.Embedding(vocab_size+1, embedding_dim, batch_input_shape=batch_input_dims))
        
    return model

Then I've built the two models:

      model = build_model(vocab_size, embedding_dim=output_dim, rnn_units=rnn_units,batch_size=batch_size, batch_input_dims=batch_input_dims)
model.summary()

Model: "LSTM_2"
_________________________________________________________________Layer (type)                 Output Shape              Param #   
=================================================================embedding (Embedding)        (32, None, 256)           6522112   
=================================================================
Total params: 6,522,112
Trainable params: 6,522,112
Non-trainable params: 0

And

model_LSTM = model_1(vocab_size, output_dim, batch_input_dims, rnn_units, input_shape_LSTM)
model_LSTM.summary()
Model: "LSTM_1"
_________________________________________________________________Layer (type)                 Output Shape              Param #   
=================================================================embedding_1 (Embedding)      (32, None, 256)           6522112   
=================================================================
Total params: 6,522,112
Trainable params: 6,522,112
Non-trainable params: 0


model_LSTM = model_1(vocab_size, output_dim, batch_input_dims, rnn_units, input_shape_LSTM)

Finally, if I try to feed an input like X[:batch_size,:]

model(X[:32,:])
tf.Tensor: id=28, shape=(32, 200, 256), dtype=float32, numpy=
array([[[-0.02251144, -0.00920795, -0.01335046, ..., -0.00379463,
          0.00821525, -0.0356279 ],
        [-0.02251144, -0.00920795, -0.01335046, ..., -0.00379463,
          0.00821525, -0.0356279 ],
        [-0.02251144, -0.00920795, -0.01335046, ..., -0.00379463,
          0.00821525, -0.0356279 ],
        ...,
        [-0.02251144, -0.00920795, -0.01335046, ..., -0.00379463,
          0.00821525, -0.0356279 ],
        [-0.02251144, -0.00920795, -0.01335046, ..., -0.00379463,
          0.00821525, -0.0356279 ],
        [-0.02251144, -0.00920795, -0.01335046, ..., -0.00379463,
          0.00821525, -0.0356279 ]],...]]]

On the other hand, If I call model_LSTM(X[:batch_size,:]I get the original error:

ValueError: Layer LSTM_1 was called with an input that isn't a symbolic tensor. Received type: <class 'numpy.ndarray'>. Full input: [array([[0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,3.92742126e-05, 3.92742126e-05, 3.92742126e-05],
       [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,
        3.92742126e-05, 3.92742126e-05, 3.92742126e-05],
       [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,
        5.30201869e-03, 2.12080748e-03, 3.92742126e-05],
       ...,
       [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,
        3.92742126e-05, 3.92742126e-05, 3.92742126e-05],
       [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,
        5.33383081e-01, 5.33383081e-01, 3.92742126e-05],
       [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,
        1.99395177e-01, 1.99395177e-01, 1.99395177e-01]])]. All inputs to the layer should be tensors.

Can someone explain this behavior??

Post a Comment for "Why Do I Have To Call Model.predict(x) Instead Of Model(x)?"