Train model using Transfer Learning, the validation accuracy not learning

I am new to transfer learning. I am doing face mask detection in 4 classes(no facemask wearing, incorrect facemask wearing, correct facemask wearing, double mask wearing). My objective is to compare different transfer learning models and compare the accuracy, but I stuck with the first model (MobileNetV2).

Method I had tried:

  1. I have tried changing my dataset a few times and mixing the dataset of different distributions but the validation and testing accuracy are not able to improve. (no improve)
  2. change the preprocessing image to greyscale (no improve)
  3. modify aug (zoom, brightness, blurring (no improve)
  4. make BatchNormalization no freeze (no improve)
  5. add more validation data (no improve)
  6. change flatten to GlobalAveragePooling2D (no improve)

My dataset: https://drive.google.com/drive/folders/1x4sWAPM_S9ECjbxppNizD-uxniborPv8?usp=sharing

Mostly retrieved from:

  1. https://www.kaggle.com/datasets/andrewmvd/face-mask-detection
  2. https://humansintheloop.org/mask-dataset-download/?submissionGuid=add801a1-b11b-4e08-8825-3f3a1d2cce2c

Import:

from tensorflow.keras.preprocessing.image import load_img, img_to_array
from tensorflow.keras.utils import to_categorical
from sklearn.utils import shuffle
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from sklearn.model_selection import train_test_split, GridSearchCV
from tensorflow.keras.layers import AveragePooling2D, Dropout, Flatten, Dense, Input, GlobalAveragePooling2D
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input as mobilenet_preprocess_input

My code:

# Data Augmentation
aug = ImageDataGenerator(
    zoom_range=0.1,
    rotation_range=25,
    width_shift_range=0.1,
    height_shift_range=0.1,
    shear_range=0.15,
    horizontal_flip=True,
    fill_mode=nearest
    )

# Model Declaration
transfer_learning_models = [{'name': 'MobileNetV2',
                             'model': MobileNetV2,
                             'preprocess_input': mobilenet_preprocess_input,
                             'image_size': 224}]

create a model:

def return_create_model(pretrained_model,img_size):
    def create_model(learning_rate, dropout_rate,optimizer):
        base_model = pretrained_model(weights='imagenet', include_top=False, 
                           input_tensor=Input(shape=(img_size, img_size, 3)), 
                           input_shape=(img_size, img_size, 3))

        headModel = base_model.output
        headModel = Flatten(name=flatten)(headModel)
        headModel = Dense(128, activation=relu)(headModel)
        headModel = Dropout(dropout_rate)(headModel)
        headModel = Dense(4, activation=softmax)(headModel)

        model = Model(inputs=base_model.input, outputs=headModel)

        for layer in base_model.layers:
            layer.trainable = False

    #         opt = Adam(learning_rate) if optimizer == 'Adam'else SGD(lr = learning_rate)

        opt = Adam(learning_rate)
        model.compile(loss=categorical_crossentropy, optimizer=opt,metrics=[accuracy])
        return model
    return create_model

model trainning:

def train_model_with_best_param(transfer_learning_model, best_param, create_model,epochs):
    model_name = transfer_learning_model[name]
    
    best_tune_model = create_model(learning_rate=best_param[learning_rate], 
                                   dropout_rate=best_param[dropout_rate],
                                   optimizer=best_param[optimizer])
    
    BS = best_param[batch_size]
    
    filepath = fC:/Users/PC/Desktop/result/{model_name}/weights-improvment-{{epoch:02d}}-{{val_accuracy:.3f}}.hdf5
    
    checkpoint = ModelCheckpoint(filepath, monitor='val_accuracy',verbose=0,save_best_only=True,mode='max')
    early_stop = EarlyStopping(monitor='val_loss',patience=8)
    log_csv = CSVLogger(f'C:/Users/PC/Desktop/result/{model_name}/{model_name}.csv',separator=',',append=False)
    callback_list = [checkpoint,early_stop,log_csv]
    
    history = best_tune_model.fit(
        aug.flow(x_train, y_train, batch_size = BS),
        steps_per_epoch=len(x_train)// BS,
        epochs = epochs,
        validation_data=(x_val, y_val),
        validation_steps=len(x_val)// BS,
        callbacks = callback_list)
    
    save_loss_and_acc_graph(history.history, model_name)
    best_tune_model.save(fC:/Users/PC/Desktop/result/{model_name}/{model_name}.h5)
    
    return best_tune_model, history

The trainning curve (the validation fluctuating)

The testing accuracy

Thank you for your time and help

Topic transfer-learning keras deep-learning

Category Data Science

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.