Why Do I Have To Call Model.predict(x) Instead Of Model(x)?
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)?"