Tools for handling class imbalance

Hello, my dataset has imbalanced classes. Does Ultralytics has tools for tackling this problematic? Usually people use resampling and/or class_loss_weights. I personally noticed that resampling works best for the cases I encountered. Currently I’m working in a project with 12 classes, and some of them have less instances, and hence more detection errors. Thanks in advance for your wisdom :slight_smile:

The best solution is always going to be collecting more samples for low frequency objects (minority class). That is the only way to assure better performance on low frequency classes in a dataset. If you are looking for the best model performance, there is no substitute for expanding your annotated dataset.

I assume by “resampling” you mean “oversampling” as resampling as a general term and oversampling is one example of resampling strategies. In general, oversampling is not the best solution, as it’s likely to cause overfitting for the minority class. It’s only something that I would save for an absolute last resort. Consider as well that there are many datasets which have low instance counts of objects. For instance, the COCO2017 dataset has 1,041 instances of toothbrush but 12,786 instances of car. YOLO11n will scores a mAP50 of 0.252 for the toothbrush class and 0.585 for the car class, while having 8% of the number of instances of car. It’s not a terrific outcome, but it’s a reasonable one.

If you have split your dataset into validation and training sets, you might consider keeping images with the minority classes in both training and validation splits. It’s not ideal, but in my opinion it’s a slightly better option than oversampling. This way if you have 20 instances of a minority class, you could place them all in both sets instead of using a 80/20 split (16 train, 4 validation). Still not ideal, but it’s an option.

Depending on your object data, you could increase the hyperparameters for image augmentations. This will randomly augment the images and annotations, which will make the model train for longer and be more robust to minor variations in the objects. This may mean you need to increase the number of epochs used for training as well, and if you’re using the default training settings (100 epochs) you could start by adding 50 epochs when adjusting augmentations. You need to be careful with augmentations however, as they are applied to all classes, not just the minority classes, so whatever augmentations are enabled need to be valid for all classes. As an example, if “left-hand” and “right-hand” were in a dataset, using the fliplr augmentation (left-right flip) wouldn’t make sense, because hands are chiral objects (a flipped left hand isn’t the exact same as a right hand).

If the other classes in your dataset aren’t compatible with the online augmentations, you could do offline augmentation of only the images with the minority classes. This is similar to oversampling, but better since the objects aren’t presented exactly the same. Again you must exercise caution here, as any online augmentations that are used, shouldn’t overlap with the offline augmentations since it would likely cause oversampling.

A pull request has been open for a while to add a pos_weight argument for training. This would be the class loss weighting strategy you mentioned, and even though it’s not implemented into the main branch of Ultralytics, you could try to implement this locally to try to help with your imbalanced training data.