braindecode 1.8.1.dev169692045__tar.gz → 1.8.1.dev169698056__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.dev169692045 → braindecode-1.8.1.dev169698056}/NOTICE.txt +0 -1
- {braindecode-1.8.1.dev169692045/braindecode.egg-info → braindecode-1.8.1.dev169698056}/PKG-INFO +2 -2
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/augmentation/functional.py +4 -2
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/chb_mit.py +5 -39
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/siena.py +5 -39
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/sleep_physio_challe_18.py +0 -46
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/utils.py +37 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/functional/initialization.py +14 -9
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/brainbert.py +47 -16
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/mapa.py +20 -12
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/medformer.py +0 -18
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/neurorvq.py +3 -17
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/neurorvq_tokenizer.py +28 -6
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/popt.py +175 -4
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/sinc_shallow.py +15 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/tmsanet.py +11 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/util.py +23 -149
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/zuna.py +77 -26
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/blocks.py +16 -4
- braindecode-1.8.1.dev169698056/braindecode/version.py +1 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056/braindecode.egg-info}/PKG-INFO +2 -2
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode.egg-info/SOURCES.txt +0 -2
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode.egg-info/requires.txt +1 -1
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/whats_new.rst +20 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/pyproject.toml +2 -2
- braindecode-1.8.1.dev169692045/braindecode/datasets/bids/format.py +0 -717
- braindecode-1.8.1.dev169692045/braindecode/modules/popt_modules.py +0 -187
- braindecode-1.8.1.dev169692045/braindecode/version.py +0 -1
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/LICENSE.txt +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/MANIFEST.in +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/README.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/augmentation/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/augmentation/base.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/augmentation/transforms.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/classifier.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/_notebook_viewer.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/base.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/bbci.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/bcicomp.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/bids/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/bids/datasets.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/bids/hub.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/bids/hub_format.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/bids/hub_io.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/bids/hub_validation.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/bids/iterable.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/collate.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/mne.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/moabb.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/nmt.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/registry.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/sleep_physionet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/tuh.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/xy.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datautil/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datautil/channel_utils.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datautil/hub_formats.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datautil/serialization.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datautil/util.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/eegneuralnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/functional/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/functional/_real_dft.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/functional/functions.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/atcnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/attentionbasenet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/attn_sleep.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/axon.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/barista.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/base.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/bendr.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/biot.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/brainmodule.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/brainomni.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/brant.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/cbramod.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/codebrain.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/config.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/contrawr.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/csbrain.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/ctnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/dance.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/deep4.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/deepsleepnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/dgcnn.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/diver1.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/duin.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eeg_clip.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eegconformer.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eegdino.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eeginception_erp.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eeginception_mi.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eegitnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eegminer.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eegnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eegnex.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eegpt.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eegsimpleconv.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eegsym.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/eegtcnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/emg2qwerty.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/epint.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/fbcnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/fblightconvnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/fbmsnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/gcnsnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/guetschel2026.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/hybrid.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/ifnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/labram.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/luna.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/meta_neuromotor.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/mirepnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/mscformer.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/msvtnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/mvpformer.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/neuropose.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/patchedtransformer.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/reve.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/sccnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/seizure_transformer.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/sensingdynamics.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/shallow_fbcsp.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/signal_jepa.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/sleepfm.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/sparcnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/sstdpn.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/steegformer.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/summary.csv +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/syncnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/tcformer.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/tcn.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/tfm_tokenizer.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/tidnet.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/tsinception.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/usleep.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/vemg2pose.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/activation.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/attention.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/channels.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/convolution.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/dance_modules.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/filter.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/layers.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/linear.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/linear_attention.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/parametrization.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/quantization.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/stats.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/util.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/modules/wrapper.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/preprocessing/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/preprocessing/mne_preprocess.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/preprocessing/preprocess.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/preprocessing/util.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/preprocessing/windowers.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/regressor.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/samplers/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/samplers/base.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/samplers/ssl.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/training/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/training/callbacks.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/training/losses.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/training/scoring.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/util.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/visualization/__init__.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/visualization/activations.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/visualization/attribution.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/visualization/confusion_matrices.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/visualization/frequency.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/visualization/metrics.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/visualization/sanity.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/visualization/topology.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode.egg-info/dependency_links.txt +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode.egg-info/top_level.txt +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/Makefile +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/_templates/autosummary/class.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/_templates/autosummary/function.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/agent_docs.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/api.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/cite.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/conf.py +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/help.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/index.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/install/install.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/install/install_pip.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/install/install_source.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/categorization/attention.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/categorization/channel.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/categorization/convolution.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/categorization/filterbank.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/categorization/gnn.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/categorization/interpretable.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/categorization/lbm.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/categorization/recurrent.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/categorization/spd.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/models.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/models_categorization.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/models_table.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/models/models_visualization.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/sg_execution_times.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/docs/user_guide/channel_strategies.rst +0 -0
- {braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/setup.cfg +0 -0
|
@@ -47,7 +47,6 @@ The following components are licensed under the MIT License:
|
|
|
47
47
|
- `braindecode/models/mirepnet.py`
|
|
48
48
|
- `braindecode/models/popt.py`
|
|
49
49
|
- `braindecode/models/tfm_tokenizer.py`
|
|
50
|
-
- `braindecode/modules/popt_modules.py`
|
|
51
50
|
- `braindecode/models/brainomni.py`
|
|
52
51
|
- `braindecode/modules/quantization.py`
|
|
53
52
|
- `braindecode/modules/linear_attention.py`
|
{braindecode-1.8.1.dev169692045/braindecode.egg-info → braindecode-1.8.1.dev169698056}/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.dev169698056
|
|
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>
|
|
@@ -32,8 +32,8 @@ Requires-Dist: joblib
|
|
|
32
32
|
Requires-Dist: torchinfo
|
|
33
33
|
Requires-Dist: pandas
|
|
34
34
|
Requires-Dist: wfdb>=4.3.1
|
|
35
|
-
Requires-Dist: linear_attention_transformer
|
|
36
35
|
Requires-Dist: docstring_inheritance
|
|
36
|
+
Requires-Dist: einops
|
|
37
37
|
Requires-Dist: pydantic>=2.0
|
|
38
38
|
Provides-Extra: moabb
|
|
39
39
|
Requires-Dist: moabb>=1.4.3; extra == "moabb"
|
|
@@ -1089,10 +1089,12 @@ def mixup(
|
|
|
1089
1089
|
Online: https://arxiv.org/abs/1710.09412
|
|
1090
1090
|
.. [2] https://github.com/facebookresearch/mixup-cifar10/blob/master/train.py
|
|
1091
1091
|
"""
|
|
1092
|
-
device = X.device
|
|
1093
1092
|
batch_size, n_channels, n_times = X.shape
|
|
1094
1093
|
|
|
1095
|
-
X_mix =
|
|
1094
|
+
X_mix = X.new_zeros(
|
|
1095
|
+
(batch_size, n_channels, n_times),
|
|
1096
|
+
dtype=X.dtype if X.is_floating_point() else torch.get_default_dtype(),
|
|
1097
|
+
)
|
|
1096
1098
|
y_a = y.clone()
|
|
1097
1099
|
y_b = y[idx_perm].clone()
|
|
1098
1100
|
|
{braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/chb_mit.py
RENAMED
|
@@ -16,12 +16,7 @@ It reorganizes the file structure to comply with the BIDS specification. To this
|
|
|
16
16
|
# License: BSD (3-clause)
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
-
from
|
|
20
|
-
|
|
21
|
-
from mne.datasets import fetch_dataset
|
|
22
|
-
|
|
23
|
-
from braindecode.datasets import BIDSDataset
|
|
24
|
-
from braindecode.datasets.utils import _correct_dataset_path
|
|
19
|
+
from braindecode.datasets.utils import _ZenodoBIDSDataset
|
|
25
20
|
|
|
26
21
|
CHB_MIT_URL = "https://zenodo.org/records/10259996/files/BIDS_CHB-MIT.zip"
|
|
27
22
|
CHB_MIT_archive_name = "chb_mit_bids.zip"
|
|
@@ -38,7 +33,7 @@ CHB_MIT_dataset_params = {
|
|
|
38
33
|
}
|
|
39
34
|
|
|
40
35
|
|
|
41
|
-
class CHBMIT(
|
|
36
|
+
class CHBMIT(_ZenodoBIDSDataset):
|
|
42
37
|
"""The Children's Hospital Boston EEG Dataset.
|
|
43
38
|
|
|
44
39
|
This database, collected at the Children's Hospital Boston, consists of EEG recordings
|
|
@@ -129,35 +124,6 @@ class CHBMIT(BIDSDataset):
|
|
|
129
124
|
.. footbibliography::
|
|
130
125
|
"""
|
|
131
126
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
path_root = fetch_dataset(
|
|
136
|
-
dataset_params=CHB_MIT_dataset_params,
|
|
137
|
-
path=None,
|
|
138
|
-
processor="unzip",
|
|
139
|
-
force_update=False,
|
|
140
|
-
)
|
|
141
|
-
# First time we fetch the dataset, we need to move the files to the
|
|
142
|
-
# correct directory.
|
|
143
|
-
path_root = _correct_dataset_path(
|
|
144
|
-
path_root, CHB_MIT_archive_name, "BIDS_CHB-MIT"
|
|
145
|
-
)
|
|
146
|
-
else:
|
|
147
|
-
# Validate that the provided root is a valid BIDS dataset
|
|
148
|
-
if not Path(f"{root}/participants.tsv").exists():
|
|
149
|
-
raise ValueError(
|
|
150
|
-
f"The provided root directory {root} does not contain a valid "
|
|
151
|
-
"BIDS dataset (missing participants.tsv). Please ensure the "
|
|
152
|
-
"root points directly to the BIDS dataset directory."
|
|
153
|
-
)
|
|
154
|
-
path_root = root
|
|
155
|
-
|
|
156
|
-
kwargs["root"] = path_root
|
|
157
|
-
|
|
158
|
-
super().__init__(
|
|
159
|
-
*args,
|
|
160
|
-
extensions=".edf",
|
|
161
|
-
check=False,
|
|
162
|
-
**kwargs,
|
|
163
|
-
)
|
|
127
|
+
_dataset_params = CHB_MIT_dataset_params
|
|
128
|
+
_archive_name = CHB_MIT_archive_name
|
|
129
|
+
_unzipped_dir = "BIDS_CHB-MIT"
|
{braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/siena.py
RENAMED
|
@@ -15,12 +15,7 @@ It reorganizes the file structure to comply with the BIDS specification. To this
|
|
|
15
15
|
# License: BSD (3-clause)
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
|
-
from
|
|
19
|
-
|
|
20
|
-
from mne.datasets import fetch_dataset
|
|
21
|
-
|
|
22
|
-
from braindecode.datasets import BIDSDataset
|
|
23
|
-
from braindecode.datasets.utils import _correct_dataset_path
|
|
18
|
+
from braindecode.datasets.utils import _ZenodoBIDSDataset
|
|
24
19
|
|
|
25
20
|
SIENA_URL = "https://zenodo.org/records/10640762/files/BIDS_Siena.zip"
|
|
26
21
|
SIENA_archive_name = "SIENA.zip"
|
|
@@ -37,7 +32,7 @@ SIENA_dataset_params = {
|
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
|
|
40
|
-
class SIENA(
|
|
35
|
+
class SIENA(_ZenodoBIDSDataset):
|
|
41
36
|
"""The Siena EEG Dataset.
|
|
42
37
|
|
|
43
38
|
The database consists of EEG recordings of 14 patients acquired at the Unit of Neurology
|
|
@@ -128,35 +123,6 @@ class SIENA(BIDSDataset):
|
|
|
128
123
|
automated seizure detection algorithms. Epilepsia, 66, 14-24.
|
|
129
124
|
"""
|
|
130
125
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
path_root = fetch_dataset(
|
|
135
|
-
dataset_params=SIENA_dataset_params,
|
|
136
|
-
path=None,
|
|
137
|
-
processor="unzip",
|
|
138
|
-
force_update=False,
|
|
139
|
-
)
|
|
140
|
-
# First time we fetch the dataset, we need to move the files to the
|
|
141
|
-
# correct directory.
|
|
142
|
-
path_root = _correct_dataset_path(
|
|
143
|
-
path_root, SIENA_archive_name, "BIDS_Siena"
|
|
144
|
-
)
|
|
145
|
-
else:
|
|
146
|
-
# Validate that the provided root is a valid BIDS dataset
|
|
147
|
-
if not Path(f"{root}/participants.tsv").exists():
|
|
148
|
-
raise ValueError(
|
|
149
|
-
f"The provided root directory {root} does not contain a valid "
|
|
150
|
-
"BIDS dataset (missing participants.tsv). Please ensure the "
|
|
151
|
-
"root points directly to the BIDS dataset directory."
|
|
152
|
-
)
|
|
153
|
-
path_root = root
|
|
154
|
-
|
|
155
|
-
kwargs["root"] = path_root
|
|
156
|
-
|
|
157
|
-
super().__init__(
|
|
158
|
-
*args,
|
|
159
|
-
extensions=".edf",
|
|
160
|
-
check=False,
|
|
161
|
-
**kwargs,
|
|
162
|
-
)
|
|
126
|
+
_dataset_params = SIENA_dataset_params
|
|
127
|
+
_archive_name = SIENA_archive_name
|
|
128
|
+
_unzipped_dir = "BIDS_Siena"
|
|
@@ -57,52 +57,6 @@ def ensure_metafiles_exist():
|
|
|
57
57
|
_download_if_missing(file_path, url)
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
def _update_pc18_sleep_records(fname=PC18_RECORDS):
|
|
61
|
-
"""Create CSV file with information about available PC18 recordings."""
|
|
62
|
-
# Load and massage the checksums.
|
|
63
|
-
sha_train_df = pd.read_csv(
|
|
64
|
-
PC18_SHA1_TRAINING,
|
|
65
|
-
sep=" ",
|
|
66
|
-
header=None,
|
|
67
|
-
names=["sha", "fname"],
|
|
68
|
-
engine="python",
|
|
69
|
-
)
|
|
70
|
-
sha_test_df = pd.read_csv(
|
|
71
|
-
PC18_SHA1_TEST, sep=" ", header=None, names=["sha", "fname"], engine="python"
|
|
72
|
-
)
|
|
73
|
-
sha_train_df["Split"] = "training"
|
|
74
|
-
sha_test_df["Split"] = "test"
|
|
75
|
-
sha_df = pd.concat([sha_train_df, sha_test_df], axis=0, ignore_index=True)
|
|
76
|
-
select_records = (
|
|
77
|
-
sha_df.fname.str.startswith("tr") | sha_df.fname.str.startswith("te")
|
|
78
|
-
) & ~sha_df.fname.str.endswith("arousal.mat")
|
|
79
|
-
sha_df = sha_df[select_records]
|
|
80
|
-
sha_df["Record"] = sha_df["fname"].str.split("/", expand=True)[0]
|
|
81
|
-
sha_df["fname"] = sha_df[["Split", "fname"]].agg("/".join, axis=1)
|
|
82
|
-
|
|
83
|
-
# Load and massage the data.
|
|
84
|
-
data = pd.read_csv(PC18_INFO)
|
|
85
|
-
|
|
86
|
-
data = data.reset_index().rename({"index": "Subject"}, axis=1)
|
|
87
|
-
data["Sex"] = (
|
|
88
|
-
data["Sex"].map({"F": "female", "M": "male", "m": "male"}).astype("category")
|
|
89
|
-
)
|
|
90
|
-
data = sha_df.merge(data, on="Record")
|
|
91
|
-
|
|
92
|
-
data["Record type"] = (
|
|
93
|
-
data["fname"]
|
|
94
|
-
.str.split(".", expand=True)[1]
|
|
95
|
-
.map({"hea": "Header", "mat": "PSG", "arousal": "Arousal"})
|
|
96
|
-
.astype("category")
|
|
97
|
-
)
|
|
98
|
-
data = data[
|
|
99
|
-
["Subject", "Record", "Record type", "Split", "Age", "Sex", "sha", "fname"]
|
|
100
|
-
].sort_values(by="Subject")
|
|
101
|
-
|
|
102
|
-
# Save the data.
|
|
103
|
-
data.to_csv(fname, index=False)
|
|
104
|
-
|
|
105
|
-
|
|
106
60
|
def _data_path(path=None):
|
|
107
61
|
"""Get path to local copy of PC18 dataset."""
|
|
108
62
|
key = "PC18_DATASET_PATH"
|
{braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/datasets/utils.py
RENAMED
|
@@ -9,6 +9,10 @@ from __future__ import annotations
|
|
|
9
9
|
import os
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
|
+
from mne.datasets import fetch_dataset
|
|
13
|
+
|
|
14
|
+
from .bids import BIDSDataset
|
|
15
|
+
|
|
12
16
|
|
|
13
17
|
def _correct_dataset_path(
|
|
14
18
|
path: str, archive_name: str, subfolder_name: str | None = None
|
|
@@ -65,3 +69,36 @@ def _correct_dataset_path(
|
|
|
65
69
|
path = subfolder_path
|
|
66
70
|
|
|
67
71
|
return path
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class _ZenodoBIDSDataset(BIDSDataset):
|
|
75
|
+
"""A BIDS dataset in EDF files, downloaded from a Zenodo archive when no
|
|
76
|
+
``root`` is given. Subclasses set the three class attributes below."""
|
|
77
|
+
|
|
78
|
+
_dataset_params: dict
|
|
79
|
+
_archive_name: str # the downloaded archive
|
|
80
|
+
_unzipped_dir: str # the folder the archive extracts to
|
|
81
|
+
|
|
82
|
+
def __init__(self, root=None, *args, **kwargs):
|
|
83
|
+
if root is None:
|
|
84
|
+
path_root = fetch_dataset(
|
|
85
|
+
dataset_params=self._dataset_params,
|
|
86
|
+
path=None,
|
|
87
|
+
processor="unzip",
|
|
88
|
+
force_update=False,
|
|
89
|
+
)
|
|
90
|
+
# The first fetch extracts into a nested folder: point at the data.
|
|
91
|
+
path_root = _correct_dataset_path(
|
|
92
|
+
path_root, self._archive_name, self._unzipped_dir
|
|
93
|
+
)
|
|
94
|
+
elif not Path(f"{root}/participants.tsv").exists():
|
|
95
|
+
raise ValueError(
|
|
96
|
+
f"The provided root directory {root} does not contain a valid "
|
|
97
|
+
"BIDS dataset (missing participants.tsv). Please ensure the "
|
|
98
|
+
"root points directly to the BIDS dataset directory."
|
|
99
|
+
)
|
|
100
|
+
else:
|
|
101
|
+
path_root = root
|
|
102
|
+
super().__init__(
|
|
103
|
+
*args, root=path_root, extensions=".edf", check=False, **kwargs
|
|
104
|
+
)
|
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
import math
|
|
2
2
|
|
|
3
|
+
import torch
|
|
3
4
|
from torch import nn
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def glorot_weight_zero_bias(model):
|
|
7
|
-
"""
|
|
8
|
+
"""Set the weights of BatchNorm layers to one and all biases to zero.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
Despite its name, this function does not apply the Glorot (Xavier)
|
|
11
|
+
initialization: other weights keep the initialization of their layer
|
|
12
|
+
(PyTorch's default, or Xavier uniform for the max-norm constrained layers
|
|
13
|
+
such as :class:`braindecode.modules.Conv2dWithConstraint`). The name is
|
|
14
|
+
kept for backward compatibility.
|
|
11
15
|
|
|
12
16
|
Parameters
|
|
13
17
|
----------
|
|
14
18
|
model : Module
|
|
15
19
|
"""
|
|
16
20
|
for module in model.modules():
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
# ``weight``/``bias`` can be None (e.g. BatchNorm with affine=False)
|
|
22
|
+
weight = getattr(module, "weight", None)
|
|
23
|
+
if isinstance(weight, torch.Tensor) and "BatchNorm" in type(module).__name__:
|
|
24
|
+
nn.init.constant_(weight, 1)
|
|
25
|
+
bias = getattr(module, "bias", None)
|
|
26
|
+
if isinstance(bias, torch.Tensor):
|
|
27
|
+
nn.init.constant_(bias, 0)
|
|
23
28
|
|
|
24
29
|
|
|
25
30
|
def rescale_parameter(param, layer_id):
|
{braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/brainbert.py
RENAMED
|
@@ -8,6 +8,8 @@ the STFT front-end moved inside the model. See :class:`BrainBERT`.
|
|
|
8
8
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
|
+
import warnings
|
|
12
|
+
|
|
11
13
|
import torch
|
|
12
14
|
import torch.nn as nn
|
|
13
15
|
import torch.nn.functional as F
|
|
@@ -16,6 +18,11 @@ from einops.layers.torch import Rearrange, Reduce
|
|
|
16
18
|
from braindecode.functional import sinusoidal_positional_encoding, spectral_input
|
|
17
19
|
from braindecode.models.base import EEGModuleMixin
|
|
18
20
|
from braindecode.models.util import warn_if_sfreq_differs
|
|
21
|
+
from braindecode.modules.blocks import (
|
|
22
|
+
_check_on_non_divisible,
|
|
23
|
+
_pad_or_crop_to_patches,
|
|
24
|
+
_patch_count,
|
|
25
|
+
)
|
|
19
26
|
|
|
20
27
|
|
|
21
28
|
class BrainBERT(EEGModuleMixin, nn.Module, license="unknown"):
|
|
@@ -122,6 +129,14 @@ class BrainBERT(EEGModuleMixin, nn.Module, license="unknown"):
|
|
|
122
129
|
pretrained).
|
|
123
130
|
drop_prob : float, optional
|
|
124
131
|
Dropout probability. Default 0.1.
|
|
132
|
+
on_non_divisible : {"pad", "crop", "error"}, optional
|
|
133
|
+
A window too short to give the ``pool_n_frames`` frames the pooling
|
|
134
|
+
needs (``n_times < 1401`` with the defaults). ``"pad"`` (default)
|
|
135
|
+
adds the missing STFT frames as zeros, half before and half after the
|
|
136
|
+
window, with a warning at construction: the ``stft_clip`` frames at
|
|
137
|
+
each end are trimmed and the centre ones pooled, so the signal stays
|
|
138
|
+
in the pooled frames. ``"crop"`` and ``"error"`` raise. A long enough
|
|
139
|
+
window gives the same output under all three.
|
|
125
140
|
|
|
126
141
|
References
|
|
127
142
|
----------
|
|
@@ -147,6 +162,7 @@ class BrainBERT(EEGModuleMixin, nn.Module, license="unknown"):
|
|
|
147
162
|
pool_n_frames: int | None = 10,
|
|
148
163
|
activation: type[nn.Module] = nn.GELU,
|
|
149
164
|
drop_prob: float = 0.1,
|
|
165
|
+
on_non_divisible: str = "pad",
|
|
150
166
|
# --- braindecode mandatory signal parameters ---
|
|
151
167
|
n_outputs=None,
|
|
152
168
|
n_chans=None,
|
|
@@ -176,6 +192,7 @@ class BrainBERT(EEGModuleMixin, nn.Module, license="unknown"):
|
|
|
176
192
|
f"pool_n_frames must be positive; got {pool_n_frames}. "
|
|
177
193
|
"Pass None to average every frame instead."
|
|
178
194
|
)
|
|
195
|
+
_check_on_non_divisible(on_non_divisible)
|
|
179
196
|
self.pool_n_frames = pool_n_frames
|
|
180
197
|
self.min_frames = 1 if pool_n_frames is None else pool_n_frames
|
|
181
198
|
warn_if_sfreq_differs("BrainBERT", self._sfreq, 2048)
|
|
@@ -186,15 +203,22 @@ class BrainBERT(EEGModuleMixin, nn.Module, license="unknown"):
|
|
|
186
203
|
idx_freq_cutoff=idx_freq_cutoff,
|
|
187
204
|
clip=stft_clip,
|
|
188
205
|
zscore_before_clip=stft_zscore_before_clip,
|
|
206
|
+
min_frames=self.min_frames if on_non_divisible == "pad" else 0,
|
|
189
207
|
)
|
|
190
208
|
n_frames = self.spectrogram.n_frames(self.n_times)
|
|
191
209
|
if n_frames < self.min_frames:
|
|
192
210
|
min_n_times = self.spectrogram.min_n_times(self.min_frames)
|
|
193
|
-
|
|
211
|
+
message = (
|
|
194
212
|
f"n_times={self.n_times} gives {n_frames} STFT frames; the pooling "
|
|
195
|
-
f"needs {self.min_frames}, i.e. n_times >= {min_n_times} with
|
|
196
|
-
"STFT settings
|
|
213
|
+
f"needs {self.min_frames}, i.e. n_times >= {min_n_times} with "
|
|
214
|
+
"these STFT settings"
|
|
197
215
|
)
|
|
216
|
+
if on_non_divisible != "pad":
|
|
217
|
+
raise ValueError(message + ".")
|
|
218
|
+
warnings.warn(
|
|
219
|
+
message + ": the input will be padded.", UserWarning, stacklevel=2
|
|
220
|
+
)
|
|
221
|
+
n_frames = self.min_frames
|
|
198
222
|
|
|
199
223
|
# The re-hosted Hub checkpoint already uses this port's names. The
|
|
200
224
|
# authors' original ``.pth`` calls the input block ``input_encoding``;
|
|
@@ -329,6 +353,10 @@ class _STFTSpectrogram(nn.Module):
|
|
|
329
353
|
Number of boundary frames trimmed from each end.
|
|
330
354
|
zscore_before_clip : bool
|
|
331
355
|
Whether the per-bin z-score over time precedes the trimming.
|
|
356
|
+
min_frames : int
|
|
357
|
+
A signal giving fewer output frames gets the missing STFT frames as
|
|
358
|
+
zeros, half before and half after it. ``0`` (default): scipy's framing
|
|
359
|
+
only.
|
|
332
360
|
"""
|
|
333
361
|
|
|
334
362
|
def __init__(
|
|
@@ -338,6 +366,7 @@ class _STFTSpectrogram(nn.Module):
|
|
|
338
366
|
idx_freq_cutoff: int = 40,
|
|
339
367
|
clip: int = 10,
|
|
340
368
|
zscore_before_clip: bool = True,
|
|
369
|
+
min_frames: int = 0,
|
|
341
370
|
):
|
|
342
371
|
super().__init__()
|
|
343
372
|
if not 0 <= noverlap < nperseg:
|
|
@@ -355,6 +384,7 @@ class _STFTSpectrogram(nn.Module):
|
|
|
355
384
|
self.idx_freq_cutoff = idx_freq_cutoff
|
|
356
385
|
self.clip = clip
|
|
357
386
|
self.zscore_before_clip = zscore_before_clip
|
|
387
|
+
self.min_frames = min_frames
|
|
358
388
|
# "zscore" as upstream; pipelines that apply their own statistics (the
|
|
359
389
|
# Neuroprobe global z-score recipes) set it to "none" on the instance.
|
|
360
390
|
self.normalizing = "zscore"
|
|
@@ -365,15 +395,11 @@ class _STFTSpectrogram(nn.Module):
|
|
|
365
395
|
"window", torch.hann_window(nperseg, periodic=True), persistent=False
|
|
366
396
|
)
|
|
367
397
|
|
|
368
|
-
def _padded_length(self, n_times: int) -> int:
|
|
369
|
-
"""Signal length after scipy's ``boundary="zeros"`` and ``padded=True``."""
|
|
370
|
-
length = n_times + 2 * self.boundary_pad
|
|
371
|
-
return length + (-(length - self.nperseg)) % self.step
|
|
372
|
-
|
|
373
398
|
def n_frames(self, n_times: int) -> int:
|
|
374
|
-
"""Number of
|
|
375
|
-
|
|
376
|
-
|
|
399
|
+
"""Number of frames scipy's framing gives ``n_times`` samples: segments of
|
|
400
|
+
``nperseg`` every ``step`` (the last one zero-padded), minus the clip."""
|
|
401
|
+
length = n_times + 2 * self.boundary_pad
|
|
402
|
+
return _patch_count(length, self.nperseg, "pad", self.step) - 2 * self.clip
|
|
377
403
|
|
|
378
404
|
def min_n_times(self, n_frames: int) -> int:
|
|
379
405
|
"""Shortest signal that yields at least ``n_frames`` output frames."""
|
|
@@ -382,15 +408,20 @@ class _STFTSpectrogram(nn.Module):
|
|
|
382
408
|
|
|
383
409
|
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
384
410
|
"""``(batch, n_chans, n_times)`` -> ``(batch, n_chans, n_frames, cutoff)``."""
|
|
385
|
-
# scipy boundary="zeros": half a window of zeros on each end, then
|
|
386
|
-
# padded=True: extend so an integer number of segments fits.
|
|
387
411
|
if not x.is_floating_point():
|
|
388
412
|
raise TypeError(
|
|
389
413
|
f"BrainBERT expects a floating-point signal, got {x.dtype}."
|
|
390
414
|
)
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
415
|
+
# scipy boundary="zeros" (half a window of zeros on each end), then
|
|
416
|
+
# padded=True (right zero-pad so the segments tile the signal). A signal
|
|
417
|
+
# short of min_frames gets the missing segments as zeros, half before
|
|
418
|
+
# it: the clip frames at each end are trimmed, so a right pad alone
|
|
419
|
+
# would leave it outside the frames that are kept.
|
|
420
|
+
xp = F.pad(x, (self.boundary_pad, self.boundary_pad))
|
|
421
|
+
min_segments = self.min_frames + 2 * self.clip if self.min_frames else 1
|
|
422
|
+
xp = _pad_or_crop_to_patches(
|
|
423
|
+
xp, self.nperseg, "pad", self.step, min_segments, center=True
|
|
424
|
+
)
|
|
394
425
|
frames = xp.unfold(-1, self.nperseg, self.step) # (b, c, n_frames, nperseg)
|
|
395
426
|
frames = spectral_input(frames)
|
|
396
427
|
win = self.window.to(frames)
|
{braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/mapa.py
RENAMED
|
@@ -27,7 +27,7 @@ from torch import nn
|
|
|
27
27
|
|
|
28
28
|
from braindecode.functional import rescale_parameter, rotate_pairs, spectral_input
|
|
29
29
|
from braindecode.models.base import EEGModuleMixin
|
|
30
|
-
from braindecode.models.util import dkt_region_slots
|
|
30
|
+
from braindecode.models.util import _in_model_resample, dkt_region_slots
|
|
31
31
|
from braindecode.modules import FeedForwardBlock
|
|
32
32
|
|
|
33
33
|
# Blocks whose output carries a deep-supervision norm, following V-JEPA 2.1.
|
|
@@ -104,9 +104,11 @@ class MAPA(EEGModuleMixin, nn.Module, license="apache-2.0"):
|
|
|
104
104
|
batch share them. Only ``pooling="flatten"`` is tied to one montage and one
|
|
105
105
|
window length.
|
|
106
106
|
|
|
107
|
-
*Sampling rate and window length.*
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
*Sampling rate and window length.* The model reads 2048 Hz; another
|
|
108
|
+
integer ``sfreq`` is resampled to 2048 Hz inside the model with
|
|
109
|
+
:class:`torchaudio.transforms.Resample`, with a warning. A 2048 Hz window
|
|
110
|
+
yields ``1 + n_times // 64`` frames, truncated to a multiple of 8, so it
|
|
111
|
+
needs at least 448 samples. With ``normalization="session"`` the input is the
|
|
110
112
|
spectrogram itself (``sfreq=32``, ``n_times`` in frames): the 20 retained
|
|
111
113
|
bins, robust z-scored per contact and bin over the whole recording.
|
|
112
114
|
|
|
@@ -252,18 +254,23 @@ class MAPA(EEGModuleMixin, nn.Module, license="apache-2.0"):
|
|
|
252
254
|
f"{normalization!r}."
|
|
253
255
|
)
|
|
254
256
|
# The bands are FFT bin slices at 2048 Hz on a 32 Hz frame clock, so
|
|
255
|
-
# another rate
|
|
256
|
-
# are already the 32 Hz spectrogram. sfreq is
|
|
257
|
-
#
|
|
258
|
-
# value is a hard error rather than a silent warning.
|
|
257
|
+
# another raw rate is resampled to 2048 Hz in forward; session inputs
|
|
258
|
+
# are already the 32 Hz spectrogram. sfreq is validated only when it
|
|
259
|
+
# is known.
|
|
259
260
|
expected_sfreq = 32 if normalization == "session" else 2048
|
|
260
261
|
sfreq_known = self._sfreq is not None or (
|
|
261
262
|
self._input_window_seconds is not None and self._n_times is not None
|
|
262
263
|
)
|
|
264
|
+
self.resample: nn.Module = nn.Identity()
|
|
265
|
+
n_times_model = self.n_times
|
|
263
266
|
if sfreq_known and float(self.sfreq) != expected_sfreq:
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
+
if normalization == "session":
|
|
268
|
+
raise ValueError(
|
|
269
|
+
f"MAPA with normalization={normalization!r} needs sfreq="
|
|
270
|
+
f"{expected_sfreq} Hz, got {self.sfreq} Hz."
|
|
271
|
+
)
|
|
272
|
+
self.resample, n_times_model = _in_model_resample(
|
|
273
|
+
"MAPA", self.sfreq, 2048, self.n_times
|
|
267
274
|
)
|
|
268
275
|
|
|
269
276
|
self.d_model = d_model
|
|
@@ -276,7 +283,7 @@ class MAPA(EEGModuleMixin, nn.Module, license="apache-2.0"):
|
|
|
276
283
|
self.activation = activation
|
|
277
284
|
|
|
278
285
|
self.n_frames = _frame_count(
|
|
279
|
-
|
|
286
|
+
n_times_model, spectrogram=normalization == "session"
|
|
280
287
|
)
|
|
281
288
|
self.k_full = sum(self.n_frames // stride for *_, stride in _BANDS)
|
|
282
289
|
|
|
@@ -617,6 +624,7 @@ class MAPA(EEGModuleMixin, nn.Module, license="apache-2.0"):
|
|
|
617
624
|
f"(batch, n_chans, n_times), but got {list(x.shape)} with "
|
|
618
625
|
f"normalization='{self.normalization}'."
|
|
619
626
|
)
|
|
627
|
+
x = self.resample(x)
|
|
620
628
|
indices = self._resolve_sensor_indices(sensor_indices, x)
|
|
621
629
|
n_frames = _frame_count(x.shape[-1], spectrogram=spectrogram)
|
|
622
630
|
if self.pooling == "flatten" and (
|
{braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/medformer.py
RENAMED
|
@@ -525,24 +525,6 @@ class _AttentionLayer(nn.Module):
|
|
|
525
525
|
return self.out_projection(out), attn
|
|
526
526
|
|
|
527
527
|
|
|
528
|
-
class _TriangularCausalMask:
|
|
529
|
-
def __init__(
|
|
530
|
-
self, batch_size: int, seq_len: int, device: Optional[torch.device] = None
|
|
531
|
-
):
|
|
532
|
-
# Normalize device to a torch.device for .to(device)
|
|
533
|
-
if device is None:
|
|
534
|
-
device = torch.device("cpu")
|
|
535
|
-
mask_shape = [batch_size, 1, seq_len, seq_len]
|
|
536
|
-
with torch.no_grad():
|
|
537
|
-
self._mask = torch.triu(
|
|
538
|
-
torch.ones(mask_shape, dtype=torch.bool), diagonal=1
|
|
539
|
-
).to(device)
|
|
540
|
-
|
|
541
|
-
@property
|
|
542
|
-
def mask(self) -> torch.Tensor:
|
|
543
|
-
return self._mask
|
|
544
|
-
|
|
545
|
-
|
|
546
528
|
class _FullAttention(nn.Module):
|
|
547
529
|
def __init__(
|
|
548
530
|
self,
|
{braindecode-1.8.1.dev169692045 → braindecode-1.8.1.dev169698056}/braindecode/models/neurorvq.py
RENAMED
|
@@ -14,11 +14,11 @@ from typing import Dict, Optional, Union
|
|
|
14
14
|
import torch
|
|
15
15
|
import torch.nn.functional as F
|
|
16
16
|
from torch import Tensor, nn
|
|
17
|
-
from torchaudio.transforms import Resample
|
|
18
17
|
|
|
19
18
|
from braindecode.models.base import EEGModuleMixin
|
|
20
19
|
from braindecode.models.labram import _Attention
|
|
21
20
|
from braindecode.models.signal_jepa import _GroupNorm
|
|
21
|
+
from braindecode.models.util import _in_model_resample
|
|
22
22
|
from braindecode.modules import MLP, DropPath, PatchTokenizer
|
|
23
23
|
from braindecode.modules.blocks import _check_on_non_divisible, _patch_count
|
|
24
24
|
|
|
@@ -534,23 +534,9 @@ class NeuroRVQ(EEGModuleMixin, nn.Module, license="cc-by-nc-4.0"):
|
|
|
534
534
|
self.resample: nn.Module = nn.Identity()
|
|
535
535
|
self._n_times_model = self.n_times
|
|
536
536
|
if in_sfreq is not None and in_sfreq != preset["sfreq"]:
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
f"NeuroRVQ resamples integer rates only, got {in_sfreq}."
|
|
540
|
-
)
|
|
541
|
-
warnings.warn(
|
|
542
|
-
f"NeuroRVQ-{modality.upper()} was trained at {preset['sfreq']} Hz; the "
|
|
543
|
-
f"{in_sfreq:g} Hz input is resampled inside the model.",
|
|
544
|
-
UserWarning,
|
|
545
|
-
)
|
|
546
|
-
self.resample = Resample(int(in_sfreq), preset["sfreq"])
|
|
547
|
-
# Derived from the rates: kept out of the state dict, so pretrained
|
|
548
|
-
# (200 Hz) weights load into a resampling model unchanged.
|
|
549
|
-
self.resample.register_buffer(
|
|
550
|
-
"kernel", self.resample.kernel, persistent=False
|
|
537
|
+
self.resample, self._n_times_model = _in_model_resample(
|
|
538
|
+
f"NeuroRVQ-{modality.upper()}", in_sfreq, preset["sfreq"], self.n_times
|
|
551
539
|
)
|
|
552
|
-
# torchaudio's output length.
|
|
553
|
-
self._n_times_model = math.ceil(self.n_times * preset["sfreq"] / in_sfreq)
|
|
554
540
|
# ceil for "pad", floor for "crop", exact for "error" (raises otherwise).
|
|
555
541
|
num_patches = _patch_count(self._n_times_model, patch_size, on_non_divisible)
|
|
556
542
|
if num_patches > max_patches:
|