cv-multilabel-rare-class-image-oversampling
SkillMediaOversample multi-label images by giving each image a duplication multiplier equal to the max per-class multiplier among its labels, so every rare class gets repetition without exploding common-class counts — the standard fix for long-tail multi-label distributions where SMOTE / per-row oversampling doesn't apply
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the cv-multilabel-rare-class-image-oversampling skill
What this skill tells your AI
The instructions your AI receives, as published by wenmin-wu/ds-skills in skills/cv/multilabel-rare-class-image-oversampling/SKILL.md and read by ahel’s review.
Overview
Multi-label image data has a long-tail label distribution but each image has multiple labels at once, so per-row oversampling is ambiguous: which class drives the multiplier? The HPA-winning trick is to define a per-class multiplier vector (e.g. 1 for common classes, 2-4 for rare), and for each image take the max multiplier across its labels. Common-only images stay at 1 copy; an image carrying any rare class gets multiplied; images with multiple rare classes still get only one bump (you don't double-multiply). This shifts the rare-class effective frequency upward without bloating common-class samples or distorting label correlations the way per-class image generation would.
Quick Start
import pandas as pd
class Oversampling:
def __init__(self, csv_path, multi):
df = pd.read_csv(csv_path).set_index('Id')
df['Target'] = [[int(i) for i in s.split()] for s in df['Target']]
self.labels = df
self.multi = multi # per-class duplication factor
def get(self, image_id):
labels = self.labels.loc[image_id, 'Target']
return max((self.multi[l] for l in labels), default=1)
# 28-class HPA example: rare classes get 4x, common stay at 1x
multi = [1,1,1,1,1,1,1,1, 4,4,4,1,1,1,1,4,
1,1,1,1,2,1,1,1, 1,1,1,4]
sampler = Oversampling(LABELS_CSV, multi)
train_ids = [iid for iid in train_ids for _ in range(sampler.get(iid))]
Workflow
- Compute per-class positive counts in the training set
- Set
multi[c]inversely proportional to count, but cap at ~4-8 (more inflates training time without lift) - For each image, lookup its labels and take the max multiplier
- Materialize the oversampled ID list once at epoch start (or use a
WeightedRandomSamplerwith the same ratios) - Shuffle the expanded list every epoch
- Validate that the rare-class effective frequency moved closer to the head — but never to parity (full balance overfits the rare classes hard)
Key Decisions
- Max not sum across labels: summing double-counts images with multiple rare classes and inflates them disproportionately.
- Cap the multiplier at ~4-8: 10x oversampling causes per-image overfitting (model memorizes rare-class images).
- Hand-tune the multiplier vector: pure inverse-frequency over-corrects; eyeball the vector and check that the effective per-class loss is close to flat.
- Per-image, not per-pixel-augmentation: this is sample replication, not heavier augmentation; combine the two for best results.
- Don't apply at validation time: oversampled validation gives misleading metrics — keep validation at natural distribution.
- Equivalent via
WeightedRandomSampler: PyTorch users can pass the per-image multipliers as weights instead of materializing duplicates.
References
Signals
- GitHub stars
- 60
- Forks
- 4
- Last commit
- Apr 2026
Advanced
- Catalog kind
- skill
- Gateway key
cv-multilabel-rare-class-image-oversampling- Source
- github.com/wenmin-wu/ds-skills