Metadata-Version: 2.1
Name: bernn
Version: 0.6.0
Summary: Batch Effect Removal Neural Networks for Tandem Mass Spectrometry
Home-page: https://github.com/spell00/BERNN_MSMS
Author: Simon Pelletier
Author-email: 
License: MIT
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: PyYAML (>=6.0.1)
Requires-Dist: importlib-metadata (<8,>=3.7.0)
Requires-Dist: joblib (>=1.2.0)
Requires-Dist: matplotlib (>=3.6.3)
Requires-Dist: mpmath (>=1.3.0)
Requires-Dist: nbformat (>=5.9.2)
Requires-Dist: nibabel
Requires-Dist: numba (>=0.57.1)
Requires-Dist: openpyxl (>=3.0.10)
Requires-Dist: pandas (<3.0.0,>=1.5.3)
Requires-Dist: patsy (>=0.5.3)
Requires-Dist: protobuf (<7,>=6.31.1)
Requires-Dist: psutil (>=5.9.4)
Requires-Dist: python-dateutil (>=2.8.2)
Requires-Dist: requests (<3.0.0,>=2.31.0)
Requires-Dist: scikit-image
Requires-Dist: scikit-learn (>=1.6.0)
Requires-Dist: scikit-optimize (>=0.9.0)
Requires-Dist: scipy (<2.0.0,>=1.9.3)
Requires-Dist: seaborn (>=0.12.2)
Requires-Dist: shapely
Requires-Dist: statsmodels
Requires-Dist: tabulate (>=0.9.0)
Requires-Dist: threadpoolctl (>=3.1.0)
Requires-Dist: tqdm
Requires-Dist: umap-learn (>=0.5.3)
Requires-Dist: xgboost (>=1.7.0)
Provides-Extra: analysis
Requires-Dist: PyYAML (<7.0.0,>=6.0.1) ; extra == 'analysis'
Requires-Dist: ax-platform (<0.4.0,>=0.3.0) ; extra == 'analysis'
Requires-Dist: ipywidgets (>=8.0.0) ; extra == 'analysis'
Requires-Dist: jupyterlab (>=4.0.0) ; extra == 'analysis'
Requires-Dist: notebook (>=7.0.0) ; extra == 'analysis'
Requires-Dist: packaging (<24.0,>=21.0) ; extra == 'analysis'
Requires-Dist: pykan ; extra == 'analysis'
Requires-Dist: python-dateutil (<2.9.0,>=2.8.2) ; extra == 'analysis'
Provides-Extra: analysis-with-ax
Requires-Dist: PyYAML (<7.0.0,>=6.0.1) ; extra == 'analysis-with-ax'
Requires-Dist: ax-platform ; extra == 'analysis-with-ax'
Requires-Dist: ax-platform (<0.4.0,>=0.3.0) ; extra == 'analysis-with-ax'
Requires-Dist: ipywidgets (>=8.0.0) ; extra == 'analysis-with-ax'
Requires-Dist: jupyterlab (>=4.0.0) ; extra == 'analysis-with-ax'
Requires-Dist: notebook (>=7.0.0) ; extra == 'analysis-with-ax'
Requires-Dist: packaging (<24.0,>=21.0) ; extra == 'analysis-with-ax'
Requires-Dist: pykan ; extra == 'analysis-with-ax'
Requires-Dist: python-dateutil (<2.9.0,>=2.8.2) ; extra == 'analysis-with-ax'
Provides-Extra: core-extended
Requires-Dist: FuzzyTM (>=0.4.0) ; extra == 'core-extended'
Requires-Dist: blosc2 (<3.0.0,>=2.0.0) ; extra == 'core-extended'
Requires-Dist: cython (>=0.29.21) ; extra == 'core-extended'
Requires-Dist: llvmlite (>=0.40.1) ; extra == 'core-extended'
Requires-Dist: pycombat ; extra == 'core-extended'
Requires-Dist: pytest ; extra == 'core-extended'
Requires-Dist: pytest-cov ; extra == 'core-extended'
Requires-Dist: shap ; extra == 'core-extended'
Provides-Extra: deep-learning
Requires-Dist: numpy (>=1.24) ; extra == 'deep-learning'
Requires-Dist: tensorflow-estimator (>=2.15.0) ; extra == 'deep-learning'
Requires-Dist: tensorflow (>=2.15.0) ; extra == 'deep-learning'
Requires-Dist: torch-geometric ; extra == 'deep-learning'
Requires-Dist: torch (>=2.1.0) ; extra == 'deep-learning'
Requires-Dist: torchvision (>=0.16.0) ; extra == 'deep-learning'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'deep-learning'
Provides-Extra: dev-tools
Requires-Dist: jedi (>=0.18.2) ; extra == 'dev-tools'
Provides-Extra: development
Requires-Dist: cython (>=0.29.21) ; extra == 'development'
Requires-Dist: fastapi (<0.103.0,>=0.89.1) ; extra == 'development'
Requires-Dist: jedi (>=0.18.2) ; extra == 'development'
Requires-Dist: platformdirs (<4.2.0,>=3.11.0) ; extra == 'development'
Requires-Dist: pytest ; extra == 'development'
Requires-Dist: pytest-cov ; extra == 'development'
Requires-Dist: shap ; extra == 'development'
Requires-Dist: websocket-client (>=1.8.0) ; extra == 'development'
Provides-Extra: experiment-tracking
Requires-Dist: mlflow[extras] (>=2.15.0) ; extra == 'experiment-tracking'
Requires-Dist: sqlalchemy (>=1.4.0) ; extra == 'experiment-tracking'
Requires-Dist: tensorboard-data-server (>=0.7.0) ; extra == 'experiment-tracking'
Requires-Dist: tensorboard (>=2.15.0) ; extra == 'experiment-tracking'
Requires-Dist: tensorboardX ; extra == 'experiment-tracking'
Requires-Dist: urllib3 (>=1.26.7) ; extra == 'experiment-tracking'
Provides-Extra: external-tools
Requires-Dist: selenium (<4.25.0,>=4.15.0) ; extra == 'external-tools'
Requires-Dist: spotdl (<4.2.5,>=4.2.0) ; extra == 'external-tools'
Requires-Dist: spyder (>=5.0.0) ; extra == 'external-tools'
Provides-Extra: full
Requires-Dist: FuzzyTM (>=0.4.0) ; extra == 'full'
Requires-Dist: PyYAML (<7.0.0,>=6.0.1) ; extra == 'full'
Requires-Dist: ax-platform ; extra == 'full'
Requires-Dist: ax-platform (<0.4.0,>=0.3.0) ; extra == 'full'
Requires-Dist: blosc2 (<3.0.0,>=2.0.0) ; extra == 'full'
Requires-Dist: cython (>=0.29.21) ; extra == 'full'
Requires-Dist: fastapi (<0.103.0,>=0.89.1) ; extra == 'full'
Requires-Dist: ipywidgets (>=8.0.0) ; extra == 'full'
Requires-Dist: jupyterlab (>=4.0.0) ; extra == 'full'
Requires-Dist: llvmlite (>=0.40.1) ; extra == 'full'
Requires-Dist: mlflow[extras] (>=2.15.0) ; extra == 'full'
Requires-Dist: notebook (>=7.0.0) ; extra == 'full'
Requires-Dist: numpy (>=1.24) ; extra == 'full'
Requires-Dist: packaging (<24.0,>=21.0) ; extra == 'full'
Requires-Dist: platformdirs (<4.2.0,>=3.11.0) ; extra == 'full'
Requires-Dist: pycombat ; extra == 'full'
Requires-Dist: pykan ; extra == 'full'
Requires-Dist: pytest ; extra == 'full'
Requires-Dist: pytest-cov ; extra == 'full'
Requires-Dist: python-dateutil (<2.9.0,>=2.8.2) ; extra == 'full'
Requires-Dist: rpy2 (>=3.6.0) ; extra == 'full'
Requires-Dist: shap ; extra == 'full'
Requires-Dist: sqlalchemy (>=1.4.0) ; extra == 'full'
Requires-Dist: tensorboard-data-server (>=0.7.0) ; extra == 'full'
Requires-Dist: tensorboard (>=2.15.0) ; extra == 'full'
Requires-Dist: tensorboardX ; extra == 'full'
Requires-Dist: tensorflow-estimator (>=2.15.0) ; extra == 'full'
Requires-Dist: tensorflow (>=2.15.0) ; extra == 'full'
Requires-Dist: torch-geometric ; extra == 'full'
Requires-Dist: torch (>=2.1.0) ; extra == 'full'
Requires-Dist: torchvision (>=0.16.0) ; extra == 'full'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'full'
Requires-Dist: urllib3 (>=1.26.7) ; extra == 'full'
Requires-Dist: websocket-client (>=1.8.0) ; extra == 'full'
Provides-Extra: full-no-ax
Requires-Dist: FuzzyTM (>=0.4.0) ; extra == 'full-no-ax'
Requires-Dist: PyYAML (<7.0.0,>=6.0.1) ; extra == 'full-no-ax'
Requires-Dist: ax-platform (<0.4.0,>=0.3.0) ; extra == 'full-no-ax'
Requires-Dist: blosc2 (<3.0.0,>=2.0.0) ; extra == 'full-no-ax'
Requires-Dist: cython (>=0.29.21) ; extra == 'full-no-ax'
Requires-Dist: fastapi (<0.103.0,>=0.89.1) ; extra == 'full-no-ax'
Requires-Dist: ipywidgets (>=8.0.0) ; extra == 'full-no-ax'
Requires-Dist: jupyterlab (>=4.0.0) ; extra == 'full-no-ax'
Requires-Dist: llvmlite (>=0.40.1) ; extra == 'full-no-ax'
Requires-Dist: mlflow[extras] (>=2.15.0) ; extra == 'full-no-ax'
Requires-Dist: notebook (>=7.0.0) ; extra == 'full-no-ax'
Requires-Dist: numpy (>=1.24) ; extra == 'full-no-ax'
Requires-Dist: packaging (<24.0,>=21.0) ; extra == 'full-no-ax'
Requires-Dist: platformdirs (<4.2.0,>=3.11.0) ; extra == 'full-no-ax'
Requires-Dist: pycombat ; extra == 'full-no-ax'
Requires-Dist: pykan ; extra == 'full-no-ax'
Requires-Dist: pytest ; extra == 'full-no-ax'
Requires-Dist: pytest-cov ; extra == 'full-no-ax'
Requires-Dist: python-dateutil (<2.9.0,>=2.8.2) ; extra == 'full-no-ax'
Requires-Dist: rpy2 (>=3.6.0) ; extra == 'full-no-ax'
Requires-Dist: shap ; extra == 'full-no-ax'
Requires-Dist: sqlalchemy (>=1.4.0) ; extra == 'full-no-ax'
Requires-Dist: tensorboard-data-server (>=0.7.0) ; extra == 'full-no-ax'
Requires-Dist: tensorboard (>=2.15.0) ; extra == 'full-no-ax'
Requires-Dist: tensorboardX ; extra == 'full-no-ax'
Requires-Dist: tensorflow-estimator (>=2.15.0) ; extra == 'full-no-ax'
Requires-Dist: tensorflow (>=2.15.0) ; extra == 'full-no-ax'
Requires-Dist: torch-geometric ; extra == 'full-no-ax'
Requires-Dist: torch (>=2.1.0) ; extra == 'full-no-ax'
Requires-Dist: torchvision (>=0.16.0) ; extra == 'full-no-ax'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'full-no-ax'
Requires-Dist: urllib3 (>=1.26.7) ; extra == 'full-no-ax'
Requires-Dist: websocket-client (>=1.8.0) ; extra == 'full-no-ax'
Provides-Extra: full-safe
Requires-Dist: cython (>=0.29.21) ; extra == 'full-safe'
Requires-Dist: ipywidgets (>=8.0.0) ; extra == 'full-safe'
Requires-Dist: jupyterlab (>=4.0.0) ; extra == 'full-safe'
Requires-Dist: mlflow[extras] (>=2.15.0) ; extra == 'full-safe'
Requires-Dist: notebook (>=7.0.0) ; extra == 'full-safe'
Requires-Dist: numpy (>=1.24) ; extra == 'full-safe'
Requires-Dist: pykan ; extra == 'full-safe'
Requires-Dist: pytest ; extra == 'full-safe'
Requires-Dist: pytest-cov ; extra == 'full-safe'
Requires-Dist: shap ; extra == 'full-safe'
Requires-Dist: sqlalchemy (>=1.4.0) ; extra == 'full-safe'
Requires-Dist: tensorboard-data-server (>=0.7.0) ; extra == 'full-safe'
Requires-Dist: tensorboard (>=2.15.0) ; extra == 'full-safe'
Requires-Dist: tensorboardX ; extra == 'full-safe'
Requires-Dist: tensorflow-estimator (>=2.15.0) ; extra == 'full-safe'
Requires-Dist: tensorflow (>=2.15.0) ; extra == 'full-safe'
Requires-Dist: torch-geometric ; extra == 'full-safe'
Requires-Dist: torch (>=2.1.0) ; extra == 'full-safe'
Requires-Dist: torchvision (>=0.16.0) ; extra == 'full-safe'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'full-safe'
Requires-Dist: urllib3 (>=1.26.7) ; extra == 'full-safe'
Provides-Extra: ide-tools
Requires-Dist: selenium (<4.25.0,>=4.15.0) ; extra == 'ide-tools'
Requires-Dist: spotdl (<4.2.5,>=4.2.0) ; extra == 'ide-tools'
Requires-Dist: spyder (>=5.0.0) ; extra == 'ide-tools'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'ide-tools'
Provides-Extra: minimal
Provides-Extra: ml-full
Requires-Dist: mlflow[extras] (>=2.15.0) ; extra == 'ml-full'
Requires-Dist: numpy (>=1.24) ; extra == 'ml-full'
Requires-Dist: sqlalchemy (>=1.4.0) ; extra == 'ml-full'
Requires-Dist: tensorboard-data-server (>=0.7.0) ; extra == 'ml-full'
Requires-Dist: tensorboard (>=2.15.0) ; extra == 'ml-full'
Requires-Dist: tensorboardX ; extra == 'ml-full'
Requires-Dist: tensorflow-estimator (>=2.15.0) ; extra == 'ml-full'
Requires-Dist: tensorflow (>=2.15.0) ; extra == 'ml-full'
Requires-Dist: torch-geometric ; extra == 'ml-full'
Requires-Dist: torch (>=2.1.0) ; extra == 'ml-full'
Requires-Dist: torchvision (>=0.16.0) ; extra == 'ml-full'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'ml-full'
Requires-Dist: urllib3 (>=1.26.7) ; extra == 'ml-full'
Provides-Extra: modern-web
Requires-Dist: fastapi (<0.104.0,>=0.103.0) ; extra == 'modern-web'
Requires-Dist: platformdirs (<5.0.0,>=4.2.0) ; extra == 'modern-web'
Requires-Dist: pydantic (<3.0.0,>=2.6.4) ; extra == 'modern-web'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'modern-web'
Provides-Extra: notebooks
Requires-Dist: ipywidgets (>=8.0.0) ; extra == 'notebooks'
Requires-Dist: jupyterlab (>=4.0.0) ; extra == 'notebooks'
Requires-Dist: notebook (>=7.0.0) ; extra == 'notebooks'
Provides-Extra: py311-plus
Provides-Extra: py312-plus
Provides-Extra: py313-plus
Provides-Extra: python311-plus
Requires-Dist: mlflow[extras] (>=2.15.0) ; extra == 'python311-plus'
Requires-Dist: numpy (>=1.24) ; extra == 'python311-plus'
Requires-Dist: sqlalchemy (>=1.4.0) ; extra == 'python311-plus'
Requires-Dist: tensorboard-data-server (>=0.7.0) ; extra == 'python311-plus'
Requires-Dist: tensorboard (>=2.15.0) ; extra == 'python311-plus'
Requires-Dist: tensorboardX ; extra == 'python311-plus'
Requires-Dist: tensorflow-estimator (>=2.15.0) ; extra == 'python311-plus'
Requires-Dist: tensorflow (>=2.15.0) ; extra == 'python311-plus'
Requires-Dist: torch-geometric ; extra == 'python311-plus'
Requires-Dist: torch (>=2.1.0) ; extra == 'python311-plus'
Requires-Dist: torchvision (>=0.16.0) ; extra == 'python311-plus'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'python311-plus'
Requires-Dist: urllib3 (>=1.26.7) ; extra == 'python311-plus'
Provides-Extra: python313-minimal-safe
Requires-Dist: jupyter (>=1.0.0) ; extra == 'python313-minimal-safe'
Requires-Dist: matplotlib (>=3.7.0) ; extra == 'python313-minimal-safe'
Requires-Dist: numpy (<2.3,>=1.24) ; extra == 'python313-minimal-safe'
Requires-Dist: pandas (>=2.2.0) ; extra == 'python313-minimal-safe'
Requires-Dist: scikit-learn (>=1.6.0) ; extra == 'python313-minimal-safe'
Requires-Dist: scipy (>=1.11.0) ; extra == 'python313-minimal-safe'
Requires-Dist: seaborn (>=0.12.2) ; extra == 'python313-minimal-safe'
Requires-Dist: torch-geometric ; extra == 'python313-minimal-safe'
Requires-Dist: torch (>=2.1.0) ; extra == 'python313-minimal-safe'
Requires-Dist: torchvision (>=0.16.0) ; extra == 'python313-minimal-safe'
Provides-Extra: python313-ml-minimal
Requires-Dist: numpy (<2.3,>=1.24) ; extra == 'python313-ml-minimal'
Requires-Dist: scikit-learn (>=1.6.0) ; extra == 'python313-ml-minimal'
Requires-Dist: torch-geometric ; extra == 'python313-ml-minimal'
Requires-Dist: torch (>=2.1.0) ; extra == 'python313-ml-minimal'
Requires-Dist: torchvision (>=0.16.0) ; extra == 'python313-ml-minimal'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'python313-ml-minimal'
Provides-Extra: python313-ml-stable
Requires-Dist: numpy (<2.3,>=1.24) ; extra == 'python313-ml-stable'
Requires-Dist: scikit-learn (>=1.6.0) ; extra == 'python313-ml-stable'
Requires-Dist: tensorflow (>=2.15.0) ; extra == 'python313-ml-stable'
Requires-Dist: torch-geometric ; extra == 'python313-ml-stable'
Requires-Dist: torch (>=2.1.0) ; extra == 'python313-ml-stable'
Requires-Dist: torchvision (>=0.16.0) ; extra == 'python313-ml-stable'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'python313-ml-stable'
Provides-Extra: python313-safe
Requires-Dist: FuzzyTM (>=0.4.0) ; extra == 'python313-safe'
Requires-Dist: blosc2 (<3.0.0,>=2.0.0) ; extra == 'python313-safe'
Requires-Dist: cython (>=0.29.21) ; extra == 'python313-safe'
Requires-Dist: ipywidgets (>=8.0.0) ; extra == 'python313-safe'
Requires-Dist: jupyterlab (>=4.0.0) ; extra == 'python313-safe'
Requires-Dist: llvmlite (>=0.40.1) ; extra == 'python313-safe'
Requires-Dist: notebook (>=7.0.0) ; extra == 'python313-safe'
Requires-Dist: numpy (<2.3,>=1.24) ; extra == 'python313-safe'
Requires-Dist: pycombat ; extra == 'python313-safe'
Requires-Dist: pykan ; extra == 'python313-safe'
Requires-Dist: pytest ; extra == 'python313-safe'
Requires-Dist: pytest-cov ; extra == 'python313-safe'
Requires-Dist: scikit-learn (>=1.6.0) ; extra == 'python313-safe'
Requires-Dist: shap ; extra == 'python313-safe'
Requires-Dist: torch-geometric ; extra == 'python313-safe'
Requires-Dist: torch (>=2.1.0) ; extra == 'python313-safe'
Requires-Dist: torchvision (>=0.16.0) ; extra == 'python313-safe'
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'python313-safe'
Provides-Extra: r-integration
Requires-Dist: rpy2 (>=3.6.0) ; extra == 'r-integration'
Provides-Extra: special
Requires-Dist: pykan ; extra == 'special'
Provides-Extra: tools
Requires-Dist: PyYAML (<7.0.0,>=6.0.1) ; extra == 'tools'
Requires-Dist: ax-platform (<0.4.0,>=0.3.0) ; extra == 'tools'
Requires-Dist: packaging (<24.0,>=21.0) ; extra == 'tools'
Requires-Dist: python-dateutil (<2.9.0,>=2.8.2) ; extra == 'tools'
Provides-Extra: tools-with-ax
Requires-Dist: PyYAML (<7.0.0,>=6.0.1) ; extra == 'tools-with-ax'
Requires-Dist: ax-platform ; extra == 'tools-with-ax'
Requires-Dist: ax-platform (<0.4.0,>=0.3.0) ; extra == 'tools-with-ax'
Requires-Dist: packaging (<24.0,>=21.0) ; extra == 'tools-with-ax'
Requires-Dist: python-dateutil (<2.9.0,>=2.8.2) ; extra == 'tools-with-ax'
Provides-Extra: typing
Requires-Dist: typing-extensions (>=4.9.0) ; extra == 'typing'
Provides-Extra: web
Requires-Dist: fastapi (<0.103.0,>=0.89.1) ; extra == 'web'
Requires-Dist: platformdirs (<4.2.0,>=3.11.0) ; extra == 'web'
Requires-Dist: websocket-client (>=1.8.0) ; extra == 'web'
Provides-Extra: web-dev
Requires-Dist: fastapi (<0.104.0,>=0.103.0) ; extra == 'web-dev'
Requires-Dist: platformdirs (<5.0.0,>=4.2.0) ; extra == 'web-dev'
Requires-Dist: pydantic (<3.0.0,>=2.6.4) ; extra == 'web-dev'

