Overfitting in ZeroCostDL4Mic U-net

I’m trying to segment some objects in brightfield images using the u-net in ZeroCostDL4Mic (80 images/masks for training, an example attached). The validation loss is all over the place after the first few epochs. Does anyone have any suggestions?

I’ve tried putting a loss function after every convolution step and playing with the various hyperparameters, but with no luck!

Hi John,

did you make sure that your mask values are 0 (background) or 255 (objects) and not 0 and 1? This is the input expected in that particular implementation.

Also I’m not sure to understand what you mean with the above sentence. The loss compares the output of the network with the target mask, so I’m not sure what you mean by having a loss function “after every convolution step”. Did you modify the U-net architecture?

Thanks for getting back to me.

Oops! I meant to say dropout, not loss function! Working late…
Yes, I was playing with the architecture to see if I could improve it.

I’ve just added few lines to resize all the images to 512x512, then run on patches of the same size. It seems to help it a bit. I guess it gets rid of lots of noise and fine detail in the images.

Any other ideas?

@guiwitz Oh and yes, my data is definitely in the right format. Good idea though.

Your images are quite large but also quite sparsely populated which can lead to two problems:

  1. It looks like your structures are about 100px wide. If you use the default settings with just two pooling layers, this means that they are going to reduce to ~25 px. This is still large and therefore the lower convolution layers probably can’t pick-up the fact that there are these “large-scale” objects in the image. So you might try to use maybe 4 pooling layers (of course that makes training slower).
  2. You want to avoid having empty patches, i.e. images with no objects at all, and I’m not sure the implementation of that project takes care of that. You could generate the patches yourself and remove those that are empty. E.g. crop your images into 256x256 patches, exclude empty patches and also use 256 as patch size.

No guarantee that this is your problem though…

Hi John and others,
I have noticed that for some dataset, it really helps to remove some transformations during augmentation. Especially, translations that seem to make the loss functions very unstable. So you can see if that helps already.

As Guillaume already pointed out above quite rightly. Large objects need many pooling layers so try and use the maximum number of pooling layers for your dataset (in our implementation we provide up to 4). Alternatively, you could simply bin your dataset to fewer pixels for segmentation and upscale the masks afterwards manually to match the orginal data sizes.Since your masks are quite regular, this should work nicely.

About empty patches: we exclude that in our implementation. You can set a minus fraction of foreground pixels for a patch to be valid and used for training. The parameter you want to play with here is called min_fraction. You can increase this to make sure that there is enough foreground pixels in each patch.

I hope this helps!


1 Like