MaldiDeepKit 0.1.0__tar.gz → 0.2.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 (65) hide show
  1. {maldideepkit-0.1.0 → maldideepkit-0.2.0/MaldiDeepKit.egg-info}/PKG-INFO +29 -9
  2. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/MaldiDeepKit.egg-info/SOURCES.txt +9 -0
  3. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/MaldiDeepKit.egg-info/requires.txt +3 -0
  4. {maldideepkit-0.1.0/MaldiDeepKit.egg-info → maldideepkit-0.2.0}/PKG-INFO +29 -9
  5. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/README.md +26 -8
  6. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/__init__.py +14 -9
  7. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/attention/mlp.py +13 -9
  8. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/base/__init__.py +4 -3
  9. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/base/classifier.py +28 -2
  10. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/cnn/cnn.py +6 -2
  11. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/resnet/resnet.py +9 -4
  12. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/transformer/transformer.py +6 -2
  13. maldideepkit-0.2.0/maldideepkit/uncertainty/__init__.py +34 -0
  14. maldideepkit-0.2.0/maldideepkit/uncertainty/_base.py +105 -0
  15. maldideepkit-0.2.0/maldideepkit/uncertainty/_result.py +102 -0
  16. maldideepkit-0.2.0/maldideepkit/uncertainty/conformal.py +207 -0
  17. maldideepkit-0.2.0/maldideepkit/uncertainty/laplace.py +248 -0
  18. maldideepkit-0.2.0/maldideepkit/uncertainty/mc_dropout.py +178 -0
  19. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/pyproject.toml +1 -0
  20. maldideepkit-0.2.0/requirements-uncertainty.txt +1 -0
  21. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_bin_scaling.py +1 -1
  22. maldideepkit-0.2.0/tests/test_uncertainty.py +307 -0
  23. maldideepkit-0.2.0/tests/test_warm_start.py +181 -0
  24. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/LICENSE +0 -0
  25. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/MaldiDeepKit.egg-info/dependency_links.txt +0 -0
  26. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/MaldiDeepKit.egg-info/top_level.txt +0 -0
  27. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/_bin_scaling.py +0 -0
  28. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/_blocks.py +0 -0
  29. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/attention/__init__.py +0 -0
  30. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/augment/__init__.py +0 -0
  31. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/augment/mixing.py +0 -0
  32. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/augment/spectra.py +0 -0
  33. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/base/data.py +0 -0
  34. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/blocks.py +0 -0
  35. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/cnn/__init__.py +0 -0
  36. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/py.typed +0 -0
  37. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/resnet/__init__.py +0 -0
  38. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/transformer/__init__.py +0 -0
  39. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/utils/__init__.py +0 -0
  40. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/utils/calibration.py +0 -0
  41. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/utils/ensemble.py +0 -0
  42. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/utils/loss.py +0 -0
  43. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/utils/lr_finder.py +0 -0
  44. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/utils/reproducibility.py +0 -0
  45. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/utils/sam.py +0 -0
  46. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/maldideepkit/utils/training.py +0 -0
  47. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/requirements-dev.txt +0 -0
  48. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/requirements-docs.txt +0 -0
  49. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/requirements.txt +0 -0
  50. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/setup.cfg +0 -0
  51. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_augment.py +0 -0
  52. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_base.py +0 -0
  53. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_blocks.py +0 -0
  54. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_calibration.py +0 -0
  55. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_cnn.py +0 -0
  56. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_ensemble.py +0 -0
  57. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_loss.py +0 -0
  58. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_lr_finder.py +0 -0
  59. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_maldiset_integration.py +0 -0
  60. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_mlp.py +0 -0
  61. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_resnet.py +0 -0
  62. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_sam.py +0 -0
  63. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_sklearn_compat.py +0 -0
  64. {maldideepkit-0.1.0 → maldideepkit-0.2.0}/tests/test_transformer.py +0 -0
  65. {maldideepkit-0.1.0 → maldideepkit-0.2.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.2.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
@@ -45,6 +45,8 @@ 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"
48
50
  Dynamic: license-file
49
51
 
50
52
  # MaldiDeepKit
@@ -87,6 +89,24 @@ pip install maldideepkit
87
89
 
88
90
  `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.
89
91
 
92
+ To enable the Laplace-approximation estimator in `maldideepkit.uncertainty`, install the optional `uncertainty` extra (pulls in [`laplace-torch`](https://github.com/aleximmer/Laplace)):
93
+
94
+ ```bash
95
+ pip install "maldideepkit[uncertainty]"
96
+ ```
97
+
98
+ Monte Carlo Dropout and split conformal prediction work without any extra.
99
+
100
+ ### Install the full MaldiSuite
101
+
102
+ 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:
103
+
104
+ ```bash
105
+ pip install maldisuite
106
+ ```
107
+
108
+ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSuite/>.
109
+
90
110
  ### Development Installation
91
111
 
92
112
  ```bash
@@ -112,6 +132,7 @@ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for coding conventions, testing, and PR
112
132
  - **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
133
  - **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
134
  - **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.
135
+ - **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
136
  - **CPU-friendly**: every classifier runs on CPU, which is what the project's CI tests against; CUDA speeds up the models' training significantly.
116
137
 
117
138
  ## Documentation
@@ -143,7 +164,7 @@ acc = clf.score(X, y)
143
164
  weights = clf.get_attention_weights(X[:10]) # (10, hidden_dim)
144
165
  ```
145
166
 
146
- ### Inside an Sklearn Pipeline
167
+ ### Inside a scikit-learn `Pipeline`
147
168
 
148
169
  ```python
149
170
  from sklearn.model_selection import StratifiedKFold, cross_val_score
@@ -241,7 +262,7 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
241
262
 
242
263
  - **`find_lr(clf, X, y)`** - learning-rate finder.
243
264
  - **`tune_threshold` / `fit_temperature`** - post-hoc calibrators usable standalone.
244
- - **`FocalLoss`, `SAMOptimizer`, `DropPath`** - building blocks for custom training loops.
265
+ - **`FocalLoss`, `SAMOptimizer`** - loss / optimizer building blocks for custom training loops. Composable `nn.Module` primitives (`DropPath`, `PatchEmbed1D`, the full backbones) live under `maldideepkit.blocks`.
245
266
 
246
267
  ## Tutorials
247
268
 
@@ -251,16 +272,17 @@ For more detailed examples, see the notebooks:
251
272
  - [Model Comparison](notebooks/02_model_comparison.ipynb) - Train all four classifiers on the same dataset and compare accuracy.
252
273
  - [Attention Interpretation](notebooks/03_attention_interpretation.ipynb) - Visualise the sigmoid-gated attention learned by `MaldiMLPClassifier`.
253
274
  - [Full Pipeline](notebooks/04_full_pipeline.ipynb) - End-to-end template: MaldiAMRKit preprocessing + MaldiDeepKit classification.
275
+ - [Uncertainty Quantification](notebooks/05_uncertainty.ipynb) - MC Dropout, split conformal prediction, and Laplace approximation on a fitted classifier; selective prediction curves.
254
276
 
255
277
  ## MaldiSuite Ecosystem
256
278
 
257
- MaldiDeepKit is the third package of the MaldiSuite ecosystem:
279
+ MaldiDeepKit is the deep-learning package of the **MaldiSuite** ecosystem:
258
280
 
259
281
  - **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - preprocessing, alignment, peak detection, differential analysis, and classical-ML evaluation for MALDI-TOF AMR workflows.
260
282
  - **[MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)** - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
261
283
  - **MaldiDeepKit** (this package) - sklearn-compatible deep learning classifiers.
262
284
 
263
- The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline.
285
+ 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
286
 
265
287
  ## Requirements
266
288
 
@@ -272,11 +294,9 @@ Pull requests, bug reports, and feature ideas are welcome. See the [Contributing
272
294
 
273
295
  ## Citing
274
296
 
275
- If you use MaldiDeepKit, please cite this repository until the companion paper is available.
276
-
277
- Related publications from the MaldiSuite ecosystem:
297
+ If you use MaldiDeepKit in academic work please cite:
278
298
 
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)
299
+ > _Citation will be available soon._
280
300
 
281
301
  See the [full publications list](https://maldideepkit.readthedocs.io/en/latest/papers.html) for more papers using the MaldiSuite.
282
302
 
@@ -3,6 +3,7 @@ README.md
3
3
  pyproject.toml
4
4
  requirements-dev.txt
5
5
  requirements-docs.txt
6
+ requirements-uncertainty.txt
6
7
  requirements.txt
7
8
  MaldiDeepKit.egg-info/PKG-INFO
8
9
  MaldiDeepKit.egg-info/SOURCES.txt
@@ -28,6 +29,12 @@ maldideepkit/resnet/__init__.py
28
29
  maldideepkit/resnet/resnet.py
29
30
  maldideepkit/transformer/__init__.py
30
31
  maldideepkit/transformer/transformer.py
32
+ maldideepkit/uncertainty/__init__.py
33
+ maldideepkit/uncertainty/_base.py
34
+ maldideepkit/uncertainty/_result.py
35
+ maldideepkit/uncertainty/conformal.py
36
+ maldideepkit/uncertainty/laplace.py
37
+ maldideepkit/uncertainty/mc_dropout.py
31
38
  maldideepkit/utils/__init__.py
32
39
  maldideepkit/utils/calibration.py
33
40
  maldideepkit/utils/ensemble.py
@@ -51,4 +58,6 @@ tests/test_resnet.py
51
58
  tests/test_sam.py
52
59
  tests/test_sklearn_compat.py
53
60
  tests/test_transformer.py
61
+ tests/test_uncertainty.py
62
+ tests/test_warm_start.py
54
63
  tests/test_warping.py
@@ -22,3 +22,6 @@ sphinx-design>=0.6.0
22
22
  nbsphinx>=0.9.0
23
23
  ipykernel>=6.0.0
24
24
  ipywidgets>=8.0.0
25
+
26
+ [uncertainty]
27
+ 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.2.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
@@ -45,6 +45,8 @@ 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"
48
50
  Dynamic: license-file
49
51
 
50
52
  # MaldiDeepKit
@@ -87,6 +89,24 @@ pip install maldideepkit
87
89
 
88
90
  `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.
89
91
 
92
+ To enable the Laplace-approximation estimator in `maldideepkit.uncertainty`, install the optional `uncertainty` extra (pulls in [`laplace-torch`](https://github.com/aleximmer/Laplace)):
93
+
94
+ ```bash
95
+ pip install "maldideepkit[uncertainty]"
96
+ ```
97
+
98
+ Monte Carlo Dropout and split conformal prediction work without any extra.
99
+
100
+ ### Install the full MaldiSuite
101
+
102
+ 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:
103
+
104
+ ```bash
105
+ pip install maldisuite
106
+ ```
107
+
108
+ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSuite/>.
109
+
90
110
  ### Development Installation
91
111
 
92
112
  ```bash
@@ -112,6 +132,7 @@ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for coding conventions, testing, and PR
112
132
  - **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
133
  - **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
134
  - **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.
135
+ - **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
136
  - **CPU-friendly**: every classifier runs on CPU, which is what the project's CI tests against; CUDA speeds up the models' training significantly.
116
137
 
117
138
  ## Documentation
@@ -143,7 +164,7 @@ acc = clf.score(X, y)
143
164
  weights = clf.get_attention_weights(X[:10]) # (10, hidden_dim)
144
165
  ```
145
166
 
146
- ### Inside an Sklearn Pipeline
167
+ ### Inside a scikit-learn `Pipeline`
147
168
 
148
169
  ```python
149
170
  from sklearn.model_selection import StratifiedKFold, cross_val_score
@@ -241,7 +262,7 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
241
262
 
242
263
  - **`find_lr(clf, X, y)`** - learning-rate finder.
243
264
  - **`tune_threshold` / `fit_temperature`** - post-hoc calibrators usable standalone.
244
- - **`FocalLoss`, `SAMOptimizer`, `DropPath`** - building blocks for custom training loops.
265
+ - **`FocalLoss`, `SAMOptimizer`** - loss / optimizer building blocks for custom training loops. Composable `nn.Module` primitives (`DropPath`, `PatchEmbed1D`, the full backbones) live under `maldideepkit.blocks`.
245
266
 
246
267
  ## Tutorials
247
268
 
@@ -251,16 +272,17 @@ For more detailed examples, see the notebooks:
251
272
  - [Model Comparison](notebooks/02_model_comparison.ipynb) - Train all four classifiers on the same dataset and compare accuracy.
252
273
  - [Attention Interpretation](notebooks/03_attention_interpretation.ipynb) - Visualise the sigmoid-gated attention learned by `MaldiMLPClassifier`.
253
274
  - [Full Pipeline](notebooks/04_full_pipeline.ipynb) - End-to-end template: MaldiAMRKit preprocessing + MaldiDeepKit classification.
275
+ - [Uncertainty Quantification](notebooks/05_uncertainty.ipynb) - MC Dropout, split conformal prediction, and Laplace approximation on a fitted classifier; selective prediction curves.
254
276
 
255
277
  ## MaldiSuite Ecosystem
256
278
 
257
- MaldiDeepKit is the third package of the MaldiSuite ecosystem:
279
+ MaldiDeepKit is the deep-learning package of the **MaldiSuite** ecosystem:
258
280
 
259
281
  - **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - preprocessing, alignment, peak detection, differential analysis, and classical-ML evaluation for MALDI-TOF AMR workflows.
260
282
  - **[MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)** - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
261
283
  - **MaldiDeepKit** (this package) - sklearn-compatible deep learning classifiers.
262
284
 
263
- The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline.
285
+ 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
286
 
265
287
  ## Requirements
266
288
 
@@ -272,11 +294,9 @@ Pull requests, bug reports, and feature ideas are welcome. See the [Contributing
272
294
 
273
295
  ## Citing
274
296
 
275
- If you use MaldiDeepKit, please cite this repository until the companion paper is available.
276
-
277
- Related publications from the MaldiSuite ecosystem:
297
+ If you use MaldiDeepKit in academic work please cite:
278
298
 
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)
299
+ > _Citation will be available soon._
280
300
 
281
301
  See the [full publications list](https://maldideepkit.readthedocs.io/en/latest/papers.html) for more papers using the MaldiSuite.
282
302
 
@@ -38,6 +38,24 @@ pip install maldideepkit
38
38
 
39
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
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
+ ### Install the full MaldiSuite
50
+
51
+ 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:
52
+
53
+ ```bash
54
+ pip install maldisuite
55
+ ```
56
+
57
+ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSuite/>.
58
+
41
59
  ### Development Installation
42
60
 
43
61
  ```bash
@@ -63,6 +81,7 @@ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for coding conventions, testing, and PR
63
81
  - **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
82
  - **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
83
  - **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.
84
+ - **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
85
  - **CPU-friendly**: every classifier runs on CPU, which is what the project's CI tests against; CUDA speeds up the models' training significantly.
67
86
 
68
87
  ## Documentation
@@ -94,7 +113,7 @@ acc = clf.score(X, y)
94
113
  weights = clf.get_attention_weights(X[:10]) # (10, hidden_dim)
95
114
  ```
96
115
 
97
- ### Inside an Sklearn Pipeline
116
+ ### Inside a scikit-learn `Pipeline`
98
117
 
99
118
  ```python
100
119
  from sklearn.model_selection import StratifiedKFold, cross_val_score
@@ -192,7 +211,7 @@ All four inherit from `BaseSpectralClassifier` and share the same hyperparameter
192
211
 
193
212
  - **`find_lr(clf, X, y)`** - learning-rate finder.
194
213
  - **`tune_threshold` / `fit_temperature`** - post-hoc calibrators usable standalone.
195
- - **`FocalLoss`, `SAMOptimizer`, `DropPath`** - building blocks for custom training loops.
214
+ - **`FocalLoss`, `SAMOptimizer`** - loss / optimizer building blocks for custom training loops. Composable `nn.Module` primitives (`DropPath`, `PatchEmbed1D`, the full backbones) live under `maldideepkit.blocks`.
196
215
 
197
216
  ## Tutorials
198
217
 
@@ -202,16 +221,17 @@ For more detailed examples, see the notebooks:
202
221
  - [Model Comparison](notebooks/02_model_comparison.ipynb) - Train all four classifiers on the same dataset and compare accuracy.
203
222
  - [Attention Interpretation](notebooks/03_attention_interpretation.ipynb) - Visualise the sigmoid-gated attention learned by `MaldiMLPClassifier`.
204
223
  - [Full Pipeline](notebooks/04_full_pipeline.ipynb) - End-to-end template: MaldiAMRKit preprocessing + MaldiDeepKit classification.
224
+ - [Uncertainty Quantification](notebooks/05_uncertainty.ipynb) - MC Dropout, split conformal prediction, and Laplace approximation on a fitted classifier; selective prediction curves.
205
225
 
206
226
  ## MaldiSuite Ecosystem
207
227
 
208
- MaldiDeepKit is the third package of the MaldiSuite ecosystem:
228
+ MaldiDeepKit is the deep-learning package of the **MaldiSuite** ecosystem:
209
229
 
210
230
  - **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - preprocessing, alignment, peak detection, differential analysis, and classical-ML evaluation for MALDI-TOF AMR workflows.
211
231
  - **[MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)** - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
212
232
  - **MaldiDeepKit** (this package) - sklearn-compatible deep learning classifiers.
213
233
 
214
- The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline.
234
+ 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
235
 
216
236
  ## Requirements
217
237
 
@@ -223,11 +243,9 @@ Pull requests, bug reports, and feature ideas are welcome. See the [Contributing
223
243
 
224
244
  ## Citing
225
245
 
226
- If you use MaldiDeepKit, please cite this repository until the companion paper is available.
227
-
228
- Related publications from the MaldiSuite ecosystem:
246
+ If you use MaldiDeepKit in academic work please cite:
229
247
 
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)
248
+ > _Citation will be available soon._
231
249
 
232
250
  See the [full publications list](https://maldideepkit.readthedocs.io/en/latest/papers.html) for more papers using the MaldiSuite.
233
251
 
@@ -1,4 +1,4 @@
1
- """MaldiDeepKit -- deep learning classifiers for MALDI-TOF binned spectra.
1
+ """MaldiDeepKit - deep learning classifiers for MALDI-TOF binned spectra.
2
2
 
3
3
  Provides a catalog of PyTorch architectures (MLP, CNN, ResNet,
4
4
  Transformer) adapted to 1-D binned MALDI-TOF spectra, each wrapped in
@@ -6,18 +6,21 @@ a scikit-learn compatible estimator with sensible defaults.
6
6
 
7
7
  Subpackages
8
8
  -----------
9
- - ``maldideepkit.base`` -- ``BaseSpectralClassifier``, ``SpectralDataset``,
9
+ - ``maldideepkit.base`` - ``BaseSpectralClassifier``, ``SpectralDataset``,
10
10
  ``make_loaders``.
11
- - ``maldideepkit.attention`` -- ``MaldiMLPClassifier`` (MLP with optional
11
+ - ``maldideepkit.attention`` - ``MaldiMLPClassifier`` (MLP with optional
12
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.blocks`` -- re-exports of every backbone and
13
+ - ``maldideepkit.cnn`` - ``MaldiCNNClassifier`` (Conv1D blocks).
14
+ - ``maldideepkit.resnet`` - ``MaldiResNetClassifier`` (1-D ResNet-18).
15
+ - ``maldideepkit.transformer`` - ``MaldiTransformerClassifier`` (1-D ViT).
16
+ - ``maldideepkit.blocks`` - re-exports of every backbone and
17
17
  composable primitive for users embedding components into their own
18
18
  networks.
19
- - ``maldideepkit.utils`` -- reproducibility helpers and shared
19
+ - ``maldideepkit.utils`` - reproducibility helpers and shared
20
20
  training primitives.
21
+ - ``maldideepkit.uncertainty`` - uncertainty-quantification
22
+ estimators (MC Dropout, Laplace approximation, split conformal
23
+ prediction) for fitted classifiers.
21
24
 
22
25
  Examples
23
26
  --------
@@ -31,6 +34,7 @@ Examples
31
34
  >>> proba = clf.predict_proba(X)
32
35
  """
33
36
 
37
+ from . import uncertainty
34
38
  from .attention.mlp import MaldiMLPClassifier
35
39
  from .base.classifier import BaseSpectralClassifier
36
40
  from .base.data import SpectralDataset, make_loaders
@@ -38,7 +42,7 @@ from .cnn.cnn import MaldiCNNClassifier
38
42
  from .resnet.resnet import MaldiResNetClassifier
39
43
  from .transformer.transformer import MaldiTransformerClassifier
40
44
 
41
- __version__ = "0.1.0"
45
+ __version__ = "0.2.0"
42
46
  __author__ = "Ettore Rocchi"
43
47
 
44
48
  __all__ = [
@@ -51,4 +55,5 @@ __all__ = [
51
55
  "__author__",
52
56
  "__version__",
53
57
  "make_loaders",
58
+ "uncertainty",
54
59
  ]
@@ -121,12 +121,14 @@ class MaldiMLPClassifier(BaseSpectralClassifier):
121
121
  Dropout after the projection and first head layer.
122
122
  dropout_low : float, default=0.2
123
123
  Dropout before the output logits.
124
- **kwargs
125
- Forwarded to :class:`~maldideepkit.base.classifier.BaseSpectralClassifier`:
126
- ``input_dim``, ``n_classes``, ``learning_rate``, ``batch_size``,
127
- ``epochs``, ``early_stopping_patience``, ``val_fraction``,
128
- ``standardize``, ``class_weight``, ``device``, ``random_state``,
129
- ``verbose``.
124
+
125
+ Notes
126
+ -----
127
+ Every parameter accepted by
128
+ :class:`~maldideepkit.base.classifier.BaseSpectralClassifier`
129
+ (e.g. ``learning_rate``, ``batch_size``, ``epochs``, ``warping``,
130
+ ``calibrate_temperature``, ``device``, ``random_state``, ...) is
131
+ forwarded to the base class. See its docstring for the full list.
130
132
 
131
133
  Attributes
132
134
  ----------
@@ -258,12 +260,14 @@ class MaldiMLPClassifier(BaseSpectralClassifier):
258
260
  self.attention_weights_ = None
259
261
  return logits
260
262
 
261
- def fit(self, X: Any, y: Any) -> MaldiMLPClassifier: # type: ignore[override]
263
+ def fit( # type: ignore[override]
264
+ self, X: Any, y: Any, *, warm_start: bool = False
265
+ ) -> MaldiMLPClassifier:
262
266
  """Fit the model and cache attention weights from the final batch.
263
267
 
264
- See :meth:`BaseSpectralClassifier.fit` for shared parameters.
268
+ See :meth:`BaseSpectralClassifier.fit` for shared parameters, including ``warm_start``.
265
269
  """
266
- super().fit(X, y)
270
+ super().fit(X, y, warm_start=warm_start)
267
271
  if self.use_attention:
268
272
  X_np = _to_numpy(X)
269
273
  tail = X_np[: min(len(X_np), 64)]
@@ -1,8 +1,9 @@
1
1
  """Shared primitives for MaldiDeepKit classifiers.
2
2
 
3
- Exposes :class:`BaseSpectralClassifier`, the abstract base for all six
4
- model families in the package, together with the :class:`SpectralDataset`
5
- / :func:`make_loaders` data utilities.
3
+ Exposes :class:`BaseSpectralClassifier`, the abstract base for the four
4
+ classifier families in the package (MLP, CNN, ResNet, Transformer),
5
+ together with the :class:`SpectralDataset` / :func:`make_loaders` data
6
+ utilities.
6
7
  """
7
8
 
8
9
  from .classifier import BaseSpectralClassifier
@@ -399,7 +399,9 @@ class BaseSpectralClassifier(ClassifierMixin, BaseEstimator, metaclass=ABCMeta):
399
399
  y_encoded = np.searchsorted(self.classes_, y_np).astype(np.int64)
400
400
  return X_np, y_encoded
401
401
 
402
- def fit(self, X: Any, y: Any) -> BaseSpectralClassifier:
402
+ def fit(
403
+ self, X: Any, y: Any, *, warm_start: bool = False
404
+ ) -> BaseSpectralClassifier:
403
405
  """Fit the model on ``(X, y)``.
404
406
 
405
407
  Parameters
@@ -410,6 +412,20 @@ class BaseSpectralClassifier(ClassifierMixin, BaseEstimator, metaclass=ABCMeta):
410
412
  y : array-like of shape (n_samples,)
411
413
  Integer or string class labels. Re-encoded to ``0..n_classes-1``
412
414
  internally; original labels are preserved in :attr:`classes_`.
415
+ warm_start : bool, default=False
416
+ When ``True`` and the estimator already has a fitted
417
+ :attr:`model_`, the underlying :class:`torch.nn.Module` is
418
+ reused as the starting point of training instead of being
419
+ rebuilt from scratch via :meth:`_build_model`. This unblocks
420
+ federated learning, continual learning, and fine-tuning
421
+ workflows that need ``fit()`` to *resume* from the current
422
+ weights rather than reinitialise. ``warm_start`` applies only
423
+ to the first training attempt; retries triggered by
424
+ ``retry_on_val_auroc_below`` always rebuild via
425
+ :meth:`_build_model` (the warm-start weights already failed
426
+ once). When ``warm_start=True`` but no prior ``model_``
427
+ exists, falls back silently to a fresh build (sklearn
428
+ convention).
413
429
 
414
430
  Returns
415
431
  -------
@@ -456,7 +472,17 @@ class BaseSpectralClassifier(ClassifierMixin, BaseEstimator, metaclass=ABCMeta):
456
472
  if attempt > 0:
457
473
  seed_everything(base_seed + 1_000_003 * attempt)
458
474
 
459
- model = self._build_model().to(device)
475
+ if (
476
+ warm_start
477
+ and attempt == 0
478
+ and getattr(self, "model_", None) is not None
479
+ ):
480
+ # Resume from the previously-fitted module. Skip
481
+ # _build_model entirely so the federated / continual
482
+ # learning caller's pre-loaded weights are not wiped.
483
+ model = self.model_.to(device)
484
+ else:
485
+ model = self._build_model().to(device)
460
486
 
461
487
  opt_cls = (
462
488
  torch.optim.AdamW if float(self.weight_decay) > 0 else torch.optim.Adam
@@ -150,11 +150,15 @@ class MaldiCNNClassifier(BaseSpectralClassifier):
150
150
  Width of the hidden dense layer.
151
151
  dropout : float, default=0.3
152
152
  Dropout applied inside every block and before the output layer.
153
- **kwargs
154
- Forwarded to :class:`~maldideepkit.base.classifier.BaseSpectralClassifier`.
155
153
 
156
154
  Notes
157
155
  -----
156
+ Every parameter accepted by
157
+ :class:`~maldideepkit.base.classifier.BaseSpectralClassifier`
158
+ (e.g. ``learning_rate``, ``batch_size``, ``epochs``, ``warping``,
159
+ ``calibrate_temperature``, ``device``, ``random_state``, ...) is
160
+ forwarded to the base class. See its docstring for the full list.
161
+
158
162
  The flat dense head scales linearly with ``input_dim``; prefer
159
163
  :class:`~maldideepkit.MaldiResNetClassifier` or
160
164
  :class:`~maldideepkit.MaldiTransformerClassifier` if you want
@@ -35,8 +35,6 @@ class BasicBlock1D(nn.Module):
35
35
  Kernel size of both Conv1D layers.
36
36
  """
37
37
 
38
- expansion = 1
39
-
40
38
  def __init__(
41
39
  self,
42
40
  in_channels: int,
@@ -220,11 +218,18 @@ class MaldiResNetClassifier(BaseSpectralClassifier):
220
218
  reproduce the literal ResNet-18 backbone.
221
219
  dropout : float, default=0.2
222
220
  Dropout before the final linear layer.
223
- **kwargs
224
- Forwarded to :class:`~maldideepkit.base.classifier.BaseSpectralClassifier`.
225
221
 
226
222
  Notes
227
223
  -----
224
+ Every parameter accepted by
225
+ :class:`~maldideepkit.base.classifier.BaseSpectralClassifier`
226
+ (e.g. ``learning_rate``, ``batch_size``, ``epochs``, ``warping``,
227
+ ``calibrate_temperature``, ``device``, ``random_state``, ...) is
228
+ forwarded to the base class. The ResNet defaults pre-set
229
+ ``weight_decay=1e-4``, ``grad_clip_norm=1.0``, ``warmup_epochs=5``,
230
+ and ``input_transform="log1p"``; override any of them at
231
+ construction time.
232
+
228
233
  Defaults deviate from literal ResNet-18 (He et al., 2016) in three
229
234
  ways for MALDI-TOF: ``stem_stride=1`` (was 2),
230
235
  ``block_kernel_size=7`` (was 3), and ``use_stem_pool=False`` (was
@@ -336,11 +336,15 @@ class MaldiTransformerClassifier(BaseSpectralClassifier):
336
336
  Token aggregation for classification.
337
337
  head_dim : int, default=128
338
338
  Width of the hidden dense layer in the classification head.
339
- **kwargs
340
- Forwarded to :class:`~maldideepkit.base.classifier.BaseSpectralClassifier`.
341
339
 
342
340
  Notes
343
341
  -----
342
+ Every parameter accepted by
343
+ :class:`~maldideepkit.base.classifier.BaseSpectralClassifier`
344
+ (e.g. ``learning_rate``, ``batch_size``, ``epochs``, ``warping``,
345
+ ``calibrate_temperature``, ``device``, ``random_state``, ...) is
346
+ forwarded to the base class. See its docstring for the full list.
347
+
344
348
  Transformer training recipe baked in as defaults: ``lr=3e-4``,
345
349
  ``weight_decay=0.05``, ``grad_clip_norm=1.0``, ``warmup_epochs=5``.
346
350
 
@@ -0,0 +1,34 @@
1
+ """Uncertainty-quantification estimators for fitted MaldiDeepKit classifiers.
2
+
3
+ Three drop-in estimators that share a single
4
+ :meth:`predict_with_uncertainty` interface:
5
+
6
+ - :class:`MCDropoutEstimator` - Monte Carlo Dropout. Stochastic
7
+ forward passes with dropout active; decomposes total uncertainty
8
+ into epistemic (model disagreement) and aleatoric (data noise)
9
+ components.
10
+ - :class:`LaplaceEstimator` - Last-layer or full-network Laplace
11
+ approximation via the optional ``laplace-torch`` dependency.
12
+ - :class:`ConformalPredictor` - Distribution-free split conformal
13
+ prediction with the LAC non-conformity score; produces calibrated
14
+ prediction sets without retraining the model.
15
+
16
+ All three return a :class:`UncertaintyResult` so downstream code can
17
+ swap methods without changing call sites.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from ._base import BaseUncertaintyEstimator
23
+ from ._result import UncertaintyResult
24
+ from .conformal import ConformalPredictor
25
+ from .laplace import LaplaceEstimator
26
+ from .mc_dropout import MCDropoutEstimator
27
+
28
+ __all__ = [
29
+ "BaseUncertaintyEstimator",
30
+ "ConformalPredictor",
31
+ "LaplaceEstimator",
32
+ "MCDropoutEstimator",
33
+ "UncertaintyResult",
34
+ ]