# 

# BERNN-MSMS

Minimal README for quick usage.

Longer historical content is kept in [LEGACY_README.md](LEGACY_README.md).

## Install

```bash
pip install bernn
```

## Basic usage

```python
from bernn import TrainAEClassifierHoldout

trainer_cls = TrainAEClassifierHoldout
trainer = trainer_cls(config=bernn_config, log_metrics=True, keep_models=False)

# Train and predict in one call
preds_encoded = trainer.fit_predict(
    X_train,
    y_train,
    X_test=X_test,
    y_test=y_test,
    groups_train=batches_train,
    groups_test=batches_test,
    cross_validation=False,
    cross_test=False,
)

# Decode predictions back to original labels
preds = trainer.predict(X_test)
```

Important runtime contract:

- groups_train is mandatory.
- If X_test is provided, groups_test is mandatory.

## Important parameters

Focus on these first:

- optimize_hyperparams: enable/disable Ax optimization.
- n_trials: number of optimization trials.
- fixed_hyperparams: force values and remove them from search.
- n_repeats: number of holdout repeats.
- n_layers, layer1: classifier depth and width seed.
- dloss: domain loss mode.
- warmup, n_epochs: core training schedule.
- device: cpu/cuda target.
- scaler, bs: preprocessing and batch size.

## Official documentation

- Full reference: [OFFICIAL_DOCUMENTATION.md](OFFICIAL_DOCUMENTATION.md)
- Full parameter catalog: [TRAINING_PARAMETERS.md](TRAINING_PARAMETERS.md)
- Minimal runnable examples notebook (4 variants): [tutorials/minimal_examples.ipynb](tutorials/minimal_examples.ipynb)
- Optimized all-config notebook (TrainAEClassifierHoldout): [tutorials/optimized_classifier_holdout_all_configs.ipynb](tutorials/optimized_classifier_holdout_all_configs.ipynb)
- Optimized all-config notebook (TrainAEThenClassifierHoldout): [tutorials/optimized_ae_then_classifier_holdout_all_configs.ipynb](tutorials/optimized_ae_then_classifier_holdout_all_configs.ipynb)
- Historical CLI-heavy guide: [LEGACY_README.md](LEGACY_README.md)


