Braindecode 1.3.2.dev183987088__tar.gz → 1.3.2.dev184103859__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.dev183987088/braindecode.egg-info → braindecode-1.3.2.dev184103859}/PKG-INFO +3 -3
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bids/hub.py +2 -7
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/__init__.py +0 -2
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/base.py +81 -142
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/cbramod.py +5 -19
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/config.py +29 -29
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/luna.py +7 -8
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/patchedtransformer.py +3 -5
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/reve.py +3 -23
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/shallow_fbcsp.py +8 -16
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/util.py +2 -133
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/__init__.py +1 -2
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/activation.py +0 -20
- braindecode-1.3.2.dev184103859/braindecode/version.py +1 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859/braindecode.egg-info}/PKG-INFO +3 -3
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode.egg-info/requires.txt +2 -2
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/conf.py +7 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/models_categorization.rst +1 -2
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/whats_new.rst +2 -32
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/pyproject.toml +2 -11
- braindecode-1.3.2.dev183987088/braindecode/version.py +0 -1
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/LICENSE.txt +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/MANIFEST.in +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/NOTICE.txt +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/README.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/__init__.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/augmentation/__init__.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/augmentation/base.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/augmentation/functional.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/augmentation/transforms.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/classifier.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/__init__.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/base.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bbci.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bcicomp.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bids/__init__.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bids/datasets.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bids/format.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bids/hub_format.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bids/hub_io.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bids/hub_validation.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bids/iterable.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/chb_mit.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/mne.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/moabb.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/nmt.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/registry.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/siena.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/sleep_physionet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/tuh.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/utils.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/xy.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datautil/__init__.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datautil/channel_utils.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datautil/hub_formats.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datautil/serialization.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datautil/util.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/eegneuralnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/functional/__init__.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/functional/functions.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/functional/initialization.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/atcnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/attentionbasenet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/attn_sleep.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/bendr.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/biot.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/brainmodule.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/contrawr.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/ctnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/deep4.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/deepsleepnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/dgcnn.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eegconformer.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eeginception_erp.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eeginception_mi.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eegitnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eegminer.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eegnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eegnex.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eegpt.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eegsimpleconv.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eegsym.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/eegtcnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/fbcnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/fblightconvnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/fbmsnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/hybrid.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/ifnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/labram.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/medformer.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/msvtnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/sccnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/signal_jepa.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/sinc_shallow.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/sparcnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/sstdpn.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/summary.csv +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/syncnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/tcn.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/tidnet.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/tsinception.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/usleep.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/attention.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/blocks.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/convolution.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/filter.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/layers.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/linear.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/parametrization.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/stats.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/util.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/modules/wrapper.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/preprocessing/__init__.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/preprocessing/mne_preprocess.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/preprocessing/preprocess.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/preprocessing/util.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/preprocessing/windowers.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/regressor.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/samplers/__init__.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/samplers/base.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/samplers/ssl.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/training/__init__.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/training/callbacks.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/training/losses.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/training/scoring.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/util.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/visualization/__init__.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/visualization/confusion_matrices.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/visualization/gradients.py +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode.egg-info/SOURCES.txt +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode.egg-info/dependency_links.txt +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode.egg-info/top_level.txt +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/Makefile +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/_templates/autosummary/class.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/_templates/autosummary/function.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/api.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/cite.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/help.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/index.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/install/install.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/install/install_pip.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/install/install_source.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/categorization/attention.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/categorization/channel.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/categorization/convolution.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/categorization/filterbank.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/categorization/gnn.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/categorization/interpretable.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/categorization/lbm.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/categorization/recurrent.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/categorization/spd.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/models.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/models_table.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/models/models_visualization.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/docs/sg_execution_times.rst +0 -0
- {braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/setup.cfg +0 -0
{braindecode-1.3.2.dev183987088/braindecode.egg-info → braindecode-1.3.2.dev184103859}/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.dev184103859
|
|
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>
|
|
@@ -22,7 +22,7 @@ Requires-Python: >=3.11
|
|
|
22
22
|
Description-Content-Type: text/x-rst
|
|
23
23
|
License-File: LICENSE.txt
|
|
24
24
|
License-File: NOTICE.txt
|
|
25
|
-
Requires-Dist: torch>=2.
|
|
25
|
+
Requires-Dist: torch>=2.2
|
|
26
26
|
Requires-Dist: torchaudio>=2.0
|
|
27
27
|
Requires-Dist: mne>=1.11.0
|
|
28
28
|
Requires-Dist: pandas<3.0.0
|
|
@@ -35,7 +35,7 @@ Requires-Dist: wfdb
|
|
|
35
35
|
Requires-Dist: linear_attention_transformer
|
|
36
36
|
Requires-Dist: docstring_inheritance
|
|
37
37
|
Requires-Dist: rotary_embedding_torch
|
|
38
|
-
Requires-Dist:
|
|
38
|
+
Requires-Dist: pandas<3.0.0
|
|
39
39
|
Provides-Extra: moabb
|
|
40
40
|
Requires-Dist: moabb>=1.4.3; extra == "moabb"
|
|
41
41
|
Provides-Extra: eegprep
|
{braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/datasets/bids/hub.py
RENAMED
|
@@ -845,16 +845,11 @@ class HubDatasetMixin:
|
|
|
845
845
|
|
|
846
846
|
# Convert to MNE objects and create dataset
|
|
847
847
|
info = Info.from_json_dict(info_dict)
|
|
848
|
-
targets = metadata["target"].values
|
|
849
|
-
if np.issubdtype(targets.dtype, np.integer):
|
|
850
|
-
event_ids = targets
|
|
851
|
-
else:
|
|
852
|
-
event_ids = np.ones(len(metadata), dtype=int)
|
|
853
848
|
events = np.column_stack(
|
|
854
849
|
[
|
|
855
|
-
metadata["i_start_in_trial"].values
|
|
850
|
+
metadata["i_start_in_trial"].values,
|
|
856
851
|
np.zeros(len(metadata), dtype=int),
|
|
857
|
-
|
|
852
|
+
metadata["target"].values,
|
|
858
853
|
]
|
|
859
854
|
)
|
|
860
855
|
epochs = mne.EpochsArray(data, info, events=events, metadata=metadata)
|
{braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/__init__.py
RENAMED
|
@@ -55,7 +55,6 @@ from .tsinception import TSception
|
|
|
55
55
|
from .usleep import USleep
|
|
56
56
|
from .util import (
|
|
57
57
|
_init_models_dict,
|
|
58
|
-
build_model_config,
|
|
59
58
|
extract_channel_locations_from_chs_info,
|
|
60
59
|
models_mandatory_parameters,
|
|
61
60
|
)
|
|
@@ -119,7 +118,6 @@ __all__ = [
|
|
|
119
118
|
"TIDNet",
|
|
120
119
|
"TSception",
|
|
121
120
|
"USleep",
|
|
122
|
-
"build_model_config",
|
|
123
121
|
"_init_models_dict",
|
|
124
122
|
"models_mandatory_parameters",
|
|
125
123
|
]
|
{braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/base.py
RENAMED
|
@@ -17,13 +17,6 @@ from docstring_inheritance import NumpyDocstringInheritanceInitMeta
|
|
|
17
17
|
from mne.utils import _soft_import
|
|
18
18
|
from torchinfo import ModelStatistics, summary
|
|
19
19
|
|
|
20
|
-
from braindecode.models.util import (
|
|
21
|
-
_EEG_PARAMS,
|
|
22
|
-
_IMPORT_ADAPTER,
|
|
23
|
-
build_model_config,
|
|
24
|
-
resolve_type_kwargs,
|
|
25
|
-
track_model_init_kwargs,
|
|
26
|
-
)
|
|
27
20
|
from braindecode.version import __version__
|
|
28
21
|
|
|
29
22
|
huggingface_hub = _soft_import(
|
|
@@ -59,25 +52,7 @@ def deprecated_args(obj, *old_new_args):
|
|
|
59
52
|
return out_args
|
|
60
53
|
|
|
61
54
|
|
|
62
|
-
class
|
|
63
|
-
"""Defer ``__init__`` wrapping until after docstring inheritance.
|
|
64
|
-
|
|
65
|
-
``NumpyDocstringInheritanceInitMeta`` uses ``inspect.unwrap()``
|
|
66
|
-
internally, which bypasses ``@wraps`` wrappers. By wrapping
|
|
67
|
-
``__init__`` *after* docstring processing, the metaclass sees the
|
|
68
|
-
unwrapped function and correctly inherits ``cls.__doc__``.
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
def __init__(cls, class_name, class_bases, class_dict):
|
|
72
|
-
super().__init__(class_name, class_bases, class_dict)
|
|
73
|
-
# Only wrap subclass __init__s, not EEGModuleMixin itself.
|
|
74
|
-
# Wrapping the mixin would cause super().__init__() calls to
|
|
75
|
-
# overwrite _braindecode_init_kwargs captured by the subclass.
|
|
76
|
-
if any(isinstance(b, _BraindecodeDocstringMeta) for b in class_bases):
|
|
77
|
-
track_model_init_kwargs(cls)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
55
|
+
class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta):
|
|
81
56
|
"""
|
|
82
57
|
Mixin class for all EEG models in braindecode.
|
|
83
58
|
|
|
@@ -155,15 +130,19 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
155
130
|
the model weights. This ensures that loaded models are correctly configured
|
|
156
131
|
for their original data specifications.
|
|
157
132
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
133
|
+
.. important::
|
|
134
|
+
Currently, only EEG-specific parameters (n_outputs, n_chans, n_times,
|
|
135
|
+
input_window_seconds, sfreq, chs_info) are saved to the Hub.
|
|
136
|
+
Model-specific parameters (e.g., dropout rates, activation functions,
|
|
137
|
+
number of filters) are not preserved and will use their default values
|
|
138
|
+
when loading from the Hub.
|
|
139
|
+
Full parameter serialization will be addressed in a future update.
|
|
161
140
|
"""
|
|
162
141
|
|
|
163
142
|
def __init_subclass__(cls, **kwargs):
|
|
164
143
|
# Append model-specific Hub integration notes to the docstring.
|
|
165
|
-
# This runs
|
|
166
|
-
#
|
|
144
|
+
# This runs after the metaclass, so we concatenate rather than
|
|
145
|
+
# override any existing Notes section in the subclass.
|
|
167
146
|
if cls.__doc__ is not None:
|
|
168
147
|
hub_notes = cls._HUB_NOTES_TEMPLATE.format(
|
|
169
148
|
name=cls.__name__,
|
|
@@ -189,19 +168,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
189
168
|
repo_url = kwargs.pop("repo_url", "https://braindecode.org")
|
|
190
169
|
library_name = kwargs.pop("library_name", "braindecode")
|
|
191
170
|
license = kwargs.pop("license", "bsd-3-clause")
|
|
192
|
-
|
|
193
|
-
# Register a coder so that type[nn.Module] parameters
|
|
194
|
-
# (e.g. activation=nn.ELU) are serialized as importable
|
|
195
|
-
# strings in config.json and decoded back on load.
|
|
196
|
-
coders = kwargs.pop("coders", None) or {}
|
|
197
|
-
coders.setdefault(
|
|
198
|
-
type,
|
|
199
|
-
(
|
|
200
|
-
lambda t: f"{t.__module__}.{t.__qualname__}",
|
|
201
|
-
lambda data: _IMPORT_ADAPTER.validate_python(data),
|
|
202
|
-
),
|
|
203
|
-
)
|
|
204
|
-
|
|
205
171
|
# TODO: model_card_template can be added in the future for custom model cards
|
|
206
172
|
super().__init_subclass__(
|
|
207
173
|
tags=tags,
|
|
@@ -209,7 +175,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
209
175
|
repo_url=repo_url,
|
|
210
176
|
library_name=library_name,
|
|
211
177
|
license=license,
|
|
212
|
-
coders=coders,
|
|
213
178
|
**kwargs,
|
|
214
179
|
)
|
|
215
180
|
|
|
@@ -251,17 +216,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
251
216
|
self._n_times = n_times # type: ignore[assignment]
|
|
252
217
|
self._sfreq = sfreq # type: ignore[assignment]
|
|
253
218
|
|
|
254
|
-
# Back-fill instance attributes from _hub_mixin_config for any
|
|
255
|
-
# params the subclass didn't store on self. Skip EEG params
|
|
256
|
-
# (stored as self._*) and descriptors (properties).
|
|
257
|
-
for key, val in getattr(self, "_hub_mixin_config", {}).items():
|
|
258
|
-
if key in _EEG_PARAMS:
|
|
259
|
-
continue
|
|
260
|
-
if hasattr(getattr(type(self), key, None), "__get__"):
|
|
261
|
-
continue
|
|
262
|
-
if not hasattr(self, key):
|
|
263
|
-
setattr(self, key, val)
|
|
264
|
-
|
|
265
219
|
super().__init__()
|
|
266
220
|
|
|
267
221
|
@property
|
|
@@ -372,76 +326,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
372
326
|
raise ValueError(msg) from exc
|
|
373
327
|
raise exc
|
|
374
328
|
|
|
375
|
-
def get_config(self) -> dict:
|
|
376
|
-
"""Return a JSON-serializable dict of all ``__init__`` parameters.
|
|
377
|
-
|
|
378
|
-
The returned dictionary can be saved to a JSON file and later
|
|
379
|
-
used with :meth:`from_config` to reconstruct the model (without
|
|
380
|
-
weights). It is also used internally by :meth:`push_to_hub` to
|
|
381
|
-
persist the full model configuration.
|
|
382
|
-
|
|
383
|
-
Returns
|
|
384
|
-
-------
|
|
385
|
-
dict
|
|
386
|
-
All ``__init__`` parameters, JSON-serializable.
|
|
387
|
-
``type[nn.Module]`` parameters (e.g. ``activation``) are
|
|
388
|
-
encoded as importable dotted-path strings.
|
|
389
|
-
|
|
390
|
-
Examples
|
|
391
|
-
--------
|
|
392
|
-
>>> import json
|
|
393
|
-
>>> from braindecode.models import EEGNet
|
|
394
|
-
>>> model = EEGNet(n_chans=22, n_times=1000, n_outputs=4, F1=16)
|
|
395
|
-
>>> config = model.get_config()
|
|
396
|
-
>>> config["F1"]
|
|
397
|
-
16
|
|
398
|
-
>>> # Save to disk
|
|
399
|
-
>>> with open("config.json", "w") as f:
|
|
400
|
-
... json.dump(config, f)
|
|
401
|
-
|
|
402
|
-
.. versionadded:: 1.4
|
|
403
|
-
"""
|
|
404
|
-
return build_model_config(self)
|
|
405
|
-
|
|
406
|
-
@classmethod
|
|
407
|
-
def from_config(cls, config: dict) -> "EEGModuleMixin":
|
|
408
|
-
"""Create a model instance from a configuration dict.
|
|
409
|
-
|
|
410
|
-
This is the inverse of :meth:`get_config`. Weights are **not**
|
|
411
|
-
loaded -- use :meth:`from_pretrained` for that.
|
|
412
|
-
|
|
413
|
-
Parameters
|
|
414
|
-
----------
|
|
415
|
-
config : dict
|
|
416
|
-
Configuration dict as returned by :meth:`get_config`.
|
|
417
|
-
|
|
418
|
-
Returns
|
|
419
|
-
-------
|
|
420
|
-
EEGModuleMixin
|
|
421
|
-
A new model instance.
|
|
422
|
-
|
|
423
|
-
Examples
|
|
424
|
-
--------
|
|
425
|
-
>>> import json
|
|
426
|
-
>>> from braindecode.models import EEGNet
|
|
427
|
-
>>> model = EEGNet(n_chans=22, n_times=1000, n_outputs=4, F1=16)
|
|
428
|
-
>>> config = model.get_config()
|
|
429
|
-
>>> # Reconstruct (without weights)
|
|
430
|
-
>>> model2 = EEGNet.from_config(config)
|
|
431
|
-
>>> model2.F1
|
|
432
|
-
16
|
|
433
|
-
>>> # Or from a JSON file
|
|
434
|
-
>>> with open("config.json") as f:
|
|
435
|
-
... config = json.load(f)
|
|
436
|
-
>>> model3 = EEGNet.from_config(config)
|
|
437
|
-
|
|
438
|
-
.. versionadded:: 1.4
|
|
439
|
-
"""
|
|
440
|
-
config = dict(config) # shallow copy
|
|
441
|
-
config.pop("braindecode_version", None)
|
|
442
|
-
resolve_type_kwargs(cls, config)
|
|
443
|
-
return cls(**config)
|
|
444
|
-
|
|
445
329
|
mapping: Optional[Dict[str, str]] = None
|
|
446
330
|
|
|
447
331
|
def load_state_dict(self, state_dict, *args, **kwargs):
|
|
@@ -546,22 +430,54 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
546
430
|
|
|
547
431
|
@staticmethod
|
|
548
432
|
def _serialize_chs_info(chs_info):
|
|
549
|
-
"""
|
|
433
|
+
"""
|
|
434
|
+
Serialize MNE channel info to JSON-compatible format.
|
|
435
|
+
|
|
436
|
+
Parameters
|
|
437
|
+
----------
|
|
438
|
+
chs_info : list of dict or None
|
|
439
|
+
Channel information from MNE Info object.
|
|
440
|
+
|
|
441
|
+
Returns
|
|
442
|
+
-------
|
|
443
|
+
list of dict or None
|
|
444
|
+
Serialized channel information that can be saved to JSON.
|
|
445
|
+
"""
|
|
550
446
|
if chs_info is None:
|
|
551
447
|
return None
|
|
552
|
-
|
|
553
|
-
_FLOAT_FIELDS = ("cal", "range")
|
|
448
|
+
|
|
554
449
|
serialized = []
|
|
555
450
|
for ch in chs_info:
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
451
|
+
# Extract serializable fields from MNE channel info
|
|
452
|
+
ch_dict = {
|
|
453
|
+
"ch_name": ch.get("ch_name", ""),
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
# Handle kind field - can be either string or integer
|
|
457
|
+
kind_val = ch.get("kind")
|
|
458
|
+
if kind_val is not None:
|
|
459
|
+
ch_dict["kind"] = (
|
|
460
|
+
kind_val if isinstance(kind_val, str) else int(kind_val)
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
# Add numeric fields with safe conversion
|
|
464
|
+
coil_type = ch.get("coil_type")
|
|
465
|
+
if coil_type is not None:
|
|
466
|
+
ch_dict["coil_type"] = int(coil_type)
|
|
467
|
+
|
|
468
|
+
unit = ch.get("unit")
|
|
469
|
+
if unit is not None:
|
|
470
|
+
ch_dict["unit"] = int(unit)
|
|
471
|
+
|
|
472
|
+
cal = ch.get("cal")
|
|
473
|
+
if cal is not None:
|
|
474
|
+
ch_dict["cal"] = float(cal)
|
|
475
|
+
|
|
476
|
+
range_val = ch.get("range")
|
|
477
|
+
if range_val is not None:
|
|
478
|
+
ch_dict["range"] = float(range_val)
|
|
479
|
+
|
|
480
|
+
# Serialize location array if present
|
|
565
481
|
if "loc" in ch and ch["loc"] is not None:
|
|
566
482
|
ch_dict["loc"] = (
|
|
567
483
|
ch["loc"].tolist()
|
|
@@ -569,19 +485,35 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
569
485
|
else list(ch["loc"])
|
|
570
486
|
)
|
|
571
487
|
serialized.append(ch_dict)
|
|
488
|
+
|
|
572
489
|
return serialized
|
|
573
490
|
|
|
574
491
|
@staticmethod
|
|
575
492
|
def _deserialize_chs_info(chs_info_dict):
|
|
576
|
-
"""
|
|
493
|
+
"""
|
|
494
|
+
Deserialize channel info from JSON-compatible format to MNE-like structure.
|
|
495
|
+
|
|
496
|
+
Parameters
|
|
497
|
+
----------
|
|
498
|
+
chs_info_dict : list of dict or None
|
|
499
|
+
Serialized channel information.
|
|
500
|
+
|
|
501
|
+
Returns
|
|
502
|
+
-------
|
|
503
|
+
list of dict or None
|
|
504
|
+
Deserialized channel information compatible with MNE.
|
|
505
|
+
"""
|
|
577
506
|
if chs_info_dict is None:
|
|
578
507
|
return None
|
|
508
|
+
|
|
579
509
|
deserialized = []
|
|
580
510
|
for ch_dict in chs_info_dict:
|
|
581
511
|
ch = ch_dict.copy()
|
|
512
|
+
# Convert location back to numpy array if present
|
|
582
513
|
if "loc" in ch and ch["loc"] is not None:
|
|
583
514
|
ch["loc"] = np.array(ch["loc"])
|
|
584
515
|
deserialized.append(ch)
|
|
516
|
+
|
|
585
517
|
return deserialized
|
|
586
518
|
|
|
587
519
|
def _save_pretrained(self, save_directory):
|
|
@@ -601,8 +533,16 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
601
533
|
|
|
602
534
|
save_directory = Path(save_directory)
|
|
603
535
|
|
|
604
|
-
|
|
605
|
-
config
|
|
536
|
+
# Collect EEG-specific configuration
|
|
537
|
+
config = {
|
|
538
|
+
"n_outputs": self._n_outputs,
|
|
539
|
+
"n_chans": self._n_chans,
|
|
540
|
+
"n_times": self._n_times,
|
|
541
|
+
"input_window_seconds": self._input_window_seconds,
|
|
542
|
+
"sfreq": self._sfreq,
|
|
543
|
+
"chs_info": self._serialize_chs_info(self._chs_info),
|
|
544
|
+
"braindecode_version": __version__,
|
|
545
|
+
}
|
|
606
546
|
|
|
607
547
|
# Save to config.json
|
|
608
548
|
config_path = save_directory / "config.json"
|
|
@@ -641,7 +581,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
641
581
|
**model_kwargs,
|
|
642
582
|
):
|
|
643
583
|
model_kwargs.pop("braindecode_version", None)
|
|
644
|
-
resolve_type_kwargs(cls, model_kwargs)
|
|
645
584
|
return super()._from_pretrained( # type: ignore
|
|
646
585
|
model_id=model_id,
|
|
647
586
|
revision=revision,
|
{braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/cbramod.py
RENAMED
|
@@ -207,25 +207,11 @@ class CBraMod(EEGModuleMixin, nn.Module):
|
|
|
207
207
|
|
|
208
208
|
self._weights_init()
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
n_chans = None
|
|
216
|
-
|
|
217
|
-
if return_encoder_output:
|
|
218
|
-
self.final_layer = nn.Identity()
|
|
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
|
|
222
|
-
self.final_layer = nn.Sequential(
|
|
223
|
-
nn.Flatten(), nn.Linear(flat_dim, self.n_outputs)
|
|
224
|
-
)
|
|
225
|
-
else:
|
|
226
|
-
self.final_layer = nn.Sequential(
|
|
227
|
-
nn.Flatten(), nn.LazyLinear(self.n_outputs)
|
|
228
|
-
)
|
|
210
|
+
self.final_layer = (
|
|
211
|
+
nn.Identity()
|
|
212
|
+
if return_encoder_output
|
|
213
|
+
else nn.Sequential(nn.Flatten(), nn.LazyLinear(self.n_outputs))
|
|
214
|
+
)
|
|
229
215
|
|
|
230
216
|
def _weights_init(self):
|
|
231
217
|
for m in self.modules():
|
{braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/config.py
RENAMED
|
@@ -4,16 +4,13 @@ from types import UnionType
|
|
|
4
4
|
from typing import Annotated, Any, Literal, Union, get_args, get_origin
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
|
-
import
|
|
7
|
+
from mne.utils import _soft_import
|
|
8
8
|
from typing_extensions import TypedDict
|
|
9
9
|
|
|
10
10
|
from braindecode.models.base import EEGModuleMixin
|
|
11
|
-
from braindecode.models.util import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
models_dict,
|
|
15
|
-
models_mandatory_parameters,
|
|
16
|
-
)
|
|
11
|
+
from braindecode.models.util import SigArgName, models_dict, models_mandatory_parameters
|
|
12
|
+
|
|
13
|
+
pydantic = _soft_import(name="pydantic", purpose="model configuration", strict=False)
|
|
17
14
|
|
|
18
15
|
try:
|
|
19
16
|
from numpydantic import NDArray, Shape
|
|
@@ -60,12 +57,8 @@ SIGNAL_ARGS_TYPES = {
|
|
|
60
57
|
}
|
|
61
58
|
|
|
62
59
|
|
|
63
|
-
class BaseBraindecodeModelConfig(pydantic.BaseModel):
|
|
64
|
-
"""Base class for braindecode model pydantic configs."""
|
|
65
|
-
|
|
60
|
+
class BaseBraindecodeModelConfig(pydantic.BaseModel): # type: ignore
|
|
66
61
|
def create_instance(self) -> EEGModuleMixin:
|
|
67
|
-
if self.model_name_ not in models_dict:
|
|
68
|
-
_init_models_dict()
|
|
69
62
|
model_cls = models_dict[self.model_name_]
|
|
70
63
|
kwargs = self.model_dump(mode="python", exclude={"model_name_"})
|
|
71
64
|
if kwargs.get("n_chans") is not None and kwargs.get("chs_info") is not None:
|
|
@@ -97,6 +90,13 @@ def make_model_config(
|
|
|
97
90
|
type
|
|
98
91
|
A pydantic BaseModel subclass representing the model config.
|
|
99
92
|
"""
|
|
93
|
+
if not pydantic:
|
|
94
|
+
raise ImportError(
|
|
95
|
+
"pydantic is required to use make_model_config. "
|
|
96
|
+
"Please install braindecode[typing]."
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# ironically, we need to ignore the type here to have the soft dependency.
|
|
100
100
|
|
|
101
101
|
@pydantic.model_validator(mode="before")
|
|
102
102
|
def validate_signal_params(cls, data: Any):
|
|
@@ -207,23 +207,23 @@ def make_model_config(
|
|
|
207
207
|
# and define __all__ based on generated classes
|
|
208
208
|
__all__ = ["make_model_config"]
|
|
209
209
|
|
|
210
|
-
if not
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
models_configs: list[type[BaseBraindecodeModelConfig]] = []
|
|
214
|
-
for model_name, req, _ in models_mandatory_parameters:
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
BraindecodeModelConfig = Annotated[ # type: ignore
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
]
|
|
210
|
+
if not pydantic:
|
|
211
|
+
pass
|
|
212
|
+
else:
|
|
213
|
+
models_configs: list[type[BaseBraindecodeModelConfig]] = []
|
|
214
|
+
for model_name, req, _ in models_mandatory_parameters:
|
|
215
|
+
model_cls = models_dict[model_name]
|
|
216
|
+
model_cfg = make_model_config(model_cls, req)
|
|
217
|
+
globals()[model_cfg.__name__] = model_cfg
|
|
218
|
+
__all__.append(model_cfg.__name__)
|
|
219
|
+
models_configs.append(model_cfg)
|
|
220
|
+
|
|
221
|
+
BraindecodeModelConfig = Annotated[ # type: ignore
|
|
222
|
+
Union[tuple(models_configs)],
|
|
223
|
+
pydantic.Field(
|
|
224
|
+
discriminator="model_name_", description="Braindecode model configuration"
|
|
225
|
+
),
|
|
226
|
+
]
|
|
227
227
|
|
|
228
228
|
# # Example usage:
|
|
229
229
|
#
|
{braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/luna.py
RENAMED
|
@@ -7,7 +7,6 @@ Retrieved from https://openreview.net/forum?id=uazfjnFL0G
|
|
|
7
7
|
|
|
8
8
|
Original Authors: Berkay Döner, Thorir Mar Ingolfsson
|
|
9
9
|
Braindecode Adaptation: Bruno Aristimunha
|
|
10
|
-
Contributions: Sarthak Tayal <sarthaktayal2@gmail.com>
|
|
11
10
|
|
|
12
11
|
the LICENSE Of this file is APACHE-2.0.
|
|
13
12
|
"""
|
|
@@ -83,8 +82,11 @@ class LUNA(EEGModuleMixin, nn.Module):
|
|
|
83
82
|
|
|
84
83
|
# Load pre-trained encoder weights
|
|
85
84
|
state_dict = load_file(model_path)
|
|
86
|
-
#
|
|
87
|
-
model.
|
|
85
|
+
# Apply key mapping for pretrained weights
|
|
86
|
+
mapping = model.mapping.copy()
|
|
87
|
+
mapping["cross_attn.temparature"] = "cross_attn.temperature"
|
|
88
|
+
mapped_state_dict = {mapping.get(k, k): v for k, v in state_dict.items()}
|
|
89
|
+
model.load_state_dict(mapped_state_dict, strict=False)
|
|
88
90
|
|
|
89
91
|
To push your own trained model to the Hub:
|
|
90
92
|
|
|
@@ -168,7 +170,6 @@ class LUNA(EEGModuleMixin, nn.Module):
|
|
|
168
170
|
"channel_location_embedder.0.fc2.bias": "channel_location_embedder.fc2.bias",
|
|
169
171
|
"channel_location_embedder.0.norm.weight": "channel_location_embedder.norm.weight",
|
|
170
172
|
"channel_location_embedder.0.norm.bias": "channel_location_embedder.norm.bias",
|
|
171
|
-
"cross_attn.temparature": "cross_attn.temperature", # typo in pretrained weights
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
# Model parameters
|
|
@@ -314,10 +315,8 @@ class LUNA(EEGModuleMixin, nn.Module):
|
|
|
314
315
|
channel_locations_emb = self.channel_location_embedder(channel_locations)
|
|
315
316
|
|
|
316
317
|
x_tokenized = rearrange(x_masked, "B (C t) D -> (B t) C D", C=num_channels)
|
|
317
|
-
channel_locations_emb = (
|
|
318
|
-
|
|
319
|
-
num_patches_per_channel, dim=0
|
|
320
|
-
)
|
|
318
|
+
channel_locations_emb = channel_locations_emb.repeat(
|
|
319
|
+
num_patches_per_channel, 1, 1
|
|
321
320
|
)
|
|
322
321
|
x_tokenized = x_tokenized + channel_locations_emb
|
|
323
322
|
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
6
|
import math
|
|
7
|
-
import warnings
|
|
8
7
|
from typing import Optional, Tuple
|
|
9
8
|
|
|
10
9
|
import torch
|
|
@@ -497,10 +496,9 @@ class _TransformerEncoderLayer(nn.Module):
|
|
|
497
496
|
|
|
498
497
|
if dim_feedforward is None:
|
|
499
498
|
dim_feedforward = 4 * embed_dim
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
"Vaswani et al. (Attention is all you need)"
|
|
503
|
-
stacklevel=2,
|
|
499
|
+
# note: preserve the original behaviour (print) from the provided code
|
|
500
|
+
print(
|
|
501
|
+
"dim_feedforward is set to 4*embed_dim, the default in Vaswani et al. (Attention is all you need)"
|
|
504
502
|
)
|
|
505
503
|
|
|
506
504
|
self.layer_norm_att = _LayerNorm(embed_dim, bias=bias)
|
{braindecode-1.3.2.dev183987088 → braindecode-1.3.2.dev184103859}/braindecode/models/reve.py
RENAMED
|
@@ -16,16 +16,7 @@ import torch
|
|
|
16
16
|
import torch.nn.functional as F
|
|
17
17
|
from einops import rearrange
|
|
18
18
|
from torch import nn
|
|
19
|
-
|
|
20
|
-
# Safe import for older PyTorch versions (Support for Intel-based Macs)
|
|
21
|
-
try:
|
|
22
|
-
from torch.nn.attention import SDPBackend, sdpa_kernel
|
|
23
|
-
|
|
24
|
-
HAS_SDPA = True
|
|
25
|
-
except ImportError:
|
|
26
|
-
HAS_SDPA = False
|
|
27
|
-
SDPBackend = None
|
|
28
|
-
sdpa_kernel = None
|
|
19
|
+
from torch.nn.attention import SDPBackend, sdpa_kernel
|
|
29
20
|
|
|
30
21
|
from braindecode.models.base import EEGModuleMixin
|
|
31
22
|
|
|
@@ -539,22 +530,11 @@ class FeedForward(nn.Module):
|
|
|
539
530
|
|
|
540
531
|
|
|
541
532
|
class ClassicalAttention(nn.Module):
|
|
542
|
-
def __init__(self, heads: int, use_sdpa: bool
|
|
533
|
+
def __init__(self, heads: int, use_sdpa: bool = True):
|
|
543
534
|
super().__init__()
|
|
535
|
+
self.use_sdpa = use_sdpa
|
|
544
536
|
self.heads = heads
|
|
545
537
|
|
|
546
|
-
if use_sdpa is None:
|
|
547
|
-
self.use_sdpa = HAS_SDPA
|
|
548
|
-
elif use_sdpa is True and not HAS_SDPA:
|
|
549
|
-
logger.warning(
|
|
550
|
-
"SDPA (Scaled Dot Product Attention) was requested, but it is not "
|
|
551
|
-
"available in your current PyTorch version. Falling back to naive "
|
|
552
|
-
"implementation. Please upgrade to PyTorch >= 2.2 for SDPA support."
|
|
553
|
-
)
|
|
554
|
-
self.use_sdpa = False
|
|
555
|
-
else:
|
|
556
|
-
self.use_sdpa = use_sdpa
|
|
557
|
-
|
|
558
538
|
def forward(self, qkv: torch.Tensor) -> torch.Tensor:
|
|
559
539
|
# Split concatenated QKV into separate tensors
|
|
560
540
|
# qkv shape: (batch, seq_len, 3 * heads * head_dim)
|
|
@@ -2,21 +2,19 @@
|
|
|
2
2
|
#
|
|
3
3
|
# License: BSD (3-clause)
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
|
|
7
|
-
from collections.abc import Callable
|
|
5
|
+
from typing import Callable
|
|
8
6
|
|
|
9
7
|
from einops.layers.torch import Rearrange
|
|
10
8
|
from torch import nn
|
|
11
9
|
from torch.nn import init
|
|
12
10
|
|
|
11
|
+
from braindecode.functional import square
|
|
13
12
|
from braindecode.models.base import EEGModuleMixin
|
|
14
13
|
from braindecode.modules import (
|
|
15
14
|
CombinedConv,
|
|
16
15
|
Ensure4d,
|
|
17
16
|
Expression,
|
|
18
17
|
SafeLog,
|
|
19
|
-
Square,
|
|
20
18
|
SqueezeFinalOutput,
|
|
21
19
|
)
|
|
22
20
|
|
|
@@ -47,14 +45,12 @@ class ShallowFBCSPNet(EEGModuleMixin, nn.Sequential):
|
|
|
47
45
|
final_conv_length: int | str
|
|
48
46
|
Length of the final convolution layer.
|
|
49
47
|
If set to "auto", length of the input signal must be specified.
|
|
50
|
-
conv_nonlin:
|
|
51
|
-
Non-linear
|
|
52
|
-
For backward compatibility, callables are also accepted and wrapped
|
|
53
|
-
with :class:`~braindecode.modules.Expression`.
|
|
48
|
+
conv_nonlin: callable
|
|
49
|
+
Non-linear function to be used after convolution layers.
|
|
54
50
|
pool_mode: str
|
|
55
51
|
Method to use on pooling layers. "max" or "mean".
|
|
56
|
-
activation_pool_nonlin:
|
|
57
|
-
Non-linear
|
|
52
|
+
activation_pool_nonlin: callable
|
|
53
|
+
Non-linear function to be used after pooling layers.
|
|
58
54
|
split_first_layer: bool
|
|
59
55
|
Split first layer into temporal and spatial layers (True) or just use temporal (False).
|
|
60
56
|
There would be no non-linearity between the split layers.
|
|
@@ -87,7 +83,7 @@ class ShallowFBCSPNet(EEGModuleMixin, nn.Sequential):
|
|
|
87
83
|
pool_time_length=75,
|
|
88
84
|
pool_time_stride=15,
|
|
89
85
|
final_conv_length="auto",
|
|
90
|
-
conv_nonlin:
|
|
86
|
+
conv_nonlin: Callable = square,
|
|
91
87
|
pool_mode="mean",
|
|
92
88
|
activation_pool_nonlin: type[nn.Module] = SafeLog,
|
|
93
89
|
split_first_layer=True,
|
|
@@ -167,11 +163,7 @@ class ShallowFBCSPNet(EEGModuleMixin, nn.Sequential):
|
|
|
167
163
|
n_filters_conv, momentum=self.batch_norm_alpha, affine=True
|
|
168
164
|
),
|
|
169
165
|
)
|
|
170
|
-
|
|
171
|
-
self.add_module("conv_nonlin_exp", self.conv_nonlin())
|
|
172
|
-
else:
|
|
173
|
-
# Backward compat: accept a callable (e.g. square function)
|
|
174
|
-
self.add_module("conv_nonlin_exp", Expression(self.conv_nonlin))
|
|
166
|
+
self.add_module("conv_nonlin_exp", Expression(self.conv_nonlin))
|
|
175
167
|
self.add_module(
|
|
176
168
|
"pool",
|
|
177
169
|
pool_class(
|