MaldiDeepKit 0.1.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. {maldideepkit-0.1.0 → maldideepkit-0.3.0/MaldiDeepKit.egg-info}/PKG-INFO +55 -15
  2. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/MaldiDeepKit.egg-info/SOURCES.txt +20 -0
  3. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/MaldiDeepKit.egg-info/requires.txt +11 -1
  4. {maldideepkit-0.1.0/MaldiDeepKit.egg-info → maldideepkit-0.3.0}/PKG-INFO +55 -15
  5. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/README.md +46 -13
  6. maldideepkit-0.3.0/maldideepkit/__init__.py +73 -0
  7. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/attention/mlp.py +19 -9
  8. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/augment/mixing.py +63 -11
  9. maldideepkit-0.3.0/maldideepkit/base/__init__.py +23 -0
  10. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/base/classifier.py +282 -51
  11. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/base/data.py +135 -18
  12. maldideepkit-0.3.0/maldideepkit/base/dual.py +266 -0
  13. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/cnn/cnn.py +6 -2
  14. maldideepkit-0.3.0/maldideepkit/dual_branch/__init__.py +22 -0
  15. maldideepkit-0.3.0/maldideepkit/dual_branch/_smiles.py +87 -0
  16. maldideepkit-0.3.0/maldideepkit/dual_branch/classifier.py +347 -0
  17. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/resnet/resnet.py +9 -4
  18. maldideepkit-0.3.0/maldideepkit/semisupervised/__init__.py +15 -0
  19. maldideepkit-0.3.0/maldideepkit/semisupervised/self_training.py +289 -0
  20. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/transformer/transformer.py +6 -2
  21. maldideepkit-0.3.0/maldideepkit/uncertainty/__init__.py +34 -0
  22. maldideepkit-0.3.0/maldideepkit/uncertainty/_base.py +85 -0
  23. maldideepkit-0.3.0/maldideepkit/uncertainty/_result.py +102 -0
  24. maldideepkit-0.3.0/maldideepkit/uncertainty/conformal.py +207 -0
  25. maldideepkit-0.3.0/maldideepkit/uncertainty/laplace.py +248 -0
  26. maldideepkit-0.3.0/maldideepkit/uncertainty/mc_dropout.py +178 -0
  27. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/utils/calibration.py +34 -4
  28. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/utils/loss.py +80 -0
  29. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/utils/lr_finder.py +2 -0
  30. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/utils/reproducibility.py +2 -2
  31. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/utils/training.py +86 -15
  32. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/pyproject.toml +3 -0
  33. maldideepkit-0.3.0/requirements-all.txt +2 -0
  34. maldideepkit-0.3.0/requirements-rdkit.txt +1 -0
  35. maldideepkit-0.3.0/requirements-uncertainty.txt +1 -0
  36. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/requirements.txt +1 -1
  37. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_base.py +5 -5
  38. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_bin_scaling.py +2 -2
  39. maldideepkit-0.3.0/tests/test_dual_branch.py +534 -0
  40. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_maldiset_integration.py +1 -1
  41. maldideepkit-0.3.0/tests/test_sample_weight.py +277 -0
  42. maldideepkit-0.3.0/tests/test_self_training.py +281 -0
  43. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_sklearn_compat.py +1 -1
  44. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_transformer.py +1 -1
  45. maldideepkit-0.3.0/tests/test_uncertainty.py +307 -0
  46. maldideepkit-0.3.0/tests/test_warm_start.py +181 -0
  47. maldideepkit-0.1.0/maldideepkit/__init__.py +0 -54
  48. maldideepkit-0.1.0/maldideepkit/base/__init__.py +0 -15
  49. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/LICENSE +0 -0
  50. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/MaldiDeepKit.egg-info/dependency_links.txt +0 -0
  51. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/MaldiDeepKit.egg-info/top_level.txt +0 -0
  52. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/_bin_scaling.py +0 -0
  53. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/_blocks.py +0 -0
  54. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/attention/__init__.py +0 -0
  55. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/augment/__init__.py +0 -0
  56. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/augment/spectra.py +0 -0
  57. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/blocks.py +0 -0
  58. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/cnn/__init__.py +0 -0
  59. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/py.typed +0 -0
  60. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/resnet/__init__.py +0 -0
  61. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/transformer/__init__.py +0 -0
  62. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/utils/__init__.py +0 -0
  63. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/utils/ensemble.py +0 -0
  64. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/maldideepkit/utils/sam.py +0 -0
  65. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/requirements-dev.txt +0 -0
  66. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/requirements-docs.txt +0 -0
  67. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/setup.cfg +0 -0
  68. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_augment.py +0 -0
  69. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_blocks.py +0 -0
  70. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_calibration.py +0 -0
  71. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_cnn.py +0 -0
  72. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_ensemble.py +0 -0
  73. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_loss.py +0 -0
  74. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_lr_finder.py +0 -0
  75. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_mlp.py +0 -0
  76. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_resnet.py +0 -0
  77. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_sam.py +0 -0
  78. {maldideepkit-0.1.0 → maldideepkit-0.3.0}/tests/test_warping.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MaldiDeepKit
3
- Version: 0.1.0
3
+ Version: 0.3.0
4
4
  Summary: A catalog of sklearn-compatible deep learning classifiers for MALDI-TOF binned spectra
5
5
  Author-email: Ettore Rocchi <ettore.rocchi3@unibo.it>
6
6
  License-Expression: MIT
@@ -30,7 +30,7 @@ Requires-Dist: scikit-learn>=1.3.0
30
30
  Requires-Dist: matplotlib>=3.4.0
31
31
  Requires-Dist: torch>=2.0.0
32
32
  Requires-Dist: einops>=0.7.0
33
- Requires-Dist: maldiamrkit>=0.12.0
33
+ Requires-Dist: maldiamrkit>=0.19.0
34
34
  Provides-Extra: dev
35
35
  Requires-Dist: pytest>=7.0.0; extra == "dev"
36
36
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
@@ -45,6 +45,13 @@ Requires-Dist: sphinx-design>=0.6.0; extra == "docs"
45
45
  Requires-Dist: nbsphinx>=0.9.0; extra == "docs"
46
46
  Requires-Dist: ipykernel>=6.0.0; extra == "docs"
47
47
  Requires-Dist: ipywidgets>=8.0.0; extra == "docs"
48
+ Provides-Extra: uncertainty
49
+ Requires-Dist: laplace-torch<1.0,>=0.2; extra == "uncertainty"
50
+ Provides-Extra: rdkit
51
+ Requires-Dist: rdkit>=2026.3.1; extra == "rdkit"
52
+ Provides-Extra: all
53
+ Requires-Dist: rdkit>=2026.3.1; extra == "all"
54
+ Requires-Dist: laplace-torch<1.0,>=0.2; extra == "all"
48
55
  Dynamic: license-file
