adding histnet

This commit is contained in:
Alejandro Moreo Fernandez 2026-08-20 11:40:55 +02:00
parent 24719ed0af
commit d5610c7821
6 changed files with 23 additions and 11 deletions

View File

@ -17,7 +17,7 @@ quapy.method.aggregative module
:undoc-members:
:show-inheritance:
.. automodule:: quapy.method._neural
.. automodule:: quapy.method._quanet
:members:
:undoc-members:
:show-inheritance:

View File

@ -17,7 +17,7 @@ try:
except ImportError:
plot = None
__version__ = '0.2.1.post1'
__version__ = '0.2.2'
def _default_cls():

View File

@ -1,17 +1,21 @@
"""
HistNetQ implementation.
HistNetQ implementation, see the original paper:
Pérez-Mon, O., Moreo, A., Coz, JJ del, & González, P. (2025).
Quantification using permutation-invariant networks based on histograms.
Neural Computing and Applications, 37(5), 3505-3520.
Ported from the reference implementation at https://github.com/pglez84/histnetq (the `HistNet`/
`DLQuantification` classes in that repo), adapted to QuaPy's own protocol-based sample generation
(replacing that repo's custom, `quantificationlib`-backed bag generators) and restricted, for now, to
the "hard" differentiable histogram variant:
the "hard" differentiable histogram variant by:
Yusuf, I., Igwegbe, G., and Azeez, O. "Differentiable Histogram with Hard-Binning."
arXiv preprint arXiv:2012.06311 (2020).
The overall architecture is: feature_extraction -> Sigmoid -> histogram layer -> small MLP -> softmax,
trained by minimizing a quantification loss over samples ("bags") of known prevalence, rather than
over individually labeled instances (in the spirit of QuaNet, see method/_neural.py).
over individually labeled instances (in the spirit of QuaNet, see method/_quanet.py).
"""
import copy
import os
@ -177,10 +181,17 @@ class HistNetQ(BaseQuantifier):
Implementation of `HistNetQ <https://github.com/pglez84/histnetq>`_, a neural network for
quantification that learns a differentiable histogram-based representation of a sample, trained
end-to-end by minimizing a quantification loss over many samples ("bags") of known prevalence.
The method was proposed in `Pérez-Mon, O., Moreo, A., Coz, JJ del, & González, P. (2025).
Quantification using permutation-invariant networks based on histograms.
Neural Computing and Applications, 37(5), 3505-3520.
<https://link.springer.com/article/10.1007/s00521-024-10721-1>`_
HistNetQ does not follow the classify-then-aggregate pattern of :class:`quapy.method.aggregative.
AggregativeQuantifier`; like :class:`quapy.method.meta.QuaNet`, it is trained and evaluated
end-to-end on whole samples rather than on individually labeled instances.
AggregativeQuantifier`. Such classical approach is termed asymmetric, in the sense that quantifiers
learn from labelled instances and perform inference over bags.
Like :class:`quapy.method.meta.QuaNet`, HistNetQ is trained and evaluated
end-to-end on whole samples rather than on individually labeled instances, following a symmetric problem setting
(learning from bags, predicting on bags).
Training data can be provided in two ways:

View File

@ -16,13 +16,13 @@ from quapy.method.base import BaseQuantifier, BinaryQuantifier
from quapy.method.aggregative import CC, ACC, PACC, HDy, EMQ, AggregativeQuantifier, AggregativeSoftQuantifier
try:
from . import _neural
from . import _quanet
except ModuleNotFoundError:
_neural = None
_quanet = None
if _neural:
QuaNet = _neural.QuaNetTrainer
if _quanet:
QuaNet = _quanet.QuaNetTrainer
else:
QuaNet = "QuaNet is not available due to missing torch package"

View File

@ -126,6 +126,7 @@ class TestMethods(unittest.TestCase):
estim_prevalences2 = model2.predict(dataset.test.X)
self.assertTrue(check_prevalence_vector(estim_prevalences2))
def test_composable(self):
try:
from quapy.method.composable import check_compatible_qunfold_version