I am using Transfer Learning to perform image classification.
Base model used :
class_2 are the classes each having 1000 samples each (small dataset). And the dataset is not similar to
FC layers used here are 3 with
[1024, 512, 256].
I have used a
drop out of 0.5 to reduce over-fitting.
When I trained the model with 100 epochs, I could clearly see the model over-fits with
training accuracy of 0.9985 and
testing accuracy of 0.875.
Is the number of FC layers used is too many which is causing this over-fit problem? How can I make the model more generalised?
The code used is as given below:
from keras.applications.resnet50 import ResNet50, preprocess_input from keras.preprocessing.image import ImageDataGenerator from keras.layers import Dense, Activation, Flatten, Dropout from keras.models import Sequential, Model from keras.optimizers import SGD, Adam from keras.callbacks import TensorBoard import keras import matplotlib.pyplot as plt HEIGHT = 300 WIDTH = 300 TRAIN_DIR = "/home/ubuntu/dataset/training_set/" TEST_DIR = "/home/ubuntu/dataset/test_set/" BATCH_SIZE = 8 class_list = ["class_1", "class_2"] FC_LAYERS = [1024, 512, 256] dropout = 0.5 NUM_EPOCHS = 100 BATCH_SIZE = 8 def build_finetune_model(base_model, dropout, fc_layers, num_classes): for layer in base_model.layers: layer.trainable = False x = base_model.output x = Flatten()(x) for fc in fc_layers: print(fc) x = Dense(fc, activation='relu')(x) x = Dropout(dropout)(x) preditions = Dense(num_classes, activation='softmax')(x) finetune_model = Model(inputs = base_model.input, outputs = preditions) return finetune_model base_model = ResNet50(weights = 'imagenet', include_top = False, input_shape = (HEIGHT, WIDTH, 3)) train_datagen = ImageDataGenerator(preprocessing_function = preprocess_input, rotation_range = 90, horizontal_flip = True, vertical_flip = False) test_datagen = ImageDataGenerator(preprocessing_function = preprocess_input, rotation_range = 90, horizontal_flip = True, vertical_flip = False) train_generator = train_datagen.flow_from_directory(TRAIN_DIR, target_size = (HEIGHT, WIDTH), batch_size = BATCH_SIZE) test_generator = test_datagen.flow_from_directory(TEST_DIR, target_size = (HEIGHT, WIDTH), batch_size = BATCH_SIZE) finetune_model = build_finetune_model(base_model, dropout = dropout, fc_layers = FC_LAYERS, num_classes = len(class_list)) adam = Adam(lr = 0.00001) finetune_model.compile(adam, loss="categorical_crossentropy", metrics=["accuracy"]) filepath = "./checkpoints" + "RestNet50" + "_model_weights.h5" checkpoint = keras.callbacks.ModelCheckpoint(filepath, monitor = ["acc"], verbose= 1, mode = "max") cb=TensorBoard(log_dir=("/home/ubuntu/")) callbacks_list = [checkpoint, cb] print(train_generator.class_indices) history = finetune_model.fit_generator(generator = train_generator, epochs = NUM_EPOCHS, steps_per_epoch = 100, shuffle = True, callbacks=callbacks_list, validation_data = test_generator)
Weight file generated from the model after training is 2.7 GB. Is it normal considering the complexity of the model?
How would I select the
steps_per_epochvalue? Is there any standard?