Why do I have to call model.predict(x) instead of model(x)?

会有一股神秘感。 提交于 2021-01-28 20:50:31

问题


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(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, input_shape=input_shape_LSTM, 
    stateful=True, 
    return_sequences=True, 
    recurrent_initializer='glorot_uniform',
    recurrent_activation='sigmoid'))

model.add(Dense(units=vocab_size))

return model

I then have the vector x_ and y_ given by:

x_, y_ = get_batches(X, y, batch_size)
x_shape: (32, 200000)
y_ shape: (32, 200000)

Now, I do not understand why if I call:

model.predict(x_)

I get the predicted array as expected.

Instead, if I call:

model(x_)

the following error appears:

ValueError: Layer model_1 was called with an input that isn't a symbolic tensor. Received type: <class 'numpy.ndarray'>. Full input: [array([[    0,     0,     0, ..., 21839, 21841,  9579],
   [    0,     0,     0, ...,     1,     1, 23012],
   [    0,     0,     0, ...,   246,  9832,  9832],
   ...,
   [    0,     0,     0, ..., 24827, 24867, 24868],
   [    0,     0,     0, ..., 22448, 22426, 22426],
   [    0,     0,     0, ...,     1,     1,     1]])]. All inputs to the layer should be tensors.

Can someone explain me why? I red the suggested questions for this topic and I didn't find the answear...


回答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?




回答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

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




回答3:


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

Try this

def model_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




回答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??



来源:https://stackoverflow.com/questions/63583021/why-do-i-have-to-call-model-predictx-instead-of-modelx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!