Hello everyone,
I trained 2 different models with 2 different classes. Then I tried to predict two different images with each of those models but the prediction result always returns the classes from the first model prediction, totally ignoring the loaded class file. Here is the code:
`from imageai.Prediction.Custom import CustomImagePrediction
import os
execution_path = os.getcwd()
predictor = CustomImagePrediction()
predictor.setModelPath(model_path=os.path.join(execution_path, "model1.h5"))
predictor.setJsonPath(model_json=os.path.join(execution_path, "class1.json"))
predictor.setModelTypeAsResNet()
predictor.loadModel(num_objects=2)
predictor2 = CustomImagePrediction()
predictor2.setModelPath(model_path=os.path.join(execution_path, "model2.h5"))
predictor2.setJsonPath(model_json=os.path.join(execution_path, "class2.json"))
predictor2.setModelTypeAsResNet()
predictor2.loadModel(num_objects=2)
results, probabilities = predictor.predictImage(image_input=os.path.join(execution_path, "image1.bmp"), result_count=2)
print(results)
print(probabilities)
results2, probabilities2 = predictor2.predictImage(image_input=os.path.join(execution_path, "image2.jpeg"),
result_count=2)
print(results2)
print(probabilities2)
print("-------------------------------")`
The classes file look like this:
class1.json:
{
"0" : "class11",
"1" : "class12"
}
class2.json:
{
"0" : "class21",
"1" : "class22"
}
If I predict using model1 first, I get this result for both images:
['class11', 'class12']
[92.94933676719666, 7.050657272338867]
['class11', 'class12']
[92.31300950050354, 7.686983793973923]
=> Both images are classified by class1.json, even though for predictor 2 i loaded class2.json
If I predicut using model2 first, I get exactly the opposite result. Both Images are being classified with class2.json.
imageai: 2.1.5
keras: 2.2.4
tensorflow-gpu:1.12
Regards,
Zordiac
Okay after a minute of checking your code, I found the bug, it is located in PredictionCustomcustom_utils.py:
`import json
CLASS_INDEX = None
def preprocess_input(x):
"""Preprocesses a tensor encoding a batch of images.
# Arguments
x: input Numpy tensor, 4D.
data_format: data format of the image tensor.
# Returns
Preprocessed tensor.
"""
# 'RGB'->'BGR'
x *= (1./255)
return x
def decode_predictions(preds, top=5, model_json=""):
global CLASS_INDEX
if CLASS_INDEX is None:
CLASS_INDEX = json.load(open(model_json))
results = []
for pred in preds:
top_indices = pred.argsort()[-top:][::-1]
for i in top_indices:
each_result = []
each_result.append(CLASS_INDEX[str(i)])
each_result.append(pred[i])
results.append(each_result)
return results`
The issue is the global variable CLASS_INDEX, which stores the models classes. This variable is set after the very first prediction, to the first model class used. However, every subsequent prediction still uses these classes loaded initially and not their own classes, even though the model paths differ.
If anybody needs a fix, I forked the repository and changed the file here:
https://github.com/OlafenwaMoses/ImageAI/compare/master...Zordiac:patch-1?diff=unified
Most helpful comment
Okay after a minute of checking your code, I found the bug, it is located in PredictionCustomcustom_utils.py:
`import json
CLASS_INDEX = None
def preprocess_input(x):
"""Preprocesses a tensor encoding a batch of images.
def decode_predictions(preds, top=5, model_json=""):
The issue is the global variable CLASS_INDEX, which stores the models classes. This variable is set after the very first prediction, to the first model class used. However, every subsequent prediction still uses these classes loaded initially and not their own classes, even though the model paths differ.
If anybody needs a fix, I forked the repository and changed the file here:
https://github.com/OlafenwaMoses/ImageAI/compare/master...Zordiac:patch-1?diff=unified