How to increase FER2013 dataset validation_accuracy for only 3 classes i.e, happy,sad,neutral?

Viewed 14

I am building a face emotion detection model using vgg16.

Using FER2013 dataset for 7 classes i am getting= train_accuracy=97%, validation_accuracy=90%.

but when i tried with 3 classes i.e, happy,sad,neutral i am getting=

train_accuracy=98% , validation_accuracy= 84%

Can anybody tell me what should i do to increase the validation_accuracy for 3 classes of FER2013 dataset ?

For clear clarification please refer the code below:

train_datagen = ImageDataGenerator(rescale = 1./255,
                                   validation_split = 0.2,
                                  
        rotation_range=5,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        #zoom_range=0.2,
        horizontal_flip=True,
        vertical_flip=True,
        fill_mode='nearest')

valid_datagen = ImageDataGenerator(rescale = 1./255,
                                  validation_split = 0.2)

test_datagen  = ImageDataGenerator(rescale = 1./255
                                  )

train_dataset  = train_datagen.flow_from_directory(directory = 'D:/Final_Dataset_4/train',
                                                   target_size = (48,48),
                                                   class_mode = 'categorical',
                                                   subset = 'training',
                                                   batch_size = 32)

valid_dataset = valid_datagen.flow_from_directory(directory = 'D:/Final_Dataset_4/train',
                                                  target_size = (48,48),
                                                  class_mode = 'categorical',
                                                  subset = 'validation',
                                                  batch_size = 32)

test_dataset = test_datagen.flow_from_directory(directory = 'D:/Final_Dataset_4/test',
                                                  target_size = (48,48),
                                                  class_mode = 'categorical',
                                                  batch_size = 32)

base_model = tf.keras.applications.VGG16(input_shape(48,48,3),include_top=False,weights="imagenet")

# Freezing Layers

for layer in base_model.layers[:-4]:
    layer.trainable=True

# Building Model

model=Sequential()
model.add(base_model)
#model.add(Dropout(0.2))
model.add(Flatten())
model.add(BatchNormalization())
model.add(Dense(32,kernel_initializer='he_uniform'))
model.add(BatchNormalization())
model.add(Activation('relu'))
#model.add(Dropout(0.2))
model.add(Dense(32,kernel_initializer='he_uniform'))
model.add(BatchNormalization())
model.add(Activation('relu'))
#model.add(Dropout(0.2))
model.add(Dense(32,kernel_initializer='he_uniform'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dense(3,activation='softmax'))


def f1_score(y_true, y_pred): #taken from old keras source code
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    recall = true_positives / (possible_positives + K.epsilon())
    f1_val = 2*(precision*recall)/(precision+recall+K.epsilon())
    return f1_val

METRICS = [
      tf.keras.metrics.BinaryAccuracy(name='accuracy')
]

lrd = ReduceLROnPlateau(monitor = 'val_loss',patience = 20,verbose = 1,factor = 0.50, min_lr = 1e-10)
mcp = ModelCheckpoint('model.h5')
#es = EarlyStopping(verbose=1, patience=20)


model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=1e-4,momentum=0.9), loss='categorical_crossentropy',metrics=METRICS)


history=model.fit(train_dataset,validation_data=valid_dataset,epochs = 100,verbose = 1,callbacks=[lrd,mcp])

0 Answers
Related