My binary classification model's accuracy seems stuck: Where did i go wrong?

I have attempted training a model for binary classification problem using a dataset made of medical pictures(LIDC dataset to be exact), which, too my understanding, shouldnt be too far from the "dog vs cat" classification problem. ( distinguishing between benign and malignant nodules )

Problem is, the accuracy seems to stucks, from the beginning to about 65% and doesnt seem to change at all. Am i doing something wrong ? The example that was provided by my friend easily reaches more than 80% and the accuracy is improving epoch after epoch, but not mine :/

I am training on already extracted patches, all of the same size and separated into two classes.

The model i am using a VGG16 fine-tuned for this task ( i replaced the FC layers with new ones, freezed the previous layer and attempted training )

I have tried changing to binary_crossentropy, applying to_categorical, change the last layer from 1 to 2. At his point, i am confused on the correct combination of parameters for my problems. Sorry if i sound like an absolute beginner...

i tried skipping the less informative parts of the code, hope its readable

training_data_dir = "flow/training" 

validation_data_dir = "flow/validation" 

test_data_dir = "flow/test" 

from keras.preprocessing.image import ImageDataGenerator
training_data_generator = ImageDataGenerator(rescale=1./255)
validation_data_generator = ImageDataGenerator(rescale=1./255)
test_data_generator = ImageDataGenerator(rescale=1./255)


training_generator = training_data_generator.flow_from_directory(
    training_data_dir,
    target_size=(IMAGE_WIDTH, IMAGE_HEIGHT),
    batch_size=BATCH_SIZE,
    class_mode="binary")
validation_generator = validation_data_generator.flow_from_directory(
    validation_data_dir,
    target_size=(IMAGE_WIDTH, IMAGE_HEIGHT),
    batch_size=BATCH_SIZE,
    class_mode="binary")
test_generator = test_data_generator.flow_from_directory(
    test_data_dir,
    target_size=(IMAGE_WIDTH, IMAGE_HEIGHT),
    batch_size=1,
    class_mode="binary", 
    shuffle=False)


vgg16_model = VGG16(weights="imagenet", include_top=False,input_tensor=Input(shape=(57, 57, 3)))
vgg16_model.summary()

model = Sequential()

for layer in vgg16_model.layers:
layer.trainable = False
  model.add(layer)

model.add(Flatten())

model.add(Dense(4096, activation='relu'))
model.add(Dense(1024, activation='relu'))
model.add(Dense(1, activation='softmax'))


model.compile(loss='binary_crossentropy',
              optimizer=keras.optimizers.Adam(lr=1e-5),
              metrics=['accuracy'])


model.fit_generator(training_generator,
    steps_per_epoch=len(training_generator.filenames) // BATCH_SIZE,
    epochs=EPOCHS,
    validation_data=validation_generator,
    validation_steps=len(validation_generator.filenames) // BATCH_SIZE, 
    verbose=2)

Upvotes: 0

Views: 521

Answers (1)

desertnaut
desertnaut

Reputation: 60389

Since you have a single-unit output layer and binary cross-entropy loss, you should use a sigmoid activation for your last layer; change it to:

model.add(Dense(1, activation='sigmoid'))

It would also be advisable to leave Adam with its default learning rate, at least for starters, i.e:

optimizer=keras.optimizers.Adam()

in your model.compile.

Upvotes: 1

Related Questions