Over fitting in Transfer Learning with small dataset I am using Transfer Learning to perform image classification.
Base model used : Resnet50 using ImageNet dataset
class_1 and class_2 are the classes each having 1000 samples each (small dataset). And the dataset is not similar to ImageNet dataset.
Number of 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 = &quot;/home/ubuntu/dataset/training_set/&quot;
TEST_DIR = &quot;/home/ubuntu/dataset/test_set/&quot;
BATCH_SIZE = 8
class_list = [&quot;class_1&quot;, &quot;class_2&quot;]
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=&quot;categorical_crossentropy&quot;, metrics=[&quot;accuracy&quot;])

filepath = &quot;./checkpoints&quot; + &quot;RestNet50&quot; + &quot;_model_weights.h5&quot;
checkpoint = keras.callbacks.ModelCheckpoint(filepath, monitor = [&quot;acc&quot;], verbose= 1, mode = &quot;max&quot;)
cb=TensorBoard(log_dir=(&quot;/home/ubuntu/&quot;))
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)

Update :

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_epoch value? Is there any standard?
First of all:

I think you should reduce the number of FC layers and number of nodes of FC layers, for example, one FC with 256 or 512, or 2 FC with 256 and 512. Try this.

Try to make your batch size 30, and decrease number of epochs to nearly 10 or 20. 100 epochs are too many for your small size dataset.


Secondly, there is more than one way to reduce overfitting:
1- Enlarge your data set by using augmentation techniques such as flip, scale, etc.
2- Using regularization techniques like dropout (you already did it), but you can play with dropout rate. Try more or less than 0.5.
3- One of the good techniques in your case is to do early stopping. In any epoch when you see that the model goes to overfit, stop it.
4- Using cross-validation to train/test your model.
and many more.

For more, see here, or here, or here.

Feel free to ask any further questions.