49
56
 
50
57
  # MaldiDeepKit
@@ -77,7 +84,7 @@ Dynamic: license-file
77
84
  <a href="#license">License</a>
78
85
  </p>
79
86
 
80
- MaldiDeepKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit): where MaldiAMRKit handles preprocessing, alignment and AMR-aware evaluation, and MaldiBatchKit harmonises multi-centre spectra, MaldiDeepKit focuses on the *classification* step, providing four PyTorch architectures wrapped in a unified scikit-learn estimator API with defaults calibrated for 6000-bin MALDI-TOF input.
87
+ MaldiDeepKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit): where MaldiAMRKit handles preprocessing, alignment and AMR-aware evaluation, and MaldiBatchKit harmonises multi-centre spectra, MaldiDeepKit focuses on the *classification* step, providing four PyTorch backbone architectures (MLP, 1-D CNN, 1-D ResNet, and 1-D Vision Transformer) plus a dual-branch classifier for spectrum + side-feature inputs and a self-training meta-classifier for semi-supervised data, all wrapped in a unified scikit-learn estimator API with defaults calibrated for 6000-bin MALDI-TOF input.
81
88
 
82
89
  ## Installation
83
90
 
@@ -85,7 +92,31 @@ MaldiDeepKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKi
85
92
  pip install maldideepkit
86
93
  ```
87
94
 
88
- `maldiamrkit` is a core dependency and is installed automatically - MaldiDeepKit duck-types on the `MaldiSet` data model and reuses `maldiamrkit.alignment.Warping` for leak-safe spectral warping.
95
+ `maldiamrkit` is a core dependency and is installed automatically (MaldiDeepKit duck-types on the `MaldiSet` data model and reuses `maldiamrkit.alignment.Warping` for leak-safe spectral warping).
96
+
97
+ To enable the Laplace-approximation estimator in `maldideepkit.uncertainty`, install the optional `uncertainty` extra (pulls in [`laplace-torch`](https://github.com/aleximmer/Laplace)):
98
+
99
+ ```bash
100
+ pip install "maldideepkit[uncertainty]"
101
+ ```
102
+
103
+ Monte Carlo Dropout and split conformal prediction work without any extra.
104
+
105
+ The `smiles_to_fingerprint` helper used in `MaldiDualBranchClassifier` workflows requires RDKit, available via the `rdkit` extra:
106
+
107
+ ```bash
108
+ pip install "maldideepkit[rdkit]"
109
+ ```
110
+
111
+ ### Install the full MaldiSuite
112
+
113
+ To install MaldiDeepKit together with [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit) at compatible versions, install the [`maldisuite`](https://pypi.org/project/maldisuite/) meta-package:
114
+
115
+ ```bash
116
+ pip install maldisuite
117
+ ```
118
+
119
+ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSuite/>.
89
120
 
90
121
  ### Development Installation
91
122
 
@@ -108,10 +139,11 @@ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for coding conventions, testing, and PR
108
139
  - `MaldiTransformerClassifier` - 1-D Vision Transformer with global self-attention, pre-norm, LayerScale, and stochastic depth.
109
140
  - **MALDI-TOF defaults**: kernel sizes, depths, patch widths, and warmup / cosine-annealing schedules are tuned for 6000-bin spectra in the 2000-20000 Da range.
110
141
  - **Auto-scaling for non-default layouts**: every classifier ships a `from_spectrum(bin_width, input_dim, **overrides)` factory that rescales conv kernels and patches when the user trims the m/z range or picks a different bin width. See the [Spectrum scaling guide](https://maldideepkit.readthedocs.io/en/latest/spectrum_scaling.html).
111
- - **Training recipes**: AdamW-on-`weight_decay` dispatch, gradient clipping, linear warmup + cosine annealing, focal loss, label smoothing, mixed precision (AMP), Stochastic Weight Averaging, Sharpness-Aware Minimization, post-hoc threshold tuning, and temperature scaling - all exposed as classifier kwargs.
142
+ - **Training recipes**: AdamW-on-`weight_decay` dispatch, gradient clipping, linear warmup + cosine annealing, focal loss, label smoothing, mixed precision (AMP), Stochastic Weight Averaging, Sharpness-Aware Minimization, post-hoc threshold tuning, and temperature scaling (all exposed as classifier kwargs).
112
143
  - **Leak-safe spectral warping**: pass any sklearn-style transformer ([`maldiamrkit.alignment.Warping`](https://github.com/EttoreRocchi/MaldiAMRKit)) via `warping=`; it is fitted on the training fold only and applied to both splits during training and to new spectra at `predict` time, *before* per-feature standardization.
113
144
  - **MaldiSet integration**: pass a `maldiamrkit.MaldiSet` directly to `fit` / `predict`; MaldiDeepKit duck-types on the DataFrame-like `.X` attribute, so MaldiSuite's data model flows end-to-end.
114
145
  - **Persistence**: `save()` writes a state-dict `.pt` plus a hyperparameter `.json` (and a sibling `.warper.pkl` if a warper was fitted); `load()` fails fast on class or `input_dim` mismatches.
146
+ - **Uncertainty quantification**: `maldideepkit.uncertainty` subpackage ships three drop-in estimators sharing a single `predict_with_uncertainty` interface. `MCDropoutEstimator` (Monte Carlo Dropout with epistemic / aleatoric decomposition), `LaplaceEstimator` (last-layer or full-network Laplace via the optional `laplace-torch` dependency), and `ConformalPredictor` (split conformal prediction with the LAC non-conformity score).
115
147
  - **CPU-friendly**: every classifier runs on CPU, which is what the project's CI tests against; CUDA speeds up the models' training significantly.
116
148
 
117
149
  ## Documentation
@@ -143,7 +175,7 @@ acc = clf.score(X, y)
143
175
  weights = clf.get_attention_weights(X[:10]) # (10, hidden_dim)
144
176
  ```
145
177
 
146
- ### Inside an Sklearn Pipeline
178
+ ### Inside a scikit-learn `Pipeline`
147
179
 
