omniloader.sampling.weights¶
Class-balance helpers for categorical targets.
Two complementary tools, named for what consumes their output, both counting only valid (unmasked) target positions:
class_weights_for_sampler()— one weight per sample for the sampler (SubsampleConfigsample_weights), so an imbalanced dataset is resampled toward a flat class histogram.class_histogram()/class_weights_for_loss()— the exact per-class counts and a(num_classes,)weight vector for a loss (e.g.CrossEntropyLoss(weight=...)). These are data-side statistics: compute once, persist (omniloader class-weights-for-loss), and reuse — the loss/model that consumes them stays in your training code.
Unlike the per-sample sampler weights, the histogram/loss weights count every valid
labelled position (each valid step of a framewise (T,) target, or the scalar of a
vector target), matching what a per-position loss actually sees.
Functions¶
|
Compute per-sample inverse-class-frequency weights for a sampler. |
|
Count valid instances of each class for a categorical target. |
|
Compute per-class weights for a loss from a categorical target. |
Module Contents¶
- omniloader.sampling.weights.class_weights_for_sampler(samples: collections.abc.Iterable[dict[str, torch.Tensor]], target_key: str) list[float][source]¶
Compute per-sample inverse-class-frequency weights for a sampler.
Feed the result to a sampler (e.g.
SubsampleConfigsample_weights) to resample an imbalanced dataset toward a flat class histogram. The loss-side counterpart isclass_weights_for_loss().- Parameters:
samples – An iterable of unified sample dicts (e.g. a source dataset or an
OmniLoader). Iterated once.target_key – A categorical (int) target name; its
<name>_maskis used to skip invalid positions.
- Returns:
A list of per-sample weights (
1 / class_countfor the sample’s class,0when the sample has no valid target), aligned withsamples.
- omniloader.sampling.weights.class_histogram(samples: collections.abc.Iterable[dict[str, torch.Tensor]], target_key: str, num_classes: int | None = None) torch.Tensor[source]¶
Count valid instances of each class for a categorical target.
- Parameters:
samples – An iterable of unified sample dicts (a source dataset or an
OmniLoader). Iterated once.target_key – A categorical (int) target name; its
<name>_maskskips invalid positions.num_classes – Number of classes. When
None, inferred asmax id + 1(so classes with zero instances are only included when given explicitly).
- Returns:
A
(num_classes,)int64tensor of per-class counts.- Raises:
ValueError – If an observed class id is negative or
>= num_classes.
- omniloader.sampling.weights.class_weights_for_loss(samples: collections.abc.Iterable[dict[str, torch.Tensor]], target_key: str, num_classes: int | None = None, scheme: str = 'inverse', beta: float = 0.999) torch.Tensor[source]¶
Compute per-class weights for a loss from a categorical target.
Intended for
CrossEntropyLoss(weight=...)and similar — it reweights the loss instead of resampling the data (the sampler-side counterpart isclass_weights_for_sampler()). Weights are normalised so they average1across classes (the loss keeps its scale). Classes with zero instances get weight0.- Parameters:
samples – An iterable of unified sample dicts. Iterated once.
target_key – A categorical (int) target name.
num_classes – Number of classes (
Noneinfersmax id + 1).scheme –
"inverse"(inverse frequency1 / count) or"effective"(effective number of samples, Cui et al. 2019:(1 - beta) / (1 - beta ** count)).beta – Re-weighting strength for
scheme="effective"(closer to1= stronger balancing).
- Returns:
A
(num_classes,)float32weight tensor.- Raises:
ValueError – If
schemeis not"inverse"or"effective".