Braindecode 1.8.1.dev182015723__tar.gz → 1.8.1.dev182199177__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.dev182015723 → braindecode-1.8.1.dev182199177}/NOTICE.txt +1 -0
- {braindecode-1.8.1.dev182015723/braindecode.egg-info → braindecode-1.8.1.dev182199177}/PKG-INFO +1 -1
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/augmentation/functional.py +6 -2
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/base.py +4 -1
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/tuh.py +12 -9
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/functional/functions.py +17 -7
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/__init__.py +2 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/attn_sleep.py +9 -11
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/axon.py +15 -8
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/biot.py +7 -2
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/brant.py +5 -4
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/codebrain.py +29 -4
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/csbrain.py +6 -2
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/dgcnn.py +2 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegsym.py +17 -1
- braindecode-1.8.1.dev182199177/braindecode/models/guetschel2026.py +775 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/luna.py +7 -12
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/mapa.py +8 -2
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/medformer.py +24 -19
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/meta_neuromotor.py +22 -24
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/msvtnet.py +3 -4
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/mvpformer.py +46 -56
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/patchedtransformer.py +0 -1
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/reve.py +13 -1
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/summary.csv +1 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/tcn.py +5 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/usleep.py +3 -2
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/util.py +139 -33
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/zuna.py +6 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/dance_modules.py +8 -9
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/filter.py +3 -14
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/quantization.py +12 -8
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/preprocessing/preprocess.py +11 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/preprocessing/windowers.py +5 -4
- braindecode-1.8.1.dev182199177/braindecode/version.py +1 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177/braindecode.egg-info}/PKG-INFO +1 -1
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode.egg-info/SOURCES.txt +1 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/api.rst +3 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/user_guide/channel_strategies.rst +1 -1
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/whats_new.rst +38 -0
- braindecode-1.8.1.dev182015723/braindecode/version.py +0 -1
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/LICENSE.txt +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/MANIFEST.in +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/README.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/augmentation/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/augmentation/base.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/augmentation/transforms.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/classifier.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/_notebook_viewer.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/bbci.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/bcicomp.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/bids/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/bids/datasets.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/bids/format.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/bids/hub.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/bids/hub_format.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/bids/hub_io.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/bids/hub_validation.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/bids/iterable.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/chb_mit.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/collate.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/mne.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/moabb.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/nmt.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/registry.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/siena.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/sleep_physionet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/utils.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/xy.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datautil/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datautil/channel_utils.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datautil/hub_formats.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datautil/serialization.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datautil/util.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/eegneuralnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/functional/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/functional/_real_dft.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/functional/initialization.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/atcnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/attentionbasenet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/barista.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/base.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/bendr.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/brainbert.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/brainmodule.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/brainomni.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/cbramod.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/config.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/contrawr.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/ctnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/dance.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/deep4.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/deepsleepnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/diver1.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eeg_clip.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegconformer.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegdino.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eeginception_erp.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eeginception_mi.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegitnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegminer.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegnex.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegpt.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegsimpleconv.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegtcnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/emg2qwerty.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/fbcnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/fblightconvnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/fbmsnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/hybrid.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/ifnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/labram.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/mirepnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/mscformer.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/neuropose.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/neurorvq.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/neurorvq_tokenizer.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/popt.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/sccnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/seizure_transformer.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/sensingdynamics.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/shallow_fbcsp.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/signal_jepa.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/sinc_shallow.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/sleepfm.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/sparcnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/sstdpn.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/steegformer.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/syncnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/tcformer.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/tfm_tokenizer.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/tidnet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/tmsanet.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/tsinception.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/vemg2pose.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/activation.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/attention.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/blocks.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/channels.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/convolution.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/layers.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/linear.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/linear_attention.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/parametrization.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/popt_modules.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/stats.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/util.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/modules/wrapper.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/preprocessing/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/preprocessing/mne_preprocess.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/preprocessing/util.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/regressor.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/samplers/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/samplers/base.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/samplers/ssl.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/training/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/training/callbacks.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/training/losses.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/training/scoring.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/util.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/visualization/__init__.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/visualization/activations.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/visualization/attribution.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/visualization/confusion_matrices.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/visualization/frequency.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/visualization/metrics.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/visualization/sanity.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/visualization/topology.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode.egg-info/dependency_links.txt +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode.egg-info/requires.txt +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode.egg-info/top_level.txt +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/Makefile +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/_templates/autosummary/class.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/_templates/autosummary/function.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/agent_docs.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/cite.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/conf.py +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/help.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/index.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/install/install.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/install/install_pip.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/install/install_source.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/categorization/attention.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/categorization/channel.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/categorization/convolution.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/categorization/filterbank.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/categorization/gnn.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/categorization/interpretable.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/categorization/lbm.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/categorization/recurrent.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/categorization/spd.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/models.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/models_categorization.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/models_table.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/models/models_visualization.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/docs/sg_execution_times.rst +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/pyproject.toml +0 -0
- {braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/setup.cfg +0 -0
|
@@ -52,6 +52,7 @@ The following components are licensed under the MIT License:
|
|
|
52
52
|
- `braindecode/modules/linear_attention.py`
|
|
53
53
|
- `braindecode/models/seizure_transformer.py`
|
|
54
54
|
- `docs/_static/model/seizure_transformer_arch.png`
|
|
55
|
+
- `braindecode/models/guetschel2026.py`
|
|
55
56
|
- `braindecode/models/tmsanet.py`
|
|
56
57
|
|
|
57
58
|
The `brainomni.py` file is a derivative of `OpenTSLab/BrainOmni` (MIT), whose
|
{braindecode-1.8.1.dev182015723/braindecode.egg-info → braindecode-1.8.1.dev182199177}/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.dev182199177
|
|
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>
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# Gustavo Rodrigues <gustavenrique01@gmail.com>
|
|
4
4
|
# Bruna Lopes <brunajaflopes@gmail.com>
|
|
5
5
|
# Sarthak Tayal <sarthaktayal2@gmail.com>
|
|
6
|
+
# Anton Soloviev <anton@praviel.com>
|
|
6
7
|
#
|
|
7
8
|
# License: BSD (3-clause)
|
|
8
9
|
|
|
@@ -931,7 +932,7 @@ def _rotate_signals(
|
|
|
931
932
|
transformed_X = X.clone()
|
|
932
933
|
sensors_positions = list(sensors_positions_matrix)
|
|
933
934
|
for s, rot_sensors_matrix in enumerate(rot_sensors_matrices):
|
|
934
|
-
rot_sensors_positions = list(rot_sensors_matrix
|
|
935
|
+
rot_sensors_positions = list(rot_sensors_matrix)
|
|
935
936
|
for time in range(X.shape[-1]):
|
|
936
937
|
interpolator_t = Rbf(*sensors_positions, X[s, :, time])
|
|
937
938
|
transformed_X[s, :, time] = torch.from_numpy(
|
|
@@ -1093,7 +1094,8 @@ def segmentation_reconstruction(
|
|
|
1093
1094
|
y : torch.Tensor
|
|
1094
1095
|
EEG labels for the example or batch.
|
|
1095
1096
|
n_segments : int
|
|
1096
|
-
Number of segments to use in the batch.
|
|
1097
|
+
Number of segments to use in the batch. Any remaining samples are
|
|
1098
|
+
included in the last segment.
|
|
1097
1099
|
data_classes : list[tuple[int, torch.Tensor]]
|
|
1098
1100
|
List of tuples. Each tuple contains the class index and the corresponding EEG data.
|
|
1099
1101
|
rand_indices : array-like
|
|
@@ -1133,6 +1135,8 @@ def segmentation_reconstruction(
|
|
|
1133
1135
|
for idx_segment in range(n_segments):
|
|
1134
1136
|
start = idx_segment * segment_size
|
|
1135
1137
|
end = (idx_segment + 1) * segment_size
|
|
1138
|
+
if idx_segment == n_segments - 1:
|
|
1139
|
+
end = window_size
|
|
1136
1140
|
|
|
1137
1141
|
# Perform the data augmentation
|
|
1138
1142
|
X_aug[np.arange(n_trials), :, start:end] = X_class[
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/base.py
RENAMED
|
@@ -1742,7 +1742,10 @@ class BaseConcatDataset(ConcatDataset, HubDatasetMixin, Generic[T]):
|
|
|
1742
1742
|
# Create path if it doesn't exist
|
|
1743
1743
|
os.makedirs(path, exist_ok=True)
|
|
1744
1744
|
|
|
1745
|
-
|
|
1745
|
+
# With an offset the caller fills one directory piece by piece (preprocess
|
|
1746
|
+
# saves each recording at its index), so the other entries are expected:
|
|
1747
|
+
# skip the scan that would stat them all on every call and list them in a warning.
|
|
1748
|
+
path_contents = os.listdir(path) if offset == 0 else []
|
|
1746
1749
|
n_sub_dirs = len(
|
|
1747
1750
|
[e for e in path_contents if os.path.isdir(os.path.join(path, e))]
|
|
1748
1751
|
)
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/datasets/tuh.py
RENAMED
|
@@ -11,10 +11,12 @@ TUH Abnormal EEG Corpus.
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
13
|
import glob
|
|
14
|
+
import json
|
|
14
15
|
import os
|
|
15
16
|
import re
|
|
16
17
|
import warnings
|
|
17
18
|
from datetime import datetime, timezone
|
|
19
|
+
from functools import cache
|
|
18
20
|
from pathlib import Path
|
|
19
21
|
from typing import Iterable, Literal
|
|
20
22
|
from unittest import mock
|
|
@@ -183,11 +185,8 @@ class TUH(BaseConcatDataset):
|
|
|
183
185
|
}
|
|
184
186
|
raw.rename_channels(mapping_strip)
|
|
185
187
|
|
|
186
|
-
montage1005 = mne.channels.make_standard_montage(
|
|
187
|
-
resolve_montage_name("standard_1005")
|
|
188
|
-
)
|
|
189
188
|
mapping_eeg_names = {
|
|
190
|
-
c.upper(): c for c in
|
|
189
|
+
c.upper(): c for c in _standard_1005().ch_names if c.upper() in raw.ch_names
|
|
191
190
|
}
|
|
192
191
|
|
|
193
192
|
# Set channels whose type could not be inferred (defaulted to "eeg") to "misc":
|
|
@@ -210,10 +209,7 @@ class TUH(BaseConcatDataset):
|
|
|
210
209
|
|
|
211
210
|
@staticmethod
|
|
212
211
|
def _set_montage(raw):
|
|
213
|
-
|
|
214
|
-
resolve_montage_name("standard_1005")
|
|
215
|
-
)
|
|
216
|
-
raw.set_montage(montage, on_missing="ignore")
|
|
212
|
+
raw.set_montage(_standard_1005(), on_missing="ignore")
|
|
217
213
|
|
|
218
214
|
@staticmethod
|
|
219
215
|
def _create_dataset(
|
|
@@ -269,6 +265,12 @@ class TUH(BaseConcatDataset):
|
|
|
269
265
|
return base_dataset
|
|
270
266
|
|
|
271
267
|
|
|
268
|
+
@cache
|
|
269
|
+
def _standard_1005():
|
|
270
|
+
# Built once per process: set_montage copies the montage before using it.
|
|
271
|
+
return mne.channels.make_standard_montage(resolve_montage_name("standard_1005"))
|
|
272
|
+
|
|
273
|
+
|
|
272
274
|
def _create_description(file_paths, version, ds_name):
|
|
273
275
|
descriptions = [
|
|
274
276
|
_parse_description_from_file_path(f, version, ds_name) for f in file_paths
|
|
@@ -289,7 +291,8 @@ def _read_date(file_path):
|
|
|
289
291
|
date_path = file_path.replace(".edf", "_date.txt")
|
|
290
292
|
# if date file exists, read it
|
|
291
293
|
if os.path.exists(date_path):
|
|
292
|
-
|
|
294
|
+
with open(date_path) as f:
|
|
295
|
+
description = json.load(f)
|
|
293
296
|
# otherwise read edf file, extract date and store to file
|
|
294
297
|
else:
|
|
295
298
|
raw = mne.io.read_raw_edf(file_path, preload=False, verbose="error")
|
|
@@ -112,8 +112,11 @@ def prefer_fft_conv(x: torch.Tensor, kernel_size: int) -> bool:
|
|
|
112
112
|
Rule measured for :class:`~braindecode.models.EEGInceptionMI` (48 to 240
|
|
113
113
|
channels, 128-500 Hz, 2 CPU threads, oneDNN on and off): on CPU the FFT
|
|
114
114
|
wins for float16/bfloat16 inputs (no fast half-precision CPU convolution)
|
|
115
|
-
and from ``batch_size * kernel_size >= 600
|
|
116
|
-
|
|
115
|
+
and from ``batch_size * kernel_size >= 600`` if also
|
|
116
|
+
``in_channels * kernel_size >= 120``: with one or two input channels a
|
|
117
|
+
float32 direct convolution stays cheaper up to k = 85 / 31 (13 long
|
|
118
|
+
temporal convolutions of the model zoo, 22 channels x batch 32). GPUs and
|
|
119
|
+
HPUs (no complex dtype) keep the direct convolution.
|
|
117
120
|
|
|
118
121
|
Parameters
|
|
119
122
|
----------
|
|
@@ -123,7 +126,8 @@ def prefer_fft_conv(x: torch.Tensor, kernel_size: int) -> bool:
|
|
|
123
126
|
Kernel length in samples.
|
|
124
127
|
"""
|
|
125
128
|
return x.device.type == "cpu" and (
|
|
126
|
-
x.element_size() == 2
|
|
129
|
+
x.element_size() == 2
|
|
130
|
+
or (x.shape[0] * kernel_size >= 600 and x.shape[1] * kernel_size >= 120)
|
|
127
131
|
)
|
|
128
132
|
|
|
129
133
|
|
|
@@ -367,18 +371,24 @@ def plv_time(
|
|
|
367
371
|
)
|
|
368
372
|
# Normalize the analytic signal to obtain unit vectors (phasors).
|
|
369
373
|
unit_phasor = analytic_signal / amplitude.unsqueeze(-1)
|
|
374
|
+
# The real/imaginary slices are strided (step 2): matmul copied each of
|
|
375
|
+
# them for every product, per batch matrix. Copy them once.
|
|
376
|
+
real = unit_phasor[..., 0].contiguous()
|
|
377
|
+
imag = unit_phasor[..., 1].contiguous()
|
|
378
|
+
real_t = real.transpose(-2, -1).contiguous()
|
|
379
|
+
imag_t = imag.transpose(-2, -1).contiguous()
|
|
370
380
|
|
|
371
381
|
# Compute the real part of the outer product between phasors of
|
|
372
382
|
# different channels.
|
|
373
|
-
real_real = torch.matmul(
|
|
383
|
+
real_real = torch.matmul(real, real_t)
|
|
374
384
|
|
|
375
385
|
# Compute the imaginary part of the outer product between phasors of
|
|
376
386
|
# different channels.
|
|
377
|
-
imag_imag = torch.matmul(
|
|
387
|
+
imag_imag = torch.matmul(imag, imag_t)
|
|
378
388
|
|
|
379
389
|
# Compute the cross-terms for the real and imaginary parts.
|
|
380
|
-
real_imag = torch.matmul(
|
|
381
|
-
imag_real = torch.matmul(
|
|
390
|
+
real_imag = torch.matmul(real, imag_t)
|
|
391
|
+
imag_real = torch.matmul(imag, real_t)
|
|
382
392
|
|
|
383
393
|
# Combine the real and imaginary parts to form the complex correlation.
|
|
384
394
|
correlation_real = real_real + imag_imag
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/__init__.py
RENAMED
|
@@ -39,6 +39,7 @@ from .emg2qwerty import EMG2QwertyNet
|
|
|
39
39
|
from .fbcnet import FBCNet
|
|
40
40
|
from .fblightconvnet import FBLightConvNet
|
|
41
41
|
from .fbmsnet import FBMSNet
|
|
42
|
+
from .guetschel2026 import Guetschel2026
|
|
42
43
|
from .hybrid import HybridNet
|
|
43
44
|
from .ifnet import IFNet
|
|
44
45
|
from .labram import Labram
|
|
@@ -139,6 +140,7 @@ __all__ = [
|
|
|
139
140
|
"FBCNet",
|
|
140
141
|
"FBLightConvNet",
|
|
141
142
|
"FBMSNet",
|
|
143
|
+
"Guetschel2026",
|
|
142
144
|
"MetaNeuromotorHand",
|
|
143
145
|
"HybridNet",
|
|
144
146
|
"IFNet",
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/attn_sleep.py
RENAMED
|
@@ -143,6 +143,10 @@ class AttnSleep(EEGModuleMixin, nn.Module):
|
|
|
143
143
|
sfreq=sfreq,
|
|
144
144
|
)
|
|
145
145
|
del n_outputs, n_chans, chs_info, n_times, input_window_seconds, sfreq
|
|
146
|
+
if self._n_chans_for_jit not in (None, 1):
|
|
147
|
+
raise ValueError(
|
|
148
|
+
f"AttnSleep takes single-channel input; got n_chans={self._n_chans_for_jit}."
|
|
149
|
+
)
|
|
146
150
|
|
|
147
151
|
self.mapping = {
|
|
148
152
|
"fc.weight": "final_layer.weight",
|
|
@@ -407,16 +411,12 @@ class _MRCNN(nn.Module):
|
|
|
407
411
|
##########################################################################################
|
|
408
412
|
|
|
409
413
|
|
|
410
|
-
def _attention(
|
|
411
|
-
|
|
412
|
-
) -> tuple[torch.Tensor, torch.Tensor]:
|
|
413
|
-
"""Implementation of Scaled dot product attention."""
|
|
414
|
+
def _attention(query: torch.Tensor, key: torch.Tensor) -> torch.Tensor:
|
|
415
|
+
"""Scaled dot product attention weights."""
|
|
414
416
|
# d_k - dimension of the query and key vectors
|
|
415
417
|
d_k = query.size(-1)
|
|
416
418
|
scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)
|
|
417
|
-
|
|
418
|
-
output = torch.matmul(p_attn, value) # (B, h, T, d_k)
|
|
419
|
-
return output, p_attn
|
|
419
|
+
return F.softmax(scores, dim=-1) # attention weights
|
|
420
420
|
|
|
421
421
|
|
|
422
422
|
class _MultiHeadedAttention(nn.Module):
|
|
@@ -464,10 +464,8 @@ class _MultiHeadedAttention(nn.Module):
|
|
|
464
464
|
.transpose(1, 2)
|
|
465
465
|
)
|
|
466
466
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
attn = self.dropout(attn_weights)
|
|
470
|
-
# recompute the weighted sum with dropped weights
|
|
467
|
+
# apply dropout to the *weights*, then the weighted sum
|
|
468
|
+
attn = self.dropout(_attention(query, key))
|
|
471
469
|
x = torch.matmul(attn, value)
|
|
472
470
|
|
|
473
471
|
# merge heads and project
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/axon.py
RENAMED
|
@@ -363,8 +363,11 @@ class _AXONEncoder(nn.Module):
|
|
|
363
363
|
position = spatial.unsqueeze(1) + temporal.unsqueeze(0) # (C, P, D)
|
|
364
364
|
tokens = tokens + position.unsqueeze(0).to(tokens.dtype)
|
|
365
365
|
|
|
366
|
-
|
|
367
|
-
band
|
|
366
|
+
# Up to temporal_window + 1 patches the band covers every pair: no mask.
|
|
367
|
+
band: Optional[torch.Tensor] = None
|
|
368
|
+
if n_patches > self.temporal_window + 1:
|
|
369
|
+
index = torch.arange(n_patches, device=tokens.device)
|
|
370
|
+
band = (index[None] - index[:, None]).abs() <= self.temporal_window
|
|
368
371
|
|
|
369
372
|
for block in self.blocks:
|
|
370
373
|
tokens = block(tokens, band)
|
|
@@ -464,19 +467,23 @@ class _AxisAttention(nn.Module):
|
|
|
464
467
|
)
|
|
465
468
|
return attended.transpose(1, 2).reshape(n_seq, length, -1)
|
|
466
469
|
|
|
467
|
-
def forward(self, x: torch.Tensor, band: torch.Tensor) -> torch.Tensor:
|
|
470
|
+
def forward(self, x: torch.Tensor, band: Optional[torch.Tensor]) -> torch.Tensor:
|
|
468
471
|
batch, n_chans, n_patches, dim = x.shape
|
|
469
472
|
axis_weights = self.axis_gate(x) # (B, C, P, 2)
|
|
470
473
|
scale_weights = self.scale_gate(x) # (B, C, P, 2)
|
|
471
474
|
|
|
472
|
-
# Temporal path: one sequence of P tokens per electrode.
|
|
475
|
+
# Temporal path: one sequence of P tokens per electrode. Without a band
|
|
476
|
+
# the restricted branch is the full one; attend once unless the two
|
|
477
|
+
# branches draw their own attention dropout.
|
|
473
478
|
per_channel = self.temporal_qkv(x.reshape(batch * n_chans, n_patches, dim))
|
|
474
479
|
restricted = self.temporal_out(self._attend(per_channel, band)).reshape(
|
|
475
480
|
batch, n_chans, n_patches, dim
|
|
476
481
|
)
|
|
477
|
-
full =
|
|
478
|
-
|
|
479
|
-
|
|
482
|
+
full = restricted
|
|
483
|
+
if band is not None or (self.training and self.att_drop_prob > 0):
|
|
484
|
+
full = self.temporal_out(self._attend(per_channel, None)).reshape(
|
|
485
|
+
batch, n_chans, n_patches, dim
|
|
486
|
+
)
|
|
480
487
|
temporal = scale_weights[..., 0:1] * restricted + scale_weights[..., 1:2] * full
|
|
481
488
|
|
|
482
489
|
# Spatial path: one sequence of C tokens per time step.
|
|
@@ -511,6 +518,6 @@ class _AXONBlock(nn.Module):
|
|
|
511
518
|
self.norm_ffn = nn.RMSNorm(embed_dim, eps=1e-8)
|
|
512
519
|
self.ffn = _GatedFeedForward(embed_dim, ffn_expansion)
|
|
513
520
|
|
|
514
|
-
def forward(self, x: torch.Tensor, band: torch.Tensor) -> torch.Tensor:
|
|
521
|
+
def forward(self, x: torch.Tensor, band: Optional[torch.Tensor]) -> torch.Tensor:
|
|
515
522
|
x = x + self.attn(self.norm_attn(x), band)
|
|
516
523
|
return x + self.ffn(self.norm_ffn(x))
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/biot.py
RENAMED
|
@@ -543,10 +543,15 @@ class _BIOTEncoder(nn.Module):
|
|
|
543
543
|
emb: Tensor
|
|
544
544
|
(batch_size, emb_size)
|
|
545
545
|
"""
|
|
546
|
+
batch_size, n_chans, n_times = x.shape
|
|
547
|
+
# One spectrogram for all channels, channel-major so that each
|
|
548
|
+
# channel's (batch, freq, ts) block is contiguous
|
|
549
|
+
spec = self.stft(x.transpose(0, 1).reshape(n_chans * batch_size, 1, n_times))
|
|
550
|
+
spec = spec.unflatten(0, [n_chans, batch_size])
|
|
546
551
|
emb_seq = []
|
|
547
|
-
for i in range(
|
|
552
|
+
for i in range(n_chans):
|
|
548
553
|
# Getting the spectrogram
|
|
549
|
-
channel_spec_emb =
|
|
554
|
+
channel_spec_emb = spec[i]
|
|
550
555
|
# Linear layer to learn some representation over the frequency domain
|
|
551
556
|
# with permutation
|
|
552
557
|
channel_spec_emb = self.patch_embedding(channel_spec_emb)
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/brant.py
RENAMED
|
@@ -309,7 +309,7 @@ class Brant(EEGModuleMixin, nn.Module, license="apache-2.0"):
|
|
|
309
309
|
time_z = self.temporal_encoder(tokens, power)
|
|
310
310
|
# 4. spatial encoder over the channels of each patch
|
|
311
311
|
time_z = self.split_time(time_z) # (batch * seq_len, n_chans, embed_dim)
|
|
312
|
-
ch_z
|
|
312
|
+
ch_z = self.spatial_encoder(time_z) # (batch * seq_len, n_chans, embed_dim)
|
|
313
313
|
emb = self.merge_time(ch_z) # (batch, n_chans, seq_len, embed_dim)
|
|
314
314
|
# 5. pool over channels and patches, then classify
|
|
315
315
|
pooled = self.pool(emb) # (batch, embed_dim)
|
|
@@ -474,6 +474,7 @@ class _BrantSpatialEncoder(nn.Module):
|
|
|
474
474
|
)
|
|
475
475
|
self.trans_enc = nn.TransformerEncoder(encoder_layer, num_layers=n_layers)
|
|
476
476
|
|
|
477
|
-
def forward(self, time_z: torch.Tensor) ->
|
|
478
|
-
|
|
479
|
-
|
|
477
|
+
def forward(self, time_z: torch.Tensor) -> torch.Tensor:
|
|
478
|
+
# proj_out (the reconstruction head) is kept for checkpoints, not run:
|
|
479
|
+
# classification does not use its output.
|
|
480
|
+
return self.trans_enc(time_z)
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/codebrain.py
RENAMED
|
@@ -697,10 +697,35 @@ class _ResidualBlock(nn.Module):
|
|
|
697
697
|
# Sliding-window attention branch
|
|
698
698
|
# (batch, 2*res_channels, seq_len) -> (batch, seq_len, 2*res_channels)
|
|
699
699
|
h_attn = h_ssm.transpose(1, 2)
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
700
|
+
if (
|
|
701
|
+
self.swa_window_size == 1
|
|
702
|
+
and not self.training
|
|
703
|
+
and not torch.is_grad_enabled()
|
|
704
|
+
and h_attn.device.type == "cpu"
|
|
705
|
+
):
|
|
706
|
+
# A one-wide window keeps only the diagonal: the softmax weights are
|
|
707
|
+
# exactly 1 and 0, so the attention returns its value projection.
|
|
708
|
+
# Same projection calls as nn.MultiheadAttention (on its (seq,
|
|
709
|
+
# batch, embed) view), so the output is unchanged bit for bit. (In
|
|
710
|
+
# training the weights carry dropout; on Gaudi the full attention
|
|
711
|
+
# was faster.)
|
|
712
|
+
# ponytail: the unused query/key projections are computed too, to
|
|
713
|
+
# keep the rounding; in_proj_weight[2E:] alone is ~2x less GEMM.
|
|
714
|
+
embed_dim = self.attention.embed_dim
|
|
715
|
+
seq_first = h_attn.transpose(0, 1)
|
|
716
|
+
value = F.linear(
|
|
717
|
+
seq_first, self.attention.in_proj_weight, self.attention.in_proj_bias
|
|
718
|
+
)[..., 2 * embed_dim :]
|
|
719
|
+
h_attn = (
|
|
720
|
+
self.attention.out_proj(value.reshape(-1, embed_dim))
|
|
721
|
+
.view(seq_first.shape)
|
|
722
|
+
.transpose(0, 1)
|
|
723
|
+
)
|
|
724
|
+
else:
|
|
725
|
+
swa_mask = self.generate_local_window_mask(
|
|
726
|
+
seq_len, self.swa_window_size, x.device, x.dtype
|
|
727
|
+
)
|
|
728
|
+
h_attn, _ = self.attention(h_attn, h_attn, h_attn, attn_mask=swa_mask)
|
|
704
729
|
# (batch, seq_len, 2*res_channels) -> (batch, 2*res_channels, seq_len)
|
|
705
730
|
h_attn = h_attn.transpose(1, 2)
|
|
706
731
|
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/csbrain.py
RENAMED
|
@@ -314,6 +314,11 @@ class CSBrain(EEGModuleMixin, nn.Module):
|
|
|
314
314
|
sfreq=sfreq,
|
|
315
315
|
)
|
|
316
316
|
del n_chans, chs_info, n_times, input_window_seconds, sfreq, n_outputs
|
|
317
|
+
n_times = self._n_times_or_none()
|
|
318
|
+
if n_times is not None and n_times % patch_size:
|
|
319
|
+
raise ValueError(
|
|
320
|
+
f"n_times ({n_times}) must be a multiple of patch_size ({patch_size})."
|
|
321
|
+
)
|
|
317
322
|
|
|
318
323
|
self.rearrange = Rearrange(
|
|
319
324
|
"batch n_chans (n_patch patch_size) -> batch n_chans n_patch patch_size",
|
|
@@ -710,8 +715,7 @@ class _CSBrainEncoderLayer(nn.Module):
|
|
|
710
715
|
for start, stop in self.region_bounds:
|
|
711
716
|
region_global = x[:, start:stop, :, :].mean(dim=1, keepdim=True)
|
|
712
717
|
region_global = region_global.permute(0, 2, 1, 3).reshape(batch * T, 1, Fea)
|
|
713
|
-
|
|
714
|
-
global_features[:, idx : idx + 1, :] = region_global
|
|
718
|
+
global_features[:, start:stop, :] = region_global
|
|
715
719
|
x_enhanced = x_flat + self.global_fc(global_features)
|
|
716
720
|
|
|
717
721
|
attn_output = self.inter_region_attn(
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/dgcnn.py
RENAMED
|
@@ -162,6 +162,8 @@ def _build_initial_adjacency(chs_info, n_chans, n_neighbors=5):
|
|
|
162
162
|
"with 3-D positions or that channel names match a standard montage."
|
|
163
163
|
)
|
|
164
164
|
|
|
165
|
+
if n_chans < 2:
|
|
166
|
+
raise ValueError("DGCNN needs at least 2 channels to build its channel graph.")
|
|
165
167
|
n_neighbors_capped = min(n_neighbors, n_chans - 1)
|
|
166
168
|
|
|
167
169
|
# Pairwise Euclidean distances
|
{braindecode-1.8.1.dev182015723 → braindecode-1.8.1.dev182199177}/braindecode/models/eegsym.py
RENAMED
|
@@ -441,6 +441,22 @@ class _AvgPoolTime(nn.Module):
|
|
|
441
441
|
return y.reshape(b, c, d, y.shape[2], s)
|
|
442
442
|
|
|
443
443
|
|
|
444
|
+
class _SpatialConv3d(nn.Conv3d):
|
|
445
|
+
"""``nn.Conv3d`` with a ``(1, 1, k)`` kernel run as ``conv2d`` on the
|
|
446
|
+
``(batch, ch, z * time, space)`` view; same parameters. The depthwise
|
|
447
|
+
``conv3d`` backward segfaults on Gaudi (synapse 1.21)."""
|
|
448
|
+
|
|
449
|
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
450
|
+
b, c, z, t, s = x.shape
|
|
451
|
+
y = nn.functional.conv2d(
|
|
452
|
+
x.reshape(b, c, z * t, s),
|
|
453
|
+
self.weight.squeeze(2),
|
|
454
|
+
self.bias,
|
|
455
|
+
groups=self.groups,
|
|
456
|
+
)
|
|
457
|
+
return y.reshape(b, -1, z, t, y.shape[-1])
|
|
458
|
+
|
|
459
|
+
|
|
444
460
|
class _InceptionBlock(nn.Module):
|
|
445
461
|
r"""Inception module used in EEGSym architecture.
|
|
446
462
|
|
|
@@ -500,7 +516,7 @@ class _InceptionBlock(nn.Module):
|
|
|
500
516
|
for _ in range(spatial_resnet_repetitions):
|
|
501
517
|
self.spatial_convs.append(
|
|
502
518
|
nn.Sequential(
|
|
503
|
-
|
|
519
|
+
_SpatialConv3d(
|
|
504
520
|
in_channels=filters_per_branch * len(scales_samples),
|
|
505
521
|
out_channels=filters_per_branch * len(scales_samples),
|
|
506
522
|
kernel_size=(1, 1, ncha),
|