简体   繁体   中英

ImageAI/Keras can't read ResNet model on Raspberry Pi but works on Windows

About

I'm trying to load and use an ImageAI ResNet model and then access it via a Flask server. More details about the project are on my Github repository .

My code runs well on Windows but not on Linux. I cloned all of my files directly to a Raspberry Pi and then installed all the pip dependencies. However, the program breaks when initializing the Predictor class.

Steps taken

  • Installed the same pip version of every package as my Windows PC
  • Used virtualenv
  • Reinstalled Tensorflow from different wheels (not just pip)
  • Searched ImageAI's issues . There were several similar issues but no solutions that worked
  • Created an issue in the ImageAI repo; no response yet
  • Used a different Raspberry Pi (both Pi 2B and 3B)
  • Searched StackOverflow for Raspberry Pi Tensorflow issues. There are surprisingly many! However, installing different versions of Tensorflow didn't work. I couldn't find any other suggested solutions.
  • Used SHA-256 checksums to verify that all of my files were the exact same as my Windows PC

Once again, an identical version of this project works on my Windows PC . It's probably a Linux/Raspberry Pi package issue, right?

Code

import base64
from binascii import a2b_base64
from difflib import ndiff
import json
from flask import Flask, request
from imageai.Prediction.Custom import CustomImagePrediction
from io import BytesIO
import logging
import numpy as np
import os
from PIL import Image
import tempfile


# Contains ImageAI Predictor class
class Predictor:
    def __init__(self, model):
        execution_path = os.getcwd()
        print(execution_path)
        self.prediction = CustomImagePrediction()
        self.prediction.setModelTypeAsResNet()
        self.prediction.setModelPath(os.path.join(
            execution_path, "training_data/models/" + model))
        self.prediction.setJsonPath(os.path.join(
            execution_path, "training_data/json/model_class.json"))
        self.prediction.loadModel(num_objects=3)

    def predict(self, image):
        predictions, probabilities = self.prediction.predictImage(
            image, result_count=3)
        result = {}
        for prediction, probability in zip(predictions, probabilities):
            result[prediction] = "{0:.8f}".format(probability.item())
        return result


# Intentionally global variable
predictor = Predictor("model_ex-067_acc-0.953125.h5")

log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
app = Flask(__name__)


# API's only route
@app.route("/mask", methods=["POST"])
def post_mask():
    image_uri = request.args.get("image").replace(" ", "+")
    image_encoded = image_uri.split(",")[1]
    binary_data = a2b_base64(image_encoded)
    with tempfile.NamedTemporaryFile(delete=False) as f:
        f.write(binary_data)
        filename = f.name
    prediction = predictor.predict(filename)
    os.remove(filename)
    return app.response_class(
        response=json.dumps(prediction),
        status=200,
        mimetype="application/json"
    )


if __name__ == "__main__":
    app.run("192.168.1.20", 8083)

Traceback

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/imageai/Prediction/Custom/__init__.py", line 487, in loadModel
    model = ResNet50(model_path=self.modelPath, weights="trained", model_input=image_input, num_classes=self.numObjects)
  File "/usr/local/lib/python3.7/dist-packages/imageai/Prediction/ResNet/resnet50.py", line 119, in ResNet50
    model.load_weights(weights_path)
  File "/usr/local/lib/python3.7/dist-packages/tensorflow_core/python/keras/engine/training.py", line 182, in load_weights
    return super(Model, self).load_weights(filepath, by_name)
  File "/usr/local/lib/python3.7/dist-packages/tensorflow_core/python/keras/engine/network.py", line 1373, in load_weights
    saving.load_weights_from_hdf5_group(f, self.layers)
  File "/usr/local/lib/python3.7/dist-packages/tensorflow_core/python/keras/saving/hdf5_format.py", line 645, in load_weights_from_hdf5_group
    original_keras_version = f.attrs['keras_version'].decode('utf8')
