0
$\begingroup$

I'm training a CNN from scratch to do tagging of images. And my training is going nowhere. I was hoping someone could help me identify an obvious error.

I would like to end up with a network that given an image can output 0 or 1 if it contains a face or not. I know there are a lot of pre-trained models that can do this, but this is only a starting point for me.

My dataset consists of a CSV that looks like this. I have chose this format, because I plan to add more tags to the dataset in the future.

filename,face
img1.jpg,0
img2.jpg,1
...

... which I load into a pandas dataframe with load_csv(). Then I create a training generator.

datagen = ImageDataGenerator(validation_split=0.2)
train_generator = datagen.flow_from_dataframe(
    dataframe=df,
    directory=image_directory,
    x_col='filename',
    y_col=label_strings,
    subset='training',  # Specify subset as training
    class_mode='raw',
    target_size=(270, 480),
    batch_size=32,
    shuffle=True
)

... and I also create a validating generator, using similar settings.

Here's my network architecture:

model = Sequential([
  layers.InputLayer(input_shape=(270, 480, 3)),

  # # data augmentation,
  layers.RandomFlip("horizontal_and_vertical"),
  layers.RandomRotation(0.025),
  # preprocessing
  layers.Rescaling(1./255),
  # do the work
  layers.Conv2D(16, 3, padding='same'),
  layers.Activation("relu"),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, padding='same'),
  layers.Activation("relu"),
  layers.MaxPooling2D(),
  layers.Conv2D(64, 3, padding='same'),
  layers.Activation("relu"),
  layers.MaxPooling2D(),
  layers.Flatten(),
  layers.Dense(256),
  layers.Activation("relu"),
  layers.Dense(256),
  layers.Activation("relu"),
  layers.Dense(num_classes),
  layers.Activation('sigmoid')
])

I then compile it as follows and train it on a set containing 2600 images:

opt = SGD(learning_rate=0.0001)
model.compile(optimizer=opt,
              loss='binary_crossentropy',
              metrics=['accuracy'])

After the first few epochs, both the training set accuracy and the validation set accuracy seem to flatline at no better than a coinflip. Strangely the loss functions for both sets seem to continue to improve, but only the slightest amount.

I've tried a few orders of magnitude learning rate in both directions, and different optimizers to no avail. Help?

$\endgroup$

1 Answer 1

0
$\begingroup$

the performance of the model depends on the data, but I see a few snags in your approach you might try to change:

  • normalization - you didn't use any normalization. You might try to interpose BatchNormalization layer between yours. Regardin of ReLU activation, it probably doesn't make any difference if the normalization would be before or after the activation.
  • too many parameters and too few images - you wrote that you use 2600 input data (that's probably not much) and it appears your model has more parameters that hinder the generalisation capabilities in many cases. Unless you have more data, try to decrease your model.
  • regularization - you might try to add Dropout layers
  • depth of the model - try adding one or two more Conv2D layers to decrease the size of the image more before putting it into Dense layer. These Dense layers also appear to be very broad.
$\endgroup$
2
  • $\begingroup$ Thanks do you have any rules of thumb for number of prarameters vs number of images assuming a 480x270 image size? Similar for dense layer width? $\endgroup$
    – laslowh
    Commented Dec 6, 2023 at 18:07
  • $\begingroup$ @laslowh for sure you must have more input data than parameters in the model to overcome overfitting. For me, the rule of thumb is to start from as small a model as possible and increase it until it stops gaining performance. $\endgroup$ Commented Dec 6, 2023 at 18:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.