TabM-UQ implements uncertainty quantification (UQ) for the TabM model (Gorishniy et al., ICLR 2025). This is an FYP (Final Year Project) addressing the paper's stated future work on UQ and OOD detection.
Key files:
plan.md— Original project plan with timelinedocs/reproducibility_report_small_config.md— Results from Phase 1 (small config)README.md— User-facing documentationrun_all.py— Parallel experiment runner
- Package:
tabm(PyPI, official) - Variants:
- TabM (default): No embeddings, raw features
- TabM† (enhanced): With
LinearReLUEmbeddingsorPiecewiseLinearEmbeddings
- Pilot config (
results_small_config/): n_blocks=1, d_block=128, k=16, NO embeddings (~1.5h, validation) - Canonical config (
results/): n_blocks=3, d_block=512, k=32, NO embeddings — true default TabM (single-model,TabM†out of scope)
uq/metrics.py— Entropy, MI, Varianceuq/calibration.py— ECE, NLL, reliability diagrams
TabM/
├── plan.md # Project plan (8-month timeline)
├── README.md # User documentation
├── requirements.txt # Dependencies
├── AGENTS.md # This file
├── docs/
│ └── reproducibility_report_small_config.md # Phase 1 results
├── data/
│ └── loaders.py # Dataset loading from .npy files
├── models/
│ └── tabm_wrapper.py # TabM training + inference
├── uq/
│ ├── metrics.py # UQ metrics (entropy, MI, variance)
│ └── calibration.py # Calibration metrics + plots
├── experiments/
│ ├── train.py # Single dataset trainer
│ └── evaluate_uq.py # Post-training UQ analysis
├── results/
│ ├── raw/ # JSON results per run
│ ├── models/ # Saved checkpoints
│ ├── predictions/ # Ensemble predictions (.npy)
│ └── figures/ # Reliability diagrams + entropy hists
├── tabm_repo/ # Official TabM repo (data access)
│ ├── data/ # 50 preprocessed datasets
│ └── local/
│ └── tabm-data.tar # HuggingFace tarball
└── run_all.py # Parallel experiment runner
# Phase 1 (small config — CPU fast)
nohup .venv/bin/python run_all.py \
--k 16 --n-blocks 1 --d-block 128 --epochs 100 \
--workers 3 --threads 5 \
> results/full_run.log 2>&1 &
# Phase 2 (canonical — default TabM k32, no embeddings, ~30h)
nohup .venv/bin/python run_all.py \
--k 32 --n-blocks 3 --d-block 512 --epochs 200 \
--workers 3 --threads 5 \
> results/k32_no_embeddings.log 2>&1 &bash check_status.sh
# Or manually:
ls results/raw/*_uq.json | wc -l # Count completed
tail -f results/k32_no_embeddings.log # Watch live log# Just rerun — completed seeds are automatically skipped
nohup .venv/bin/python run_all.py \
--k 16 --n-blocks 1 --d-block 128 --epochs 100 \
--workers 3 --threads 5 \
> results/full_run.log 2>&1 &# Train
.venv/bin/python -m experiments.train phoneme \
--seed 0 --k 16 --n-blocks 1 --d-block 128 --epochs 100
# Evaluate UQ
.venv/bin/python -m experiments.evaluate_uq phoneme --seed 0All from the TabM paper's official 50-dataset suite (HuggingFace: rototoHF/tabm-data):
- adult — binclass, 26K train
- bank-marketing — binclass, 7K train
- california — regression, 13K train
- wine_quality — regression, 4.5K train
- wine — binclass, 1.7K train
- phoneme — binclass, 2.2K train
- churn — binclass, 6.4K train
- MagicTelescope — binclass, 9.3K train
- credit — binclass, 10K train
- MiniBooNE — binclass, 50K train
- Ailerons — regression, 9.6K train
Loading: from data.loaders import load_dataset; X_num, X_cat, Y, info = load_dataset('adult')
# Virtual environment
.venv/bin/python --version # 3.11.15
# Key packages
.venv/bin/pip list | grep -E "torch|tabm|sklearn|numpy"
# CPU threads per worker (set automatically)
export OMP_NUM_THREADS=5
export MKL_NUM_THREADS=5{
"dataset": "phoneme",
"seed": 0,
"task_type": "binclass",
"accuracy": 0.8651,
"ECE": 0.0298,
"NLL": 0.3065,
"uq": {
"predictive_entropy_mean": 0.3295,
"mutual_information_mean": 0.0133
}
}results/figures/{dataset}_seed{seed}_reliability.pngresults/figures/{dataset}_seed{seed}_entropy_hist.png
results/models/{dataset}_seed{seed}.pt(PyTorch state_dict)
-
Embeddings: We currently use TabM without embeddings for speed. To enable
LinearReLUEmbeddings, editmodels/tabm_wrapper.py:from rtdl_num_embeddings import LinearReLUEmbeddings num_embeddings = LinearReLUEmbeddings(n_num_features)
-
Parallel execution:
run_all.pyspawns 3 parallel processes (seeds). Each process gets 5 CPU threads via environment variables. -
Resumability: Experiments check for existing
results/raw/{dataset}_seed{seed}_uq.jsonbefore running. Interrupted runs resume automatically. -
Categorical features: String categories are encoded to integers via
OrdinalEncoderindata/loaders.py. -
Batch size: Auto-scaled based on train set size (256-2048).
- ✅ Phase 1 complete: 11 datasets × 3 seeds with small config (
results_small_config/) - ✅ Phase 2 complete: 11 datasets × 3 seeds with canonical config (
results/k32/no-emb, 33/33) — seedocs/k32_canonical_summary.md - 🔄 Phase 3 in progress: OOD evaluation (synthetic noise,
experiments/ood_evaluate.py) - ⏳ M4-M8 pending (baselines deferred per single-model scope)
torch>=2.0
tabm>=0.0.3
rtdl-num-embeddings>=0.0.12
scikit-learn>=1.3
numpy>=1.24
matplotlib>=3.7
- TabM Paper: https://arxiv.org/abs/2410.24210
- TabM Code: https://github.com/yandex-research/tabm
- Datasets: https://huggingface.co/datasets/rototoHF/tabm-data