Multilabel classification with class imbalance

username: fransilvion
cooked: <p>Hi,</p>
<p>I have a multilabel classification problem, which I am trying to solve with CNNs in Pytorch. I have 80,000 training examples and 7900 classes; every example can belong to multiple classes at the same time, mean number of classes per example is 130. Here is the plot that shows numbers of samples per each class:</p>
<p><img src="https://discuss.pytorch.org/uploads/default/original/3X/0/b/0bda36bede7740476546fa5f4fcb24232c4ef722.png" alt="Screenshot%20from%202019-10-02%2009-49-37" data-base62-sha1="1GQLW9mbW2fWHAf5eoUdj9CxyJY" width="504" height="312"></p>
<p>As you can see the data is very imbalanced. For some classes, I have only ~900 examples, which is around 1%. For “overrepresented” classes I have ~12000 examples (15%). When I train the model I use BCEWithLogitsLoss with a positive weights parameter. I calculate the weights the same way as described in the documentation: the number of negative examples divided by the number of positives.</p>
<p>As a result, my model overestimates almost every class… Mor minor and major classes I get almost twice as many predictions as true labels. And my AUPRC is just 0.18. Even though it’s much better than no weighting at all, since in this case the model predicts everything as zero.</p>
<p>So my question is, how do I improve the performance? Is there anything else I can do? I tried different batch sampling techniques (to oversample minority class), but they don’t seem to work.</p>

username: michalwols
cooked: <p>I’d recommend trying out using softmax with cross entropy with each target class set to 1/num_target_labels. That has usually worked better for me than binary cross entropy and sigmoid outputs.</p>
<p>There are a few papers from facebook that also mention doing that (<a href="https://arxiv.org/abs/1805.00932" class="inline-onebox" rel="noopener nofollow ugc">[1805.00932] Exploring the Limits of Weakly Supervised Pretraining</a>)</p>
<p><img src="https://discuss.pytorch.org/uploads/default/original/3X/7/1/71e86fd08219b403772d903d2e2012e6e9c95748.png" alt="image" data-base62-sha1="gfFWKMLerTB5HEJyQrZ8yJjLCWc" width="481" height="224"></p>

username: mailcorahul
cooked: <p>Try to augment the under-represented class and undersample the dominant class to some extent. I think augmentation + BCEWithLogitsLoss(and without weights assigned) should improve the accuracy by a significant amount.</p>

username: mailcorahul
cooked: <p>hi <a class="mention" href="/u/michalwols">@michalwols</a><br>
incase of softmax with CE with ground truth set to 1/num_target_labels, what will be the threshold above which you choose the class during inference? won’t it vary depending on num_target_labels for every example?</p>

username: fransilvion
cooked: <p>Thank you! But how do I do augmentation in multilabel case?</p>

username: mailcorahul
cooked: <p>Can you give me an overall picture of the problem that you’re trying to solve? You have mentioned that every example has an average of 130 class labels.</p>
<ol>
<li>Do you think detection could help in such a case?(but annotating 80K samples can be expensive)</li>
<li>Can you use existing detectors to run on the train set, extract individual class objects and add them(along with augmentation) to your train set? This may help in tackling class imbalance.</li>
</ol>