🔥 HMC-Torch
A Modular Platform for Hierarchical Multi-Label Classification with R-Matrix Constraints
HMC-Torch is a modular, extensible platform for Hierarchical Multi-Label Classification (HMC) that integrates the R-matrix constraint — originally proposed by Giunchiglia & Lukasiewicz (2018, NeurIPS) — as a reusable, first-class architectural component.
📄 Paper: HMC-Torch: A Modular Platform for Hierarchical Multi-Label Classification with R-Matrix Constraints (Bruno Sette, UFSCar, 2026)
✨ Key Features
- 🔌 Modular pipeline:
DatasetAdapter → FeatureEncoder → HierarchicalHead → Calibrator → Reconciler - 🧱 R-Matrix as infrastructure: reusable ancestor-closure constraint for training + inference
- 🌳 Explicit hierarchy modeling: Tree (FunCat) and DAG (Gene Ontology) with type-specific reconciliation
- 📊 25+ datasets across 5 domains: scientific text, genomics, email, microscopy, medical imaging
- 🧬 Multi-modal: tabular, text (transformers), protein sequences, images
- ⚡ GPU-accelerated: 14× training speedup
- 📦 Plugin system: register your own datasets without modifying the package
- 🔁 Reproducible: experiment manifests with git SHA, seeds, and dependency versions
📦 Installation
pip install hmc-torch
For optional features:
pip install "hmc-torch[vision]" # Image models (timm)
pip install "hmc-torch[protein]" # Protein models (fair-esm)
pip install "hmc-torch[expression]" # Expression autoencoders
From source
git clone https://github.com/Sette/hmc-torch.git
cd hmc-torch
uv sync --all-groups
export PYTHONPATH=src
🚀 Quick Start
Python API
import hmc
# Train a global classifier with R-matrix constraint
results = hmc.train("wos", method="globalE2E", device="cuda", epochs=5)
# Train a tabular baseline
results = hmc.train("cellcycle_FUN", method="tabular_mlp", device="cuda", epochs=100)
CLI
# Frozen embeddings baseline
python -m hmc.main --dataset_name wos --method global --device cuda \
--dataset_path ./data --output_path ./output
# Fine-tuned transformer (SOTA)
python -m hmc.main --dataset_name arxiv --method globalE2E --device cuda \
--dataset_path ./data --epochs 50 --batch_size 32 --output_path ./output
# Tabular baseline
python -m hmc.main --dataset_name cellcycle_FUN --method tabular_mlp --device cuda \
--dataset_path ./data --output_path ./output
🗂️ Supported Datasets
Built-in datasets (25+)
| Domain | Datasets | Modality | Hierarchy | Classes |
|---|---|---|---|---|
| Scientific Text | ArXiv, WOS | Text (SPECTER2) | Tree | 141–156 |
| Genomics (FunCat) | cellcycle, church, derisi, eisen, expr, gasch1, gasch2, pheno, seq, spo | Tabular | Tree | ~499 |
| Genomics (GO) | cellcycle, derisi, eisen, expr, gasch1, gasch2, pheno, seq, spo | Tabular | DAG | 3,570–4,130 |
| Enron | Tabular | Tree | 56 | |
| Microscopy | Diatoms | Tabular | Tree | 398 |
| Medical Imaging | ImCLEF07a, ImCLEF07d | Tabular | Tree | 46–96 |
| Multi-label Text | AAPD, RCV1, EURLex | Text | Tree | 54–3,993 |
Register your own dataset
from hmc.data import DatasetRegistry, Split, DatasetBundle, Hierarchy
# Option 1: Programmatic registration
class MyDataset:
def get_datasets(self):
train = Split(features=X_train, labels=Y_train)
test = Split(features=X_test, labels=Y_test)
return train, None, test
@property
def hierarchy(self):
return TreeHierarchy.from_edges([("root", "child1"), ...])
DatasetRegistry.register("my_data", lambda **kw: MyDataset(**kw))
# Option 2: Entry points (for packages)
# In your setup.cfg or pyproject.toml:
# [project.entry-points."hmc_torch.datasets"]
# my_data = "my_package:create_manager"
🧠 Methods
| Method | Description |
|---|---|
global |
Frozen embeddings + MLP + R-matrix constraint |
globalE2E |
End-to-end fine-tuned transformer + MLP + R-matrix |
globalSOTA |
E2E + GCN label-graph encoder (HiAGM-style) |
local |
Frozen embeddings, one MLP per hierarchy level |
localE2E |
Fine-tuned transformer + per-level MLPs |
tabular_gbdt |
Gradient Boosting One-vs-Rest baseline |
tabular_mlp |
Residual MLP baseline for tabular data |
📊 Results
Text Benchmarks (Micro-F1)
| Method | ArXiv | WOS |
|---|---|---|
| HiAGM (Zhou+, ACL'20) | 0.5950 | 0.8604 |
| HTC-infoMAX | — | 0.8720 |
| HMC-Torch (frozen) | 0.7295 | 0.7515 |
| HMC-Torch (E2E) | — | 0.8743 |
🏆 New SOTA on ArXiv (+13.5 pts over HiAGM) and WOS (+0.2 pts over HTC-infoMAX)
FunCat Genomic Benchmarks (AUPRC)
| Dataset | HMCN-F | C-HMCNN | HMC-Torch (GBDT) | HMC-Torch (MLP) |
|---|---|---|---|---|
| cellcycle_FUN | 0.235 | 0.248 | 0.253 | 0.255 |
| seq_FUN | 0.291 | 0.299 | 0.306 | 0.307 |
| spo_FUN | 0.228 | 0.228 | 0.229 | 0.229 |
🏆 Beats HMCN-F on seq_FUN (0.307 vs 0.291)
Gene Ontology (Block-Diagonal R-Matrix)
AUPRC improves on all 9 GO datasets (avg +0.0055) with zero hierarchy violations, using $O(N)$ memory instead of $O(N^2)$ (>1,400× reduction).
GPU Speedup
| Configuration | CPU | GPU | Speedup |
|---|---|---|---|
| global (FunCat avg) | 16.7s | 1.2s | 14× |
| tabular_mlp (FunCat avg) | 5.3s | 2.0s | 2.7× |
🧬 Architecture
DatasetAdapter → FeatureEncoder → HierarchicalHead → Calibrator → Reconciler
↓ ↓ ↓ ↓ ↓
DatasetBundle fit/transform GlobalSigmoidHead Platt Scaling Bottom-up
+ Hierarchy (tabular, text, LocalLevelHead Temperature max-prop
+ Splits protein, vision) TreePathHead
R-Matrix Constraint
The ancestor closure matrix $R_{ij} = 1$ iff class $i$ is an ancestor of $j$. Applied at:
- Training: $\mathcal{L}_{\text{hier}} = \max(0, p_j - p_i + \gamma)$ for all ancestor pairs
- Inference: $p_i^{\text{rec}} = \max(p_i, \max_{j: \text{child}(i,j)} p_j^{\text{rec}})$
Block-Diagonal R-Matrix (Sparse)
For large DAGs (4,000+ classes), the dense $R$ matrix requires $>65$ MB. Our sparse approximation uses graph traversal ($O(N+E)$ memory) with zero hierarchy violations.
📁 Project Structure
src/hmc/
├── data/ # Data contracts (DatasetBundle, Split, Hierarchy)
├── datasets/ # Built-in dataset implementations
│ ├── arxiv/ # ArXiv (JSONL + SPECTER2)
│ ├── wos/ # WOS (Web of Science)
│ ├── gofun/ # FunCat + GO (ARFF tabular)
│ ├── aapd/ # Arxiv Academic Paper Dataset
│ ├── rcv1/ # Reuters Corpus Volume 1
│ └── eurlex/ # EUR-Lex documents
├── features/ # Feature encoders (text, tabular, vision, protein)
├── models/ # HMC model components
│ ├── global_classifier/ # Global heads + R-matrix
│ ├── local_classifier/ # Per-level local heads
│ ├── hierarchical/ # Sparse R-matrix, label GCN
│ └── tabular/ # GBDT + MLP baselines
├── pipeline/ # Training pipelines
└── utils/ # Metrics, manifests, caching
🤝 Contributing
Contributions welcome! Areas we'd love help with:
- New dataset adapters
- Additional feature encoders (genomics, graphs)
- New hierarchical heads and reconciliation strategies
- Documentation and tutorials
git clone https://github.com/Sette/hmc-torch.git
cd hmc-torch
uv sync --all-groups
make test
make lint
📚 Citation
@article{sette2026hmctorch,
title = {HMC-Torch: A Modular Platform for Hierarchical Multi-Label
Classification with R-Matrix Constraints},
author = {Bruno Sette},
journal = {arXiv preprint},
year = {2026},
}
📄 License
MIT © Bruno Sette
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hmc_torch-0.0.9.tar.gz.
File metadata
- Download URL: hmc_torch-0.0.9.tar.gz
- Upload date:
- Size: 141.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47c25c524ece044932ed5377546019ccbb5f99e97f74b33684adea6759b3b29d
|
|
| MD5 |
edee2065f29548a3674dce790815f862
|
|
| BLAKE2b-256 |
0f16b0c08a12fb4ebc5a98315b6d953b43260b2232c26774112d495a2326c032
|
Provenance
The following attestation bundles were made for hmc_torch-0.0.9.tar.gz:
Publisher:
python-publish.yml on Sette/hmc-torch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hmc_torch-0.0.9.tar.gz -
Subject digest:
47c25c524ece044932ed5377546019ccbb5f99e97f74b33684adea6759b3b29d - Sigstore transparency entry: 2395839948
- Sigstore integration time:
-
Permalink:
Sette/hmc-torch@149a6c84a71c25e4bf3abc5dba089caf9db75786 -
Branch / Tag:
refs/tags/0.0.9 - Owner: https://github.com/Sette
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@149a6c84a71c25e4bf3abc5dba089caf9db75786 -
Trigger Event:
release
-
Statement type:
File details
Details for the file hmc_torch-0.0.9-py3-none-any.whl.
File metadata
- Download URL: hmc_torch-0.0.9-py3-none-any.whl
- Upload date:
- Size: 195.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98dd9b0d1e3360fdde51fe2f390d197d86dd5cc05ec71f24d8f6a570f1c4139a
|
|
| MD5 |
19e0877770d36aa970af2917d626eb3e
|
|
| BLAKE2b-256 |
b442c99a8a8e639f0690e74ac5aaec7e22bbe2ec266ee3721f674778f2f3b490
|
Provenance
The following attestation bundles were made for hmc_torch-0.0.9-py3-none-any.whl:
Publisher:
python-publish.yml on Sette/hmc-torch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hmc_torch-0.0.9-py3-none-any.whl -
Subject digest:
98dd9b0d1e3360fdde51fe2f390d197d86dd5cc05ec71f24d8f6a570f1c4139a - Sigstore transparency entry: 2395840082
- Sigstore integration time:
-
Permalink:
Sette/hmc-torch@149a6c84a71c25e4bf3abc5dba089caf9db75786 -
Branch / Tag:
refs/tags/0.0.9 - Owner: https://github.com/Sette
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@149a6c84a71c25e4bf3abc5dba089caf9db75786 -
Trigger Event:
release
-
Statement type: