Braindecode 1.3.2.dev183566201__tar.gz → 1.3.2.dev183987088__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.
- {braindecode-1.3.2.dev183566201/braindecode.egg-info → braindecode-1.3.2.dev183987088}/PKG-INFO +1 -1
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/base.py +15 -132
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/bendr.py +6 -17
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/biot.py +5 -23
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/cbramod.py +11 -19
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eeginception_mi.py +1 -2
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegitnet.py +3 -4
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegpt.py +2 -15
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/labram.py +1 -15
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/luna.py +16 -5
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/reve.py +20 -36
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/signal_jepa.py +13 -63
- braindecode-1.3.2.dev183987088/braindecode/version.py +1 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088/braindecode.egg-info}/PKG-INFO +1 -1
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/whats_new.rst +0 -22
- braindecode-1.3.2.dev183566201/braindecode/version.py +0 -1
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/LICENSE.txt +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/MANIFEST.in +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/NOTICE.txt +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/README.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/augmentation/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/augmentation/base.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/augmentation/functional.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/augmentation/transforms.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/classifier.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/base.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bbci.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bcicomp.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/datasets.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/format.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/hub.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/hub_format.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/hub_io.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/hub_validation.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/iterable.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/chb_mit.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/mne.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/moabb.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/nmt.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/registry.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/siena.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/sleep_physionet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/tuh.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/utils.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/xy.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datautil/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datautil/channel_utils.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datautil/hub_formats.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datautil/serialization.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datautil/util.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/eegneuralnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/functional/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/functional/functions.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/functional/initialization.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/atcnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/attentionbasenet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/attn_sleep.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/brainmodule.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/config.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/contrawr.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/ctnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/deep4.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/deepsleepnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/dgcnn.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegconformer.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eeginception_erp.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegminer.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegnex.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegsimpleconv.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegsym.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegtcnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/fbcnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/fblightconvnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/fbmsnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/hybrid.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/ifnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/medformer.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/msvtnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/patchedtransformer.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sccnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/shallow_fbcsp.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sinc_shallow.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sparcnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sstdpn.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/summary.csv +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/syncnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/tcn.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/tidnet.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/tsinception.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/usleep.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/util.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/activation.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/attention.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/blocks.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/convolution.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/filter.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/layers.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/linear.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/parametrization.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/stats.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/util.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/wrapper.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/mne_preprocess.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/preprocess.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/util.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/windowers.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/regressor.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/samplers/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/samplers/base.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/samplers/ssl.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/training/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/training/callbacks.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/training/losses.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/training/scoring.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/util.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/visualization/__init__.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/visualization/confusion_matrices.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/visualization/gradients.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode.egg-info/SOURCES.txt +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode.egg-info/dependency_links.txt +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode.egg-info/requires.txt +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode.egg-info/top_level.txt +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/Makefile +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/_templates/autosummary/class.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/_templates/autosummary/function.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/api.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/cite.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/conf.py +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/help.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/index.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/install/install.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/install/install_pip.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/install/install_source.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/attention.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/channel.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/convolution.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/filterbank.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/gnn.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/interpretable.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/lbm.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/recurrent.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/spd.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/models.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/models_categorization.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/models_table.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/models_visualization.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/sg_execution_times.rst +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/pyproject.toml +0 -0
- {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/setup.cfg +0 -0
{braindecode-1.3.2.dev183566201/braindecode.egg-info → braindecode-1.3.2.dev183987088}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: braindecode
|
|
3
|
-
Version: 1.3.2.
|
|
3
|
+
Version: 1.3.2.dev183987088
|
|
4
4
|
Summary: Deep learning software to decode EEG, ECG or MEG signals
|
|
5
5
|
Author-email: Robin Tibor Schirrmeister <robintibor@gmail.com>, Bruno Aristimunha Pinto <b.aristimunha@gmail.com>, Alexandre Gramfort <agramfort@meta.com>
|
|
6
6
|
Maintainer-email: Alexandre Gramfort <agramfort@meta.com>, Bruno Aristimunha Pinto <b.aristimunha@gmail.com>, Robin Tibor Schirrmeister <robintibor@gmail.com>
|
{braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/base.py
RENAMED
|
@@ -150,40 +150,14 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
150
150
|
# Load pretrained model
|
|
151
151
|
model = {name}.from_pretrained("username/my-{name_lower}-model")
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
.. code-block::
|
|
159
|
-
|
|
160
|
-
import torch
|
|
161
|
-
|
|
162
|
-
x = torch.randn(1, model.n_chans, model.n_times)
|
|
163
|
-
# Extract encoder features (consistent dict across all models)
|
|
164
|
-
out = model(x, return_features=True)
|
|
165
|
-
features = out["features"]
|
|
166
|
-
|
|
167
|
-
# Replace the classification head
|
|
168
|
-
model.reset_head(n_outputs=10)
|
|
169
|
-
|
|
170
|
-
**Saving and restoring full configuration:**
|
|
171
|
-
|
|
172
|
-
.. code-block::
|
|
173
|
-
|
|
174
|
-
import json
|
|
175
|
-
|
|
176
|
-
config = model.get_config() # all __init__ params
|
|
177
|
-
with open("config.json", "w") as f:
|
|
178
|
-
json.dump(config, f)
|
|
179
|
-
|
|
180
|
-
model2 = {name}.from_config(config) # reconstruct (no weights)
|
|
153
|
+
The integration automatically handles EEG-specific parameters (n_chans,
|
|
154
|
+
n_times, sfreq, chs_info, etc.) by saving them in a config file alongside
|
|
155
|
+
the model weights. This ensures that loaded models are correctly configured
|
|
156
|
+
for their original data specifications.
|
|
181
157
|
|
|
182
158
|
All model parameters (both EEG-specific and model-specific such as
|
|
183
159
|
dropout rates, activation functions, number of filters) are automatically
|
|
184
160
|
saved to the Hub and restored when loading.
|
|
185
|
-
|
|
186
|
-
See :ref:`load-pretrained-models` for a complete tutorial.
|
|
187
161
|
"""
|
|
188
162
|
|
|
189
163
|
def __init_subclass__(cls, **kwargs):
|
|
@@ -468,34 +442,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
468
442
|
resolve_type_kwargs(cls, config)
|
|
469
443
|
return cls(**config)
|
|
470
444
|
|
|
471
|
-
def reset_head(self, n_outputs):
|
|
472
|
-
"""Replace the classification head for a new number of outputs.
|
|
473
|
-
|
|
474
|
-
This is called automatically by :meth:`from_pretrained` when the
|
|
475
|
-
user passes an ``n_outputs`` that differs from the saved config.
|
|
476
|
-
Override in subclasses that need a model-specific head structure.
|
|
477
|
-
|
|
478
|
-
Parameters
|
|
479
|
-
----------
|
|
480
|
-
n_outputs : int
|
|
481
|
-
New number of output classes.
|
|
482
|
-
|
|
483
|
-
Examples
|
|
484
|
-
--------
|
|
485
|
-
>>> from braindecode.models import BENDR
|
|
486
|
-
>>> model = BENDR(n_chans=22, n_times=1000, n_outputs=4)
|
|
487
|
-
>>> model.reset_head(10)
|
|
488
|
-
>>> model.n_outputs
|
|
489
|
-
10
|
|
490
|
-
|
|
491
|
-
.. versionadded:: 1.4
|
|
492
|
-
"""
|
|
493
|
-
raise NotImplementedError(
|
|
494
|
-
f"{type(self).__name__} does not implement reset_head(). "
|
|
495
|
-
"Override this method to support changing n_outputs after "
|
|
496
|
-
"loading pretrained weights."
|
|
497
|
-
)
|
|
498
|
-
|
|
499
445
|
mapping: Optional[Dict[str, str]] = None
|
|
500
446
|
|
|
501
447
|
def load_state_dict(self, state_dict, *args, **kwargs):
|
|
@@ -695,78 +641,15 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
695
641
|
**model_kwargs,
|
|
696
642
|
):
|
|
697
643
|
model_kwargs.pop("braindecode_version", None)
|
|
698
|
-
filename = model_kwargs.pop("filename", None)
|
|
699
644
|
resolve_type_kwargs(cls, model_kwargs)
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
filename="config.json",
|
|
712
|
-
revision=revision,
|
|
713
|
-
cache_dir=cache_dir,
|
|
714
|
-
force_download=force_download,
|
|
715
|
-
token=token,
|
|
716
|
-
local_files_only=local_files_only,
|
|
717
|
-
)
|
|
718
|
-
with open(config_file, "r") as f:
|
|
719
|
-
saved_n_outputs = json.load(f).get("n_outputs")
|
|
720
|
-
except (OSError, json.JSONDecodeError, KeyError):
|
|
721
|
-
pass # config unavailable; skip reset_head logic
|
|
722
|
-
|
|
723
|
-
requested_n_outputs = model_kwargs.get("n_outputs")
|
|
724
|
-
|
|
725
|
-
# If the user requests different n_outputs, load with the
|
|
726
|
-
# saved value first (so weights match), then swap the head.
|
|
727
|
-
if (
|
|
728
|
-
saved_n_outputs is not None
|
|
729
|
-
and requested_n_outputs is not None
|
|
730
|
-
and requested_n_outputs != saved_n_outputs
|
|
731
|
-
):
|
|
732
|
-
model_kwargs["n_outputs"] = saved_n_outputs
|
|
733
|
-
|
|
734
|
-
# If a custom filename is provided, temporarily override the
|
|
735
|
-
# HuggingFace constant so the parent class downloads the
|
|
736
|
-
# correct file (e.g. "LUNA_base.safetensors" instead of
|
|
737
|
-
# "model.safetensors").
|
|
738
|
-
hf_constants = huggingface_hub.constants
|
|
739
|
-
_orig_safetensors = hf_constants.SAFETENSORS_SINGLE_FILE
|
|
740
|
-
if filename is not None:
|
|
741
|
-
hf_constants.SAFETENSORS_SINGLE_FILE = filename
|
|
742
|
-
try:
|
|
743
|
-
model = super()._from_pretrained( # type: ignore
|
|
744
|
-
model_id=model_id,
|
|
745
|
-
revision=revision,
|
|
746
|
-
cache_dir=cache_dir,
|
|
747
|
-
force_download=force_download,
|
|
748
|
-
local_files_only=local_files_only,
|
|
749
|
-
token=token,
|
|
750
|
-
map_location=map_location,
|
|
751
|
-
strict=strict,
|
|
752
|
-
**model_kwargs,
|
|
753
|
-
)
|
|
754
|
-
finally:
|
|
755
|
-
hf_constants.SAFETENSORS_SINGLE_FILE = _orig_safetensors
|
|
756
|
-
|
|
757
|
-
if (
|
|
758
|
-
saved_n_outputs is not None
|
|
759
|
-
and requested_n_outputs is not None
|
|
760
|
-
and requested_n_outputs != saved_n_outputs
|
|
761
|
-
):
|
|
762
|
-
try:
|
|
763
|
-
model.reset_head(requested_n_outputs)
|
|
764
|
-
except NotImplementedError:
|
|
765
|
-
raise ValueError(
|
|
766
|
-
f"{type(model).__name__} does not support changing "
|
|
767
|
-
f"n_outputs after loading. Saved model has "
|
|
768
|
-
f"n_outputs={saved_n_outputs}, but "
|
|
769
|
-
f"n_outputs={requested_n_outputs} was requested."
|
|
770
|
-
) from None
|
|
771
|
-
|
|
772
|
-
return model
|
|
645
|
+
return super()._from_pretrained( # type: ignore
|
|
646
|
+
model_id=model_id,
|
|
647
|
+
revision=revision,
|
|
648
|
+
cache_dir=cache_dir,
|
|
649
|
+
force_download=force_download,
|
|
650
|
+
local_files_only=local_files_only,
|
|
651
|
+
token=token,
|
|
652
|
+
map_location=map_location,
|
|
653
|
+
strict=strict,
|
|
654
|
+
**model_kwargs,
|
|
655
|
+
)
|
{braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/bendr.py
RENAMED
|
@@ -291,23 +291,15 @@ class BENDR(EEGModuleMixin, nn.Module):
|
|
|
291
291
|
else:
|
|
292
292
|
in_features = encoder_h
|
|
293
293
|
|
|
294
|
-
self._head_in_features = in_features
|
|
295
294
|
self.final_layer = None
|
|
296
295
|
if self.include_final_layer:
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
linear, name="weight", dim=1
|
|
303
|
-
)
|
|
304
|
-
|
|
305
|
-
def reset_head(self, n_outputs):
|
|
306
|
-
self._n_outputs = n_outputs
|
|
307
|
-
self.include_final_layer = True
|
|
308
|
-
self._build_head(n_outputs)
|
|
296
|
+
# in_features: encoder_h*4 (encoder_only) or encoder_h (full model)
|
|
297
|
+
linear = nn.Linear(in_features=in_features, out_features=self.n_outputs)
|
|
298
|
+
self.final_layer = nn.utils.parametrizations.weight_norm(
|
|
299
|
+
linear, name="weight", dim=1
|
|
300
|
+
)
|
|
309
301
|
|
|
310
|
-
def forward(self, x
|
|
302
|
+
def forward(self, x):
|
|
311
303
|
if self.channel_projection is not None:
|
|
312
304
|
x = self.channel_projection(x)
|
|
313
305
|
encoded = self.encoder(x)
|
|
@@ -336,9 +328,6 @@ class BENDR(EEGModuleMixin, nn.Module):
|
|
|
336
328
|
feature = context[:, :, 0]
|
|
337
329
|
# feature: [batch_size, encoder_h]
|
|
338
330
|
|
|
339
|
-
if return_features:
|
|
340
|
-
return {"features": feature, "cls_token": None}
|
|
341
|
-
|
|
342
331
|
if self.final_layer is not None:
|
|
343
332
|
feature = self.final_layer(feature)
|
|
344
333
|
# feature: [batch_size, n_outputs]
|
{braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/biot.py
RENAMED
|
@@ -183,22 +183,13 @@ class BIOT(EEGModuleMixin, nn.Module):
|
|
|
183
183
|
attn_layer_dropout=att_layer_drop_prob,
|
|
184
184
|
)
|
|
185
185
|
|
|
186
|
-
self._head_activation = activation
|
|
187
186
|
self.final_layer = _ClassificationHead(
|
|
188
187
|
emb_size=self.embed_dim,
|
|
189
188
|
n_outputs=self.n_outputs,
|
|
190
189
|
activation=activation,
|
|
191
190
|
)
|
|
192
191
|
|
|
193
|
-
def
|
|
194
|
-
self._n_outputs = n_outputs
|
|
195
|
-
self.final_layer = _ClassificationHead(
|
|
196
|
-
emb_size=self.embed_dim,
|
|
197
|
-
n_outputs=n_outputs,
|
|
198
|
-
activation=self._head_activation,
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
def forward(self, x, return_features=False):
|
|
192
|
+
def forward(self, x):
|
|
202
193
|
"""
|
|
203
194
|
Pass the input through the BIOT encoder, and then through the
|
|
204
195
|
classification head.
|
|
@@ -207,24 +198,15 @@ class BIOT(EEGModuleMixin, nn.Module):
|
|
|
207
198
|
----------
|
|
208
199
|
x: Tensor
|
|
209
200
|
(batch_size, n_channels, n_times)
|
|
210
|
-
return_features : bool
|
|
211
|
-
If True, return a dict with ``"features"`` and ``"cls_token"``
|
|
212
|
-
instead of the classification output.
|
|
213
201
|
|
|
214
202
|
Returns
|
|
215
203
|
-------
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
If legacy ``return_feature=True`` (init param):
|
|
221
|
-
``(out, emb)`` tuple (ignored when ``return_features=True``).
|
|
204
|
+
out: Tensor
|
|
205
|
+
(batch_size, n_outputs)
|
|
206
|
+
(out, emb): tuple Tensor
|
|
207
|
+
(batch_size, n_outputs), (batch_size, emb_size)
|
|
222
208
|
"""
|
|
223
209
|
emb = self.encoder(x)
|
|
224
|
-
|
|
225
|
-
if return_features:
|
|
226
|
-
return {"features": emb, "cls_token": None}
|
|
227
|
-
|
|
228
210
|
x = self.final_layer(emb)
|
|
229
211
|
|
|
230
212
|
if self.return_feature:
|
{braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/cbramod.py
RENAMED
|
@@ -205,15 +205,20 @@ class CBraMod(EEGModuleMixin, nn.Module):
|
|
|
205
205
|
self.encoder = _TransformerEncoder(encoder_layer, num_layers=n_layer)
|
|
206
206
|
self.proj_out = nn.Sequential(nn.Linear(d_model, emb_dim))
|
|
207
207
|
|
|
208
|
-
self._emb_dim = emb_dim
|
|
209
|
-
self._patch_size = patch_size
|
|
210
208
|
self._weights_init()
|
|
211
209
|
|
|
210
|
+
try:
|
|
211
|
+
n_times = self.n_times
|
|
212
|
+
n_chans = self.n_chans
|
|
213
|
+
except ValueError:
|
|
214
|
+
n_times = None
|
|
215
|
+
n_chans = None
|
|
216
|
+
|
|
212
217
|
if return_encoder_output:
|
|
213
218
|
self.final_layer = nn.Identity()
|
|
214
|
-
elif
|
|
215
|
-
n_patch =
|
|
216
|
-
flat_dim =
|
|
219
|
+
elif n_times is not None and n_chans is not None:
|
|
220
|
+
n_patch = n_times // patch_size
|
|
221
|
+
flat_dim = n_chans * n_patch * emb_dim
|
|
217
222
|
self.final_layer = nn.Sequential(
|
|
218
223
|
nn.Flatten(), nn.Linear(flat_dim, self.n_outputs)
|
|
219
224
|
)
|
|
@@ -222,17 +227,6 @@ class CBraMod(EEGModuleMixin, nn.Module):
|
|
|
222
227
|
nn.Flatten(), nn.LazyLinear(self.n_outputs)
|
|
223
228
|
)
|
|
224
229
|
|
|
225
|
-
def reset_head(self, n_outputs):
|
|
226
|
-
self._n_outputs = n_outputs
|
|
227
|
-
if self._n_times is not None and self._n_chans is not None:
|
|
228
|
-
n_patch = self._n_times // self._patch_size
|
|
229
|
-
flat_dim = self._n_chans * n_patch * self._emb_dim
|
|
230
|
-
self.final_layer = nn.Sequential(
|
|
231
|
-
nn.Flatten(), nn.Linear(flat_dim, n_outputs)
|
|
232
|
-
)
|
|
233
|
-
else:
|
|
234
|
-
self.final_layer = nn.Sequential(nn.Flatten(), nn.LazyLinear(n_outputs))
|
|
235
|
-
|
|
236
230
|
def _weights_init(self):
|
|
237
231
|
for m in self.modules():
|
|
238
232
|
if isinstance(m, nn.Linear):
|
|
@@ -243,13 +237,11 @@ class CBraMod(EEGModuleMixin, nn.Module):
|
|
|
243
237
|
nn.init.constant_(m.weight, 1)
|
|
244
238
|
nn.init.constant_(m.bias, 0)
|
|
245
239
|
|
|
246
|
-
def forward(self, x, mask=None
|
|
240
|
+
def forward(self, x, mask=None):
|
|
247
241
|
x = self.rearrange(x)
|
|
248
242
|
patch_emb = self.patch_embedding(x, mask)
|
|
249
243
|
feats = self.encoder(patch_emb)
|
|
250
244
|
out = self.proj_out(feats)
|
|
251
|
-
if return_features:
|
|
252
|
-
return {"features": out, "cls_token": None}
|
|
253
245
|
return self.final_layer(out)
|
|
254
246
|
|
|
255
247
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# Authors: Cedric Rommel <cedric.rommel@inria.fr>
|
|
2
|
-
# Sarthak Tayal <sarthaktayal2@gmail.com>
|
|
3
2
|
#
|
|
4
3
|
# License: BSD (3-clause)
|
|
5
4
|
|
|
@@ -96,7 +95,7 @@ class EEGInceptionMI(EEGModuleMixin, nn.Module):
|
|
|
96
95
|
|
|
97
96
|
self.mapping = {
|
|
98
97
|
"fc.weight": "final_layer.fc.weight",
|
|
99
|
-
"
|
|
98
|
+
"tc.bias": "final_layer.fc.bias",
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
# ======== Inception branches ========================
|
{braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegitnet.py
RENAMED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# Authors: Ghaith Bouallegue <ghaithbouallegue@gmail.com>
|
|
2
|
-
# Sarthak Tayal <sarthaktayal2@gmail.com>
|
|
3
2
|
#
|
|
4
3
|
# License: BSD-3
|
|
5
4
|
from einops.layers.torch import Rearrange
|
|
@@ -95,8 +94,8 @@ class EEGITNet(EEGModuleMixin, nn.Sequential):
|
|
|
95
94
|
sfreq=sfreq,
|
|
96
95
|
)
|
|
97
96
|
self.mapping = {
|
|
98
|
-
"classification.1.weight": "final_layer.weight",
|
|
99
|
-
"classification.1.bias": "final_layer.
|
|
97
|
+
"classification.1.weight": "final_layer.clf.weight",
|
|
98
|
+
"classification.1.bias": "final_layer.clf.weight",
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
del n_outputs, n_chans, chs_info, n_times, input_window_seconds, sfreq
|
|
@@ -122,7 +121,7 @@ class EEGITNet(EEGModuleMixin, nn.Sequential):
|
|
|
122
121
|
block13 = self._get_inception_branch(
|
|
123
122
|
in_channels=self.n_chans,
|
|
124
123
|
out_channels=n_filters_time * 4,
|
|
125
|
-
kernel_length=
|
|
124
|
+
kernel_length=n_filters_time * 4,
|
|
126
125
|
activation=activation,
|
|
127
126
|
)
|
|
128
127
|
self.add_module("inception_block", InceptionBlock((block11, block12, block13)))
|
{braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegpt.py
RENAMED
|
@@ -368,13 +368,6 @@ class EEGPT(EEGModuleMixin, nn.Module):
|
|
|
368
368
|
"""Number of temporal patches from encoder."""
|
|
369
369
|
return self.target_encoder.num_patches[1]
|
|
370
370
|
|
|
371
|
-
def reset_head(self, n_outputs):
|
|
372
|
-
self._n_outputs = n_outputs
|
|
373
|
-
self.final_layer = _LinearConstraintProbe(
|
|
374
|
-
**self.get_probe_params(),
|
|
375
|
-
n_outputs=n_outputs,
|
|
376
|
-
)
|
|
377
|
-
|
|
378
371
|
def get_probe_params(self) -> dict:
|
|
379
372
|
"""Get parameters needed to create a _LinearConstraintProbe.
|
|
380
373
|
|
|
@@ -389,7 +382,7 @@ class EEGPT(EEGModuleMixin, nn.Module):
|
|
|
389
382
|
"embed_dim": self.embed_dim,
|
|
390
383
|
}
|
|
391
384
|
|
|
392
|
-
def forward(self, x
|
|
385
|
+
def forward(self, x):
|
|
393
386
|
"""
|
|
394
387
|
Forward pass.
|
|
395
388
|
|
|
@@ -397,13 +390,10 @@ class EEGPT(EEGModuleMixin, nn.Module):
|
|
|
397
390
|
----------
|
|
398
391
|
x : torch.Tensor
|
|
399
392
|
EEG data of shape (batch, n_chans, n_times).
|
|
400
|
-
return_features : bool
|
|
401
|
-
If True, return a dict with ``"features"`` and ``"cls_token"``
|
|
402
|
-
instead of the classification output.
|
|
403
393
|
|
|
404
394
|
Returns
|
|
405
395
|
-------
|
|
406
|
-
torch.Tensor
|
|
396
|
+
torch.Tensor
|
|
407
397
|
Model output. Shape depends on `n_outputs` and `return_encoder_output`.
|
|
408
398
|
"""
|
|
409
399
|
# Channel projection (if configured)
|
|
@@ -412,9 +402,6 @@ class EEGPT(EEGModuleMixin, nn.Module):
|
|
|
412
402
|
# z shape: (batch, n_patches, embed_num, embed_dim)
|
|
413
403
|
z = self.target_encoder(x, self.chans_id)
|
|
414
404
|
|
|
415
|
-
if return_features:
|
|
416
|
-
return {"features": z.flatten(2), "cls_token": None}
|
|
417
|
-
|
|
418
405
|
if self.return_encoder_output:
|
|
419
406
|
return z
|
|
420
407
|
|
{braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/labram.py
RENAMED
|
@@ -790,7 +790,6 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
790
790
|
ch_names: list[str] | None = None,
|
|
791
791
|
return_patch_tokens=False,
|
|
792
792
|
return_all_tokens=False,
|
|
793
|
-
return_features=False,
|
|
794
793
|
):
|
|
795
794
|
"""
|
|
796
795
|
Forward the input EEG data through the model.
|
|
@@ -806,9 +805,6 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
806
805
|
If not provided, the channels provided during model initialization
|
|
807
806
|
(via ``chs_info``), channels will be used instead
|
|
808
807
|
If neither is provided, an error will be raised.
|
|
809
|
-
return_features : bool
|
|
810
|
-
If True, return a dict with ``"features"`` (patch tokens) and
|
|
811
|
-
``"cls_token"`` instead of the classification output.
|
|
812
808
|
return_patch_tokens: bool
|
|
813
809
|
Return the patch tokens
|
|
814
810
|
return_all_tokens: bool
|
|
@@ -816,18 +812,12 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
816
812
|
|
|
817
813
|
Returns
|
|
818
814
|
-------
|
|
819
|
-
torch.Tensor
|
|
815
|
+
torch.Tensor
|
|
820
816
|
The output of the model with dimensions (batch, n_outputs)
|
|
821
817
|
"""
|
|
822
818
|
# Apply automatic channel reordering if configured and input_chans not provided
|
|
823
819
|
x, input_chans = self._select_channels(x, ch_names=ch_names)
|
|
824
820
|
|
|
825
|
-
if return_features:
|
|
826
|
-
x = self.forward_features(
|
|
827
|
-
x, input_chans=input_chans, return_all_tokens=True
|
|
828
|
-
)
|
|
829
|
-
return {"features": x[:, 1:, :], "cls_token": x[:, 0, :]}
|
|
830
|
-
|
|
831
821
|
x = self.forward_features(
|
|
832
822
|
x,
|
|
833
823
|
input_chans=input_chans,
|
|
@@ -861,10 +851,6 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
861
851
|
nn.Linear(self.embed_dim, n_outputs) if n_outputs > 0 else nn.Identity()
|
|
862
852
|
)
|
|
863
853
|
|
|
864
|
-
def reset_head(self, n_outputs):
|
|
865
|
-
self._n_outputs = n_outputs
|
|
866
|
-
self.reset_classifier(n_outputs)
|
|
867
|
-
|
|
868
854
|
def _adj_temporal_embedding(self, num_ch, batch_size, dim_embed=None):
|
|
869
855
|
"""
|
|
870
856
|
Adjust the dimensions of the time embedding to match the
|
{braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/luna.py
RENAMED
|
@@ -49,7 +49,7 @@ class LUNA(EEGModuleMixin, nn.Module):
|
|
|
49
49
|
**Pre-trained Weights Available**
|
|
50
50
|
|
|
51
51
|
This model has pre-trained weights available on the Hugging Face Hub
|
|
52
|
-
at `
|
|
52
|
+
at `thorir/LUNA <https://huggingface.co/thorir/LUNA>`_.
|
|
53
53
|
|
|
54
54
|
Available model variants:
|
|
55
55
|
|
|
@@ -61,13 +61,19 @@ class LUNA(EEGModuleMixin, nn.Module):
|
|
|
61
61
|
|
|
62
62
|
.. code-block:: python
|
|
63
63
|
|
|
64
|
+
from huggingface_hub import hf_hub_download
|
|
65
|
+
from safetensors.torch import load_file
|
|
64
66
|
from braindecode.models import LUNA
|
|
65
67
|
|
|
66
|
-
#
|
|
67
|
-
|
|
68
|
-
"
|
|
68
|
+
# Download pre-trained weights
|
|
69
|
+
model_path = hf_hub_download(
|
|
70
|
+
repo_id="thorir/LUNA",
|
|
69
71
|
filename="LUNA_base.safetensors",
|
|
70
|
-
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Create model for classification (fine-tuning)
|
|
75
|
+
model = LUNA(
|
|
76
|
+
n_outputs=2, # Number of classes for your task
|
|
71
77
|
n_chans=22,
|
|
72
78
|
n_times=1000,
|
|
73
79
|
embed_dim=64,
|
|
@@ -75,6 +81,11 @@ class LUNA(EEGModuleMixin, nn.Module):
|
|
|
75
81
|
depth=8,
|
|
76
82
|
)
|
|
77
83
|
|
|
84
|
+
# Load pre-trained encoder weights
|
|
85
|
+
state_dict = load_file(model_path)
|
|
86
|
+
# load_state_dict applies model.mapping automatically
|
|
87
|
+
model.load_state_dict(state_dict, strict=False)
|
|
88
|
+
|
|
78
89
|
To push your own trained model to the Hub:
|
|
79
90
|
|
|
80
91
|
.. code-block:: python
|
{braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/reve.py
RENAMED
|
@@ -311,7 +311,19 @@ class REVE(EEGModuleMixin, nn.Module):
|
|
|
311
311
|
geglu=self.use_geglu,
|
|
312
312
|
)
|
|
313
313
|
|
|
314
|
-
self.
|
|
314
|
+
final_dim = self._get_flattened_output_dim()
|
|
315
|
+
|
|
316
|
+
if self.use_attention_pooling:
|
|
317
|
+
self.final_layer = nn.Sequential(
|
|
318
|
+
nn.LayerNorm(self.embed_dim),
|
|
319
|
+
nn.Linear(self.embed_dim, self.n_outputs),
|
|
320
|
+
)
|
|
321
|
+
else:
|
|
322
|
+
self.final_layer = nn.Sequential(
|
|
323
|
+
nn.Flatten(),
|
|
324
|
+
nn.LayerNorm(final_dim),
|
|
325
|
+
nn.Linear(final_dim, self.n_outputs),
|
|
326
|
+
)
|
|
315
327
|
|
|
316
328
|
if self.use_attention_pooling:
|
|
317
329
|
self.cls_query_token = nn.Parameter(torch.randn(1, 1, self.embed_dim))
|
|
@@ -340,24 +352,6 @@ class REVE(EEGModuleMixin, nn.Module):
|
|
|
340
352
|
flat_dim = self.n_chans * n_patches * self.embed_dim
|
|
341
353
|
return flat_dim
|
|
342
354
|
|
|
343
|
-
def _build_head(self, n_outputs):
|
|
344
|
-
if self.use_attention_pooling:
|
|
345
|
-
self.final_layer = nn.Sequential(
|
|
346
|
-
nn.LayerNorm(self.embed_dim),
|
|
347
|
-
nn.Linear(self.embed_dim, n_outputs),
|
|
348
|
-
)
|
|
349
|
-
else:
|
|
350
|
-
final_dim = self._get_flattened_output_dim()
|
|
351
|
-
self.final_layer = nn.Sequential(
|
|
352
|
-
nn.Flatten(),
|
|
353
|
-
nn.LayerNorm(final_dim),
|
|
354
|
-
nn.Linear(final_dim, n_outputs),
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
def reset_head(self, n_outputs):
|
|
358
|
-
self._n_outputs = n_outputs
|
|
359
|
-
self._build_head(n_outputs)
|
|
360
|
-
|
|
361
355
|
def get_positions(self, channel_names: list[str]) -> torch.Tensor:
|
|
362
356
|
"""Fetch channel positions from the position bank. The position bank is downloaded when the model is instantiated.
|
|
363
357
|
|
|
@@ -379,8 +373,7 @@ class REVE(EEGModuleMixin, nn.Module):
|
|
|
379
373
|
eeg: torch.Tensor,
|
|
380
374
|
pos: Optional[torch.Tensor] = None,
|
|
381
375
|
return_output: bool = False,
|
|
382
|
-
|
|
383
|
-
) -> Union[torch.Tensor, list[torch.Tensor], dict]:
|
|
376
|
+
) -> Union[torch.Tensor, list[torch.Tensor]]:
|
|
384
377
|
"""
|
|
385
378
|
Forward pass of the model.
|
|
386
379
|
|
|
@@ -399,22 +392,16 @@ class REVE(EEGModuleMixin, nn.Module):
|
|
|
399
392
|
return_output : bool, optional
|
|
400
393
|
If True, returns the output from the transformer directly.
|
|
401
394
|
If False, applies the final layer and returns the processed output. Default is False.
|
|
402
|
-
return_features : bool, optional
|
|
403
|
-
If True, returns a dict ``{"features": Tensor, "cls_token": None}``
|
|
404
|
-
with encoder features before the final layer. Default is False.
|
|
405
395
|
|
|
406
396
|
Returns
|
|
407
397
|
-------
|
|
408
|
-
torch.Tensor
|
|
409
|
-
|
|
410
|
-
If
|
|
411
|
-
If ``return_features=True``: ``dict`` with ``"features"`` and ``"cls_token"`` keys.
|
|
412
|
-
"""
|
|
398
|
+
Union[torch.Tensor, list[torch.Tensor]]
|
|
399
|
+
- If `return_output` is False: Returns a single `torch.Tensor` (output after final layer).
|
|
400
|
+
- If `return_output` is True: Returns a `list[torch.Tensor]` (outputs from transformer layers).
|
|
413
401
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
)
|
|
402
|
+
The output tensor(s) from the model. If `return_output` is True,
|
|
403
|
+
returns the transformer output; otherwise, returns the output after the final layer.
|
|
404
|
+
"""
|
|
418
405
|
|
|
419
406
|
patches = eeg.unfold(
|
|
420
407
|
dimension=2,
|
|
@@ -466,9 +453,6 @@ class REVE(EEGModuleMixin, nn.Module):
|
|
|
466
453
|
emb=self.embed_dim,
|
|
467
454
|
)
|
|
468
455
|
|
|
469
|
-
if return_features:
|
|
470
|
-
return {"features": x, "cls_token": None}
|
|
471
|
-
|
|
472
456
|
if self.use_attention_pooling:
|
|
473
457
|
x = self._attention_pooling(x)
|
|
474
458
|
|