Braindecode 1.8.0.dev179993000__tar.gz → 1.8.0.dev180935432__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.8.0.dev180935432/NOTICE.txt +25 -0
- {braindecode-1.8.0.dev179993000/braindecode.egg-info → braindecode-1.8.0.dev180935432}/PKG-INFO +5 -8
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/README.rst +3 -6
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/base.py +0 -3
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/functional/functions.py +3 -4
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/base.py +3 -28
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/brainmodule.py +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/ctnet.py +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/dance.py +10 -2
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegconformer.py +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegminer.py +1 -2
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegsimpleconv.py +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/emg2qwerty.py +133 -9
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/ifnet.py +1 -2
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/luna.py +5 -31
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/medformer.py +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/meta_neuromotor.py +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/mvpformer.py +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sstdpn.py +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/summary.csv +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/tcformer.py +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/usleep.py +7 -3
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/zuna.py +12 -26
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/__init__.py +2 -14
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/blocks.py +0 -213
- braindecode-1.8.0.dev180935432/braindecode/version.py +1 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432/braindecode.egg-info}/PKG-INFO +5 -8
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode.egg-info/SOURCES.txt +0 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode.egg-info/requires.txt +1 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/whats_new.rst +1 -31
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/pyproject.toml +1 -1
- braindecode-1.8.0.dev179993000/NOTICE.txt +0 -65
- braindecode-1.8.0.dev179993000/braindecode/datasets/_notebook_viewer.py +0 -255
- braindecode-1.8.0.dev179993000/braindecode/version.py +0 -1
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/LICENSE.txt +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/MANIFEST.in +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/augmentation/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/augmentation/base.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/augmentation/functional.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/augmentation/transforms.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/classifier.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bbci.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bcicomp.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/datasets.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/format.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/hub.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/hub_format.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/hub_io.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/hub_validation.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/iterable.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/chb_mit.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/collate.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/mne.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/moabb.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/nmt.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/registry.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/siena.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/sleep_physionet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/tuh.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/utils.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/xy.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datautil/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datautil/channel_utils.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datautil/hub_formats.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datautil/serialization.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datautil/util.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/eegneuralnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/functional/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/functional/initialization.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/atcnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/attentionbasenet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/attn_sleep.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/bendr.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/biot.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/cbramod.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/codebrain.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/config.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/contrawr.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/deep4.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/deepsleepnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/dgcnn.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegdino.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eeginception_erp.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eeginception_mi.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegitnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegnex.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegpt.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegsym.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegtcnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/fbcnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/fblightconvnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/fbmsnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/hybrid.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/interpolated.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/labram.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/msvtnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/patchedtransformer.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/reve.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sccnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/shallow_fbcsp.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/signal_jepa.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sinc_shallow.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sparcnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/steegformer.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/syncnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/tcn.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/tidnet.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/tsinception.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/util.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/activation.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/attention.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/convolution.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/dance_modules.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/filter.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/interpolation.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/layers.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/linear.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/parametrization.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/stats.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/util.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/wrapper.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/mne_preprocess.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/preprocess.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/util.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/windowers.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/regressor.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/samplers/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/samplers/base.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/samplers/ssl.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/training/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/training/callbacks.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/training/losses.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/training/scoring.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/util.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/__init__.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/attribution.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/confusion_matrices.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/frequency.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/metrics.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/sanity.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/topology.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode.egg-info/dependency_links.txt +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode.egg-info/top_level.txt +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/Makefile +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/_templates/autosummary/class.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/_templates/autosummary/function.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/api.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/cite.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/conf.py +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/help.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/index.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/install/install.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/install/install_pip.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/install/install_source.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/attention.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/channel.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/convolution.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/filterbank.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/gnn.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/interpretable.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/lbm.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/recurrent.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/spd.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/models.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/models_categorization.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/models_table.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/models_visualization.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/sg_execution_times.rst +0 -0
- {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/setup.cfg +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# BRAINDECODE Notice
|
|
2
|
+
|
|
3
|
+
## Licensed Components
|
|
4
|
+
|
|
5
|
+
### BSD-3-Clause Licensed Files
|
|
6
|
+
|
|
7
|
+
All files within the `src/` directory are licensed under the BSD-3-Clause License.
|
|
8
|
+
|
|
9
|
+
### CC BY-NC 4.0 Licensed Files
|
|
10
|
+
|
|
11
|
+
The following components are licensed under the Creative Commons Attribution-NonCommercial 4.0 International License:
|
|
12
|
+
|
|
13
|
+
- `braindecode/models/eegminer.py`
|
|
14
|
+
- `braindecode/models/meta_neuromotor.py`
|
|
15
|
+
|
|
16
|
+
As well as class later imported into the `braindecode.models.module` named as GeneralizedGaussianFilter.
|
|
17
|
+
|
|
18
|
+
The `meta_neuromotor.py` file is a derivative of
|
|
19
|
+
`facebookresearch/generic-neuromotor-interface`, released by Meta Platforms,
|
|
20
|
+
Inc. under CC BY-NC 4.0, and inherits the same noncommercial terms.
|
|
21
|
+
|
|
22
|
+
## License Links
|
|
23
|
+
|
|
24
|
+
- [BSD-3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
|
25
|
+
- [CC BY-NC 4.0 License](https://creativecommons.org/licenses/by-nc/4.0/)
|
{braindecode-1.8.0.dev179993000/braindecode.egg-info → braindecode-1.8.0.dev180935432}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: braindecode
|
|
3
|
-
Version: 1.8.0.
|
|
3
|
+
Version: 1.8.0.dev180935432
|
|
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>
|
|
@@ -34,6 +34,7 @@ Requires-Dist: pandas
|
|
|
34
34
|
Requires-Dist: wfdb>=4.3.1
|
|
35
35
|
Requires-Dist: linear_attention_transformer
|
|
36
36
|
Requires-Dist: docstring_inheritance
|
|
37
|
+
Requires-Dist: rotary_embedding_torch
|
|
37
38
|
Requires-Dist: pydantic>=2.0
|
|
38
39
|
Provides-Extra: moabb
|
|
39
40
|
Requires-Dist: moabb>=1.4.3; extra == "moabb"
|
|
@@ -50,7 +51,6 @@ Requires-Dist: pytest-cov; extra == "tests"
|
|
|
50
51
|
Requires-Dist: codecov; extra == "tests"
|
|
51
52
|
Requires-Dist: pytest_cases; extra == "tests"
|
|
52
53
|
Requires-Dist: mypy; extra == "tests"
|
|
53
|
-
Requires-Dist: ipython; extra == "tests"
|
|
54
54
|
Requires-Dist: transformers>=4.57.0; extra == "tests"
|
|
55
55
|
Requires-Dist: bids_validator; extra == "tests"
|
|
56
56
|
Provides-Extra: typing
|
|
@@ -260,10 +260,7 @@ This project is primarily licensed under the BSD-3-Clause License.
|
|
|
260
260
|
Additional Components
|
|
261
261
|
=====================
|
|
262
262
|
|
|
263
|
-
Some components within this repository are licensed under
|
|
264
|
-
|
|
265
|
-
Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0), MIT
|
|
266
|
-
and Apache-2.0.
|
|
263
|
+
Some components within this repository are licensed under the Creative Commons
|
|
264
|
+
Attribution-NonCommercial 4.0 International License.
|
|
267
265
|
|
|
268
|
-
Please refer to the ``LICENSE`` and ``NOTICE`` files for
|
|
269
|
-
detailed information.
|
|
266
|
+
Please refer to the ``LICENSE`` and ``NOTICE`` files for more detailed information.
|
|
@@ -170,10 +170,7 @@ This project is primarily licensed under the BSD-3-Clause License.
|
|
|
170
170
|
Additional Components
|
|
171
171
|
=====================
|
|
172
172
|
|
|
173
|
-
Some components within this repository are licensed under
|
|
174
|
-
|
|
175
|
-
Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0), MIT
|
|
176
|
-
and Apache-2.0.
|
|
173
|
+
Some components within this repository are licensed under the Creative Commons
|
|
174
|
+
Attribution-NonCommercial 4.0 International License.
|
|
177
175
|
|
|
178
|
-
Please refer to the ``LICENSE`` and ``NOTICE`` files for
|
|
179
|
-
detailed information.
|
|
176
|
+
Please refer to the ``LICENSE`` and ``NOTICE`` files for more detailed information.
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/base.py
RENAMED
|
@@ -32,7 +32,6 @@ from mne.utils.docs import deprecated
|
|
|
32
32
|
from torch.utils.data import ConcatDataset, Dataset, IterableDataset
|
|
33
33
|
from typing_extensions import TypeVar
|
|
34
34
|
|
|
35
|
-
from ._notebook_viewer import plot as _viewer_plot
|
|
36
35
|
from .bids.hub import HubDatasetMixin
|
|
37
36
|
from .bids.hub_io import _restore_nan_from_json
|
|
38
37
|
from .registry import register_dataset
|
|
@@ -1175,8 +1174,6 @@ class BaseConcatDataset(ConcatDataset, HubDatasetMixin, Generic[T]):
|
|
|
1175
1174
|
If True, defer computing cumulative sizes until length or item access.
|
|
1176
1175
|
"""
|
|
1177
1176
|
|
|
1178
|
-
plot = _viewer_plot # eegdash-viewer embed; a direct member so the API docs list it
|
|
1179
|
-
|
|
1180
1177
|
datasets: list[T]
|
|
1181
1178
|
|
|
1182
1179
|
def __init__(
|
|
@@ -40,7 +40,7 @@ def drop_path(
|
|
|
40
40
|
x : torch.Tensor
|
|
41
41
|
input tensor
|
|
42
42
|
drop_prob : float, optional
|
|
43
|
-
probability of
|
|
43
|
+
survival rate (i.e. probability of being kept), by default 0.0
|
|
44
44
|
training : bool, optional
|
|
45
45
|
whether the model is in training mode, by default False
|
|
46
46
|
scale_by_keep : bool, optional
|
|
@@ -68,10 +68,9 @@ def drop_path(
|
|
|
68
68
|
shape = (x.shape[0],) + (1,) * (
|
|
69
69
|
x.ndim - 1
|
|
70
70
|
) # work with diff dim tensors, not just 2D ConvNets
|
|
71
|
-
|
|
72
|
-
random_tensor = torch.bernoulli(probabilities).to(dtype=x.dtype)
|
|
71
|
+
random_tensor = x.new_empty(shape).bernoulli_(keep_prob)
|
|
73
72
|
if keep_prob > 0.0 and scale_by_keep:
|
|
74
|
-
random_tensor
|
|
73
|
+
random_tensor.div_(keep_prob)
|
|
75
74
|
return x * random_tensor
|
|
76
75
|
|
|
77
76
|
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/base.py
RENAMED
|
@@ -80,7 +80,7 @@ class _BraindecodeDocstringMeta(NumpyDocstringInheritanceInitMeta):
|
|
|
80
80
|
unwrapped function and correctly inherits ``cls.__doc__``.
|
|
81
81
|
"""
|
|
82
82
|
|
|
83
|
-
def __init__(cls, class_name, class_bases, class_dict
|
|
83
|
+
def __init__(cls, class_name, class_bases, class_dict):
|
|
84
84
|
super().__init__(class_name, class_bases, class_dict)
|
|
85
85
|
# Only wrap subclass __init__s, not EEGModuleMixin itself.
|
|
86
86
|
# Wrapping the mixin would cause super().__init__() calls to
|
|
@@ -214,8 +214,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
214
214
|
__jit_unused_properties__ = ["chs_info"]
|
|
215
215
|
|
|
216
216
|
def __init_subclass__(cls, **kwargs):
|
|
217
|
-
license = kwargs.pop("license", "bsd-3-clause")
|
|
218
|
-
|
|
219
217
|
# TorchScript only honours ``__jit_ignored_attributes__`` for
|
|
220
218
|
# properties defined directly on the concrete class: it collects them
|
|
221
219
|
# with ``vars(type(module))``, which skips inherited ones. Rebinding
|
|
@@ -255,6 +253,8 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
255
253
|
)
|
|
256
254
|
repo_url = kwargs.pop("repo_url", "https://braindecode.org")
|
|
257
255
|
library_name = kwargs.pop("library_name", "braindecode")
|
|
256
|
+
license = kwargs.pop("license", "bsd-3-clause")
|
|
257
|
+
|
|
258
258
|
# Register a coder so that type[nn.Module] parameters
|
|
259
259
|
# (e.g. activation=nn.ELU) are serialized as importable
|
|
260
260
|
# strings in config.json and decoded back on load.
|
|
@@ -519,31 +519,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
519
519
|
resolve_type_kwargs(cls, config)
|
|
520
520
|
return cls(**config)
|
|
521
521
|
|
|
522
|
-
def _set_n_outputs(self, n_outputs: int) -> None:
|
|
523
|
-
"""Record a new ``n_outputs`` on the model and its saved configs.
|
|
524
|
-
|
|
525
|
-
Helper for :meth:`reset_head` implementations: validates the value,
|
|
526
|
-
then keeps the ``n_outputs`` property, the braindecode init kwargs
|
|
527
|
-
and the Hugging Face hub config in sync, so a re-serialized model
|
|
528
|
-
reports the head it actually has.
|
|
529
|
-
|
|
530
|
-
Parameters
|
|
531
|
-
----------
|
|
532
|
-
n_outputs : int
|
|
533
|
-
New number of outputs. Must be positive.
|
|
534
|
-
|
|
535
|
-
.. versionadded:: 1.8
|
|
536
|
-
"""
|
|
537
|
-
if n_outputs <= 0:
|
|
538
|
-
raise ValueError(f"n_outputs must be positive; got {n_outputs}.")
|
|
539
|
-
self._n_outputs = n_outputs
|
|
540
|
-
for config in (
|
|
541
|
-
getattr(self, "_braindecode_init_kwargs", None),
|
|
542
|
-
getattr(self, "_hub_mixin_config", None),
|
|
543
|
-
):
|
|
544
|
-
if config is not None and "n_outputs" in config:
|
|
545
|
-
config["n_outputs"] = n_outputs
|
|
546
|
-
|
|
547
522
|
def reset_head(self, n_outputs):
|
|
548
523
|
"""Replace the classification head for a new number of outputs.
|
|
549
524
|
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/brainmodule.py
RENAMED
|
@@ -25,7 +25,7 @@ from braindecode.modules.layers import SubjectLayers
|
|
|
25
25
|
__all__ = ["BrainModule"]
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
class BrainModule(EEGModuleMixin, nn.Module
|
|
28
|
+
class BrainModule(EEGModuleMixin, nn.Module):
|
|
29
29
|
r"""BrainModule from [brainmagick]_, also known as SimpleConv.
|
|
30
30
|
|
|
31
31
|
A dilated convolutional encoder for EEG decoding, using residual
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/ctnet.py
RENAMED
|
@@ -24,7 +24,7 @@ from braindecode.modules import (
|
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
class CTNet(EEGModuleMixin, nn.Module
|
|
27
|
+
class CTNet(EEGModuleMixin, nn.Module):
|
|
28
28
|
r"""CTNet from Zhao, W et al (2024) [ctnet]_.
|
|
29
29
|
|
|
30
30
|
:bdg-success:`Convolution` :bdg-info:`Attention/Transformer`
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/dance.py
RENAMED
|
@@ -22,7 +22,7 @@ from braindecode.modules import ChannelMerger, Perceiver, SimpleConv
|
|
|
22
22
|
from braindecode.modules.dance_modules import DanceDetrDecoder
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class DANCE(EEGModuleMixin, nn.Module
|
|
25
|
+
class DANCE(EEGModuleMixin, nn.Module):
|
|
26
26
|
r"""DANCE from Lévy et al (2026) [dance]_.
|
|
27
27
|
|
|
28
28
|
:bdg-success:`Convolution` :bdg-info:`Attention/Transformer` :bdg-dark-line:`Channel`
|
|
@@ -349,7 +349,8 @@ class DANCE(EEGModuleMixin, nn.Module, license="mit"):
|
|
|
349
349
|
|
|
350
350
|
def reset_head(self, n_outputs: int) -> None:
|
|
351
351
|
"""Replace the dense head and the DETR class head for a new ``n_outputs``."""
|
|
352
|
-
|
|
352
|
+
if n_outputs <= 0:
|
|
353
|
+
raise ValueError(f"n_outputs must be positive; got {n_outputs}.")
|
|
353
354
|
old = self.final_layer
|
|
354
355
|
self.final_layer = nn.Linear(old.in_features, n_outputs).to(
|
|
355
356
|
device=old.weight.device, dtype=old.weight.dtype
|
|
@@ -358,3 +359,10 @@ class DANCE(EEGModuleMixin, nn.Module, license="mit"):
|
|
|
358
359
|
self.decoder.class_head = nn.Linear(ch.in_features, n_outputs).to(
|
|
359
360
|
device=ch.weight.device, dtype=ch.weight.dtype
|
|
360
361
|
)
|
|
362
|
+
self._n_outputs = n_outputs
|
|
363
|
+
init_kwargs = getattr(self, "_braindecode_init_kwargs", None)
|
|
364
|
+
if init_kwargs is not None and "n_outputs" in init_kwargs:
|
|
365
|
+
init_kwargs["n_outputs"] = n_outputs
|
|
366
|
+
hub_config = getattr(self, "_hub_mixin_config", None)
|
|
367
|
+
if hub_config is not None and "n_outputs" in hub_config:
|
|
368
|
+
hub_config["n_outputs"] = n_outputs
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegconformer.py
RENAMED
|
@@ -185,7 +185,7 @@ class EEGConformer(EEGModuleMixin, nn.Module):
|
|
|
185
185
|
31, pp.710-719. https://ieeexplore.ieee.org/document/9991178
|
|
186
186
|
.. [ConformerCode] Song, Y., Zheng, Q., Liu, B. and Gao, X., 2022. EEG
|
|
187
187
|
conformer: Convolutional transformer for EEG decoding and visualization.
|
|
188
|
-
https://github.com/eeyhsong/EEG-Conformer
|
|
188
|
+
https://github.com/eeyhsong/EEG-Conformer.
|
|
189
189
|
"""
|
|
190
190
|
|
|
191
191
|
def __init__(
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegminer.py
RENAMED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
# Authors: Sarthak Tayal <sarthaktayal2@gmail.com>
|
|
9
|
-
# License: Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
|
|
10
9
|
|
|
11
10
|
import torch
|
|
12
11
|
from torch import nn
|
|
@@ -49,7 +48,7 @@ class _EEGMinerFeatures(nn.Module):
|
|
|
49
48
|
return x[:, self.triu_row, self.triu_col, :]
|
|
50
49
|
|
|
51
50
|
|
|
52
|
-
class EEGMiner(EEGModuleMixin, nn.Module
|
|
51
|
+
class EEGMiner(EEGModuleMixin, nn.Module):
|
|
53
52
|
r"""EEGMiner from Ludwig et al (2024) [eegminer]_.
|
|
54
53
|
|
|
55
54
|
:bdg-success:`Convolution` :bdg-warning:`Interpretability`
|
|
@@ -93,7 +93,7 @@ class EEGSimpleConv(EEGModuleMixin, torch.nn.Module):
|
|
|
93
93
|
.. [Yassine2023Code] Yassine El Ouahidi, V. Gripon, B. Pasdeloup, G. Bouallegue
|
|
94
94
|
N. Farrugia, G. Lioi, 2023. A Strong and Simple Deep Learning Baseline for
|
|
95
95
|
BCI Motor Imagery Decoding. GitHub repository.
|
|
96
|
-
https://github.com/elouayas/EEGSimpleConv
|
|
96
|
+
https://github.com/elouayas/EEGSimpleConv.
|
|
97
97
|
|
|
98
98
|
"""
|
|
99
99
|
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/emg2qwerty.py
RENAMED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
# Authors: Meta Platforms, Inc. and affiliates (original emg2qwerty)
|
|
2
2
|
# Bruno Aristimunha <b.aristimunha@gmail.com> (Braindecode adaptation)
|
|
3
3
|
#
|
|
4
|
-
# License: Creative Commons Attribution-NonCommercial-
|
|
5
|
-
# International (CC BY-NC-SA 4.0)
|
|
4
|
+
# License: Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
|
|
6
5
|
# Adapted from https://github.com/facebookresearch/emg2qwerty (NeurIPS 2024).
|
|
7
|
-
# Inherits CC BY-NC
|
|
6
|
+
# Inherits CC BY-NC 4.0; not covered by braindecode's BSD-3 license.
|
|
8
7
|
"""``EMG2QwertyNet``: TDS-Conv-CTC for sEMG-to-keystroke decoding."""
|
|
9
8
|
|
|
10
9
|
from __future__ import annotations
|
|
@@ -17,10 +16,9 @@ import torchaudio.transforms as ta_transforms
|
|
|
17
16
|
from torch import nn
|
|
18
17
|
|
|
19
18
|
from braindecode.models.base import EEGModuleMixin
|
|
20
|
-
from braindecode.modules import TDSConvEncoder
|
|
21
19
|
|
|
22
20
|
|
|
23
|
-
class EMG2QwertyNet(EEGModuleMixin, nn.Module
|
|
21
|
+
class EMG2QwertyNet(EEGModuleMixin, nn.Module):
|
|
24
22
|
r"""Decoder mapping surface electromyography (sEMG) to keystrokes
|
|
25
23
|
(emg2qwerty) [emg2qwerty2024]_.
|
|
26
24
|
|
|
@@ -91,7 +89,7 @@ class EMG2QwertyNet(EEGModuleMixin, nn.Module, license="cc-by-nc-sa-4.0"):
|
|
|
91
89
|
.. warning::
|
|
92
90
|
**License: noncommercial use only.** This module is a derivative
|
|
93
91
|
of Meta's reference implementation released under
|
|
94
|
-
`CC BY-NC
|
|
92
|
+
`CC BY-NC 4.0 <https://creativecommons.org/licenses/by-nc/4.0/>`_,
|
|
95
93
|
the same license as the upstream repository. Not covered by
|
|
96
94
|
braindecode's BSD-3 license. Must not be used in commercial
|
|
97
95
|
products or services. Pretrained weights from the upstream release
|
|
@@ -347,7 +345,7 @@ class EMG2QwertyNet(EEGModuleMixin, nn.Module, license="cc-by-nc-sa-4.0"):
|
|
|
347
345
|
activation=activation,
|
|
348
346
|
),
|
|
349
347
|
nn.Flatten(start_dim=2),
|
|
350
|
-
|
|
348
|
+
_TDSConvEncoder(
|
|
351
349
|
num_features=num_features,
|
|
352
350
|
block_channels=list(block_channels),
|
|
353
351
|
kernel_width=kernel_width,
|
|
@@ -358,7 +356,9 @@ class EMG2QwertyNet(EEGModuleMixin, nn.Module, license="cc-by-nc-sa-4.0"):
|
|
|
358
356
|
|
|
359
357
|
self.final_layer = nn.Linear(num_features, self.n_outputs)
|
|
360
358
|
|
|
361
|
-
self._n_conv_blocks =
|
|
359
|
+
self._n_conv_blocks = sum(
|
|
360
|
+
isinstance(m, _TDSConv2dBlock) for m in self.model[3].tds_conv_blocks
|
|
361
|
+
)
|
|
362
362
|
|
|
363
363
|
def forward(
|
|
364
364
|
self, x: torch.Tensor, return_features: bool = False
|
|
@@ -452,11 +452,22 @@ class EMG2QwertyNet(EEGModuleMixin, nn.Module, license="cc-by-nc-sa-4.0"):
|
|
|
452
452
|
captured init config (``get_config()``) is also kept in sync so
|
|
453
453
|
save/load round-trips rebuild the new head.
|
|
454
454
|
"""
|
|
455
|
-
|
|
455
|
+
if n_outputs <= 0:
|
|
456
|
+
raise ValueError(f"n_outputs must be positive; got {n_outputs}.")
|
|
456
457
|
old_head = self.final_layer
|
|
457
458
|
self.final_layer = nn.Linear(old_head.in_features, n_outputs).to(
|
|
458
459
|
device=old_head.weight.device, dtype=old_head.weight.dtype
|
|
459
460
|
)
|
|
461
|
+
self._n_outputs = n_outputs
|
|
462
|
+
# Keep the init-kwargs snapshot used by ``get_config()`` aligned with
|
|
463
|
+
# the live head, so ``EMG2QwertyNet.from_config(m.get_config())``
|
|
464
|
+
# rebuilds the head with the new vocab size.
|
|
465
|
+
init_kwargs = getattr(self, "_braindecode_init_kwargs", None)
|
|
466
|
+
if init_kwargs is not None and "n_outputs" in init_kwargs:
|
|
467
|
+
init_kwargs["n_outputs"] = n_outputs
|
|
468
|
+
hub_config = getattr(self, "_hub_mixin_config", None)
|
|
469
|
+
if hub_config is not None and "n_outputs" in hub_config:
|
|
470
|
+
hub_config["n_outputs"] = n_outputs
|
|
460
471
|
|
|
461
472
|
def compute_output_lengths(self, input_lengths: torch.Tensor) -> torch.Tensor:
|
|
462
473
|
"""Map per-sample input lengths to CTC emission lengths.
|
|
@@ -788,3 +799,116 @@ class _MultiBandRotationInvariantMLP(nn.Module):
|
|
|
788
799
|
for band_idx, mlp in enumerate(self.mlps):
|
|
789
800
|
band_outputs.append(mlp(per_band_inputs[band_idx]))
|
|
790
801
|
return torch.stack(band_outputs, dim=self.stack_dim)
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
class _TDSConv2dBlock(nn.Module):
|
|
805
|
+
r"""Time-Depth-Separable 2-D conv block ([hannun2019tds]_).
|
|
806
|
+
|
|
807
|
+
1×``kernel_width`` conv + activation + residual + LayerNorm. No
|
|
808
|
+
temporal padding: strips ``kernel_width - 1`` frames per block.
|
|
809
|
+
"""
|
|
810
|
+
|
|
811
|
+
def __init__(
|
|
812
|
+
self,
|
|
813
|
+
channels: int,
|
|
814
|
+
width: int,
|
|
815
|
+
kernel_width: int,
|
|
816
|
+
activation: type[nn.Module] = nn.ReLU,
|
|
817
|
+
) -> None:
|
|
818
|
+
super().__init__()
|
|
819
|
+
self.channels = channels
|
|
820
|
+
self.width = width
|
|
821
|
+
self.conv2d = nn.Conv2d(
|
|
822
|
+
in_channels=channels,
|
|
823
|
+
out_channels=channels,
|
|
824
|
+
kernel_size=(1, kernel_width),
|
|
825
|
+
)
|
|
826
|
+
self.activation = activation()
|
|
827
|
+
self.layer_norm = nn.LayerNorm(channels * width)
|
|
828
|
+
|
|
829
|
+
def forward(self, inputs: torch.Tensor) -> torch.Tensor:
|
|
830
|
+
n_in_frames, batch_size, n_features = inputs.shape
|
|
831
|
+
folded = inputs.movedim(0, -1).reshape(
|
|
832
|
+
batch_size, self.channels, self.width, n_in_frames
|
|
833
|
+
)
|
|
834
|
+
conv_out = self.activation(self.conv2d(folded))
|
|
835
|
+
conv_out = conv_out.reshape(batch_size, n_features, -1).movedim(-1, 0)
|
|
836
|
+
n_out_frames = conv_out.shape[0]
|
|
837
|
+
# Output frame i aligns with input frame i+(kernel_width-1), so
|
|
838
|
+
# the residual is the LAST n_out_frames input frames.
|
|
839
|
+
residual_added = conv_out + inputs[-n_out_frames:]
|
|
840
|
+
return self.layer_norm(residual_added)
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
class _TDSFullyConnectedBlock(nn.Module):
|
|
844
|
+
r"""Two-layer FFN with residual skip, LayerNorm, and optional dropout."""
|
|
845
|
+
|
|
846
|
+
def __init__(
|
|
847
|
+
self,
|
|
848
|
+
num_features: int,
|
|
849
|
+
activation: type[nn.Module] = nn.ReLU,
|
|
850
|
+
drop_prob: float = 0.0,
|
|
851
|
+
) -> None:
|
|
852
|
+
super().__init__()
|
|
853
|
+
layers: list[nn.Module] = [
|
|
854
|
+
nn.Linear(num_features, num_features),
|
|
855
|
+
activation(),
|
|
856
|
+
]
|
|
857
|
+
if drop_prob > 0:
|
|
858
|
+
layers.append(nn.Dropout(drop_prob))
|
|
859
|
+
layers.append(nn.Linear(num_features, num_features))
|
|
860
|
+
if drop_prob > 0:
|
|
861
|
+
layers.append(nn.Dropout(drop_prob))
|
|
862
|
+
self.fc_block = nn.Sequential(*layers)
|
|
863
|
+
self.layer_norm = nn.LayerNorm(num_features)
|
|
864
|
+
|
|
865
|
+
def forward(self, inputs: torch.Tensor) -> torch.Tensor:
|
|
866
|
+
return self.layer_norm(self.fc_block(inputs) + inputs)
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
class _TDSConvEncoder(nn.Module):
|
|
870
|
+
r"""``_TDSConv2dBlock`` + ``_TDSFullyConnectedBlock`` stack.
|
|
871
|
+
|
|
872
|
+
With ``K = len(block_channels)`` blocks and no temporal padding, the
|
|
873
|
+
encoder strips ``K * (kernel_width - 1)`` frames in total. Each ``ch``
|
|
874
|
+
must evenly divide ``num_features`` so the conv block can fold features
|
|
875
|
+
as ``(channels=ch, width=num_features // ch)``.
|
|
876
|
+
"""
|
|
877
|
+
|
|
878
|
+
def __init__(
|
|
879
|
+
self,
|
|
880
|
+
num_features: int,
|
|
881
|
+
block_channels: Sequence[int] = (24, 24, 24, 24),
|
|
882
|
+
kernel_width: int = 32,
|
|
883
|
+
activation: type[nn.Module] = nn.ReLU,
|
|
884
|
+
drop_prob: float = 0.0,
|
|
885
|
+
) -> None:
|
|
886
|
+
super().__init__()
|
|
887
|
+
if not block_channels:
|
|
888
|
+
raise ValueError("block_channels must be non-empty.")
|
|
889
|
+
blocks: list[nn.Module] = []
|
|
890
|
+
for n_block_channels in block_channels:
|
|
891
|
+
if num_features % n_block_channels != 0:
|
|
892
|
+
raise ValueError(
|
|
893
|
+
f"block_channels entry {n_block_channels} does not evenly "
|
|
894
|
+
f"divide num_features={num_features}."
|
|
895
|
+
)
|
|
896
|
+
blocks.extend(
|
|
897
|
+
[
|
|
898
|
+
_TDSConv2dBlock(
|
|
899
|
+
n_block_channels,
|
|
900
|
+
num_features // n_block_channels,
|
|
901
|
+
kernel_width,
|
|
902
|
+
activation=activation,
|
|
903
|
+
),
|
|
904
|
+
_TDSFullyConnectedBlock(
|
|
905
|
+
num_features,
|
|
906
|
+
activation=activation,
|
|
907
|
+
drop_prob=drop_prob,
|
|
908
|
+
),
|
|
909
|
+
]
|
|
910
|
+
)
|
|
911
|
+
self.tds_conv_blocks = nn.Sequential(*blocks)
|
|
912
|
+
|
|
913
|
+
def forward(self, inputs: torch.Tensor) -> torch.Tensor:
|
|
914
|
+
return self.tds_conv_blocks(inputs)
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/ifnet.py
RENAMED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# License: MIT
|
|
2
1
|
"""IFNet Neural Network.
|
|
3
2
|
|
|
4
3
|
Authors: Jiaheng Wang
|
|
@@ -29,7 +28,7 @@ from braindecode.modules import (
|
|
|
29
28
|
)
|
|
30
29
|
|
|
31
30
|
|
|
32
|
-
class IFNet(EEGModuleMixin, nn.Module
|
|
31
|
+
class IFNet(EEGModuleMixin, nn.Module):
|
|
33
32
|
r"""IFNetV2 from Wang J et al (2023) [ifnet]_.
|
|
34
33
|
|
|
35
34
|
:bdg-success:`Convolution` :bdg-primary:`Filterbank`
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/luna.py
RENAMED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# License: Apache-2.0
|
|
2
1
|
"""This implementation is adapted from ETH Zurich's BioFoundation repository.
|
|
3
2
|
|
|
4
3
|
Döner, B., Ingolfsson, T. M., Benini, L., & Li, Y. (2025).
|
|
@@ -21,13 +20,14 @@ import torch.fft as fft
|
|
|
21
20
|
import torch.nn as nn
|
|
22
21
|
import torch.nn.functional as F
|
|
23
22
|
from einops import rearrange
|
|
23
|
+
from rotary_embedding_torch import RotaryEmbedding
|
|
24
24
|
|
|
25
25
|
from braindecode.models.base import EEGModuleMixin
|
|
26
26
|
from braindecode.models.util import extract_channel_locations_from_chs_info
|
|
27
27
|
from braindecode.modules.layers import DropPath
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
class LUNA(EEGModuleMixin, nn.Module
|
|
30
|
+
class LUNA(EEGModuleMixin, nn.Module):
|
|
31
31
|
r"""LUNA from Döner et al [LUNA]_.
|
|
32
32
|
|
|
33
33
|
:bdg-success:`Convolution` :bdg-danger:`Foundation Model` :bdg-dark-line:`Channel`
|
|
@@ -535,7 +535,7 @@ class _RotarySelfAttentionBlock(nn.Module):
|
|
|
535
535
|
self.dim = dim
|
|
536
536
|
self.num_heads = num_heads
|
|
537
537
|
head_dim = dim // num_heads
|
|
538
|
-
self.rotary_emb =
|
|
538
|
+
self.rotary_emb = RotaryEmbedding(dim=head_dim, learned_freq=False)
|
|
539
539
|
|
|
540
540
|
self.scale = qk_scale or head_dim**-0.5
|
|
541
541
|
|
|
@@ -545,17 +545,6 @@ class _RotarySelfAttentionBlock(nn.Module):
|
|
|
545
545
|
self.proj = nn.Linear(dim, dim)
|
|
546
546
|
self.proj_drop = nn.Dropout(proj_drop)
|
|
547
547
|
|
|
548
|
-
def _rotate_queries_or_keys(self, tensor: torch.Tensor) -> torch.Tensor:
|
|
549
|
-
"""Apply full-head RoPE without concatenating empty boundary views."""
|
|
550
|
-
seq_len = tensor.shape[-2]
|
|
551
|
-
positions = torch.arange(seq_len, device=tensor.device, dtype=tensor.dtype)
|
|
552
|
-
freqs = self.rotary_emb(positions)
|
|
553
|
-
|
|
554
|
-
pairs = tensor.reshape(*tensor.shape[:-1], -1, 2)
|
|
555
|
-
rotated = torch.stack((-pairs[..., 1], pairs[..., 0]), dim=-1).flatten(-2)
|
|
556
|
-
transformed = tensor * freqs.cos() + rotated * freqs.sin()
|
|
557
|
-
return transformed.to(tensor.dtype)
|
|
558
|
-
|
|
559
548
|
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
560
549
|
B, N, C = x.shape
|
|
561
550
|
qkv = (
|
|
@@ -564,8 +553,8 @@ class _RotarySelfAttentionBlock(nn.Module):
|
|
|
564
553
|
.permute(2, 0, 3, 1, 4)
|
|
565
554
|
) # (K, B, H, N, D)
|
|
566
555
|
q, k, v = qkv[0], qkv[1], qkv[2]
|
|
567
|
-
q = self.
|
|
568
|
-
k = self.
|
|
556
|
+
q = self.rotary_emb.rotate_queries_or_keys(q)
|
|
557
|
+
k = self.rotary_emb.rotate_queries_or_keys(k)
|
|
569
558
|
# Calculate attention scores
|
|
570
559
|
attn_weights = (q @ k.transpose(-2, -1)) * self.scale # (B, H, N, N)
|
|
571
560
|
|
|
@@ -581,21 +570,6 @@ class _RotarySelfAttentionBlock(nn.Module):
|
|
|
581
570
|
return self.proj_drop(self.proj(attn))
|
|
582
571
|
|
|
583
572
|
|
|
584
|
-
class _RotaryEmbedding(nn.Module):
|
|
585
|
-
"""Minimal language RoPE frequency generator used by LUNA."""
|
|
586
|
-
|
|
587
|
-
def __init__(self, dim: int, theta: float = 10000.0) -> None:
|
|
588
|
-
super().__init__()
|
|
589
|
-
frequencies = 1.0 / (
|
|
590
|
-
theta ** (torch.arange(0, dim, 2, dtype=torch.float32) / dim)
|
|
591
|
-
)
|
|
592
|
-
self.freqs = nn.Parameter(frequencies, requires_grad=False)
|
|
593
|
-
|
|
594
|
-
def forward(self, positions: torch.Tensor) -> torch.Tensor:
|
|
595
|
-
angles = positions.to(self.freqs.dtype).unsqueeze(-1) * self.freqs
|
|
596
|
-
return angles.repeat_interleave(2, dim=-1)
|
|
597
|
-
|
|
598
|
-
|
|
599
573
|
class _FeedForwardBlock(nn.Module):
|
|
600
574
|
def __init__(self, dim: int, hidden_dim: int, dropout: float = 0.0) -> None:
|
|
601
575
|
super().__init__()
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/medformer.py
RENAMED
|
@@ -17,7 +17,7 @@ from braindecode.functional import sinusoidal_positional_encoding
|
|
|
17
17
|
from braindecode.models.base import EEGModuleMixin
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
class MEDFormer(EEGModuleMixin, nn.Module
|
|
20
|
+
class MEDFormer(EEGModuleMixin, nn.Module):
|
|
21
21
|
r"""
|
|
22
22
|
Medformer from Wang et al (2024) [Medformer2024]_.
|
|
23
23
|
|
|
@@ -31,7 +31,7 @@ _LPadType = int | Literal["none", "steady", "full"]
|
|
|
31
31
|
# ---------------------------------------------------------------------------
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
class MetaNeuromotorHand(EEGModuleMixin, nn.Module
|
|
34
|
+
class MetaNeuromotorHand(EEGModuleMixin, nn.Module):
|
|
35
35
|
r"""Generic neuromotor interface for handwriting from Meta (2025) [gni2025]_.
|
|
36
36
|
|
|
37
37
|
:bdg-info:`Attention/Transformer` :bdg-success:`Convolution`
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/mvpformer.py
RENAMED
|
@@ -26,7 +26,7 @@ from braindecode.models.base import EEGModuleMixin
|
|
|
26
26
|
from braindecode.modules import PatchTokenizer
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
class MVPFormer(EEGModuleMixin, nn.Module
|
|
29
|
+
class MVPFormer(EEGModuleMixin, nn.Module):
|
|
30
30
|
r"""MVPFormer from Carzaniga et al. (2026) [Carzaniga2026]_.
|
|
31
31
|
|
|
32
32
|
:bdg-danger:`Foundation Model` :bdg-info:`Attention/Transformer`
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sstdpn.py
RENAMED
|
@@ -216,7 +216,7 @@ class SSTDPN(EEGModuleMixin, nn.Module):
|
|
|
216
216
|
temporal dual prototype network for motor imagery
|
|
217
217
|
brain–computer interface. Knowledge-Based Systems,
|
|
218
218
|
315, 113315. GitHub repository.
|
|
219
|
-
https://github.com/hancan16/SST-DPN
|
|
219
|
+
https://github.com/hancan16/SST-DPN.
|
|
220
220
|
"""
|
|
221
221
|
|
|
222
222
|
def __init__(
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/summary.csv
RENAMED
|
@@ -31,7 +31,7 @@ SincShallowNet,Motor Imagery,Prediction,250,"n_chans, n_outputs, n_times, sfreq"
|
|
|
31
31
|
ShallowFBCSPNet,General,Prediction,250,"n_chans, n_outputs, n_times",46084,"ShallowFBCSPNet(n_chans=22, n_outputs=4, n_times=1000, sfreq=250)","Convolution",EEG
|
|
32
32
|
SleepStagerBlanco2020,Sleep Staging,Prediction,100,"n_chans, n_outputs, n_times",2845,"SleepStagerBlanco2020(n_chans=2, n_outputs=5, n_times=3000, sfreq=100)","Convolution",EEG
|
|
33
33
|
SleepStagerChambon2018,Sleep Staging,Prediction,128,"n_chans, n_outputs, n_times, sfreq",5835,"SleepStagerChambon2018(n_chans=2, n_outputs=5, n_times=3840, sfreq=128)","Convolution",EEG
|
|
34
|
-
AttnSleep,Sleep Staging,Prediction,100,"n_chans, n_outputs, n_times, sfreq",
|
|
34
|
+
AttnSleep,Sleep Staging,Prediction,100,"n_chans, n_outputs, n_times, sfreq",719925,"AttnSleep(n_chans=2, n_outputs=5, n_times=3000, sfreq=100)","Convolution, Attention/Transformer",EEG
|
|
35
35
|
SPARCNet,Epilepsy,Prediction,200,"n_chans, n_outputs, n_times",1141921,"SPARCNet(n_chans=16, n_outputs=6, n_times=2000, sfreq=200)","Convolution",EEG
|
|
36
36
|
SyncNet,"Emotion Recognition, Alcoholism",Prediction,256,"n_chans, n_outputs, n_times",554,"SyncNet(n_chans=62, n_outputs=3, n_times=5120, sfreq=256)","Interpretability",EEG
|
|
37
37
|
TSception,Emotion Recognition,Prediction,256,"n_chans, n_outputs, n_times, sfreq",2187206,"TSception(n_chans=62, n_outputs=3, n_times=5120, sfreq=256)","Convolution",EEG
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/tcformer.py
RENAMED
|
@@ -14,7 +14,7 @@ from braindecode.models.base import EEGModuleMixin
|
|
|
14
14
|
from braindecode.modules import CausalConv1d, Conv1dWithConstraint, DropPath
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
class TCFormer(EEGModuleMixin, nn.Module
|
|
17
|
+
class TCFormer(EEGModuleMixin, nn.Module):
|
|
18
18
|
r"""TCFormer from Altaheri et al (2025) [tcformer]_.
|
|
19
19
|
|
|
20
20
|
:bdg-success:`Convolution` :bdg-info:`Attention/Transformer`
|
{braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/usleep.py
RENAMED
|
@@ -431,7 +431,11 @@ class _DecoderBlock(nn.Module):
|
|
|
431
431
|
) -> tuple[torch.Tensor, torch.Tensor]:
|
|
432
432
|
"""Crops two tensors to their lowest-common-dimension along an axis."""
|
|
433
433
|
dim_cropped = min(x1.shape[axis], x2.shape[axis])
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
434
|
+
|
|
435
|
+
x1_cropped = torch.index_select(
|
|
436
|
+
x1, dim=axis, index=torch.arange(dim_cropped).to(device=x1.device)
|
|
437
|
+
)
|
|
438
|
+
x2_cropped = torch.index_select(
|
|
439
|
+
x2, dim=axis, index=torch.arange(dim_cropped).to(device=x1.device)
|
|
437
440
|
)
|
|
441
|
+
return x1_cropped, x2_cropped
|