I created a model using transfer learning fine tuning for identify snakes using 5 snake breeds with Mobile net. My problem is within the snake breeds it identify the breed almost every time.But when i tried images like worms,lizards it still identify them with nearly 60% score. Even a human was identified as a snake once.
`IM_WIDTH, IM_HEIGHT = 224, 224
NB_EPOCHS = 3
BAT_SIZE = 32
FC_SIZE = 64
NB_MN_LAYERS_TO_FREEZE = 20
dataset_folder = "C:\\Users\\XDD\\FYP\\Dataset"
train_dir = "Dataset/Train"
val_dir = "Dataset/Val"
test_dir = "Dataset/Test"
def get_nb_files(directory):
count = 0
for root, dirs, files in os.walk(directory):
count += len(files)
return count
def add_new_last_layer_mobilenet(base_model, nb_classes, dropout_rate=0.5):
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(FC_SIZE, activation='relu')(x)
x = Dropout(dropout_rate)(x) # Add dropout layer
predictions = Dense(nb_classes, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)
return model
def setup_to_transfer_learn_mobilenet(model, base_model):
for layer in base_model.layers:
layer.trainable = False
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
def setup_to_finetune_mobilenet(model):
for layer in model.layers[:NB_MN_LAYERS_TO_FREEZE]:
layer.trainable = False
for layer in model.layers[NB_MN_LAYERS_TO_FREEZE:]:
layer.trainable = True
model.compile(optimizer=SGD(learning_rate=0.0001, momentum=0.9), loss='categorical_crossentropy',metrics=['accuracy'])
def plot_training(history):
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'b', label='Training acc')
plt.plot(epochs, val_acc, 'r', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'b', label='Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
def train_mobilenet(train_dir, val_dir, nb_epoch=NB_EPOCHS, batch_size=BAT_SIZE, output_model_file="mobilenet-ft.model", plot=True):
nb_train_samples = get_nb_files(train_dir)
nb_classes = len(glob.glob(train_dir + "/*"))
nb_val_samples = get_nb_files(val_dir)
train_datagen = ImageDataGenerator(
preprocessing_function=preprocess_input_tf_mobilenet,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
fill_mode='nearest', # Filling strategy for rotated images
)
val_datagen = ImageDataGenerator(
preprocessing_function=preprocess_input_tf_mobilenet,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
fill_mode='nearest',
)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(IM_WIDTH, IM_HEIGHT),
batch_size=batch_size,
class_mode='categorical'
)
validation_generator = val_datagen.flow_from_directory(
val_dir,
target_size=(IM_WIDTH, IM_HEIGHT),
batch_size=batch_size,
class_mode='categorical'
)
base_model = MobileNet(weights='imagenet', include_top=False, input_shape=(IM_WIDTH, IM_HEIGHT, 3))
model = add_new_last_layer_mobilenet(base_model, nb_classes)
setup_to_transfer_learn_mobilenet(model, base_model)
history_tl = model.fit(
train_generator,
epochs=nb_epoch,
steps_per_epoch=nb_train_samples // batch_size,
validation_data=validation_generator,
validation_steps=nb_val_samples // batch_size,
)
setup_to_finetune_mobilenet(model)
history_ft = model.fit(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=nb_epoch,
validation_data=validation_generator,
validation_steps=nb_val_samples // batch_size,
)
model.save(output_model_file)
if plot:
plot_training(history_ft)
return model
trained_mobilenet_model = train_mobilenet(train_dir=train_dir, val_dir=val_dir, nb_epoch=NB_EPOCHS, batch_size=BAT_SIZE, output_model_file="mobilenet-ft.model", plot=True)
trained_mobilenet_model.summary()`
This is the confusion matrix and classification report with test result
Accuracy: 0.9271523178807947
Confusion Matrix:
[[28 0 0 0 1]
[ 1 30 0 0 0]
[ 0 2 24 2 2]
[ 0 0 0 27 3]
[ 0 0 0 0 31]]
Classification Report:
precision recall f1-score support
Cobra 0.97 0.97 0.97 29
Common_Crait 0.94 0.97 0.95 31
Hump_Nosed_Viper 1.00 0.80 0.89 30
Russells_Viper 0.93 0.90 0.92 30
Saw_Scaled_Viper 0.84 1.00 0.91 31
accuracy 0.93 151
macro avg 0.93 0.93 0.93 151
weighted avg 0.93 0.93 0.93 151
I wanted to classify the snake breed correctly within training.It is working with snake images but i was expecting to get a lower accuracy for outside data like lizards and objects and animals which has shape of snake.