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 = "/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)
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?