0
votes

I am running an image classification model with images and my problem is that my validation accuracy is higher than my training accuracy. The data (train/validation) is set up randomly. I am using the InceptionV3 as a pre-trained model. The ratio between accuracy and validation accuracy stays the same over 100 epochs.
I tried a lower learning rate and an additional batch normalization layer.

Does anyone have any ideas on what to look into? I'd appreciate some help, thank you!

base_model = InceptionV3(weights='imagenet', include_top=False)
# add a global spatial average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)
# add a fully-connected layer
x = Dense(468, activation='relu')(x)
x = Dropout(0.5)(x)

# and a logistic layer
predictions = Dense(468, activation='softmax')(x)

# this is the model we will train
model = Model(base_model.input,predictions)

# first: train only the top layers (which were randomly initialized)
# i.e. freeze all convolutional InceptionV3 layers
for layer in base_model.layers:
    layer.trainable = False

# compile the model (should be done *after* setting layers to non-trainable)
adam = Adam(lr=0.0001, beta_1=0.9)
model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy'])

# train the model on the new data for a few epochs
batch_size = 64
epochs = 100
img_height = 224
img_width = 224
train_samples = 127647
val_samples = 27865

train_datagen = ImageDataGenerator(
    rescale=1./255,
    #shear_range=0.2,
    zoom_range=0.2,
    zca_whitening=True,
    #rotation_range=0.5,
    horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
    'AD/AutoDetect/',
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    'AD/validation/',
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='categorical')

# fine-tune the model
model.fit_generator(
    train_generator,
    samples_per_epoch=train_samples // batch_size,
    nb_epoch=epochs,
    validation_data=validation_generator,
    nb_val_samples=val_samples // batch_size)

Found 127647 images belonging to 468 classes.
Found 27865 images belonging to 468 classes.
Epoch 1/100
2048/1994 [==============================] - 48s - loss: 6.2839 - acc: 0.0073 - val_loss: 5.8506 - val_acc: 0.0179
Epoch 2/100
2048/1994 [==============================] - 44s - loss: 5.8338 - acc: 0.0430 - val_loss: 5.4865 - val_acc: 0.1004
Epoch 3/100
2048/1994 [==============================] - 45s - loss: 5.5147 - acc: 0.0786 - val_loss: 5.1474 - val_acc: 0.1161
Epoch 4/100
2048/1994 [==============================] - 44s - loss: 5.1921 - acc: 0.1074 - val_loss: 4.8049 - val_acc: 0.1786

1
Can you give more details why you zoom, flip and whiten your data? With over 100k images it seems you have sufficient data to at least try without augmentation. In addition to that you could give your fully connected layer a bit more complexity. I´d try 1024 neurons or bigger and would get rid of the Dropout / BatchNorm.petezurich
Just for completeness: The proper image size for Inception is 299x299px. 224 is for VGG. See here: keras.io/applicationspetezurich

1 Answers

-2
votes

see this answer

This occours becauce you add a dropout layer in your model that prevents the accuracy from going to 1.0 during training.