AttributeError: 'str' object has no attribute 'decode'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "app.py", line 38, in <module>
    predictor = Predictor("model_ex-067_acc-0.953125.h5")
  File "app.py", line 26, in __init__
    self.prediction.loadModel(num_objects=3)
  File "/usr/local/lib/python3.7/dist-packages/imageai/Prediction/Custom/__init__.py", line 491, in loadModel
    raise ValueError("You have specified an incorrect path to the ResNet model file.")
ValueError: You have specified an incorrect path to the ResNet model file.

python3 -m pip freeze output from Raspberry Pi

absl-py==0.11.0
appdirs==1.4.4
asn1crypto==0.24.0
astor==0.8.1
cached-property==1.5.2
cachetools==4.1.1
certifi==2020.6.20
chardet==3.0.4
click==7.1.2
cryptography==2.6.1
cycler==0.10.0
distlib==0.3.1
entrypoints==0.3
filelock==3.0.12
Flask==0.12.2
gast==0.2.2
google-auth==1.23.0
google-auth-oauthlib==0.4.2
google-pasta==0.2.0
grpcio==1.33.2
h5py==2.10.0
idna==2.6
imageai==2.1.5
importlib-metadata==2.0.0
itsdangerous==1.1.0
Jinja2==2.11.2
Keras==2.4.3
Keras-Applications==1.0.8
Keras-Preprocessing==1.1.2
keyring==17.1.1
keyrings.alt==3.1.1
kiwisolver==1.3.0
Markdown==3.3.3
MarkupSafe==1.1.1
matplotlib==3.3.2
numpy==1.18.5
oauthlib==3.1.0
opencv-python==4.4.0.44
opt-einsum==3.3.0
Pillow==8.0.0
protobuf==3.13.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycrypto==2.6.1
PyGObject==3.30.4
pyparsing==2.4.7
python-apt==1.8.4.1
python-dateutil==2.8.1
pyxdg==0.25
PyYAML==5.3.1
requests==2.21.0
requests-oauthlib==1.3.0
rsa==4.6
scipy==1.4.1
SecretStorage==2.3.1
six==1.12.0
ssh-import-id==5.7
tensorboard==1.15.0
tensorflow==1.15.2
tensorflow-estimator==1.15.1
termcolor==1.1.0
urllib3==1.24.1
virtualenv==20.1.0
Werkzeug==1.0.1
wrapt==1.12.1
zipp==3.4.0

pip3 freeze output from Windows PC

absl-py==0.10.0
astor==0.8.1
autopep8==1.5.4
certifi==2020.6.20
click==7.1.2
cycler==0.10.0
Flask==0.12.2
gast==0.2.2
google-pasta==0.2.0
grpcio==1.33.1
h5py==2.10.0
imageai==2.1.5
importlib-metadata==2.0.0
itsdangerous==1.1.0
Jinja2==2.11.2
Keras==2.4.3
Keras-Applications==1.0.8
Keras-Preprocessing==1.1.2
kiwisolver==1.2.0
Markdown==3.3.2
MarkupSafe==1.1.1
matplotlib==3.3.2
numpy==1.18.5
opencv-python==4.4.0.44
opt-einsum==3.3.0
Pillow==8.0.0
protobuf==3.13.0
pycodestyle==2.6.0
pyparsing==2.4.7
python-dateutil==2.8.1
PyYAML==5.3.1
scipy==1.4.1
six==1.15.0
tensorboard==1.14.0
tensorflow==1.14.0
tensorflow-estimator==1.14.0
termcolor==1.1.0
toml==0.10.1
Werkzeug==1.0.1
wrapt==1.12.1
zipp==3.3.1

Edit: added pip3 freeze for Windows

I had the same Issue. As installing all your freezed packages was not an option for me I checked which packages we have in common and which makes sense that it would call troubles with keras loading h5 files

And the result is: h5py was the problem

Using pip install h5py==2.10.0 fixed the problem

Well this is odd...

I fixed the issue by installing literally every package at the same version as my Windows machine.

Steps:

  1. Create file dependencies.txt with the contents of the pip3 freeze Windows output
  2. Run python3 -m pip install -r dependencies.txt . This forces pip to install literally every dependency at the same version.
  3. Run the program with sudo python3 app.py

It seems like it was a package error after all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM