Ports GMNet (from https://github.com/pglez84/gmnet) into quapy/method/_gmnet.py,
mirroring how HistNetQ was ported: dropping that repo's quantificationlib-backed
bag generators in favor of QuaPy's own sampling protocols, and adding geotorch
(now a 'neural' extra dependency) to keep the Gaussian layers' covariance matrices
positive-definite during training.
- GMNet represents each bag instance by its likelihood under one or more learned
mixtures of Gaussians ("GM branches"), mean-pools these representations over the
bag, and predicts prevalence from the result. Supports multiple stacked GM
branches with an optional CKA-regularization term encouraging their latent
representations to be dissimilar.
- Fixes two aspects of the original architecture that assumed a fixed, training-time
bag_size baked into the network (a reshape step, and forward-hook-based activation
capture for CKA): both are now computed from the actual input shape/plain
attributes at forward time, so the model also works on predict()'s arbitrary-sized
test samples, not just same-size bags.
- Factors the bag-based training loop shared by HistNetQ and GMNet (bag generation,
fit/fit_from_samples, early stopping, LR scheduling, checkpointing, predict) out of
_histnet.py into a new BagTrainedQuantifier base class in
quapy/method/_neural_bags.py; HistNetQ's public API and behavior are unchanged.
- Aliased in meta.py (torch/geotorch-optional, mirroring HistNetQ/QuaNet) and
registered in META_METHODS.
- Adds test_gmnet covering single-branch and multi-branch+CKA (via
fit_from_samples/mix_bags) variants.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ports the "hard" histogram variant of HistNetQ (from
https://github.com/pglez84/histnetq) into quapy/method/_histnet.py, dropping
that repo's quantificationlib-backed bag generators in favor of QuaPy's own
sampling protocols (UPP by default). Implemented as a BaseQuantifier,
alongside QuaNet, since it trains end-to-end on samples of known prevalence
rather than following the classify-then-aggregate pattern.
- HistNetQ.fit(X, y): resamples training/validation bags from a
LabelledCollection via a configurable protocol (UPP by default; fresh
random bags each training epoch, a fixed reproducible sequence for
validation).
- HistNetQ.fit_from_samples(protocol, val_protocol=None, mix_bags=False):
trains directly from a protocol that already yields bags (e.g. LeQua's
SamplesFromDir), with an optional mixer to synthesize extra
intermediate-prevalence bags from the given ones.
- Aliased in meta.py (torch-optional, mirroring the existing QuaNet guard)
and registered in META_METHODS.
- Adds test_histnetq covering both entry points on binary and multiclass
synthetic data.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>