148
180
  ```python
149
181
  from sklearn.model_selection import StratifiedKFold, cross_val_score
@@ -215,8 +247,15 @@ For more examples covering training recipes, calibration, attention inspection,
215
247
  | `MaldiCNNClassifier` | 1-D Conv1D + BatchNorm + ReLU + MaxPool blocks | Local pattern learning from binned spectra |
216
248
  | `MaldiResNetClassifier` | 1-D ResNet-18-style residual blocks | Deeper convolutional backbone |
217
249
  | `MaldiTransformerClassifier` | 1-D Vision Transformer (LayerScale, stochastic depth) | Long-range peak combinations via global self-attention |
250
+ | `MaldiDualBranchClassifier` | Spectrum branch + per-row side-feature branch + fused head | Multi-modal: condition on antibiotic fingerprint, instrument ID, patient feature, ... |
251
+
252
+ All five inherit from `BaseSpectralClassifier` (or its dual-input subclass `BaseDualSpectralClassifier`) and share the same hyperparameter surface for optimisation, device placement, early stopping, calibration, and persistence.
218
253
 
219
- All four inherit from `BaseSpectralClassifier` and share the same hyperparameter surface for optimisation, device placement, early stopping, calibration, and persistence.
254
+ ### Semi-supervised wrapper
255
+
256
+ | Class | Purpose |
257
+ |---|---|
258
+ | `MaldiSelfTrainingClassifier` | Iterative pseudo-labeling on a labeled seed plus an unlabeled pool (rows marked `-1` by default). Wraps any classifier (defaults to `MaldiMLPClassifier`); follows the `sklearn.semi_supervised.SelfTrainingClassifier` API. |
220
259
 
221
260
  ### Shared Training Knobs
222
261
 
@@ -226,7 +265,7 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
226
265
  | Gradient clipping | `grad_clip_norm` | `clip_grad_norm_` before every step. Default on (`1.0`) for the deep models. |
227
266
  | Warmup + cosine annealing | `warmup_epochs` | Replaces plateau scheduler. Default `5` (deep models), `0` (MLP/CNN). |
228
267
  | Stochastic depth (Transformer) | `drop_path_rate` | Linearly ramped across blocks. Default `0.1`. |
229
- | LayerScale (Transformer) | `layerscale_init` | Per-channel residual scaling initialised near zero - crucial on small cohorts. |
268
+ | LayerScale (Transformer) | `layerscale_init` | Per-channel residual scaling initialised near zero (crucial on small cohorts). |
230
269
  | Focal loss | `loss="focal"` + `focal_gamma` | For imbalanced binary problems. |
231
270
  | Label smoothing | `label_smoothing` | Passed to both cross-entropy and focal paths. |
232
271
  | Stochastic Weight Averaging | `swa_start_epoch` | `AveragedModel` replaces best-val at end of fit. |
@@ -234,6 +273,8 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
234
273
  | Temperature scaling | `calibrate_temperature` | One-parameter LBFGS calibration on val logits. |
235
274
  | Sharpness-Aware Minimization | `use_sam` + `sam_rho` | Two-pass training, ~2× compute. |
236
275
  | Spectral warping | `warping` | Any `Warping`-like sklearn transformer; fitted on train only, applied before standardization. |
276
+ | Per-sample weighting | `sample_weight` (`fit`) | sklearn-style weighted-mean loss; composes with `class_weight` and flows into early stopping, threshold tuning, and temperature scaling. |
277
+ | Warm-start / resume | `warm_start` (`fit`) | Reuse the existing fitted module as the training start point (continual / federated / fine-tuning). |
237
278
 
238
279
  ### Utilities
239
280
 
@@ -241,7 +282,7 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
241
282
 
242
283
  - **`find_lr(clf, X, y)`** - learning-rate finder.
243
284
  - **`tune_threshold` / `fit_temperature`** - post-hoc calibrators usable standalone.
244
- - **`FocalLoss`, `SAMOptimizer`, `DropPath`** - building blocks for custom training loops.
285
+ - **`FocalLoss`, `SAMOptimizer`** - loss / optimizer building blocks for custom training loops. Composable `nn.Module` primitives (`DropPath`, `PatchEmbed1D`, the full backbones) live under `maldideepkit.blocks`.
245
286
 
246
287
  ## Tutorials
247
288
 
@@ -251,16 +292,17 @@ For more detailed examples, see the notebooks:
251
292
  - [Model Comparison](notebooks/02_model_comparison.ipynb) - Train all four classifiers on the same dataset and compare accuracy.
252
293
  - [Attention Interpretation](notebooks/03_attention_interpretation.ipynb) - Visualise the sigmoid-gated attention learned by `MaldiMLPClassifier`.
253
294
  - [Full Pipeline](notebooks/04_full_pipeline.ipynb) - End-to-end template: MaldiAMRKit preprocessing + MaldiDeepKit classification.
295
+ - [Uncertainty Quantification](notebooks/05_uncertainty.ipynb) - MC Dropout, split conformal prediction, and Laplace approximation on a fitted classifier; selective prediction curves.
254
296
 
255
297
  ## MaldiSuite Ecosystem
256
298
 
257
- MaldiDeepKit is the third package of the MaldiSuite ecosystem:
299
+ MaldiDeepKit is the deep-learning package of the **MaldiSuite** ecosystem:
258
300
 
259
301
  - **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - preprocessing, alignment, peak detection, differential analysis, and classical-ML evaluation for MALDI-TOF AMR workflows.
260
302
  - **[MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)** - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
261
303
  - **MaldiDeepKit** (this package) - sklearn-compatible deep learning classifiers.
262
304
 
263
- The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline.
305
+ The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline. Install the full suite with `pip install maldisuite`. Landing page: [MaldiSuite](<https://ettorerocchi.github.io/MaldiSuite/>).
264
306
 
265
307
  ## Requirements
266
308
 
@@ -272,11 +314,9 @@ Pull requests, bug reports, and feature ideas are welcome. See the [Contributing
272
314
 
273
315
  ## Citing
274
316
 
275
- If you use MaldiDeepKit, please cite this repository until the companion paper is available.
276
-
277
- Related publications from the MaldiSuite ecosystem:
317
+ If you use MaldiDeepKit in academic work please cite:
278
318
 
279
- > Rocchi, E., Nicitra, E., Calvo, M. et al. *Combining mass spectrometry and machine learning models for predicting Klebsiella pneumoniae antimicrobial resistance: a multicenter experience from clinical isolates in Italy*. **BMC Microbiol** (2026). [doi:10.1186/s12866-025-04657-2](https://link.springer.com/article/10.1186/s12866-025-04657-2)
319
+ > _Citation will be available soon._
280
320
 
281
321
  See the [full publications list](https://maldideepkit.readthedocs.io/en/latest/papers.html) for more papers using the MaldiSuite.
282
322
 
@@ -1,8 +1,11 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
+ requirements-all.txt
4
5
  requirements-dev.txt
5
6
  requirements-docs.txt
7
+ requirements-rdkit.txt
8
+ requirements-uncertainty.txt
6
9
  requirements.txt
7
10
  MaldiDeepKit.egg-info/PKG-INFO
8
11
  MaldiDeepKit.egg-info/SOURCES.txt
@@ -22,12 +25,24 @@ maldideepkit/augment/spectra.py
22
25
  maldideepkit/base/__init__.py
23
26
  maldideepkit/base/classifier.py
24
27
  maldideepkit/base/data.py
28
+ maldideepkit/base/dual.py
25
29
  maldideepkit/cnn/__init__.py
26
30
  maldideepkit/cnn/cnn.py
31
+ maldideepkit/dual_branch/__init__.py
32
+ maldideepkit/dual_branch/_smiles.py
33
+ maldideepkit/dual_branch/classifier.py
27
34
  maldideepkit/resnet/__init__.py
28
35
  maldideepkit/resnet/resnet.py
36
+ maldideepkit/semisupervised/__init__.py
37
+ maldideepkit/semisupervised/self_training.py
29
38
  maldideepkit/transformer/__init__.py
30
39
  maldideepkit/transformer/transformer.py
40
+ maldideepkit/uncertainty/__init__.py
41
+ maldideepkit/uncertainty/_base.py
42
+ maldideepkit/uncertainty/_result.py
43
+ maldideepkit/uncertainty/conformal.py
44
+ maldideepkit/uncertainty/laplace.py
45
+ maldideepkit/uncertainty/mc_dropout.py
31
46
  maldideepkit/utils/__init__.py
32
47
  maldideepkit/utils/calibration.py
33
48
  maldideepkit/utils/ensemble.py
@@ -42,6 +57,7 @@ tests/test_bin_scaling.py
42
57
  tests/test_blocks.py
43
58
  tests/test_calibration.py
44
59
  tests/test_cnn.py
60
+ tests/test_dual_branch.py
45
61
  tests/test_ensemble.py
46
62
  tests/test_loss.py
47
63
  tests/test_lr_finder.py
@@ -49,6 +65,10 @@ tests/test_maldiset_integration.py
49
65
  tests/test_mlp.py
50
66
  tests/test_resnet.py
51
67
  tests/test_sam.py
68
+ tests/test_sample_weight.py
69
+ tests/test_self_training.py
52
70
  tests/test_sklearn_compat.py
53
71
  tests/test_transformer.py
72
+ tests/test_uncertainty.py
73
+ tests/test_warm_start.py
54
74
  tests/test_warping.py
@@ -5,7 +5,11 @@ scikit-learn>=1.3.0
5
5
  matplotlib>=3.4.0
6
6
  torch>=2.0.0
7
7
  einops>=0.7.0
8
- maldiamrkit>=0.12.0
8
+ maldiamrkit>=0.19.0
9
+
10
+ [all]
11
+ rdkit>=2026.3.1
12
+ laplace-torch<1.0,>=0.2
9
13
 
10
14
  [dev]
11
15
  pytest>=7.0.0
@@ -22,3 +26,9 @@ sphinx-design>=0.6.0
22
26
  nbsphinx>=0.9.0
23
27
  ipykernel>=6.0.0
24
28
  ipywidgets>=8.0.0
29
+
30
+ [rdkit]
31
+ rdkit>=2026.3.1
32
+
33
+ [uncertainty]
34
+ laplace-torch<1.0,>=0.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MaldiDeepKit
3
- Version: 0.1.0
3
+ Version: 0.3.0
4
4
  Summary: A catalog of sklearn-compatible deep learning classifiers for MALDI-TOF binned spectra
5
5
  Author-email: Ettore Rocchi <ettore.rocchi3@unibo.it>
6
6
  License-Expression: MIT
@@ -30,7 +30,7 @@ Requires-Dist: scikit-learn>=1.3.0
30
30
  Requires-Dist: matplotlib>=3.4.0
31
31
  Requires-Dist: torch>=2.0.0
32
32
  Requires-Dist: einops>=0.7.0
33
- Requires-Dist: maldiamrkit>=0.12.0
33
+ Requires-Dist: maldiamrkit>=0.19.0
34
34
  Provides-Extra: dev
35
35
  Requires-Dist: pytest>=7.0.0; extra == "dev"
36
36
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
@@ -45,6 +45,13 @@ Requires-Dist: sphinx-design>=0.6.0; extra == "docs"
45
45
  Requires-Dist: nbsphinx>=0.9.0; extra == "docs"
46
46
  Requires-Dist: ipykernel>=6.0.0; extra == "docs"
47
47
  Requires-Dist: ipywidgets>=8.0.0; extra == "docs"
48
+ Provides-Extra: uncertainty
49
+ Requires-Dist: laplace-torch<1.0,>=0.2; extra == "uncertainty"
50
+ Provides-Extra: rdkit
51
+ Requires-Dist: rdkit>=2026.3.1; extra == "rdkit"
52
+ Provides-Extra: all
53
+ Requires-Dist: rdkit>=2026.3.1; extra == "all"
54
+ Requires-Dist: laplace-torch<1.0,>=0.2; extra == "all"
48
55
  Dynamic: license-file
49
56
 
50
57
  # MaldiDeepKit
@@ -77,7 +84,7 @@ Dynamic: license-file
77
84
  <a href="#license">License</a>
78
85
  </p>
79
86
 
80
- MaldiDeepKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit): where MaldiAMRKit handles preprocessing, alignment and AMR-aware evaluation, and MaldiBatchKit harmonises multi-centre spectra, MaldiDeepKit focuses on the *classification* step, providing four PyTorch architectures wrapped in a unified scikit-learn estimator API with defaults calibrated for 6000-bin MALDI-TOF input.
87
+ MaldiDeepKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit): where MaldiAMRKit handles preprocessing, alignment and AMR-aware evaluation, and MaldiBatchKit harmonises multi-centre spectra, MaldiDeepKit focuses on the *classification* step, providing four PyTorch backbone architectures (MLP, 1-D CNN, 1-D ResNet, and 1-D Vision Transformer) plus a dual-branch classifier for spectrum + side-feature inputs and a self-training meta-classifier for semi-supervised data, all wrapped in a unified scikit-learn estimator API with defaults calibrated for 6000-bin MALDI-TOF input.
81
88
 
82
89
  ## Installation
83
90
 
@@ -85,7 +92,31 @@ MaldiDeepKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKi
85
92
  pip install maldideepkit
86
93
  ```
