Braindecode 1.8.1.dev183674431__tar.gz → 1.8.1.dev183849953__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.1.dev183674431 → braindecode-1.8.1.dev183849953}/NOTICE.txt +0 -1
- {braindecode-1.8.1.dev183674431/braindecode.egg-info → braindecode-1.8.1.dev183849953}/PKG-INFO +1 -5
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/classifier.py +2 -3
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/tuh.py +1 -2
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/functional/__init__.py +0 -2
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/functional/functions.py +0 -18
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/__init__.py +0 -2
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/deep4.py +0 -1
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/labram.py +30 -117
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/luna.py +1 -3
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/summary.csv +0 -1
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/util.py +27 -149
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/blocks.py +6 -57
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/convolution.py +5 -15
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/regressor.py +3 -35
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/training/losses.py +2 -7
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/training/scoring.py +4 -12
- braindecode-1.8.1.dev183849953/braindecode/version.py +1 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953/braindecode.egg-info}/PKG-INFO +1 -5
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode.egg-info/SOURCES.txt +0 -2
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode.egg-info/requires.txt +0 -5
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/api.rst +0 -6
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/conf.py +0 -7
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/whats_new.rst +0 -73
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/pyproject.toml +0 -3
- braindecode-1.8.1.dev183674431/braindecode/models/diver1.py +0 -945
- braindecode-1.8.1.dev183674431/braindecode/version.py +0 -1
- braindecode-1.8.1.dev183674431/docs/agent_docs.rst +0 -60
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/LICENSE.txt +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/MANIFEST.in +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/README.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/__init__.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/augmentation/__init__.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/augmentation/base.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/augmentation/functional.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/augmentation/transforms.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/__init__.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/_notebook_viewer.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/base.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bbci.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bcicomp.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/__init__.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/datasets.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/format.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/hub.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/hub_format.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/hub_io.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/hub_validation.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/iterable.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/chb_mit.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/collate.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/mne.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/moabb.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/nmt.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/registry.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/siena.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/sleep_physionet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/utils.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/xy.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datautil/__init__.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datautil/channel_utils.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datautil/hub_formats.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datautil/serialization.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datautil/util.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/eegneuralnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/functional/_real_dft.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/functional/initialization.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/atcnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/attentionbasenet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/attn_sleep.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/barista.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/base.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/bendr.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/biot.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/brainbert.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/brainmodule.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/brant.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/cbramod.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/codebrain.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/config.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/contrawr.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/ctnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/dance.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/deepsleepnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/dgcnn.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegconformer.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegdino.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eeginception_erp.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eeginception_mi.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegitnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegminer.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegnex.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegpt.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegsimpleconv.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegsym.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegtcnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/emg2qwerty.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/fbcnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/fblightconvnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/fbmsnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/hybrid.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/ifnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/interpolated.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/medformer.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/meta_neuromotor.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/mirepnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/mscformer.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/msvtnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/mvpformer.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/neuropose.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/patchedtransformer.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/reve.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sccnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sensingdynamics.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/shallow_fbcsp.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/signal_jepa.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sinc_shallow.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sparcnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sstdpn.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/steegformer.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/syncnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/tcformer.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/tcn.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/tidnet.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/tsinception.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/usleep.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/vemg2pose.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/zuna.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/__init__.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/activation.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/attention.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/dance_modules.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/filter.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/interpolation.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/layers.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/linear.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/parametrization.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/stats.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/util.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/wrapper.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/__init__.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/mne_preprocess.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/preprocess.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/util.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/windowers.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/samplers/__init__.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/samplers/base.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/samplers/ssl.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/training/__init__.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/training/callbacks.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/util.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/__init__.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/activations.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/attribution.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/confusion_matrices.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/frequency.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/metrics.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/sanity.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/topology.py +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode.egg-info/dependency_links.txt +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode.egg-info/top_level.txt +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/Makefile +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/_templates/autosummary/class.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/_templates/autosummary/function.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/cite.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/help.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/index.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/install/install.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/install/install_pip.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/install/install_source.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/attention.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/channel.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/convolution.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/filterbank.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/gnn.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/interpretable.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/lbm.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/recurrent.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/spd.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/models.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/models_categorization.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/models_table.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/models_visualization.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/sg_execution_times.rst +0 -0
- {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/setup.cfg +0 -0
|
@@ -52,7 +52,6 @@ The following components are licensed under the Apache License 2.0:
|
|
|
52
52
|
- `braindecode/models/zuna.py`
|
|
53
53
|
- `braindecode/models/luna.py`
|
|
54
54
|
- `braindecode/models/brant.py`
|
|
55
|
-
- `braindecode/models/diver1.py`
|
|
56
55
|
- `braindecode/models/mscformer.py`
|
|
57
56
|
|
|
58
57
|
### USC Academic License Files
|
{braindecode-1.8.1.dev183674431/braindecode.egg-info → braindecode-1.8.1.dev183849953}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: braindecode
|
|
3
|
-
Version: 1.8.1.
|
|
3
|
+
Version: 1.8.1.dev183849953
|
|
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>
|
|
@@ -44,8 +44,6 @@ Requires-Dist: huggingface_hub[torch]>=0.20.0; extra == "hub"
|
|
|
44
44
|
Requires-Dist: zarr>=3.0; extra == "hub"
|
|
45
45
|
Provides-Extra: viz
|
|
46
46
|
Requires-Dist: captum>=0.7.0; extra == "viz"
|
|
47
|
-
Provides-Extra: sae
|
|
48
|
-
Requires-Dist: sae-lens==6.51.3; extra == "sae"
|
|
49
47
|
Provides-Extra: tests
|
|
50
48
|
Requires-Dist: pytest<9.1; extra == "tests"
|
|
51
49
|
Requires-Dist: pytest-cov; extra == "tests"
|
|
@@ -60,8 +58,6 @@ Provides-Extra: typing
|
|
|
60
58
|
Requires-Dist: exca>=0.5.10; extra == "typing"
|
|
61
59
|
Requires-Dist: numpydantic>=1.7; extra == "typing"
|
|
62
60
|
Provides-Extra: docs
|
|
63
|
-
Requires-Dist: pytest<9.1; extra == "docs"
|
|
64
|
-
Requires-Dist: sphinx-markdown-builder==0.6.11; extra == "docs"
|
|
65
61
|
Requires-Dist: sphinx_gallery>=0.17; extra == "docs"
|
|
66
62
|
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
67
63
|
Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
|
|
@@ -207,11 +207,10 @@ class EEGClassifier(_EEGNeuralNet, NeuralNetClassifier):
|
|
|
207
207
|
|
|
208
208
|
Returns
|
|
209
209
|
-------
|
|
210
|
-
trial_predictions : np.ndarray
|
|
210
|
+
trial_predictions : np.ndarray
|
|
211
211
|
3-dimensional array (n_trials x n_classes x n_predictions), where
|
|
212
212
|
the number of predictions depend on the chosen window size and the
|
|
213
|
-
receptive field of the network.
|
|
214
|
-
a list with one (n_classes x n_predictions) array per trial.
|
|
213
|
+
receptive field of the network.
|
|
215
214
|
trial_targets : np.ndarray
|
|
216
215
|
Ground-truth targets from the dataset in a 2-dimensional array
|
|
217
216
|
(n_trials x n_targets). Only returned when ``return_targets=True``.
|
{braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/tuh.py
RENAMED
|
@@ -815,8 +815,7 @@ def _get_header(*args, **kwargs):
|
|
|
815
815
|
for paths_dict in [_TUH_EEG_PATHS, _TUH_EEG_ABNORMAL_PATHS, _TUH_EEG_EVENTS_PATHS]:
|
|
816
816
|
for version_dict in paths_dict.values():
|
|
817
817
|
all_paths.update(version_dict)
|
|
818
|
-
|
|
819
|
-
return all_paths[os.fspath(args[0]).replace("\\", "/")]
|
|
818
|
+
return all_paths[args[0]]
|
|
820
819
|
|
|
821
820
|
|
|
822
821
|
_TUH_EEG_PATHS = {
|
{braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/functional/__init__.py
RENAMED
|
@@ -8,7 +8,6 @@ from .functions import (
|
|
|
8
8
|
iou_1d,
|
|
9
9
|
pairwise_iou_1d,
|
|
10
10
|
plv_time,
|
|
11
|
-
rotate_pairs,
|
|
12
11
|
safe_log,
|
|
13
12
|
sinusoidal_positional_encoding,
|
|
14
13
|
square,
|
|
@@ -26,7 +25,6 @@ __all__ = [
|
|
|
26
25
|
"iou_1d",
|
|
27
26
|
"pairwise_iou_1d",
|
|
28
27
|
"plv_time",
|
|
29
|
-
"rotate_pairs",
|
|
30
28
|
"safe_log",
|
|
31
29
|
"sinusoidal_positional_encoding",
|
|
32
30
|
"square",
|
|
@@ -470,21 +470,3 @@ def sinusoidal_positional_encoding(n_positions: int, dim: int) -> torch.Tensor:
|
|
|
470
470
|
# ``.contiguous()`` so an odd-``dim`` truncation owns tight storage -- a
|
|
471
471
|
# non-contiguous view over the padded width breaks safetensors buffer saving.
|
|
472
472
|
return pe[:, :dim].contiguous()
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
def rotate_pairs(x: torch.Tensor) -> torch.Tensor:
|
|
476
|
-
"""Rotate adjacent feature pairs from ``(a, b)`` to ``(-b, a)``.
|
|
477
|
-
|
|
478
|
-
Parameters
|
|
479
|
-
----------
|
|
480
|
-
x : torch.Tensor
|
|
481
|
-
Tensor of shape ``(..., features)`` with an even final dimension.
|
|
482
|
-
|
|
483
|
-
Returns
|
|
484
|
-
-------
|
|
485
|
-
torch.Tensor
|
|
486
|
-
Same shape, device and dtype as ``x``. Frequencies, positional indexing
|
|
487
|
-
and mixed-precision policy are left to the caller.
|
|
488
|
-
"""
|
|
489
|
-
pairs = x.unflatten(-1, (-1, 2))
|
|
490
|
-
return torch.stack((-pairs[..., 1], pairs[..., 0]), dim=-1).flatten(-2)
|
{braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/__init__.py
RENAMED
|
@@ -18,7 +18,6 @@ from .dance import DANCE
|
|
|
18
18
|
from .deep4 import Deep4Net
|
|
19
19
|
from .deepsleepnet import DeepSleepNet
|
|
20
20
|
from .dgcnn import DGCNN
|
|
21
|
-
from .diver1 import DIVER1
|
|
22
21
|
from .eegconformer import EEGConformer
|
|
23
22
|
from .eegdino import EEGDINO
|
|
24
23
|
from .eeginception_erp import EEGInceptionERP
|
|
@@ -102,7 +101,6 @@ __all__ = [
|
|
|
102
101
|
"DANCE",
|
|
103
102
|
"Deep4Net",
|
|
104
103
|
"DeepSleepNet",
|
|
105
|
-
"DIVER1",
|
|
106
104
|
"BrainModule",
|
|
107
105
|
"Brant",
|
|
108
106
|
"EEGConformer",
|
{braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/labram.py
RENAMED
|
@@ -191,11 +191,6 @@ _LABRAM_TARGET_CHS_INFO = [
|
|
|
191
191
|
for ch, loc in _LABRAM_TARGET_CHS_TUPLES
|
|
192
192
|
]
|
|
193
193
|
LABRAM_CHANNEL_ORDER = [ch for ch, _ in _LABRAM_TARGET_CHS_TUPLES]
|
|
194
|
-
|
|
195
|
-
#: Absolute time slots of the original LaBraM (``time_embed`` in its
|
|
196
|
-
#: ``modeling_finetune.py``), whatever the window length. A window of P patches
|
|
197
|
-
#: uses slots 0..P-1, and the released weights hold all 16 of them.
|
|
198
|
-
_LABRAM_N_TIME_SLOTS = 16
|
|
199
194
|
_LABRAM_CANONICAL_INDEX = {n.upper(): i for i, n in enumerate(LABRAM_CHANNEL_ORDER)}
|
|
200
195
|
|
|
201
196
|
|
|
@@ -324,13 +319,7 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
324
319
|
use_abs_pos_emb : bool (default=True)
|
|
325
320
|
If True, use absolute position embedding.
|
|
326
321
|
use_mean_pooling : bool (default=True)
|
|
327
|
-
If True,
|
|
328
|
-
tokens, as in the original fine-tuning. If False, the readout is the
|
|
329
|
-
[CLS] token after the final ``norm``; the original pretraining loss
|
|
330
|
-
never uses the [CLS] output. A pretraining checkpoint (with ``norm``
|
|
331
|
-
and without ``fc_norm`` or head, such as the released weights) loads
|
|
332
|
-
into a mean-pooling model as in the original fine-tuning script:
|
|
333
|
-
``norm`` is unused and ``fc_norm`` keeps its initialization.
|
|
322
|
+
If True, use mean pooling.
|
|
334
323
|
init_scale : float (default=0.001)
|
|
335
324
|
The initial scale to be used in the parameters of the model.
|
|
336
325
|
neural_tokenizer : bool (default=True)
|
|
@@ -382,7 +371,7 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
382
371
|
norm_layer: type[nn.Module] = nn.LayerNorm,
|
|
383
372
|
init_values=0.1,
|
|
384
373
|
use_abs_pos_emb=True,
|
|
385
|
-
use_mean_pooling=
|
|
374
|
+
use_mean_pooling=False,
|
|
386
375
|
init_scale=0.001,
|
|
387
376
|
neural_tokenizer=True,
|
|
388
377
|
attn_head_dim=None,
|
|
@@ -509,15 +498,8 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
509
498
|
else:
|
|
510
499
|
self.position_embedding = None
|
|
511
500
|
|
|
512
|
-
# The tokenizer keeps the original's absolute time slots, so the
|
|
513
|
-
# pretrained slots load at every window length; longer windows get
|
|
514
|
-
# extra slots. The decoder mode keeps one slot per patch plus one.
|
|
515
|
-
n_patches = self.patch_embed[0].n_patchs
|
|
516
|
-
n_time_slots = (
|
|
517
|
-
max(_LABRAM_N_TIME_SLOTS, n_patches) if neural_tokenizer else n_patches + 1
|
|
518
|
-
)
|
|
519
501
|
self.temporal_embedding = nn.Parameter(
|
|
520
|
-
torch.zeros(1,
|
|
502
|
+
torch.zeros(1, self.patch_embed[0].n_patchs + 1, self.embed_dim),
|
|
521
503
|
requires_grad=True,
|
|
522
504
|
)
|
|
523
505
|
self.pos_drop = nn.Dropout(p=drop_prob)
|
|
@@ -656,11 +638,10 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
656
638
|
temporal = self.embed_dim
|
|
657
639
|
else:
|
|
658
640
|
# For neural decoder: input is (batch, n_chans, n_times)
|
|
659
|
-
# patch_embed returns
|
|
660
|
-
# (batch, n_patches_per_channel, emb_dim)
|
|
641
|
+
# patch_embed returns (batch, n_patchs, emb_dim)
|
|
661
642
|
x = self.patch_embed(x)
|
|
662
|
-
# x shape: (batch,
|
|
663
|
-
batch_size,
|
|
643
|
+
# x shape: (batch, n_patchs, emb_dim)
|
|
644
|
+
batch_size, n_patch, temporal = x.shape
|
|
664
645
|
|
|
665
646
|
# add the [CLS] token to the embedded patch tokens
|
|
666
647
|
cls_tokens = self.cls_token.expand(batch_size, -1, -1)
|
|
@@ -678,13 +659,10 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
678
659
|
pos_embed_used=pos_embed_used, batch_size=batch_size
|
|
679
660
|
)
|
|
680
661
|
else:
|
|
681
|
-
# In decoder mode,
|
|
682
|
-
#
|
|
683
|
-
#
|
|
684
|
-
n_pos = min(
|
|
685
|
-
self.position_embedding.shape[1],
|
|
686
|
-
n_patches_per_channel + 1,
|
|
687
|
-
)
|
|
662
|
+
# In decoder mode, we have different number of patches
|
|
663
|
+
# Adapt position embedding for n_patch patches
|
|
664
|
+
# Use the first n_patch+1 positions from position_embedding
|
|
665
|
+
n_pos = min(self.position_embedding.shape[1], n_patch + 1)
|
|
688
666
|
pos_embed_used = self.position_embedding[:, :n_pos, :]
|
|
689
667
|
pos_embed = pos_embed_used.expand(batch_size, -1, -1)
|
|
690
668
|
|
|
@@ -694,26 +672,23 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
694
672
|
if self.neural_tokenizer:
|
|
695
673
|
num_ch = n_input_chans # Use actual input channels
|
|
696
674
|
time_embed = self._adj_temporal_embedding(
|
|
697
|
-
num_ch=num_ch,
|
|
698
|
-
batch_size=batch_size,
|
|
699
|
-
n_patches=self.patch_embed[0].n_patchs,
|
|
675
|
+
num_ch=num_ch, batch_size=batch_size, dim_embed=temporal
|
|
700
676
|
)
|
|
701
677
|
x[:, 1:, :] += time_embed
|
|
702
678
|
else:
|
|
703
|
-
# In decoder mode,
|
|
704
|
-
#
|
|
679
|
+
# In decoder mode, we have n_patch patches and don't need to expand
|
|
680
|
+
# Just broadcast the temporal embedding
|
|
705
681
|
if temporal is None:
|
|
706
682
|
temporal = self.embed_dim
|
|
707
683
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
)
|
|
684
|
+
# Get temporal embeddings for n_patch patches
|
|
685
|
+
n_time_tokens = min(n_patch, self.temporal_embedding.shape[1] - 1)
|
|
711
686
|
time_embed = self.temporal_embedding[
|
|
712
687
|
:, 1 : n_time_tokens + 1, :
|
|
713
|
-
] # (1,
|
|
688
|
+
] # (1, n_patch, emb_dim)
|
|
714
689
|
time_embed = time_embed.expand(
|
|
715
690
|
batch_size, -1, -1
|
|
716
|
-
) # (batch,
|
|
691
|
+
) # (batch, n_patch, emb_dim)
|
|
717
692
|
x[:, 1:, :] += time_embed
|
|
718
693
|
|
|
719
694
|
x = self.pos_drop(x)
|
|
@@ -851,20 +826,19 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
851
826
|
self._update_init_kwargs(n_outputs=n_outputs)
|
|
852
827
|
self.reset_classifier(n_outputs)
|
|
853
828
|
|
|
854
|
-
def _adj_temporal_embedding(self, num_ch, batch_size,
|
|
829
|
+
def _adj_temporal_embedding(self, num_ch, batch_size, dim_embed=None):
|
|
855
830
|
"""
|
|
856
831
|
Adjust the dimensions of the time embedding to match the
|
|
857
|
-
number of channels
|
|
832
|
+
number of channels or patches.
|
|
858
833
|
|
|
859
834
|
Parameters
|
|
860
835
|
----------
|
|
861
836
|
num_ch : int
|
|
862
|
-
The number of channels.
|
|
837
|
+
The number of channels or number of patches.
|
|
863
838
|
batch_size : int
|
|
864
839
|
Batch size of the input data.
|
|
865
|
-
|
|
866
|
-
The
|
|
867
|
-
``p``, as in the original implementation.
|
|
840
|
+
dim_embed : int
|
|
841
|
+
The embedding dimension (temporal feature dimension).
|
|
868
842
|
|
|
869
843
|
Returns
|
|
870
844
|
-------
|
|
@@ -872,9 +846,13 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
872
846
|
The adjusted time embedding to be added across the channels
|
|
873
847
|
after the [CLS] token. (x[:, 1:, :] += time_embed)
|
|
874
848
|
"""
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
849
|
+
if dim_embed is None:
|
|
850
|
+
cut_dimension = self.patch_size
|
|
851
|
+
else:
|
|
852
|
+
cut_dimension = min(dim_embed, self.temporal_embedding.shape[1] - 1)
|
|
853
|
+
|
|
854
|
+
# Get the temporal embedding: (1, temporal_embedding_dim, emb_size)
|
|
855
|
+
# Slice to cut_dimension: (1, cut_dimension, emb_size)
|
|
878
856
|
temporal_embedding = self.temporal_embedding[:, 0:cut_dimension, :]
|
|
879
857
|
|
|
880
858
|
# Add a new dimension to the time embedding
|
|
@@ -891,70 +869,6 @@ class Labram(EEGModuleMixin, nn.Module):
|
|
|
891
869
|
|
|
892
870
|
return temporal_embedding
|
|
893
871
|
|
|
894
|
-
def _load_from_state_dict(
|
|
895
|
-
self,
|
|
896
|
-
state_dict,
|
|
897
|
-
prefix,
|
|
898
|
-
local_metadata,
|
|
899
|
-
strict,
|
|
900
|
-
missing_keys,
|
|
901
|
-
unexpected_keys,
|
|
902
|
-
error_msgs,
|
|
903
|
-
):
|
|
904
|
-
# Time slots are absolute positions: take every slot the checkpoint
|
|
905
|
-
# holds and keep the model's own values for the others. This loads the
|
|
906
|
-
# released 16 slots at any window length, and checkpoints saved when
|
|
907
|
-
# the embedding had one slot per patch plus one.
|
|
908
|
-
key = prefix + "temporal_embedding"
|
|
909
|
-
loaded = state_dict.get(key)
|
|
910
|
-
own = self.temporal_embedding
|
|
911
|
-
if (
|
|
912
|
-
self.neural_tokenizer
|
|
913
|
-
and isinstance(loaded, torch.Tensor)
|
|
914
|
-
and loaded.dim() == own.dim() == 3
|
|
915
|
-
and loaded.shape[0] == own.shape[0]
|
|
916
|
-
and loaded.shape[2] == own.shape[2]
|
|
917
|
-
and loaded.shape[1] != own.shape[1]
|
|
918
|
-
):
|
|
919
|
-
n_copied = min(loaded.shape[1], own.shape[1])
|
|
920
|
-
resized = own.detach().clone()
|
|
921
|
-
resized[:, :n_copied] = loaded[:, :n_copied].to(resized)
|
|
922
|
-
n_used = self.patch_embed[0].n_patchs
|
|
923
|
-
if n_copied < n_used:
|
|
924
|
-
warn(
|
|
925
|
-
f"The checkpoint holds {loaded.shape[1]} time slots but this "
|
|
926
|
-
f"model uses {n_used} (one per patch); time slots "
|
|
927
|
-
f"{n_copied} to {n_used - 1} keep their initialization.",
|
|
928
|
-
UserWarning,
|
|
929
|
-
)
|
|
930
|
-
state_dict[key] = resized
|
|
931
|
-
# A pretraining checkpoint has the per-token final ``norm`` and no
|
|
932
|
-
# pooling ``fc_norm`` or head. As in the original fine-tuning script,
|
|
933
|
-
# a mean-pooling model leaves that ``norm`` unused and starts
|
|
934
|
-
# ``fc_norm`` from its initialization. A checkpoint with a head was
|
|
935
|
-
# fine-tuned with its own readout and is not converted.
|
|
936
|
-
if (
|
|
937
|
-
self.fc_norm is not None
|
|
938
|
-
and prefix + "cls_token" in state_dict
|
|
939
|
-
and not any(
|
|
940
|
-
k.startswith((prefix + "fc_norm.", prefix + "final_layer."))
|
|
941
|
-
for k in state_dict
|
|
942
|
-
)
|
|
943
|
-
):
|
|
944
|
-
for k in [k for k in state_dict if k.startswith(prefix + "norm.")]:
|
|
945
|
-
del state_dict[k]
|
|
946
|
-
for name, value in self.fc_norm.state_dict().items():
|
|
947
|
-
state_dict[prefix + "fc_norm." + name] = value
|
|
948
|
-
super()._load_from_state_dict(
|
|
949
|
-
state_dict,
|
|
950
|
-
prefix,
|
|
951
|
-
local_metadata,
|
|
952
|
-
strict,
|
|
953
|
-
missing_keys,
|
|
954
|
-
unexpected_keys,
|
|
955
|
-
error_msgs,
|
|
956
|
-
)
|
|
957
|
-
|
|
958
872
|
def _adj_position_embedding(self, pos_embed_used, batch_size):
|
|
959
873
|
"""Copy/pasted from https://github.com/935963004/LaBraM/blob/c431221e6cfd23dbfa9950e0180682fb322b0548/modeling_finetune.py#L358-L362"""
|
|
960
874
|
input_time_window = self.patch_embed[0].n_patchs
|
|
@@ -1087,8 +1001,7 @@ class _PatchEmbed(nn.Module):
|
|
|
1087
1001
|
but the original LaBraM expects pre-patched data (Batch, n_channels, n_patches, patch_size).
|
|
1088
1002
|
This class reshapes the input to the pre-patched format, then applies a 2D
|
|
1089
1003
|
convolution to project this pre-patched data to the embedding dimension,
|
|
1090
|
-
and finally
|
|
1091
|
-
temporal patch.
|
|
1004
|
+
and finally flattens across channels to produce a unified embedding.
|
|
1092
1005
|
|
|
1093
1006
|
Parameters:
|
|
1094
1007
|
-----------
|
{braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/luna.py
RENAMED
|
@@ -22,7 +22,6 @@ import torch.nn as nn
|
|
|
22
22
|
import torch.nn.functional as F
|
|
23
23
|
from einops import rearrange
|
|
24
24
|
|
|
25
|
-
from braindecode.functional import rotate_pairs
|
|
26
25
|
from braindecode.models.base import EEGModuleMixin
|
|
27
26
|
from braindecode.models.util import extract_channel_locations_from_chs_info
|
|
28
27
|
from braindecode.modules.layers import DropPath
|
|
@@ -552,9 +551,8 @@ class _RotarySelfAttentionBlock(nn.Module):
|
|
|
552
551
|
positions = torch.arange(seq_len, device=tensor.device, dtype=tensor.dtype)
|
|
553
552
|
freqs = self.rotary_emb(positions)
|
|
554
553
|
|
|
555
|
-
# Keep the full-head reshape (including its empty-input boundary).
|
|
556
554
|
pairs = tensor.reshape(*tensor.shape[:-1], -1, 2)
|
|
557
|
-
rotated =
|
|
555
|
+
rotated = torch.stack((-pairs[..., 1], pairs[..., 0]), dim=-1).flatten(-2)
|
|
558
556
|
transformed = tensor * freqs.cos() + rotated * freqs.sin()
|
|
559
557
|
return transformed.to(tensor.dtype)
|
|
560
558
|
|
{braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/summary.csv
RENAMED
|
@@ -58,7 +58,6 @@ LUNA,General,"Prediction, Embedding",128,"n_chans, n_times, sfreq, chs_info",710
|
|
|
58
58
|
MEDFormer,General,Prediction,250,"n_chans, n_outputs, n_times",5313924,"MEDFormer(n_chans=22, n_outputs=4, n_times=1000)","Foundation Model,Convolution",EEG
|
|
59
59
|
REVE,General,Prediction,200,"n_outputs, n_times, n_chans",69481476,"REVE(n_times=1000, n_outputs=4, n_chans=19)","Foundation Model,Attention/Transformer",EEG
|
|
60
60
|
DGCNN,Emotion Recognition,Prediction,128,"n_chans, n_outputs, n_times, chs_info",1037385,"DGCNN(n_chans=62, n_outputs=4, n_times=128)","Graph Neural Network,Channel",EEG
|
|
61
|
-
DIVER1,General,Prediction,500,"chs_info, n_outputs, n_times",12711366,"DIVER1(chs_info=<user>, n_outputs=4, n_times=1000, sfreq=500)","Attention/Transformer,Foundation Model,Channel",iEEG
|
|
62
61
|
InterpolatedBENDR,General,"Prediction, Embedding",250,"chs_info, n_outputs, n_times",157143101,"InterpolatedBENDR(chs_info=<user>, n_outputs=4, n_times=1000)","Foundation Model,Convolution,Channel",EEG
|
|
63
62
|
InterpolatedBIOT,"Sleep Staging, Epilepsy",Prediction,200,"chs_info, n_outputs, n_times, sfreq",3184101,"InterpolatedBIOT(chs_info=<user>, n_outputs=5, sfreq=200, n_times=6000)","Foundation Model,Channel",EEG
|
|
64
63
|
InterpolatedEEGPT,General,Prediction,256,"chs_info, n_outputs, n_times",25323137,"InterpolatedEEGPT(chs_info=<user>, n_outputs=4, n_times=1024)","Foundation Model,Attention/Transformer,Channel",EEG
|
{braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/util.py
RENAMED
|
@@ -21,19 +21,6 @@ from torch import nn
|
|
|
21
21
|
|
|
22
22
|
from braindecode.util import resolve_montage_name
|
|
23
23
|
|
|
24
|
-
# Canonical MNE channel-type name for the electrode kinds braindecode models
|
|
25
|
-
# tell apart.
|
|
26
|
-
_KIND_TO_CH_TYPE = {
|
|
27
|
-
FIFF.FIFFV_EEG_CH: "eeg",
|
|
28
|
-
FIFF.FIFFV_SEEG_CH: "seeg",
|
|
29
|
-
FIFF.FIFFV_DBS_CH: "dbs",
|
|
30
|
-
FIFF.FIFFV_ECOG_CH: "ecog",
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
#: MNE channel types recorded from inside the skull.
|
|
34
|
-
INTRACRANIAL_CH_TYPES = frozenset({"seeg", "dbs", "ecog"})
|
|
35
|
-
|
|
36
|
-
|
|
37
24
|
models_dict = {}
|
|
38
25
|
# Interpolated models are channel-interpolating wrappers around existing
|
|
39
26
|
# braindecode backbones (see :func:`braindecode.models.InterpolatedModel`).
|
|
@@ -565,11 +552,6 @@ models_mandatory_parameters: list[
|
|
|
565
552
|
{"n_chans": 19, "n_times": 6000},
|
|
566
553
|
),
|
|
567
554
|
("DGCNN", ["n_chans", "n_outputs", "n_times", "chs_info"], None),
|
|
568
|
-
(
|
|
569
|
-
"DIVER1",
|
|
570
|
-
["chs_info", "n_outputs", "n_times"],
|
|
571
|
-
{"sfreq": 500.0},
|
|
572
|
-
),
|
|
573
555
|
("EEGDINO", ["n_chans", "n_outputs", "n_times"], None),
|
|
574
556
|
(
|
|
575
557
|
"DANCE",
|
|
@@ -764,7 +746,6 @@ def get_summary_table(dir_name=None):
|
|
|
764
746
|
def extract_channel_locations_from_chs_info(
|
|
765
747
|
chs_info: Optional[Sequence[Dict[str, Any]]],
|
|
766
748
|
num_channels: Optional[int] = None,
|
|
767
|
-
fill_missing: bool = False,
|
|
768
749
|
) -> Optional[np.ndarray]:
|
|
769
750
|
"""Extract 3D channel locations from MNE-style channel information.
|
|
770
751
|
|
|
@@ -781,31 +762,19 @@ def extract_channel_locations_from_chs_info(
|
|
|
781
762
|
num_channels : int or None
|
|
782
763
|
If specified, only extract the first ``num_channels`` channel locations.
|
|
783
764
|
If None, extract all available channels.
|
|
784
|
-
fill_missing : bool
|
|
785
|
-
If False (default), extraction stops at the first channel whose location
|
|
786
|
-
is missing or malformed, so the result may be shorter than requested,
|
|
787
|
-
and an all-zero montage yields None. If True, each such channel
|
|
788
|
-
contributes a row of ``NaN`` instead, an all-zero montage yields all
|
|
789
|
-
``NaN``, and the result always has one row per requested channel.
|
|
790
765
|
|
|
791
766
|
Returns
|
|
792
767
|
-------
|
|
793
768
|
channel_locations : np.ndarray of shape (n_channels, 3) or None
|
|
794
769
|
Array of 3D channel locations in cartesian coordinates. Returns None if
|
|
795
|
-
no valid locations are found
|
|
796
|
-
case missing locations are reported as ``NaN`` rows and None is only
|
|
797
|
-
returned when ``chs_info`` is None or no channel was requested.
|
|
770
|
+
no valid locations are found.
|
|
798
771
|
|
|
799
772
|
Notes
|
|
800
773
|
-----
|
|
801
774
|
- This function handles both 12-element MNE location format (using indices 0:3)
|
|
802
775
|
and 3-element location format (using directly).
|
|
803
|
-
- Invalid or missing locations cause extraction to stop at that point
|
|
804
|
-
|
|
805
|
-
- An all-zero montage is treated as no montage at all, which is also how
|
|
806
|
-
:func:`has_valid_locations` reads it.
|
|
807
|
-
- Returns None if no valid locations can be extracted, except with
|
|
808
|
-
``fill_missing=True`` as described above.
|
|
776
|
+
- Invalid or missing locations cause extraction to stop at that point.
|
|
777
|
+
- Returns None if no valid locations can be extracted.
|
|
809
778
|
- This is a unified utility compatible with models like SignalJEPA and LUNA.
|
|
810
779
|
|
|
811
780
|
Examples
|
|
@@ -823,22 +792,26 @@ def extract_channel_locations_from_chs_info(
|
|
|
823
792
|
locations = []
|
|
824
793
|
n_to_extract = num_channels if num_channels is not None else len(chs_info)
|
|
825
794
|
|
|
826
|
-
for i in
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
try:
|
|
830
|
-
coordinates = np.asarray(loc, dtype=np.float32)
|
|
831
|
-
except (ValueError, TypeError):
|
|
832
|
-
coordinates = np.asarray(np.nan, dtype=np.float32)
|
|
795
|
+
for i, ch_info in enumerate(chs_info[:n_to_extract]):
|
|
796
|
+
if not isinstance(ch_info, dict):
|
|
797
|
+
break
|
|
833
798
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
elif fill_missing:
|
|
837
|
-
coordinates = np.full(3, np.nan, dtype=np.float32)
|
|
838
|
-
else:
|
|
799
|
+
loc = ch_info.get("loc")
|
|
800
|
+
if loc is None:
|
|
839
801
|
break
|
|
840
802
|
|
|
841
|
-
|
|
803
|
+
try:
|
|
804
|
+
loc_array = np.asarray(loc, dtype=np.float32)
|
|
805
|
+
|
|
806
|
+
# MNE format: 12-element array with electrode position at indices 0:3
|
|
807
|
+
if loc_array.ndim == 1 and loc_array.size >= 3:
|
|
808
|
+
coordinates = loc_array[:3]
|
|
809
|
+
else:
|
|
810
|
+
break
|
|
811
|
+
|
|
812
|
+
locations.append(coordinates)
|
|
813
|
+
except (ValueError, TypeError):
|
|
814
|
+
break
|
|
842
815
|
|
|
843
816
|
if len(locations) == 0:
|
|
844
817
|
return None
|
|
@@ -847,10 +820,7 @@ def extract_channel_locations_from_chs_info(
|
|
|
847
820
|
|
|
848
821
|
# Check positions are not all zero / degenerate
|
|
849
822
|
if np.allclose(result, 0):
|
|
850
|
-
|
|
851
|
-
return None
|
|
852
|
-
# An all-zero montage carries no position, just like an absent one
|
|
853
|
-
result = np.full_like(result, np.nan)
|
|
823
|
+
return None
|
|
854
824
|
|
|
855
825
|
return result
|
|
856
826
|
|
|
@@ -958,7 +928,7 @@ def resolve_channel_indices(
|
|
|
958
928
|
return cast(list[int], indices)
|
|
959
929
|
|
|
960
930
|
|
|
961
|
-
def positions_from_chs_info(chs_info):
|
|
931
|
+
def positions_from_chs_info(chs_info) -> np.ndarray:
|
|
962
932
|
"""``(n_chans, 2)`` electrode xy normalized to ``[0, 1]`` per axis.
|
|
963
933
|
|
|
964
934
|
Takes the raw 3D sensor coordinates ``ch["loc"][:3]``, keeps ``xy`` and
|
|
@@ -970,26 +940,15 @@ def positions_from_chs_info(chs_info):
|
|
|
970
940
|
|
|
971
941
|
Parameters
|
|
972
942
|
----------
|
|
973
|
-
chs_info : list of dict
|
|
943
|
+
chs_info : list of dict
|
|
974
944
|
MNE-style channel info dicts, each with a ``"loc"`` array whose first
|
|
975
|
-
three entries are the head-frame ``x, y, z`` coordinates
|
|
976
|
-
coordinate tensor of shape ``(n_chans, 3)`` in consistent units.
|
|
945
|
+
three entries are the head-frame ``x, y, z`` coordinates.
|
|
977
946
|
|
|
978
947
|
Returns
|
|
979
948
|
-------
|
|
980
|
-
numpy.ndarray
|
|
981
|
-
``(n_chans, 2)`` float positions in ``[0, 1]``.
|
|
982
|
-
the NumPy float64 result. Tensor inputs preserve device and dtype and
|
|
983
|
-
support autograd and TorchScript. This does not return raw xyz or
|
|
984
|
-
convert metres to millimetres.
|
|
949
|
+
numpy.ndarray
|
|
950
|
+
``(n_chans, 2)`` float positions in ``[0, 1]``.
|
|
985
951
|
"""
|
|
986
|
-
if isinstance(chs_info, torch.Tensor):
|
|
987
|
-
xy = chs_info[:, :2]
|
|
988
|
-
# Preserve the floor and backward intermediates at small half spans.
|
|
989
|
-
if xy.dtype == torch.float16 or xy.dtype == torch.bfloat16:
|
|
990
|
-
xy = xy.float()
|
|
991
|
-
mn, mx = xy.amin(dim=0), xy.amax(dim=0)
|
|
992
|
-
return ((xy - mn) / (mx - mn).clamp_min(1e-9)).to(chs_info.dtype)
|
|
993
952
|
xyz = np.array([ch["loc"][:3] for ch in chs_info], dtype=float)
|
|
994
953
|
xy = xyz[:, :2]
|
|
995
954
|
mn, mx = xy.min(axis=0), xy.max(axis=0)
|
|
@@ -997,20 +956,7 @@ def positions_from_chs_info(chs_info):
|
|
|
997
956
|
|
|
998
957
|
|
|
999
958
|
def has_valid_locations(chs_info) -> bool:
|
|
1000
|
-
"""
|
|
1001
|
-
|
|
1002
|
-
``chs_info`` accepts MNE channel dictionaries or a coordinate tensor of
|
|
1003
|
-
shape ``(n_chans, 3)``. Coordinates retain their input units. The result is
|
|
1004
|
-
a montage-wide Python bool, not a per-channel mask; zero rows are allowed
|
|
1005
|
-
when another row is nonzero. The all-zero tolerance is ``1e-8``.
|
|
1006
|
-
For a TorchScript-compatible per-row check, use :func:`valid_location_mask`.
|
|
1007
|
-
"""
|
|
1008
|
-
if isinstance(chs_info, torch.Tensor):
|
|
1009
|
-
return bool(
|
|
1010
|
-
chs_info.numel() > 0
|
|
1011
|
-
and torch.isfinite(chs_info).all()
|
|
1012
|
-
and chs_info.abs().max().item() > 1e-8
|
|
1013
|
-
)
|
|
959
|
+
"""``True`` if ``chs_info`` carries finite, non-all-zero electrode locations."""
|
|
1014
960
|
if chs_info is None:
|
|
1015
961
|
return False
|
|
1016
962
|
try:
|
|
@@ -1024,72 +970,4 @@ def has_valid_locations(chs_info) -> bool:
|
|
|
1024
970
|
return True
|
|
1025
971
|
|
|
1026
972
|
|
|
1027
|
-
def valid_location_mask(locations: torch.Tensor) -> torch.Tensor:
|
|
1028
|
-
"""Flag finite, exactly nonzero coordinate rows without changing their units.
|
|
1029
|
-
|
|
1030
|
-
Parameters
|
|
1031
|
-
----------
|
|
1032
|
-
locations : torch.Tensor
|
|
1033
|
-
Coordinates of shape ``(..., 3)``, in any consistent coordinate frame
|
|
1034
|
-
and units (e.g. xyz in metres or millimetres, not normalized xy).
|
|
1035
|
-
|
|
1036
|
-
Returns
|
|
1037
|
-
-------
|
|
1038
|
-
torch.Tensor
|
|
1039
|
-
Boolean mask of shape ``(..., 1)`` on the input device. Unlike
|
|
1040
|
-
:func:`has_valid_locations`, this tests each row against exact zero,
|
|
1041
|
-
not an approximate montage-wide zero. Supports TorchScript.
|
|
1042
|
-
"""
|
|
1043
|
-
return torch.isfinite(locations).all(dim=-1, keepdim=True) & (locations != 0).any(
|
|
1044
|
-
dim=-1, keepdim=True
|
|
1045
|
-
)
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
def channel_types_from_chs_info(
|
|
1049
|
-
chs_info: Optional[Sequence[Dict[str, Any]]],
|
|
1050
|
-
num_channels: Optional[int] = None,
|
|
1051
|
-
) -> list[str]:
|
|
1052
|
-
"""Canonical MNE channel-type name for each channel of ``chs_info``.
|
|
1053
|
-
|
|
1054
|
-
Parameters
|
|
1055
|
-
----------
|
|
1056
|
-
chs_info : list of dict or None
|
|
1057
|
-
MNE-style channel info dicts, typically from ``mne.Info.chs``. Each
|
|
1058
|
-
``"kind"`` entry may be an MNE FIFF integer code or a plain type string.
|
|
1059
|
-
num_channels : int or None
|
|
1060
|
-
Number of channels to report. Channels beyond ``chs_info`` yield
|
|
1061
|
-
``"unknown"``, so the returned list always has this length. If None, one
|
|
1062
|
-
entry per ``chs_info`` channel is returned (empty when it is None).
|
|
1063
|
-
|
|
1064
|
-
Returns
|
|
1065
|
-
-------
|
|
1066
|
-
list of str
|
|
1067
|
-
Lowercase channel-type names such as ``"eeg"``, ``"seeg"``, ``"ecog"`` or
|
|
1068
|
-
``"dbs"``, and ``"unknown"`` where the kind is missing or is not one of
|
|
1069
|
-
the electrode kinds resolved here.
|
|
1070
|
-
|
|
1071
|
-
Notes
|
|
1072
|
-
-----
|
|
1073
|
-
Only electrode kinds are resolved. An MNE ``"kind"`` code does not identify
|
|
1074
|
-
every channel type on its own: code 2 is shared by ``"eeg"`` and ``"csd"``,
|
|
1075
|
-
code 1 by ``"grad"`` and ``"mag"``, because MNE disambiguates those with
|
|
1076
|
-
``"unit"`` and ``"coil_type"``. Use :func:`mne.channel_type` with a full
|
|
1077
|
-
:class:`mne.Info` when those channel types matter.
|
|
1078
|
-
"""
|
|
1079
|
-
if num_channels is None:
|
|
1080
|
-
num_channels = len(chs_info) if chs_info is not None else 0
|
|
1081
|
-
|
|
1082
|
-
types = []
|
|
1083
|
-
for i in range(num_channels):
|
|
1084
|
-
ch_info = chs_info[i] if chs_info is not None and i < len(chs_info) else None
|
|
1085
|
-
kind = ch_info.get("kind") if isinstance(ch_info, dict) else None
|
|
1086
|
-
if isinstance(kind, str):
|
|
1087
|
-
types.append(kind.lower())
|
|
1088
|
-
elif isinstance(kind, int):
|
|
1089
|
-
types.append(_KIND_TO_CH_TYPE.get(kind, "unknown"))
|
|
1090
|
-
else:
|
|
1091
|
-
types.append("unknown")
|
|
1092
|
-
return types
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
973
|
_summary_table = get_summary_table()
|