ModuleNotFoundError: No module named 'keras.engine.sequential'

Viewed 3415

I am trying to integrate image classification in web-based application using Flask. The model was trained in google colab where everything worked fine. The problem arises when I load the saved model using pickle, which went smoothly in colab.

Here is my index.py file:

from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import os
import numpy as np
from PIL import Image
import pickle
import cv2


app = Flask(__name__)
app.config['IMAGE_UPLOADS'] = 'ML_project-master/finalfl/static/'

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        image = request.files['image']
        filename = secure_filename(image.filename)
        image.save(os.path.join(app.config["IMAGE_UPLOADS"], filename))
        status = True

        img = 'static/' + filename
        idata = cv2.imread(img)
        idata = Image.fromarray(idata, 'RGB')
        idata = idata.resize((64, 64))
        idata = np.array(idata)
        idata = np.expand_dims(idata, axis=0)

        classify = 'ML_project-master/finalfl/CNNmodel3.sav'
        classifier = pickle.load(open(classify, 'rb'))
        result = classifier.predict(idata)
        print('result')

        return render_template('index.html', status = status, filename = filename)
    else:
        status = False
        return render_template('index.html')


if __name__ == '__main__':
    app.run()

And here is the stack trace:

Traceback (most recent call last):
  File "C:\Users\SUBHANEE\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\SUBHANEE\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\SUBHANEE\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\SUBHANEE\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\SUBHANEE\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\SUBHANEE\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "index.py", line 29, in index
    classifier = pickle.load(open(classify, 'rb'))
ModuleNotFoundError: No module named 'keras.engine.sequential'

What seems to be the problem? I tried importing sequential without any result. Any help would be highly appreciated.

1 Answers

This is probably because you don't have package tensorflow or keras (incase of TF version less than 2.0) installed.

Note: From Tensorflow V2.0 onwards, keras is integrated in tensorflow as 'tf.keras', so no need to call keras separately

You can install current stable release as below

$ pip install tensorflow

According to Keras documentation sequential model class

from tensorflow.keras import Sequential

Keras doesn't support Pickle to serialize its objects (Models). Basically, if an object has __getstate__ and __setstate__ methods, pickle will use them] to serialize the object. The problem is that Keras Model doesn't implement these.

Zach Moshe, proposed hotfix for solving this issue. For more details please refer here.

# Hotfix function
def make_keras_picklable():
    def __getstate__(self):
        model_str = ""
        with tempfile.NamedTemporaryFile(suffix='.hdf5', delete=True) as fd:
            save_model(self, fd.name, overwrite=True)
            model_str = fd.read()
        d = {'model_str': model_str}
        return d

    def __setstate__(self, state):
        with tempfile.NamedTemporaryFile(suffix='.hdf5', delete=True) as fd:
            fd.write(state['model_str'])
            fd.flush()
            model = load_model(fd.name)
        self.__dict__ = model.__dict__


    cls = Model
    cls.__getstate__ = __getstate__
    cls.__setstate__ = __setstate__

# Run the function
make_keras_picklable()

And a usage example:

import keras
import pickle

make_keras_picklable()

m = keras.models.Sequential()
m.add(keras.layers.Dense(10, input_shape=(10,)))
m.compile(optimizer='sgd', loss='mse')

pickle.dumps(m)
Related