Search code examples
kerasnlplstmtensorflow2.0tensorflow-lite

Error in the conversion of Bidirectional LSTM Text Classification Model to TFLite Model


My model is trained on the "imdb reviews dataset" and works fine when predicting the sentiment of movie reviews. However, when I convert my model for Tensorflow Lite, it outputs: None is only supported in the 1st dimension. Tensor 'embedding 1 input' has invalid shape '[None, None]'. When training my model, I did not specify a specific shape, therefore I am unsure of what shape to pass for my model to work with my android app. (As long as I convert the embedding_input shape to something else, the TFLite model will be created, but does not work with my android app)

Code for model:

from tensorflow import keras
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.layers import Dense , Input , LSTM , Embedding, Dropout , Activation, GRU, Flatten
from keras.layers import Bidirectional, GlobalMaxPool1D
from keras.models import Model, Sequential
from keras.layers import Convolution1D
from keras import initializers, regularizers, constraints, optimizers, layers

max_features = 6000
tokenizer = Tokenizer(num_words=max_features)
tokenizer.fit_on_texts(df['Processed_Reviews'])
list_tokenized_train = tokenizer.texts_to_sequences(df['Processed_Reviews'])

maxlen = 130
X_t = pad_sequences(list_tokenized_train, maxlen=maxlen)
y = df['sentiment']

embed_size = 128
model = Sequential()
model.add(Embedding(max_features, embed_size))
model.add(Bidirectional(LSTM(32, return_sequences = True)))
model.add(GlobalMaxPool1D())
model.add(Dense(20, activation="relu"))
model.add(Dropout(0.05))
model.add(Dense(1, activation="sigmoid"))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

batch_size = 100
epochs = 3
model.fit(X_t,y, batch_size=batch_size, epochs=epochs, validation_split=0.2)

#Conversion Code
import tensorflow as tf

inference_model = tf.keras.models.load_model('imdb-reviews-final.h5')
#inference_model.input.set_shape((6000, 128)) --> Reshaping allows model conversion to happen, but does not actually work with the app
converter = tf.lite.TFLiteConverter.from_keras_model(inference_model)
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)


Solution

  • Current stable versions of Tensorflow don't support dynamic input shapes.

    However, using the nightly build could solve your problem. I found this issue in Tensorflow github where this method is discussed. However, I'm not sure if this works on Android.