87
94
 
88
- `maldiamrkit` is a core dependency and is installed automatically - MaldiDeepKit duck-types on the `MaldiSet` data model and reuses `maldiamrkit.alignment.Warping` for leak-safe spectral warping.
95
+ `maldiamrkit` is a core dependency and is installed automatically (MaldiDeepKit duck-types on the `MaldiSet` data model and reuses `maldiamrkit.alignment.Warping` for leak-safe spectral warping).
96
+
97
+ To enable the Laplace-approximation estimator in `maldideepkit.uncertainty`, install the optional `uncertainty` extra (pulls in [`laplace-torch`](https://github.com/aleximmer/Laplace)):
98
+
99
+ ```bash
100
+ pip install "maldideepkit[uncertainty]"
101
+ ```
102
+
103
+ Monte Carlo Dropout and split conformal prediction work without any extra.
104
+
105
+ The `smiles_to_fingerprint` helper used in `MaldiDualBranchClassifier` workflows requires RDKit, available via the `rdkit` extra:
106
+
107
+ ```bash
108
+ pip install "maldideepkit[rdkit]"
109
+ ```
110
+
111
+ ### Install the full MaldiSuite
112
+
113
+ To install MaldiDeepKit together with [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit) at compatible versions, install the [`maldisuite`](https://pypi.org/project/maldisuite/) meta-package:
114
+
115
+ ```bash
116
+ pip install maldisuite
117
+ ```
118
+
119
+ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSuite/>.
89
120
 
90
121
  ### Development Installation
91
122
 
@@ -108,10 +139,11 @@ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for coding conventions, testing, and PR
108
139
  - `MaldiTransformerClassifier` - 1-D Vision Transformer with global self-attention, pre-norm, LayerScale, and stochastic depth.
109
140
  - **MALDI-TOF defaults**: kernel sizes, depths, patch widths, and warmup / cosine-annealing schedules are tuned for 6000-bin spectra in the 2000-20000 Da range.
110
141
  - **Auto-scaling for non-default layouts**: every classifier ships a `from_spectrum(bin_width, input_dim, **overrides)` factory that rescales conv kernels and patches when the user trims the m/z range or picks a different bin width. See the [Spectrum scaling guide](https://maldideepkit.readthedocs.io/en/latest/spectrum_scaling.html).
111
- - **Training recipes**: AdamW-on-`weight_decay` dispatch, gradient clipping, linear warmup + cosine annealing, focal loss, label smoothing, mixed precision (AMP), Stochastic Weight Averaging, Sharpness-Aware Minimization, post-hoc threshold tuning, and temperature scaling - all exposed as classifier kwargs.
142
+ - **Training recipes**: AdamW-on-`weight_decay` dispatch, gradient clipping, linear warmup + cosine annealing, focal loss, label smoothing, mixed precision (AMP), Stochastic Weight Averaging, Sharpness-Aware Minimization, post-hoc threshold tuning, and temperature scaling (all exposed as classifier kwargs).
112
143
  - **Leak-safe spectral warping**: pass any sklearn-style transformer ([`maldiamrkit.alignment.Warping`](https://github.com/EttoreRocchi/MaldiAMRKit)) via `warping=`; it is fitted on the training fold only and applied to both splits during training and to new spectra at `predict` time, *before* per-feature standardization.
113
144
  - **MaldiSet integration**: pass a `maldiamrkit.MaldiSet` directly to `fit` / `predict`; MaldiDeepKit duck-types on the DataFrame-like `.X` attribute, so MaldiSuite's data model flows end-to-end.
114
145
  - **Persistence**: `save()` writes a state-dict `.pt` plus a hyperparameter `.json` (and a sibling `.warper.pkl` if a warper was fitted); `load()` fails fast on class or `input_dim` mismatches.
146
+ - **Uncertainty quantification**: `maldideepkit.uncertainty` subpackage ships three drop-in estimators sharing a single `predict_with_uncertainty` interface. `MCDropoutEstimator` (Monte Carlo Dropout with epistemic / aleatoric decomposition), `LaplaceEstimator` (last-layer or full-network Laplace via the optional `laplace-torch` dependency), and `ConformalPredictor` (split conformal prediction with the LAC non-conformity score).
115
147
  - **CPU-friendly**: every classifier runs on CPU, which is what the project's CI tests against; CUDA speeds up the models' training significantly.
116
148
 
117
149
  ## Documentation
@@ -143,7 +175,7 @@ acc = clf.score(X, y)
143
175
  weights = clf.get_attention_weights(X[:10]) # (10, hidden_dim)
144
176
  ```
145
177
 
146
- ### Inside an Sklearn Pipeline
178
+ ### Inside a scikit-learn `Pipeline`
147
179
 
148
180
  ```python
149
181
  from sklearn.model_selection import StratifiedKFold, cross_val_score
@@ -215,8 +247,15 @@ For more examples covering training recipes, calibration, attention inspection,
215
247
  | `MaldiCNNClassifier` | 1-D Conv1D + BatchNorm + ReLU + MaxPool blocks | Local pattern learning from binned spectra |
216
248
  | `MaldiResNetClassifier` | 1-D ResNet-18-style residual blocks | Deeper convolutional backbone |
217
249
  | `MaldiTransformerClassifier` | 1-D Vision Transformer (LayerScale, stochastic depth) | Long-range peak combinations via global self-attention |
250
+ | `MaldiDualBranchClassifier` | Spectrum branch + per-row side-feature branch + fused head | Multi-modal: condition on antibiotic fingerprint, instrument ID, patient feature, ... |
251
+
252
+ All five inherit from `BaseSpectralClassifier` (or its dual-input subclass `BaseDualSpectralClassifier`) and share the same hyperparameter surface for optimisation, device placement, early stopping, calibration, and persistence.
218
253
 
219
- All four inherit from `BaseSpectralClassifier` and share the same hyperparameter surface for optimisation, device placement, early stopping, calibration, and persistence.
254
+ ### Semi-supervised wrapper
255
+
256
+ | Class | Purpose |
257
+ |---|---|
258
+ | `MaldiSelfTrainingClassifier` | Iterative pseudo-labeling on a labeled seed plus an unlabeled pool (rows marked `-1` by default). Wraps any classifier (defaults to `MaldiMLPClassifier`); follows the `sklearn.semi_supervised.SelfTrainingClassifier` API. |
220
259
 
221
260
  ### Shared Training Knobs
222
261
 
@@ -226,7 +265,7 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
226
265
  | Gradient clipping | `grad_clip_norm` | `clip_grad_norm_` before every step. Default on (`1.0`) for the deep models. |
227
266
  | Warmup + cosine annealing | `warmup_epochs` | Replaces plateau scheduler. Default `5` (deep models), `0` (MLP/CNN). |
228
267
  | Stochastic depth (Transformer) | `drop_path_rate` | Linearly ramped across blocks. Default `0.1`. |
229
- | LayerScale (Transformer) | `layerscale_init` | Per-channel residual scaling initialised near zero - crucial on small cohorts. |
268
+ | LayerScale (Transformer) | `layerscale_init` | Per-channel residual scaling initialised near zero (crucial on small cohorts). |
230
269
  | Focal loss | `loss="focal"` + `focal_gamma` | For imbalanced binary problems. |
231
270
  | Label smoothing | `label_smoothing` | Passed to both cross-entropy and focal paths. |
232
271
  | Stochastic Weight Averaging | `swa_start_epoch` | `AveragedModel` replaces best-val at end of fit. |
@@ -234,6 +273,8 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
234
273
  | Temperature scaling | `calibrate_temperature` | One-parameter LBFGS calibration on val logits. |
235
274
  | Sharpness-Aware Minimization | `use_sam` + `sam_rho` | Two-pass training, ~2× compute. |
236
275
  | Spectral warping | `warping` | Any `Warping`-like sklearn transformer; fitted on train only, applied before standardization. |
276
+ | Per-sample weighting | `sample_weight` (`fit`) | sklearn-style weighted-mean loss; composes with `class_weight` and flows into early stopping, threshold tuning, and temperature scaling. |
277
+ | Warm-start / resume | `warm_start` (`fit`) | Reuse the existing fitted module as the training start point (continual / federated / fine-tuning). |
237
278
 
238
279
  ### Utilities
239
280
 
@@ -241,7 +282,7 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
241
282
 
242
283
  - **`find_lr(clf, X, y)`** - learning-rate finder.
243
284
  - **`tune_threshold` / `fit_temperature`** - post-hoc calibrators usable standalone.
244
- - **`FocalLoss`, `SAMOptimizer`, `DropPath`** - building blocks for custom training loops.
285
+ - **`FocalLoss`, `SAMOptimizer`** - loss / optimizer building blocks for custom training loops. Composable `nn.Module` primitives (`DropPath`, `PatchEmbed1D`, the full backbones) live under `maldideepkit.blocks`.
245
286
 
246
287
  ## Tutorials
247
288
 
@@ -251,16 +292,17 @@ For more detailed examples, see the notebooks:
251
292
  - [Model Comparison](notebooks/02_model_comparison.ipynb) - Train all four classifiers on the same dataset and compare accuracy.
252
293
  - [Attention Interpretation](notebooks/03_attention_interpretation.ipynb) - Visualise the sigmoid-gated attention learned by `MaldiMLPClassifier`.
253
294
  - [Full Pipeline](notebooks/04_full_pipeline.ipynb) - End-to-end template: MaldiAMRKit preprocessing + MaldiDeepKit classification.
295
+ - [Uncertainty Quantification](notebooks/05_uncertainty.ipynb) - MC Dropout, split conformal prediction, and Laplace approximation on a fitted classifier; selective prediction curves.
254
296
 
255
297
  ## MaldiSuite Ecosystem
256
298
 
257
- MaldiDeepKit is the third package of the MaldiSuite ecosystem:
299
+ MaldiDeepKit is the deep-learning package of the **MaldiSuite** ecosystem:
258
300
 
259
301
  - **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - preprocessing, alignment, peak detection, differential analysis, and classical-ML evaluation for MALDI-TOF AMR workflows.
260
302
  - **[MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)** - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
261
303
  - **MaldiDeepKit** (this package) - sklearn-compatible deep learning classifiers.
262
304
 
263
- The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline.
305
+ The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline. Install the full suite with `pip install maldisuite`. Landing page: [MaldiSuite](<https://ettorerocchi.github.io/MaldiSuite/>).
264
306
 
265
307
  ## Requirements
266
308
 
@@ -272,11 +314,9 @@ Pull requests, bug reports, and feature ideas are welcome. See the [Contributing
272
314
 
273
315
  ## Citing
274
316
 
275
- If you use MaldiDeepKit, please cite this repository until the companion paper is available.
276
-
277
- Related publications from the MaldiSuite ecosystem:
317
+ If you use MaldiDeepKit in academic work please cite:
278
318
 
279
- > Rocchi, E., Nicitra, E., Calvo, M. et al. *Combining mass spectrometry and machine learning models for predicting Klebsiella pneumoniae antimicrobial resistance: a multicenter experience from clinical isolates in Italy*. **BMC Microbiol** (2026). [doi:10.1186/s12866-025-04657-2](https://link.springer.com/article/10.1186/s12866-025-04657-2)
319
+ > _Citation will be available soon._
280
320
 
281
321
  See the [full publications list](https://maldideepkit.readthedocs.io/en/latest/papers.html) for more papers using the MaldiSuite.
282
322
 
@@ -28,7 +28,7 @@
28
28
  <a href="#license">License</a>
29
29
  </p>
30
30
 
31
- MaldiDeepKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit): where MaldiAMRKit handles preprocessing, alignment and AMR-aware evaluation, and MaldiBatchKit harmonises multi-centre spectra, MaldiDeepKit focuses on the *classification* step, providing four PyTorch architectures wrapped in a unified scikit-learn estimator API with defaults calibrated for 6000-bin MALDI-TOF input.
31
+ MaldiDeepKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit): where MaldiAMRKit handles preprocessing, alignment and AMR-aware evaluation, and MaldiBatchKit harmonises multi-centre spectra, MaldiDeepKit focuses on the *classification* step, providing four PyTorch backbone architectures (MLP, 1-D CNN, 1-D ResNet, and 1-D Vision Transformer) plus a dual-branch classifier for spectrum + side-feature inputs and a self-training meta-classifier for semi-supervised data, all wrapped in a unified scikit-learn estimator API with defaults calibrated for 6000-bin MALDI-TOF input.
32
32
 
33
33
  ## Installation
34
34
 
@@ -36,7 +36,31 @@ MaldiDeepKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKi
36
36
  pip install maldideepkit
37
37
  ```
38
38
 
39
- `maldiamrkit` is a core dependency and is installed automatically - MaldiDeepKit duck-types on the `MaldiSet` data model and reuses `maldiamrkit.alignment.Warping` for leak-safe spectral warping.
39
+ `maldiamrkit` is a core dependency and is installed automatically (MaldiDeepKit duck-types on the `MaldiSet` data model and reuses `maldiamrkit.alignment.Warping` for leak-safe spectral warping).
40
+
41
+ To enable the Laplace-approximation estimator in `maldideepkit.uncertainty`, install the optional `uncertainty` extra (pulls in [`laplace-torch`](https://github.com/aleximmer/Laplace)):
42
+
43
+ ```bash
44
+ pip install "maldideepkit[uncertainty]"
45
+ ```
46
+
47
+ Monte Carlo Dropout and split conformal prediction work without any extra.
48
+
49
+ The `smiles_to_fingerprint` helper used in `MaldiDualBranchClassifier` workflows requires RDKit, available via the `rdkit` extra:
50
+
51
+ ```bash
52
+ pip install "maldideepkit[rdkit]"
53
+ ```
54
+
55
+ ### Install the full MaldiSuite
56
+
57
+ To install MaldiDeepKit together with [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit) at compatible versions, install the [`maldisuite`](https://pypi.org/project/maldisuite/) meta-package:
58
+
59
+ ```bash
60
+ pip install maldisuite
61
+ ```
62
+
63
+ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSuite/>.
40
64
 
41
65
  ### Development Installation
42
66
 
@@ -59,10 +83,11 @@ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for coding conventions, testing, and PR
59
83
  - `MaldiTransformerClassifier` - 1-D Vision Transformer with global self-attention, pre-norm, LayerScale, and stochastic depth.
60
84
  - **MALDI-TOF defaults**: kernel sizes, depths, patch widths, and warmup / cosine-annealing schedules are tuned for 6000-bin spectra in the 2000-20000 Da range.
61
85
  - **Auto-scaling for non-default layouts**: every classifier ships a `from_spectrum(bin_width, input_dim, **overrides)` factory that rescales conv kernels and patches when the user trims the m/z range or picks a different bin width. See the [Spectrum scaling guide](https://maldideepkit.readthedocs.io/en/latest/spectrum_scaling.html).
62
- - **Training recipes**: AdamW-on-`weight_decay` dispatch, gradient clipping, linear warmup + cosine annealing, focal loss, label smoothing, mixed precision (AMP), Stochastic Weight Averaging, Sharpness-Aware Minimization, post-hoc threshold tuning, and temperature scaling - all exposed as classifier kwargs.
86
+ - **Training recipes**: AdamW-on-`weight_decay` dispatch, gradient clipping, linear warmup + cosine annealing, focal loss, label smoothing, mixed precision (AMP), Stochastic Weight Averaging, Sharpness-Aware Minimization, post-hoc threshold tuning, and temperature scaling (all exposed as classifier kwargs).
63
87
  - **Leak-safe spectral warping**: pass any sklearn-style transformer ([`maldiamrkit.alignment.Warping`](https://github.com/EttoreRocchi/MaldiAMRKit)) via `warping=`; it is fitted on the training fold only and applied to both splits during training and to new spectra at `predict` time, *before* per-feature standardization.
64
88
  - **MaldiSet integration**: pass a `maldiamrkit.MaldiSet` directly to `fit` / `predict`; MaldiDeepKit duck-types on the DataFrame-like `.X` attribute, so MaldiSuite's data model flows end-to-end.
65
89
  - **Persistence**: `save()` writes a state-dict `.pt` plus a hyperparameter `.json` (and a sibling `.warper.pkl` if a warper was fitted); `load()` fails fast on class or `input_dim` mismatches.
90
+ - **Uncertainty quantification**: `maldideepkit.uncertainty` subpackage ships three drop-in estimators sharing a single `predict_with_uncertainty` interface. `MCDropoutEstimator` (Monte Carlo Dropout with epistemic / aleatoric decomposition), `LaplaceEstimator` (last-layer or full-network Laplace via the optional `laplace-torch` dependency), and `ConformalPredictor` (split conformal prediction with the LAC non-conformity score).
66
91
  - **CPU-friendly**: every classifier runs on CPU, which is what the project's CI tests against; CUDA speeds up the models' training significantly.
67
92
 
68
93
  ## Documentation
@@ -94,7 +119,7 @@ acc = clf.score(X, y)
94
119
  weights = clf.get_attention_weights(X[:10]) # (10, hidden_dim)
95
120
  ```
96
121
 
97
- ### Inside an Sklearn Pipeline
122
+ ### Inside a scikit-learn `Pipeline`
98
123
 
99
124
  ```python
100
125
  from sklearn.model_selection import StratifiedKFold, cross_val_score
@@ -166,8 +191,15 @@ For more examples covering training recipes, calibration, attention inspection,
166
191
  | `MaldiCNNClassifier` | 1-D Conv1D + BatchNorm + ReLU + MaxPool blocks | Local pattern learning from binned spectra |
167
192
  | `MaldiResNetClassifier` | 1-D ResNet-18-style residual blocks | Deeper convolutional backbone |
168
193
  | `MaldiTransformerClassifier` | 1-D Vision Transformer (LayerScale, stochastic depth) | Long-range peak combinations via global self-attention |
194
+ | `MaldiDualBranchClassifier` | Spectrum branch + per-row side-feature branch + fused head | Multi-modal: condition on antibiotic fingerprint, instrument ID, patient feature, ... |
195
+
196
+ All five inherit from `BaseSpectralClassifier` (or its dual-input subclass `BaseDualSpectralClassifier`) and share the same hyperparameter surface for optimisation, device placement, early stopping, calibration, and persistence.
169
197
 
170
- All four inherit from `BaseSpectralClassifier` and share the same hyperparameter surface for optimisation, device placement, early stopping, calibration, and persistence.
198
+ ### Semi-supervised wrapper
199
+
200
+ | Class | Purpose |
201
+ |---|---|
202
+ | `MaldiSelfTrainingClassifier` | Iterative pseudo-labeling on a labeled seed plus an unlabeled pool (rows marked `-1` by default). Wraps any classifier (defaults to `MaldiMLPClassifier`); follows the `sklearn.semi_supervised.SelfTrainingClassifier` API. |
171
203
 
172
204
  ### Shared Training Knobs
173
205
 
@@ -177,7 +209,7 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
177
209
  | Gradient clipping | `grad_clip_norm` | `clip_grad_norm_` before every step. Default on (`1.0`) for the deep models. |
178
210
  | Warmup + cosine annealing | `warmup_epochs` | Replaces plateau scheduler. Default `5` (deep models), `0` (MLP/CNN). |
179
211
  | Stochastic depth (Transformer) | `drop_path_rate` | Linearly ramped across blocks. Default `0.1`. |
180
- | LayerScale (Transformer) | `layerscale_init` | Per-channel residual scaling initialised near zero - crucial on small cohorts. |
212
+ | LayerScale (Transformer) | `layerscale_init` | Per-channel residual scaling initialised near zero (crucial on small cohorts). |
181
213
  | Focal loss | `loss="focal"` + `focal_gamma` | For imbalanced binary problems. |
182
214
  | Label smoothing | `label_smoothing` | Passed to both cross-entropy and focal paths. |
183
215
  | Stochastic Weight Averaging | `swa_start_epoch` | `AveragedModel` replaces best-val at end of fit. |
@@ -185,6 +217,8 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
185
217
  | Temperature scaling | `calibrate_temperature` | One-parameter LBFGS calibration on val logits. |
186
218
  | Sharpness-Aware Minimization | `use_sam` + `sam_rho` | Two-pass training, ~2× compute. |
187
219
  | Spectral warping | `warping` | Any `Warping`-like sklearn transformer; fitted on train only, applied before standardization. |
220
+ | Per-sample weighting | `sample_weight` (`fit`) | sklearn-style weighted-mean loss; composes with `class_weight` and flows into early stopping, threshold tuning, and temperature scaling. |
221
+ | Warm-start / resume | `warm_start` (`fit`) | Reuse the existing fitted module as the training start point (continual / federated / fine-tuning). |
188
222
 
189
223
  ### Utilities
190
224
 
@@ -192,7 +226,7 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
192
226
 
193
227
  - **`find_lr(clf, X, y)`** - learning-rate finder.
194
228
  - **`tune_threshold` / `fit_temperature`** - post-hoc calibrators usable standalone.
195
- - **`FocalLoss`, `SAMOptimizer`, `DropPath`** - building blocks for custom training loops.
229
+ - **`FocalLoss`, `SAMOptimizer`** - loss / optimizer building blocks for custom training loops. Composable `nn.Module` primitives (`DropPath`, `PatchEmbed1D`, the full backbones) live under `maldideepkit.blocks`.
196
230
 
197
231
  ## Tutorials
198
232
 
@@ -202,16 +236,17 @@ For more detailed examples, see the notebooks:
202
236
  - [Model Comparison](notebooks/02_model_comparison.ipynb) - Train all four classifiers on the same dataset and compare accuracy.
203
237
  - [Attention Interpretation](notebooks/03_attention_interpretation.ipynb) - Visualise the sigmoid-gated attention learned by `MaldiMLPClassifier`.
204
238
  - [Full Pipeline](notebooks/04_full_pipeline.ipynb) - End-to-end template: MaldiAMRKit preprocessing + MaldiDeepKit classification.
239
+ - [Uncertainty Quantification](notebooks/05_uncertainty.ipynb) - MC Dropout, split conformal prediction, and Laplace approximation on a fitted classifier; selective prediction curves.
205
240
 
206
241
  ## MaldiSuite Ecosystem
207
242
 
208
- MaldiDeepKit is the third package of the MaldiSuite ecosystem:
243
+ MaldiDeepKit is the deep-learning package of the **MaldiSuite** ecosystem:
209
244
 
210
245
  - **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - preprocessing, alignment, peak detection, differential analysis, and classical-ML evaluation for MALDI-TOF AMR workflows.
211
246
  - **[MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)** - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
212
247
  - **MaldiDeepKit** (this package) - sklearn-compatible deep learning classifiers.
213
248
 
214
- The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline.
249
+ The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline. Install the full suite with `pip install maldisuite`. Landing page: [MaldiSuite](<https://ettorerocchi.github.io/MaldiSuite/>).
215
250
 
216
251
  ## Requirements
217
252
 
@@ -223,11 +258,9 @@ Pull requests, bug reports, and feature ideas are welcome. See the [Contributing
223
258
 
224
259
  ## Citing
225
260
 
226
- If you use MaldiDeepKit, please cite this repository until the companion paper is available.
227
-
228
- Related publications from the MaldiSuite ecosystem:
261
+ If you use MaldiDeepKit in academic work please cite:
229
262
 
230
- > Rocchi, E., Nicitra, E., Calvo, M. et al. *Combining mass spectrometry and machine learning models for predicting Klebsiella pneumoniae antimicrobial resistance: a multicenter experience from clinical isolates in Italy*. **BMC Microbiol** (2026). [doi:10.1186/s12866-025-04657-2](https://link.springer.com/article/10.1186/s12866-025-04657-2)
263
+ > _Citation will be available soon._
231
264
 
232
265
  See the [full publications list](https://maldideepkit.readthedocs.io/en/latest/papers.html) for more papers using the MaldiSuite.
233
266
 
@@ -0,0 +1,73 @@
1
+ """MaldiDeepKit - deep learning classifiers for MALDI-TOF binned spectra.
2
+
3
+ Provides a catalog of PyTorch architectures (MLP, CNN, ResNet,
4
+ Transformer) adapted to 1-D binned MALDI-TOF spectra, each wrapped in
5
+ a scikit-learn compatible estimator with sensible defaults.
6
+
7
+ Subpackages
8
+ -----------
9
+ - ``maldideepkit.base`` - ``BaseSpectralClassifier``,
10
+ ``BaseDualSpectralClassifier``, ``SpectralDataset``, ``make_loaders``.
11
+ - ``maldideepkit.attention`` - ``MaldiMLPClassifier`` (MLP with optional
12
+ sigmoid-gated attention).
13
+ - ``maldideepkit.cnn`` - ``MaldiCNNClassifier`` (Conv1D blocks).
14
+ - ``maldideepkit.resnet`` - ``MaldiResNetClassifier`` (1-D ResNet-18).
15
+ - ``maldideepkit.transformer`` - ``MaldiTransformerClassifier`` (1-D ViT).
16
+ - ``maldideepkit.dual_branch`` - ``MaldiDualBranchClassifier``
17
+ (spectrum + per-row side feature) and ``smiles_to_fingerprint``
18
+ helper (requires the ``[rdkit]`` extra).
19
+ - ``maldideepkit.semisupervised`` - ``MaldiSelfTrainingClassifier``
20
+ (iterative pseudo-labeling meta-classifier).
21
+ - ``maldideepkit.blocks`` - re-exports of every backbone and
22
+ composable primitive for users embedding components into their own
23
+ networks.
24
+ - ``maldideepkit.augment`` - per-batch training-time augmentations
25
+ (``SpectrumAugment``, MixUp / CutMix helpers).
26
+ - ``maldideepkit.utils`` - reproducibility helpers and shared
27
+ training primitives.
28
+ - ``maldideepkit.uncertainty`` - uncertainty-quantification
29
+ estimators (MC Dropout, Laplace approximation, split conformal
30
+ prediction) for fitted classifiers.
31
+
32
+ Examples
33
+ --------
34
+ >>> import numpy as np
35
+ >>> from maldideepkit import MaldiMLPClassifier
36
+ >>> rng = np.random.default_rng(0)
37
+ >>> X = rng.standard_normal((64, 256)).astype("float32")
38
+ >>> y = rng.integers(0, 2, size=64)
39
+ >>> clf = MaldiMLPClassifier(epochs=2, batch_size=16, random_state=0)
40
+ >>> _ = clf.fit(X, y)
41
+ >>> proba = clf.predict_proba(X)
42
+ """
43
+
44
+ from . import uncertainty
45
+ from .attention.mlp import MaldiMLPClassifier
46
+ from .base.classifier import BaseSpectralClassifier
47
+ from .base.data import SpectralDataset, make_loaders
48
+ from .base.dual import BaseDualSpectralClassifier
49
+ from .cnn.cnn import MaldiCNNClassifier
50
+ from .dual_branch import MaldiDualBranchClassifier, smiles_to_fingerprint
51
+ from .resnet.resnet import MaldiResNetClassifier
52
+ from .semisupervised import MaldiSelfTrainingClassifier
53
+ from .transformer.transformer import MaldiTransformerClassifier
54
+
55
+ __version__ = "0.3.0"
56
+ __author__ = "Ettore Rocchi"
57
+
58
+ __all__ = [
59
+ "BaseDualSpectralClassifier",
60
+ "BaseSpectralClassifier",
61
+ "MaldiCNNClassifier",
62
+ "MaldiDualBranchClassifier",
63
+ "MaldiMLPClassifier",
64
+ "MaldiResNetClassifier",
65
+ "MaldiSelfTrainingClassifier",
66
+ "MaldiTransformerClassifier",
67
+ "SpectralDataset",
68
+ "__author__",
69
+ "__version__",
70
+ "make_loaders",
71
+ "smiles_to_fingerprint",
72
+ "uncertainty",
73
+ ]