Braindecode 1.5.0.dev179275821__tar.gz → 1.5.0.dev182195895__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.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/NOTICE.txt +0 -5
- {braindecode-1.5.0.dev179275821/braindecode.egg-info → braindecode-1.5.0.dev182195895}/PKG-INFO +2 -6
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/base.py +1 -119
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/sleep_physionet.py +1 -15
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/__init__.py +3 -16
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/base.py +4 -16
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/bendr.py +28 -92
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/biot.py +1 -61
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/config.py +4 -5
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/labram.py +266 -208
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/reve.py +1 -1
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/signal_jepa.py +38 -463
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/summary.csv +0 -7
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/util.py +20 -151
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/__init__.py +0 -2
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/eegprep_preprocess.py +6 -51
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/preprocess.py +17 -38
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/windowers.py +4 -13
- braindecode-1.5.0.dev182195895/braindecode/version.py +1 -0
- braindecode-1.5.0.dev182195895/braindecode/visualization/__init__.py +8 -0
- braindecode-1.5.0.dev182195895/braindecode/visualization/gradients.py +62 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895/braindecode.egg-info}/PKG-INFO +2 -6
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode.egg-info/SOURCES.txt +1 -10
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode.egg-info/requires.txt +1 -6
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/api.rst +4 -106
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/cite.rst +2 -2
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/conf.py +2 -34
- braindecode-1.5.0.dev182195895/docs/index.rst +48 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/whats_new.rst +0 -142
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/pyproject.toml +1 -4
- braindecode-1.5.0.dev179275821/braindecode/models/codebrain.py +0 -977
- braindecode-1.5.0.dev179275821/braindecode/models/emg2qwerty.py +0 -714
- braindecode-1.5.0.dev179275821/braindecode/models/interpolated.py +0 -182
- braindecode-1.5.0.dev179275821/braindecode/models/meta_neuromotor.py +0 -1774
- braindecode-1.5.0.dev179275821/braindecode/modules/interpolation.py +0 -201
- braindecode-1.5.0.dev179275821/braindecode/version.py +0 -1
- braindecode-1.5.0.dev179275821/braindecode/visualization/__init__.py +0 -45
- braindecode-1.5.0.dev179275821/braindecode/visualization/attribution.py +0 -152
- braindecode-1.5.0.dev179275821/braindecode/visualization/frequency.py +0 -89
- braindecode-1.5.0.dev179275821/braindecode/visualization/metrics.py +0 -414
- braindecode-1.5.0.dev179275821/braindecode/visualization/sanity.py +0 -117
- braindecode-1.5.0.dev179275821/braindecode/visualization/topology.py +0 -64
- braindecode-1.5.0.dev179275821/docs/index.rst +0 -749
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/LICENSE.txt +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/MANIFEST.in +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/README.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/__init__.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/augmentation/__init__.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/augmentation/base.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/augmentation/functional.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/augmentation/transforms.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/classifier.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/__init__.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bbci.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bcicomp.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/__init__.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/datasets.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/format.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/hub.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/hub_format.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/hub_io.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/hub_validation.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/iterable.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/chb_mit.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/mne.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/moabb.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/nmt.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/registry.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/siena.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/tuh.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/utils.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/xy.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datautil/__init__.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datautil/channel_utils.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datautil/hub_formats.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datautil/serialization.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datautil/util.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/eegneuralnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/functional/__init__.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/functional/functions.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/functional/initialization.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/atcnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/attentionbasenet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/attn_sleep.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/brainmodule.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/cbramod.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/contrawr.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/ctnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/deep4.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/deepsleepnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/dgcnn.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegconformer.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eeginception_erp.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eeginception_mi.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegitnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegminer.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegnex.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegpt.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegsimpleconv.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegsym.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegtcnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/fbcnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/fblightconvnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/fbmsnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/hybrid.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/ifnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/luna.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/medformer.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/msvtnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/patchedtransformer.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sccnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/shallow_fbcsp.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sinc_shallow.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sparcnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sstdpn.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/syncnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/tcn.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/tidnet.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/tsinception.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/usleep.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/activation.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/attention.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/blocks.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/convolution.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/filter.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/layers.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/linear.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/parametrization.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/stats.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/util.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/wrapper.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/__init__.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/mne_preprocess.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/util.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/regressor.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/samplers/__init__.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/samplers/base.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/samplers/ssl.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/training/__init__.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/training/callbacks.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/training/losses.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/training/scoring.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/util.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/visualization/confusion_matrices.py +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode.egg-info/dependency_links.txt +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode.egg-info/top_level.txt +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/Makefile +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/_templates/autosummary/class.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/_templates/autosummary/function.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/help.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/install/install.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/install/install_pip.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/install/install_source.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/attention.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/channel.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/convolution.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/filterbank.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/gnn.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/interpretable.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/lbm.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/recurrent.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/spd.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/models.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/models_categorization.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/models_table.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/models_visualization.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/sg_execution_times.rst +0 -0
- {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/setup.cfg +0 -0
|
@@ -11,14 +11,9 @@ All files within the `src/` directory are licensed under the BSD-3-Clause Licens
|
|
|
11
11
|
The following components are licensed under the Creative Commons Attribution-NonCommercial 4.0 International License:
|
|
12
12
|
|
|
13
13
|
- `braindecode/models/eegminer.py`
|
|
14
|
-
- `braindecode/models/meta_neuromotor.py`
|
|
15
14
|
|
|
16
15
|
As well as class later imported into the `braindecode.models.module` named as GeneralizedGaussianFilter.
|
|
17
16
|
|
|
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
17
|
## License Links
|
|
23
18
|
|
|
24
19
|
- [BSD-3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
{braindecode-1.5.0.dev179275821/braindecode.egg-info → braindecode-1.5.0.dev182195895}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: braindecode
|
|
3
|
-
Version: 1.5.0.
|
|
3
|
+
Version: 1.5.0.dev182195895
|
|
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>
|
|
@@ -43,8 +43,6 @@ Requires-Dist: eegprep[eeglabio]>=0.2.23; extra == "eegprep"
|
|
|
43
43
|
Provides-Extra: hub
|
|
44
44
|
Requires-Dist: huggingface_hub[torch]>=0.20.0; extra == "hub"
|
|
45
45
|
Requires-Dist: zarr>=3.0; extra == "hub"
|
|
46
|
-
Provides-Extra: viz
|
|
47
|
-
Requires-Dist: captum>=0.7.0; extra == "viz"
|
|
48
46
|
Provides-Extra: tests
|
|
49
47
|
Requires-Dist: pytest; extra == "tests"
|
|
50
48
|
Requires-Dist: pytest-cov; extra == "tests"
|
|
@@ -63,7 +61,6 @@ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
|
|
|
63
61
|
Requires-Dist: sphinx-autobuild; extra == "docs"
|
|
64
62
|
Requires-Dist: sphinxcontrib-bibtex; extra == "docs"
|
|
65
63
|
Requires-Dist: sphinx_sitemap; extra == "docs"
|
|
66
|
-
Requires-Dist: sphinxext-opengraph; extra == "docs"
|
|
67
64
|
Requires-Dist: pydata_sphinx_theme; extra == "docs"
|
|
68
65
|
Requires-Dist: numpydoc; extra == "docs"
|
|
69
66
|
Requires-Dist: memory_profiler; extra == "docs"
|
|
@@ -73,7 +70,7 @@ Requires-Dist: sphinx_design; extra == "docs"
|
|
|
73
70
|
Requires-Dist: lightning; extra == "docs"
|
|
74
71
|
Requires-Dist: seaborn; extra == "docs"
|
|
75
72
|
Requires-Dist: pre-commit; extra == "docs"
|
|
76
|
-
Requires-Dist: openneuro-py
|
|
73
|
+
Requires-Dist: openneuro-py; extra == "docs"
|
|
77
74
|
Requires-Dist: plotly; extra == "docs"
|
|
78
75
|
Requires-Dist: shap; extra == "docs"
|
|
79
76
|
Requires-Dist: nbformat; extra == "docs"
|
|
@@ -85,7 +82,6 @@ Requires-Dist: braindecode[docs]; extra == "all"
|
|
|
85
82
|
Requires-Dist: braindecode[hub]; extra == "all"
|
|
86
83
|
Requires-Dist: braindecode[eegprep]; extra == "all"
|
|
87
84
|
Requires-Dist: braindecode[typing]; extra == "all"
|
|
88
|
-
Requires-Dist: braindecode[viz]; extra == "all"
|
|
89
85
|
Dynamic: license-file
|
|
90
86
|
|
|
91
87
|
.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.17699192.svg
|
{braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/base.py
RENAMED
|
@@ -18,7 +18,7 @@ import shutil
|
|
|
18
18
|
import warnings
|
|
19
19
|
from abc import abstractmethod
|
|
20
20
|
from collections import Counter
|
|
21
|
-
from collections.abc import Callable
|
|
21
|
+
from collections.abc import Callable
|
|
22
22
|
from glob import glob
|
|
23
23
|
from pathlib import Path
|
|
24
24
|
from typing import Any, Generic, Iterable, no_type_check
|
|
@@ -1340,124 +1340,6 @@ class BaseConcatDataset(ConcatDataset, HubDatasetMixin, Generic[T]):
|
|
|
1340
1340
|
raise TypeError("target_transform must be a callable.")
|
|
1341
1341
|
self._target_transform = fn
|
|
1342
1342
|
|
|
1343
|
-
def set_target(self, column: Hashable) -> "BaseConcatDataset":
|
|
1344
|
-
"""Use ``column`` as the target ``y`` for every subdataset.
|
|
1345
|
-
|
|
1346
|
-
Dispatches on the subdataset type:
|
|
1347
|
-
|
|
1348
|
-
* For :class:`WindowsDataset` / :class:`EEGWindowsDataset`,
|
|
1349
|
-
``column`` is looked up in per-window ``metadata`` first, then in
|
|
1350
|
-
the per-record ``description`` (broadcast to every window). The
|
|
1351
|
-
resolved values overwrite ``ds.metadata['target']`` and ``ds.y``.
|
|
1352
|
-
For :class:`WindowsDataset`, the underlying ``ds.windows.metadata``
|
|
1353
|
-
is kept in sync so ``get_metadata()`` and the repr reflect the
|
|
1354
|
-
new target.
|
|
1355
|
-
* For :class:`RawDataset`, ``column`` must exist on the
|
|
1356
|
-
``description``. ``ds.target_name`` is set to ``column`` so
|
|
1357
|
-
``__getitem__`` reads ``description[column]`` as ``y`` on every
|
|
1358
|
-
access — no rebuild needed.
|
|
1359
|
-
|
|
1360
|
-
Parameters
|
|
1361
|
-
----------
|
|
1362
|
-
column : Hashable
|
|
1363
|
-
Name of a metadata column or description field (BIDS entity,
|
|
1364
|
-
participants.tsv extra, ...). Typically a string, but any
|
|
1365
|
-
hashable that pandas accepts as a column label is allowed.
|
|
1366
|
-
|
|
1367
|
-
Returns
|
|
1368
|
-
-------
|
|
1369
|
-
self : BaseConcatDataset
|
|
1370
|
-
|
|
1371
|
-
Raises
|
|
1372
|
-
------
|
|
1373
|
-
TypeError
|
|
1374
|
-
If any subdataset is not a :class:`WindowsDataset`,
|
|
1375
|
-
:class:`EEGWindowsDataset`, or :class:`RawDataset`, or if a
|
|
1376
|
-
windowed subdataset has lazy (non-DataFrame) metadata.
|
|
1377
|
-
ValueError
|
|
1378
|
-
If ``column`` is not present on a subdataset's metadata or
|
|
1379
|
-
description, or if a windowed subdataset has
|
|
1380
|
-
``targets_from='channels'`` (which would make this a silent
|
|
1381
|
-
no-op since ``__getitem__`` reads y from misc channels, not
|
|
1382
|
-
from ``metadata['target']``).
|
|
1383
|
-
"""
|
|
1384
|
-
for i, ds in enumerate(self.datasets):
|
|
1385
|
-
if isinstance(ds, (WindowsDataset, EEGWindowsDataset)):
|
|
1386
|
-
if not isinstance(ds.metadata, pd.DataFrame):
|
|
1387
|
-
# _LazyDataFrame (lazy_metadata=True) does not implement
|
|
1388
|
-
# .copy()/__setitem__, so the in-place write below would
|
|
1389
|
-
# raise AttributeError. Surface the precondition cleanly.
|
|
1390
|
-
raise TypeError(
|
|
1391
|
-
"set_target requires a materialized metadata "
|
|
1392
|
-
f"DataFrame; datasets[{i}].metadata is "
|
|
1393
|
-
f"{type(ds.metadata).__name__}. Re-window with "
|
|
1394
|
-
"lazy_metadata=False to use set_target."
|
|
1395
|
-
)
|
|
1396
|
-
if getattr(ds, "targets_from", "metadata") != "metadata":
|
|
1397
|
-
# __getitem__ would read y from misc channels; writing
|
|
1398
|
-
# metadata['target']/ds.y would be a silent no-op.
|
|
1399
|
-
raise ValueError(
|
|
1400
|
-
f"datasets[{i}] has targets_from="
|
|
1401
|
-
f"{ds.targets_from!r}; set_target only applies when "
|
|
1402
|
-
"targets_from='metadata' (otherwise __getitem__ "
|
|
1403
|
-
"derives y from misc channels and would ignore the "
|
|
1404
|
-
"rewritten target column)."
|
|
1405
|
-
)
|
|
1406
|
-
n = len(ds)
|
|
1407
|
-
md = ds.metadata
|
|
1408
|
-
if column in md.columns:
|
|
1409
|
-
values = md[column].iloc[:n].to_list()
|
|
1410
|
-
elif (
|
|
1411
|
-
isinstance(ds.description, pd.Series)
|
|
1412
|
-
and column in ds.description.index
|
|
1413
|
-
):
|
|
1414
|
-
values = [ds.description[column]] * n
|
|
1415
|
-
else:
|
|
1416
|
-
desc_keys = (
|
|
1417
|
-
list(ds.description.index)
|
|
1418
|
-
if isinstance(ds.description, pd.Series)
|
|
1419
|
-
else []
|
|
1420
|
-
)
|
|
1421
|
-
raise ValueError(
|
|
1422
|
-
f"Column {column!r} not found on datasets[{i}]: "
|
|
1423
|
-
f"metadata cols={list(md.columns)}, "
|
|
1424
|
-
f"description keys={desc_keys}."
|
|
1425
|
-
)
|
|
1426
|
-
# In-place write so the WindowsDataset's metadata and the
|
|
1427
|
-
# underlying mne.Epochs.metadata (which start as the same
|
|
1428
|
-
# object reference) both reflect the new target. Defensive
|
|
1429
|
-
# second write covers the case where they got de-aliased
|
|
1430
|
-
# earlier by a caller-side reassignment.
|
|
1431
|
-
md["target"] = values
|
|
1432
|
-
windows_obj = getattr(ds, "_windows", None)
|
|
1433
|
-
if windows_obj is not None and windows_obj.metadata is not md:
|
|
1434
|
-
windows_obj.metadata["target"] = values
|
|
1435
|
-
# values is already a fresh list (Series.to_list() / [x] * n);
|
|
1436
|
-
# no defensive copy needed — pandas keeps its own representation
|
|
1437
|
-
# for md["target"] so mutating ds.y won't reach back into it.
|
|
1438
|
-
ds.y = values
|
|
1439
|
-
elif isinstance(ds, RawDataset):
|
|
1440
|
-
if (
|
|
1441
|
-
not isinstance(ds.description, pd.Series)
|
|
1442
|
-
or column not in ds.description.index
|
|
1443
|
-
):
|
|
1444
|
-
desc_keys = (
|
|
1445
|
-
list(ds.description.index)
|
|
1446
|
-
if isinstance(ds.description, pd.Series)
|
|
1447
|
-
else []
|
|
1448
|
-
)
|
|
1449
|
-
raise ValueError(
|
|
1450
|
-
f"Column {column!r} not found on datasets[{i}] "
|
|
1451
|
-
f"description (keys={desc_keys})."
|
|
1452
|
-
)
|
|
1453
|
-
ds.target_name = column
|
|
1454
|
-
else:
|
|
1455
|
-
raise TypeError(
|
|
1456
|
-
"set_target requires WindowsDataset, EEGWindowsDataset, "
|
|
1457
|
-
f"or RawDataset; datasets[{i}] is {type(ds).__name__}."
|
|
1458
|
-
)
|
|
1459
|
-
return self
|
|
1460
|
-
|
|
1461
1343
|
def _outdated_save(self, path, overwrite=False):
|
|
1462
1344
|
"""This is a copy of the old saving function, that had inconsistent.
|
|
1463
1345
|
|
|
@@ -6,12 +6,10 @@
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
import os
|
|
9
|
-
import time
|
|
10
9
|
|
|
11
10
|
import mne
|
|
12
11
|
import numpy as np
|
|
13
12
|
import pandas as pd
|
|
14
|
-
import requests
|
|
15
13
|
from mne.datasets.sleep_physionet.age import fetch_data
|
|
16
14
|
|
|
17
15
|
from .base import BaseConcatDataset, RawDataset
|
|
@@ -61,19 +59,7 @@ class SleepPhysionet(BaseConcatDataset):
|
|
|
61
59
|
if recording_ids is None:
|
|
62
60
|
recording_ids = [1, 2]
|
|
63
61
|
|
|
64
|
-
|
|
65
|
-
retry_delay_s = 10
|
|
66
|
-
|
|
67
|
-
for attempt in range(max_attempts):
|
|
68
|
-
try:
|
|
69
|
-
paths = fetch_data(
|
|
70
|
-
subject_ids, recording=recording_ids, on_missing="warn"
|
|
71
|
-
)
|
|
72
|
-
break
|
|
73
|
-
except requests.exceptions.RequestException:
|
|
74
|
-
if attempt == max_attempts - 1:
|
|
75
|
-
raise
|
|
76
|
-
time.sleep(retry_delay_s)
|
|
62
|
+
paths = fetch_data(subject_ids, recording=recording_ids, on_missing="warn")
|
|
77
63
|
|
|
78
64
|
all_base_ds = list()
|
|
79
65
|
for p in paths:
|
{braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/__init__.py
RENAMED
|
@@ -4,11 +4,10 @@ from .atcnet import ATCNet
|
|
|
4
4
|
from .attentionbasenet import AttentionBaseNet
|
|
5
5
|
from .attn_sleep import AttnSleep
|
|
6
6
|
from .base import EEGModuleMixin
|
|
7
|
-
from .bendr import BENDR
|
|
8
|
-
from .biot import BIOT
|
|
7
|
+
from .bendr import BENDR
|
|
8
|
+
from .biot import BIOT
|
|
9
9
|
from .brainmodule import BrainModule
|
|
10
10
|
from .cbramod import CBraMod
|
|
11
|
-
from .codebrain import CodeBrain
|
|
12
11
|
from .contrawr import ContraWR
|
|
13
12
|
from .ctnet import CTNet
|
|
14
13
|
from .deep4 import Deep4Net
|
|
@@ -25,24 +24,20 @@ from .eegpt import EEGPT
|
|
|
25
24
|
from .eegsimpleconv import EEGSimpleConv
|
|
26
25
|
from .eegsym import EEGSym
|
|
27
26
|
from .eegtcnet import EEGTCNet
|
|
28
|
-
from .emg2qwerty import EMG2QwertyNet
|
|
29
27
|
from .fbcnet import FBCNet
|
|
30
28
|
from .fblightconvnet import FBLightConvNet
|
|
31
29
|
from .fbmsnet import FBMSNet
|
|
32
30
|
from .hybrid import HybridNet
|
|
33
31
|
from .ifnet import IFNet
|
|
34
|
-
from .
|
|
35
|
-
from .labram import InterpolatedLaBraM, Labram
|
|
32
|
+
from .labram import Labram
|
|
36
33
|
from .luna import LUNA
|
|
37
34
|
from .medformer import MEDFormer
|
|
38
|
-
from .meta_neuromotor import MetaNeuromotorHand
|
|
39
35
|
from .msvtnet import MSVTNet
|
|
40
36
|
from .patchedtransformer import PBT
|
|
41
37
|
from .reve import REVE
|
|
42
38
|
from .sccnet import SCCNet
|
|
43
39
|
from .shallow_fbcsp import ShallowFBCSPNet
|
|
44
40
|
from .signal_jepa import (
|
|
45
|
-
InterpolatedSignalJEPA,
|
|
46
41
|
SignalJEPA,
|
|
47
42
|
SignalJEPA_Contextual,
|
|
48
43
|
SignalJEPA_PostLocal,
|
|
@@ -77,7 +72,6 @@ __all__ = [
|
|
|
77
72
|
"BIOT",
|
|
78
73
|
"BENDR",
|
|
79
74
|
"CBraMod",
|
|
80
|
-
"CodeBrain",
|
|
81
75
|
"ContraWR",
|
|
82
76
|
"CTNet",
|
|
83
77
|
"Deep4Net",
|
|
@@ -96,18 +90,11 @@ __all__ = [
|
|
|
96
90
|
"EEGSimpleConv",
|
|
97
91
|
"EEGTCNet",
|
|
98
92
|
"DGCNN",
|
|
99
|
-
"EMG2QwertyNet",
|
|
100
93
|
"FBCNet",
|
|
101
94
|
"FBLightConvNet",
|
|
102
95
|
"FBMSNet",
|
|
103
|
-
"MetaNeuromotorHand",
|
|
104
96
|
"HybridNet",
|
|
105
97
|
"IFNet",
|
|
106
|
-
"InterpolatedBENDR",
|
|
107
|
-
"InterpolatedBIOT",
|
|
108
|
-
"InterpolatedLaBraM",
|
|
109
|
-
"InterpolatedModel",
|
|
110
|
-
"InterpolatedSignalJEPA",
|
|
111
98
|
"Labram",
|
|
112
99
|
"LUNA",
|
|
113
100
|
"extract_channel_locations_from_chs_info",
|
{braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/base.py
RENAMED
|
@@ -33,25 +33,13 @@ huggingface_hub = _soft_import(
|
|
|
33
33
|
HAS_HF_HUB = huggingface_hub is not False
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"Install with: pip install 'braindecode[hub]'"
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class _BaseHubMixinStub:
|
|
43
|
-
@classmethod
|
|
44
|
-
def from_pretrained(cls, *args, **kwargs):
|
|
45
|
-
raise ImportError(f"{cls.__name__}.from_pretrained() {_HF_INSTALL_HINT}")
|
|
46
|
-
|
|
47
|
-
def push_to_hub(self, *args, **kwargs):
|
|
48
|
-
raise ImportError(f"{type(self).__name__}.push_to_hub() {_HF_INSTALL_HINT}")
|
|
36
|
+
class _BaseHubMixin:
|
|
37
|
+
pass
|
|
49
38
|
|
|
50
39
|
|
|
51
40
|
# Define base class for hub mixin
|
|
52
|
-
|
|
53
|
-
huggingface_hub.PyTorchModelHubMixin
|
|
54
|
-
)
|
|
41
|
+
if HAS_HF_HUB:
|
|
42
|
+
_BaseHubMixin: Type = huggingface_hub.PyTorchModelHubMixin # type: ignore
|
|
55
43
|
|
|
56
44
|
|
|
57
45
|
def deprecated_args(obj, *old_new_args):
|
{braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/bendr.py
RENAMED
|
@@ -1,60 +1,12 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
|
|
3
|
-
import numpy as np
|
|
4
3
|
import torch
|
|
5
4
|
from einops.layers.torch import Rearrange
|
|
6
5
|
from torch import nn
|
|
6
|
+
from torch.nn.utils.parametrize import register_parametrization
|
|
7
7
|
|
|
8
8
|
from braindecode.models.base import EEGModuleMixin
|
|
9
|
-
|
|
10
|
-
# The 20 channels used to pre-train BENDR, in the order expected by the
|
|
11
|
-
# `braindecode/braindecode-bendr` checkpoint. The first 19 entries are the
|
|
12
|
-
# EEG channels taken verbatim from `dn3.transforms.instance.To1020.EEG_20_div`
|
|
13
|
-
# (https://github.com/SPOClab-ca/dn3/blob/master/dn3/transforms/instance.py).
|
|
14
|
-
# Their positions come from MNE's ``standard_1005`` montage (T5/T6 are
|
|
15
|
-
# legacy names that share positions with P7/P8 there).
|
|
16
|
-
#
|
|
17
|
-
# The 20th entry is ``SCALE``, a relative-amplitude statistic (not an
|
|
18
|
-
# electrode) appended by ``To1020(include_scale_ch=True)`` during
|
|
19
|
-
# pre-training. Since it has no physical position, the ``loc`` below is
|
|
20
|
-
# the centroid of the 19 EEG positions — purely a placeholder so that
|
|
21
|
-
# :class:`~braindecode.modules.ChannelInterpolationLayer` (used by
|
|
22
|
-
# :class:`InterpolatedBENDR`) can build a valid spline interpolation
|
|
23
|
-
# matrix. It is NOT the SCALE the pre-training pipeline computes
|
|
24
|
-
# (which is an RMS-like amplitude via ``dn3.MappingDeep1010``); users
|
|
25
|
-
# who need a faithful SCALE must compute it themselves and feed 20
|
|
26
|
-
# channels to :class:`BENDR` directly.
|
|
27
|
-
_BENDR_TARGET_CHS_TUPLES: list[tuple[str, tuple[float, float, float]]] = [
|
|
28
|
-
("FP1", (-0.0294367, +0.0839171, -0.0069900)), # standard_1005
|
|
29
|
-
("FP2", (+0.0298723, +0.0848959, -0.0070800)), # standard_1005
|
|
30
|
-
("F7", (-0.0702629, +0.0424743, -0.0114200)), # standard_1005
|
|
31
|
-
("F3", (-0.0502438, +0.0531112, +0.0421920)), # standard_1005
|
|
32
|
-
("FZ", (+0.0003122, +0.0585120, +0.0664620)), # standard_1005
|
|
33
|
-
("F4", (+0.0518362, +0.0543048, +0.0408140)), # standard_1005
|
|
34
|
-
("F8", (+0.0730431, +0.0444217, -0.0120000)), # standard_1005
|
|
35
|
-
("T7", (-0.0841611, -0.0160187, -0.0093460)), # standard_1005
|
|
36
|
-
("C3", (-0.0653581, -0.0116317, +0.0643580)), # standard_1005
|
|
37
|
-
("CZ", (+0.0004009, -0.0091670, +0.1002440)), # standard_1005
|
|
38
|
-
("C4", (+0.0671179, -0.0109003, +0.0635800)), # standard_1005
|
|
39
|
-
("T8", (+0.0850799, -0.0150203, -0.0094900)), # standard_1005
|
|
40
|
-
("T5", (-0.0724343, -0.0734527, -0.0024870)), # standard_1005 (= P7)
|
|
41
|
-
("P3", (-0.0530073, -0.0787878, +0.0559400)), # standard_1005
|
|
42
|
-
("PZ", (+0.0003247, -0.0811150, +0.0826150)), # standard_1005
|
|
43
|
-
("P4", (+0.0556667, -0.0785602, +0.0565610)), # standard_1005
|
|
44
|
-
("T6", (+0.0730557, -0.0730683, -0.0025400)), # standard_1005 (= P8)
|
|
45
|
-
("O1", (-0.0294134, -0.1124490, +0.0088390)), # standard_1005
|
|
46
|
-
("O2", (+0.0298426, -0.1121560, +0.0088000)), # standard_1005
|
|
47
|
-
(
|
|
48
|
-
"SCALE",
|
|
49
|
-
(+0.0006439, -0.0131942, +0.0278448),
|
|
50
|
-
), # centroid of the 19 EEG positions (placeholder; see comment above)
|
|
51
|
-
]
|
|
52
|
-
|
|
53
|
-
_BENDR_TARGET_CHS_INFO: list[dict] = [
|
|
54
|
-
{"ch_name": ch, "kind": "eeg", "loc": np.asarray(loc, dtype=float)}
|
|
55
|
-
for ch, loc in _BENDR_TARGET_CHS_TUPLES
|
|
56
|
-
]
|
|
57
|
-
BENDR_CHANNEL_ORDER: list[str] = [ch for ch, _ in _BENDR_TARGET_CHS_TUPLES]
|
|
9
|
+
from braindecode.modules.parametrization import MaxNormParametrize
|
|
58
10
|
|
|
59
11
|
|
|
60
12
|
class BENDR(EEGModuleMixin, nn.Module):
|
|
@@ -243,6 +195,15 @@ class BENDR(EEGModuleMixin, nn.Module):
|
|
|
243
195
|
The contextualizer is still created (to allow loading pretrained weights) but is not
|
|
244
196
|
used in the forward pass. Requires input length of at least
|
|
245
197
|
``4 * product(enc_downsample)`` samples (384 with default downsampling of 96x).
|
|
198
|
+
n_chans_pretrained : int or None, default=None
|
|
199
|
+
Number of input channels the pretrained weights expect (20 for the official BENDR
|
|
200
|
+
checkpoint). When set and ``n_chans != n_chans_pretrained``, a 1x1 Conv1d with
|
|
201
|
+
max-norm constraint projects from ``n_chans`` to ``n_chans_pretrained`` before the
|
|
202
|
+
encoder. This allows fine-tuning pretrained BENDR on datasets with arbitrary channel
|
|
203
|
+
counts. When using ``from_pretrained``, pass ``strict=False`` since the checkpoint
|
|
204
|
+
will not contain ``channel_projection`` weights.
|
|
205
|
+
chan_proj_max_norm : float, default=1.0
|
|
206
|
+
Max-norm constraint value for the channel projection weights.
|
|
246
207
|
"""
|
|
247
208
|
|
|
248
209
|
def __init__(
|
|
@@ -270,6 +231,8 @@ class BENDR(EEGModuleMixin, nn.Module):
|
|
|
270
231
|
start_token=-5, # Value for start token embedding
|
|
271
232
|
final_layer=True, # Whether to include the final linear layer
|
|
272
233
|
encoder_only=False, # If True, bypass contextualizer and use 4-chunk pooling
|
|
234
|
+
n_chans_pretrained=None, # Expected input channels of pretrained weights
|
|
235
|
+
chan_proj_max_norm=1.0, # Max-norm for channel projection weights
|
|
273
236
|
):
|
|
274
237
|
super().__init__(
|
|
275
238
|
n_outputs=n_outputs,
|
|
@@ -283,34 +246,25 @@ class BENDR(EEGModuleMixin, nn.Module):
|
|
|
283
246
|
# Keep these parameters if needed later, otherwise they are captured by the mixin
|
|
284
247
|
del n_outputs, n_chans, chs_info, n_times, input_window_seconds, sfreq
|
|
285
248
|
|
|
286
|
-
# If the user supplies chs_info, require it to match BENDR_CHANNEL_ORDER
|
|
287
|
-
# exactly (case-insensitive). Arbitrary channel sets should go through
|
|
288
|
-
# InterpolatedBENDR — same pattern as Labram / InterpolatedLaBraM.
|
|
289
|
-
# When chs_info is absent (the usual n_chans=20 path, incl.
|
|
290
|
-
# from_pretrained), no check is performed.
|
|
291
|
-
try:
|
|
292
|
-
_chs_info = self.chs_info
|
|
293
|
-
except ValueError:
|
|
294
|
-
_chs_info = None
|
|
295
|
-
if _chs_info is not None:
|
|
296
|
-
user_names = [ch["ch_name"] for ch in _chs_info] # type: ignore[index]
|
|
297
|
-
canonical = BENDR_CHANNEL_ORDER
|
|
298
|
-
if [n.lower() for n in user_names] != [n.lower() for n in canonical]:
|
|
299
|
-
raise ValueError(
|
|
300
|
-
f"BENDR requires chs_info to match BENDR_CHANNEL_ORDER exactly "
|
|
301
|
-
f"({len(canonical)} channels, specific order; last is 'SCALE'). "
|
|
302
|
-
f"Got {len(user_names)} channel(s). For arbitrary channel sets, "
|
|
303
|
-
f"use InterpolatedBENDR "
|
|
304
|
-
f"(from braindecode.models import InterpolatedBENDR)."
|
|
305
|
-
)
|
|
306
|
-
|
|
307
249
|
self.encoder_h = encoder_h
|
|
308
250
|
self.contextualizer_hidden = contextualizer_hidden
|
|
309
251
|
self.include_final_layer = final_layer
|
|
310
252
|
self.encoder_only = encoder_only
|
|
311
253
|
|
|
254
|
+
# Channel projection for pretrained weight compatibility
|
|
255
|
+
encoder_n_chans = self.n_chans
|
|
256
|
+
if n_chans_pretrained is not None and self.n_chans != n_chans_pretrained:
|
|
257
|
+
conv = nn.Conv1d(self.n_chans, n_chans_pretrained, 1, bias=False)
|
|
258
|
+
register_parametrization(
|
|
259
|
+
conv, "weight", MaxNormParametrize(chan_proj_max_norm)
|
|
260
|
+
)
|
|
261
|
+
self.channel_projection = conv
|
|
262
|
+
encoder_n_chans = n_chans_pretrained
|
|
263
|
+
else:
|
|
264
|
+
self.channel_projection = None
|
|
265
|
+
|
|
312
266
|
self.encoder = _ConvEncoderBENDR(
|
|
313
|
-
in_features=
|
|
267
|
+
in_features=encoder_n_chans,
|
|
314
268
|
encoder_h=encoder_h,
|
|
315
269
|
dropout=drop_prob,
|
|
316
270
|
projection_head=projection_head,
|
|
@@ -354,6 +308,8 @@ class BENDR(EEGModuleMixin, nn.Module):
|
|
|
354
308
|
self._build_head(n_outputs)
|
|
355
309
|
|
|
356
310
|
def forward(self, x, return_features=False):
|
|
311
|
+
if self.channel_projection is not None:
|
|
312
|
+
x = self.channel_projection(x)
|
|
357
313
|
encoded = self.encoder(x)
|
|
358
314
|
# encoded: [batch_size, encoder_h, n_encoded_times]
|
|
359
315
|
|
|
@@ -596,23 +552,3 @@ class _BENDRContextualizer(nn.Module):
|
|
|
596
552
|
# x: [batch_size, in_features, seq_len + 1]
|
|
597
553
|
|
|
598
554
|
return x
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
# -----------------------------------------------------------------------------
|
|
602
|
-
# InterpolatedBENDR — experimental channel-interpolation variant of BENDR
|
|
603
|
-
# -----------------------------------------------------------------------------
|
|
604
|
-
# Wraps :class:`BENDR` with an MNE-backed channel-interpolation layer that
|
|
605
|
-
# projects arbitrary user ``chs_info`` to the canonical 20-channel BENDR
|
|
606
|
-
# input (:data:`_BENDR_TARGET_CHS_INFO` — the 19 pre-training EEG channels
|
|
607
|
-
# plus a ``SCALE`` placeholder at the centroid of those 19 positions).
|
|
608
|
-
# Frozen by default; set ``trainable=True`` to fine-tune the projection.
|
|
609
|
-
#
|
|
610
|
-
# NOTE: the ``SCALE`` target has no physical position, so the row of the
|
|
611
|
-
# interpolation matrix that produces it is a spatial spline of the user's
|
|
612
|
-
# EEG channels — *not* the dn3 ``MappingDeep1010`` RMS statistic the
|
|
613
|
-
# checkpoint saw during pre-training. Expect degraded zero-shot transfer
|
|
614
|
-
# from the SCALE channel; downstream fine-tuning should still work.
|
|
615
|
-
|
|
616
|
-
from braindecode.models.interpolated import InterpolatedModel # noqa: E402
|
|
617
|
-
|
|
618
|
-
InterpolatedBENDR = InterpolatedModel(BENDR, _BENDR_TARGET_CHS_INFO)
|
{braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/biot.py
RENAMED
|
@@ -1,57 +1,12 @@
|
|
|
1
1
|
import math
|
|
2
2
|
from warnings import warn
|
|
3
3
|
|
|
4
|
-
import numpy as np
|
|
5
4
|
import torch
|
|
6
5
|
import torch.nn as nn
|
|
7
6
|
from linear_attention_transformer import LinearAttentionTransformer
|
|
8
7
|
|
|
9
8
|
from braindecode.models.base import EEGModuleMixin
|
|
10
9
|
|
|
11
|
-
# -----------------------------------------------------------------------------
|
|
12
|
-
# Canonical channel order for InterpolatedBIOT — the 18-channel TCP bipolar
|
|
13
|
-
# montage used by BIOT's shhs-prest and six-datasets pretrained checkpoints.
|
|
14
|
-
# Source: https://github.com/ycq091044/BIOT (README + datasets/TUAB/process.py
|
|
15
|
-
# + datasets/SHHS/process.py). Indices 0-15 are the TCP 16-channel bipolar
|
|
16
|
-
# derivations; indices 16-17 are SHHS differential channels.
|
|
17
|
-
#
|
|
18
|
-
# The `loc` values are only used to build an MNE interpolation matrix for
|
|
19
|
-
# InterpolatedBIOT. All entries are bipolar / differential derivations.
|
|
20
|
-
# TODO: positions are stored as the midpoint of the two constituent
|
|
21
|
-
# electrodes. This is a simplification — a bipolar signal V(A)-V(B) cannot
|
|
22
|
-
# be faithfully recovered by spatial interpolation at the midpoint. Revisit
|
|
23
|
-
# in a follow-up PR (e.g. a dedicated BipolarDerivationLayer).
|
|
24
|
-
# -----------------------------------------------------------------------------
|
|
25
|
-
|
|
26
|
-
# fmt: off
|
|
27
|
-
_BIOT_TARGET_CHS_TUPLES: list[tuple[str, tuple[float, float, float]]] = [
|
|
28
|
-
("FP1-F7", (-0.04984980, 0.06319570, -0.00920500)),
|
|
29
|
-
("F7-T7", (-0.07721200, 0.01322780, -0.01038300)),
|
|
30
|
-
("T7-P7", (-0.07829770, -0.04473570, -0.00591650)),
|
|
31
|
-
("P7-O1", (-0.05092385, -0.09295085, 0.00317600)),
|
|
32
|
-
("FP2-F8", (0.05145770, 0.06465880, -0.00954000)),
|
|
33
|
-
("F8-T8", (0.07906150, 0.01470070, -0.01074500)),
|
|
34
|
-
("T8-P8", (0.07906780, -0.04404430, -0.00601500)),
|
|
35
|
-
("P8-O2", (0.05144915, -0.09261215, 0.00313000)),
|
|
36
|
-
("FP1-F3", (-0.03984025, 0.06851415, 0.01760100)),
|
|
37
|
-
("F3-C3", (-0.05780095, 0.02073975, 0.05327500)),
|
|
38
|
-
("C3-P3", (-0.05918270, -0.04520975, 0.06014900)),
|
|
39
|
-
("P3-O1", (-0.04121035, -0.09561840, 0.03238950)),
|
|
40
|
-
("FP2-F4", (0.04085425, 0.06960035, 0.01686700)),
|
|
41
|
-
("F4-C4", (0.05947705, 0.02170225, 0.05219700)),
|
|
42
|
-
("C4-P4", (0.06139230, -0.04473025, 0.06007050)),
|
|
43
|
-
("P4-O2", (0.04275465, -0.09535810, 0.03268050)),
|
|
44
|
-
("C3-A2", (0.01021790, -0.01832050, -0.00183650)),
|
|
45
|
-
("C4-A1", (-0.00947910, -0.01794500, -0.00220300)),
|
|
46
|
-
]
|
|
47
|
-
# fmt: on
|
|
48
|
-
|
|
49
|
-
_BIOT_TARGET_CHS_INFO = [
|
|
50
|
-
{"ch_name": ch, "kind": "eeg", "loc": np.asarray(loc, dtype=float)}
|
|
51
|
-
for ch, loc in _BIOT_TARGET_CHS_TUPLES
|
|
52
|
-
]
|
|
53
|
-
BIOT_CHANNEL_ORDER = [ch for ch, _ in _BIOT_TARGET_CHS_TUPLES]
|
|
54
|
-
|
|
55
10
|
|
|
56
11
|
class BIOT(EEGModuleMixin, nn.Module):
|
|
57
12
|
r"""BIOT from Yang et al (2023) [Yang2023]_
|
|
@@ -484,9 +439,7 @@ class _BIOTEncoder(nn.Module):
|
|
|
484
439
|
self.channel_tokens = nn.Embedding(
|
|
485
440
|
num_embeddings=n_chans, embedding_dim=emb_size
|
|
486
441
|
)
|
|
487
|
-
self.register_buffer(
|
|
488
|
-
"index", torch.arange(n_chans, dtype=torch.long), persistent=False
|
|
489
|
-
)
|
|
442
|
+
self.register_buffer("index", torch.arange(n_chans, dtype=torch.long))
|
|
490
443
|
|
|
491
444
|
def stft(self, sample):
|
|
492
445
|
"""
|
|
@@ -600,16 +553,3 @@ class _BIOTEncoder(nn.Module):
|
|
|
600
553
|
# (batch_size, emb)
|
|
601
554
|
emb = self.transformer(emb).mean(dim=1)
|
|
602
555
|
return emb
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
# -----------------------------------------------------------------------------
|
|
606
|
-
# InterpolatedBIOT — experimental channel-interpolation variant of BIOT
|
|
607
|
-
# -----------------------------------------------------------------------------
|
|
608
|
-
# Wraps :class:`BIOT` with an MNE-backed channel-interpolation layer that
|
|
609
|
-
# projects arbitrary user ``chs_info`` to the canonical 18-channel BIOT
|
|
610
|
-
# montage (:data:`_BIOT_TARGET_CHS_INFO`). Frozen by default; set
|
|
611
|
-
# ``trainable=True`` to fine-tune the projection matrix.
|
|
612
|
-
|
|
613
|
-
from braindecode.models.interpolated import InterpolatedModel # noqa: E402
|
|
614
|
-
|
|
615
|
-
InterpolatedBIOT = InterpolatedModel(BIOT, _BIOT_TARGET_CHS_INFO)
|
{braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/config.py
RENAMED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# Authors: Sarthak Tayal <sarthaktayal2@gmail.com>
|
|
2
1
|
from collections.abc import Callable
|
|
3
2
|
from inspect import signature
|
|
4
3
|
from types import UnionType
|
|
@@ -18,10 +17,10 @@ from braindecode.models.util import (
|
|
|
18
17
|
|
|
19
18
|
try:
|
|
20
19
|
from numpydantic import NDArray, Shape
|
|
21
|
-
|
|
22
|
-
_loc_type = NDArray[Shape["12"], np.float64]
|
|
23
20
|
except ImportError:
|
|
24
|
-
|
|
21
|
+
# we can't use soft import for numpydantic because numpydantic does not define its version in __init__
|
|
22
|
+
NDArray = Any # type: ignore
|
|
23
|
+
Shape = Any # type: ignore
|
|
25
24
|
|
|
26
25
|
|
|
27
26
|
class ChsInfoType(TypedDict, total=False, closed=True): # type: ignore[call-arg]
|
|
@@ -30,7 +29,7 @@ class ChsInfoType(TypedDict, total=False, closed=True): # type: ignore[call-arg
|
|
|
30
29
|
coil_type: int
|
|
31
30
|
coord_frame: int
|
|
32
31
|
kind: str
|
|
33
|
-
loc:
|
|
32
|
+
loc: NDArray[Shape["12"], np.float64] # type: ignore[misc]
|
|
34
33
|
logno: int
|
|
35
34
|
range: float
|
|
36
35
|
scanno: int
|