Open AsifGhaffar2220 opened 3 years ago
Can you send you code that you used for training and prediction thy
Here is code for training, that I used:
from imageai.Classification.Custom import ClassificationModelTrainer
model_trainer = ClassificationModelTrainer()
model_trainer.setModelTypeAsResNet50() model_trainer.setDataDirectory("v_data") model_trainer.trainModel(num_objects=2, num_experiments=100, enhance_data=True, batch_size=32, show_network_summary=True)
Here is code for prediction, that I used:
from imageai.Classification.Custom import CustomImageClassification
prediction = CustomImageClassification()
model_path = "./v_data/models/model_ex-001_acc-0.522500.h5" json_path = "./v_data/json/model_class.json" input_path = "./v_data/test/cars/1.jpg"
prediction.setModelTypeAsResNet50() prediction.setModelPath(model_path) prediction.setJsonPath(json_path) prediction.loadModel(num_objects=2)
predictions, probabilities = prediction.classifyImage(input_path, result_count=2)
for eachPrediction, eachProbability in zip(predictions, probabilities): print(eachPrediction , " : " , eachProbability)
I will use different num_experiments some times but not same result
I will use different num_experiments some times but always same result
You code you used looks fine :)
I think that your dataset might be the problem bc it seems like you have only two items in your dataset like objects A and B. How big is the amount of images for class A and how big for class B? If they're very different like 2000 A and 500 B I do not doubt why it just detects one class bc you trained to do a coin flip is it A or B. The only problem is that due to the unbalanced dataset the probabilities of getting head or tail are not 50-50 they are more like 500-1 for example and that little chance is so rare that you model always goes for one class then the other bc image ai goes for the class with the highest score.
short version
More training images = higher score Less training images = lower score
Unbalanced dataset (500xA and 50xB)= one class preferred
Balanced dataset (500xA and 500xB) = all classes the same probability to get right detected
Ok thanks, I will look about it, then inform about result.
In my dataset every class contains 200 for training and 50 for testing
And you have 2 classes ?
yes
And do you get the same class for each image ??
yes
Do you check what score you're predictions get ?
I am training model again, So I will inform you about score.
In previous predication every time 100 score and same class.
Same result again
train.txt use this model it will work for sure this file is for
predict.txt this file is for the actual prediction
run those files as a python script by replacing .txt with .py
your dataset folder should look like this
Dataset
|-- Class A .... |-- image1 .....|-- imagexyz
|-- Class B .... |-- image1 .....|-- imagexyz
(the actual image name doesn't matter bc the folder there in stands for the class they belong to)
Hi,
I had the same issue, i tried the example idenprof, but after running with ResNet50 amd DenseNet121 the problem is the same.
Here is the train code: from imageai.Classification.Custom import ClassificationModelTrainer
model_trainer = ClassificationModelTrainer() model_trainer.setModelTypeAsDenseNet121() model_trainer.setDataDirectory("idenprof") model_trainer.trainModel(num_objects=10, num_experiments=15, enhance_data=True, batch_size=32, show_network_summary=True)
Here is de classify code: from imageai.Classification.Custom import CustomImageClassification import os
execution_path = os.getcwd()
prediction = CustomImageClassification() prediction.setModelTypeAsDenseNet121() prediction.setModelPath("model_ex-076_acc-0.999108.h5") prediction.setJsonPath("model_class.json") prediction.loadModel(num_objects=10)
predictions, probabilities = prediction.classifyImage("image.jpg", result_count=10)
for eachPrediction, eachProbability in zip(predictions, probabilities): print(eachPrediction , " : " , eachProbability)
Doesn't matter the image i use the result always related to police class: police : 99.76385831832886 engineer : 0.23614077363163233 firefighter : 5.706436625313449e-10 waiter : 7.887313984442437e-12 pilot : 3.6265207416924516e-13 farmer : 1.3212530248623297e-13 doctor : 7.946953637786084e-14 chef : 8.109176277871243e-19 mechanic : 6.302315649809356e-27 judge : 3.379923151490309e-31
I tried the code suggested Above with some adaption:
Train import matplotlib.pyplot as plt import tensorflow as tf from tensorflow.keras import layers from tensorflow.keras.models import Sequential from time import time
start = time()
data_dir = "idenprof/train" batch_size = 32 img_height = 244 img_width = 244
train_ds = tf.keras.preprocessing.image_dataset_from_directory( data_dir, validation_split=0.3, subset="training", seed=123, image_size=(img_height, img_width), batch_size=batch_size)
class_names = train_ds.class_names
val_ds = tf.keras.preprocessing.image_dataset_from_directory( data_dir, validation_split=0.3, subset="validation", seed=123, image_size=(img_height, img_width), batch_size=batch_size)
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE) val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
num_classes = len(class_names)
model = Sequential([ layers.experimental.preprocessing.Rescaling(1./255), layers.Conv2D(32, 3, padding='same', activation='relu'), layers.MaxPooling2D(), layers.Conv2D(64, 3, padding='same', activation='gelu'), layers.MaxPooling2D(), layers.Conv2D(128, 3, padding='same', activation='relu'), layers.MaxPooling2D(), layers.Dropout(0.3), layers.Flatten(), layers.Dense(256, activation='relu'), layers.Dense(num_classes) ])
model.compile(optimizer='sgd', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
epochs=25 history = model.fit(train_ds,validation_data=val_ds,epochs=epochs) model.summary() acc = history.history['accuracy'] val_acc = history.history['val_accuracy']
loss = history.history['loss'] val_loss = history.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(8, 8)) plt.subplot(1, 2, 1) plt.plot(epochs_range, acc, label='Training Accuracy') plt.plot(epochs_range, val_acc, label='Validation Accuracy') plt.legend(loc='lower right') plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2) plt.plot(epochs_range, loss, label='Training Loss') plt.plot(epochs_range, val_loss, label='Validation Loss') plt.legend(loc='upper right') plt.title('Training and Validation Loss') print(f"Trained Model in {(time()-start)/60} minutes") plt.show()
model.save("models")
Classify:
import numpy as np from tensorflow import keras import tensorflow as tf from PIL import Image from tqdm import tqdm import os
image_path = "image.jpg"
class_names = sorted(os.listdir("idenprof/train")) reconstructed_model = keras.models.load_model("models")
img = np.asarray(Image.open(image_path).resize((244, 244), Image.NEAREST)) img = np.reshape(img, (1, 244, 244, 3))
predictions = reconstructed_model.predict(img) score = tf.nn.softmax(predictions[0]) label = class_names[np.argmax(score)][0]
for class_name_prt, score_prt in zip(class_names, predictions[0]): print(class_name_prt , " : " , score_prt)
In this case, the high score is related to image, but is very low all the time: import numpy as np from tensorflow import keras import tensorflow as tf from PIL import Image from tqdm import tqdm import os
image_path = "image.jpg"
class_names = sorted(os.listdir("idenprof/train")) reconstructed_model = keras.models.load_model("models")
img = np.asarray(Image.open(image_path).resize((244, 244), Image.NEAREST)) img = np.reshape(img, (1, 244, 244, 3))
predictions = reconstructed_model.predict(img) score = tf.nn.softmax(predictions[0]) label = class_names[np.argmax(score)][0]
for class_name_prt, score_prt in zip(class_names, predictions[0]): print(class_name_prt , " : " , score_prt)
I'm trying to implement a custom image prediction that classifies images into one of the two discrete categories, I trained model. The problem is, however, that it currently always predicts same class for any input and I'm not really sure why.