Home > Software design >  How to increase the validation accuracy in CNN model
How to increase the validation accuracy in CNN model

Time:12-08

I want to build a CNN model to classify down syndrome faces from normal, then classify gender by another model. I've tried to change the number of layers, nodes, epochs, optimizers. Also, I tried with colored images and grayscale. The data set is 799 images including normal and down syndrome. This is my code

model.add(Conv2D(filters=16, kernel_size=(5,5), activation="relu",
                 input_shape=X_train[0].shape))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2))) 
model.add(Dropout(0.2))

model.add(Conv2D(filters=32, kernel_size=(5,5), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
model.add(Dropout(0.3))

model.add(Conv2D(filters=64, kernel_size=(5,5), activation="relu"))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
model.add(Dropout(0.3))

model.add(Conv2D(filters=64, kernel_size=(5,5), activation="relu"))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
model.add(Dropout(0.2))

model.add(Flatten())

#Two dense layers and then output layer
model.add(Dense(256, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5)) #Using dropouts to make sure that 
                        #the model isn't overfitting

model.add(Dense(128, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))


model.add(Dense(2, activation='softmax'))

I've tried to change the last activation layer from softmax to sigmoid and vise versa with no success. The size of the input images is 200x200

Model: "sequential_4"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d_16 (Conv2D)          (None, 196, 196, 16)      416       
                                                                 
 batch_normalization_24 (Bat  (None, 196, 196, 16)     64        
 chNormalization)                                                
                                                                 
 max_pooling2d_16 (MaxPoolin  (None, 98, 98, 16)       0         
 g2D)                                                            
                                                                 
 dropout_24 (Dropout)        (None, 98, 98, 16)        0         
                                                                 
 conv2d_17 (Conv2D)          (None, 94, 94, 32)        12832     
                                                                 
 batch_normalization_25 (Bat  (None, 94, 94, 32)       128       
 chNormalization)                                                
                                                                 
 max_pooling2d_17 (MaxPoolin  (None, 47, 47, 32)       0         
 g2D)                                                            
                                                                 
 dropout_25 (Dropout)        (None, 47, 47, 32)        0         
                                                                 
 conv2d_18 (Conv2D)          (None, 43, 43, 64)        51264     
                                                                 
 batch_normalization_26 (Bat  (None, 43, 43, 64)       256       
 chNormalization)                                                
                                                                 
 max_pooling2d_18 (MaxPoolin  (None, 21, 21, 64)       0         
 g2D)                                                            
                                                                 
 dropout_26 (Dropout)        (None, 21, 21, 64)        0         
                                                                 
 conv2d_19 (Conv2D)          (None, 17, 17, 64)        102464    
                                                                 
 batch_normalization_27 (Bat  (None, 17, 17, 64)       256       
 chNormalization)                                                
                                                                 
 max_pooling2d_19 (MaxPoolin  (None, 8, 8, 64)         0         
 g2D)                                                            
                                                                 
 dropout_27 (Dropout)        (None, 8, 8, 64)          0         
                                                                 
 flatten_4 (Flatten)         (None, 4096)              0         
                                                                 
 dense_12 (Dense)            (None, 256)               1048832   
                                                                 
 batch_normalization_28 (Bat  (None, 256)              1024      
 chNormalization)                                                
                                                                 
 dropout_28 (Dropout)        (None, 256)               0         
                                                                 
 dense_13 (Dense)            (None, 128)               32896     
                                                                 
 batch_normalization_29 (Bat  (None, 128)              512       
 chNormalization)                                                
                                                                 
 dropout_29 (Dropout)        (None, 128)               0         
                                                                 
 dense_14 (Dense)            (None, 2)                 258       
                                                                 
=================================================================
Total params: 1,251,202
Trainable params: 1,250,082
Non-trainable params: 1,120
_________________________________________________________________

model.compile(optimizer='Adam',  loss='binary_crossentropy', metrics=['accuracy'])
# split train and VALID data
X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size=0.15)

I want to increase the accuracy at least to 70 but the highest score I reach is 47%

history = model.fit(X_train, y_train, epochs=50, validation_data=(X_valid, y_valid), batch_size=64)

Epoch 1/50
5/5 [==============================] - 23s 4s/step - loss: 0.9838 - accuracy: 0.5390 - val_loss: 0.6931 - val_accuracy: 0.4800
Epoch 2/50
5/5 [==============================] - 21s 4s/step - loss: 0.8043 - accuracy: 0.6348 - val_loss: 0.7109 - val_accuracy: 0.4800
Epoch 3/50
5/5 [==============================] - 21s 4s/step - loss: 0.6745 - accuracy: 0.6915 - val_loss: 0.7554 - val_accuracy: 0.4800
Epoch 4/50
5/5 [==============================] - 21s 4s/step - loss: 0.6429 - accuracy: 0.7589 - val_loss: 0.8261 - val_accuracy: 0.4800
Epoch 5/50
5/5 [==============================] - 21s 4s/step - loss: 0.5571 - accuracy: 0.8014 - val_loss: 0.9878 - val_accuracy: 0.4800

Is there any way to increase it more? and how do I combine two models? Any help will be appreciated. Thank you very much.

CodePudding user response:

Try Image Augmentation. I mean; it's pretty clear the model is overfitting the data

Maybe even change the train_test_split ratio(Increase It.)

CodePudding user response:

I think one of 2 things is going on. The training data would point to over fitting but given the amount of dropout you have in the model I would not suspect that is the case. I think it may be that the probability distribution of the training data is significantly different from that of the validation data. That can happen if you have to few training samples. So how many training samples do you have in each of your 2 classes? If less than say 120 samples per class use image augmentation to create more training samples. How did you generate the validation images? If you have seperate validation images it is best to combine the train set with the validatioon set then use sklearn train_test_split to randomly split the combined data into train and validation sets. Note: only use augmentation for the training set not the validation set. I also recommend you use the Keras callback Reduce learning rate on plateau to implement an adjustable learning rate. Documentation is here. Code below shows the settings I use for that

rlronp=tf.keras.callbacks.ReduceLROnPlateau(monitor="val_loss", factor=0.5, 
                                            patience=1,  verbose=1)

Also recommend using Keras callback Early Stopping, documentation is here. Code below shows my implementation for that

estop=tf.keras.callbacks.EarlyStopping( monitor="val_loss",  patience=3,
                                         verbose=1, 
                                         restore_best_weights=True)

In model.fit include the code

history=model.fit(.....  callbacks[estop, rlronp])

Set the number of epoch to run to a fairly large value .

  • Related