braindecode 1.8.1.dev170153392__tar.gz → 1.8.1.dev170208067__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.dev170153392/braindecode.egg-info → braindecode-1.8.1.dev170208067}/PKG-INFO +1 -1
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/augmentation/__init__.py +2 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/augmentation/base.py +7 -1
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/augmentation/functional.py +133 -13
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/augmentation/transforms.py +104 -2
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/base.py +3 -1
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/mne.py +5 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/tuh.py +2 -1
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datautil/serialization.py +11 -4
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/functional/initialization.py +14 -9
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/atcnet.py +11 -8
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/base.py +13 -1
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/biot.py +4 -2
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/ctnet.py +9 -3
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/guetschel2026.py +8 -8
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/labram.py +11 -1
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/luna.py +4 -1
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/medformer.py +12 -15
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/neurorvq_tokenizer.py +28 -6
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/reve.py +5 -11
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/sinc_shallow.py +15 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/tmsanet.py +11 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/zuna.py +10 -10
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/attention.py +25 -10
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/blocks.py +21 -85
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/preprocessing/eegprep_preprocess.py +6 -3
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/preprocessing/preprocess.py +2 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/preprocessing/windowers.py +28 -17
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/regressor.py +6 -1
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/samplers/base.py +13 -2
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/training/scoring.py +4 -1
- braindecode-1.8.1.dev170208067/braindecode/version.py +1 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067/braindecode.egg-info}/PKG-INFO +1 -1
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/api.rst +4 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/whats_new.rst +79 -22
- braindecode-1.8.1.dev170153392/braindecode/version.py +0 -1
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/LICENSE.txt +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/MANIFEST.in +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/NOTICE.txt +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/README.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/classifier.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/_notebook_viewer.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/bbci.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/bcicomp.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/bids/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/bids/datasets.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/bids/format.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/bids/hub.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/bids/hub_format.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/bids/hub_io.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/bids/hub_validation.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/bids/iterable.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/chb_mit.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/collate.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/moabb.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/nmt.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/registry.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/siena.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/sleep_physionet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/utils.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/xy.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datautil/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datautil/channel_utils.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datautil/hub_formats.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datautil/util.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/eegneuralnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/functional/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/functional/_real_dft.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/functional/functions.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/attentionbasenet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/attn_sleep.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/axon.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/barista.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/bendr.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/brainbert.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/brainmodule.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/brainomni.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/brant.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/cbramod.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/codebrain.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/config.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/contrawr.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/csbrain.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/dance.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/deep4.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/deepsleepnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/dgcnn.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/diver1.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/duin.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eeg_clip.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eegconformer.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eegdino.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eeginception_erp.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eeginception_mi.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eegitnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eegminer.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eegnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eegnex.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eegpt.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eegsimpleconv.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eegsym.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/eegtcnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/emg2qwerty.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/epint.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/fbcnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/fblightconvnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/fbmsnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/gcnsnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/hybrid.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/ifnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/mapa.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/meta_neuromotor.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/mirepnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/mscformer.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/msvtnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/mvpformer.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/neuropose.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/neurorvq.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/patchedtransformer.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/popt.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/sccnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/seizure_transformer.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/sensingdynamics.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/shallow_fbcsp.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/signal_jepa.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/sleepfm.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/sparcnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/sstdpn.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/steegformer.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/summary.csv +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/syncnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/tcformer.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/tcn.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/tfm_tokenizer.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/tidnet.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/tsinception.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/usleep.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/util.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/vemg2pose.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/activation.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/channels.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/convolution.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/dance_modules.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/filter.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/layers.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/linear.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/linear_attention.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/parametrization.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/popt_modules.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/quantization.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/stats.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/util.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/modules/wrapper.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/preprocessing/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/preprocessing/mne_preprocess.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/preprocessing/util.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/samplers/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/samplers/ssl.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/training/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/training/callbacks.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/training/losses.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/util.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/visualization/__init__.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/visualization/activations.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/visualization/attribution.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/visualization/confusion_matrices.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/visualization/frequency.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/visualization/metrics.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/visualization/sanity.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/visualization/topology.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode.egg-info/SOURCES.txt +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode.egg-info/dependency_links.txt +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode.egg-info/requires.txt +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode.egg-info/top_level.txt +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/Makefile +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/_templates/autosummary/class.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/_templates/autosummary/function.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/agent_docs.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/cite.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/conf.py +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/help.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/index.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/install/install.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/install/install_pip.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/install/install_source.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/categorization/attention.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/categorization/channel.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/categorization/convolution.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/categorization/filterbank.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/categorization/gnn.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/categorization/interpretable.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/categorization/lbm.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/categorization/recurrent.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/categorization/spd.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/models.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/models_categorization.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/models_table.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/models/models_visualization.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/sg_execution_times.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/docs/user_guide/channel_strategies.rst +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/pyproject.toml +0 -0
- {braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/setup.cfg +0 -0
{braindecode-1.8.1.dev170153392/braindecode.egg-info → braindecode-1.8.1.dev170208067}/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.dev170208067
|
|
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>
|
|
@@ -14,6 +14,7 @@ from .transforms import (
|
|
|
14
14
|
FrequencyShift,
|
|
15
15
|
FTSurrogate,
|
|
16
16
|
GaussianNoise,
|
|
17
|
+
LabelSmoothing,
|
|
17
18
|
MaskEncoding,
|
|
18
19
|
Mixup,
|
|
19
20
|
SegmentationReconstruction,
|
|
@@ -40,6 +41,7 @@ __all__ = [
|
|
|
40
41
|
"CutMix",
|
|
41
42
|
"ChannelsDropout",
|
|
42
43
|
"GaussianNoise",
|
|
44
|
+
"LabelSmoothing",
|
|
43
45
|
"ChannelsSymmetry",
|
|
44
46
|
"SmoothTimeMask",
|
|
45
47
|
"BandstopFilter",
|
{braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/augmentation/base.py
RENAMED
|
@@ -171,7 +171,13 @@ class Compose(Transform):
|
|
|
171
171
|
self.transforms = transforms
|
|
172
172
|
super().__init__()
|
|
173
173
|
|
|
174
|
-
def forward(self, X, y):
|
|
174
|
+
def forward(self, X, y=None):
|
|
175
|
+
# like Transform.forward, return only X when no target is given (each
|
|
176
|
+
# transform then returns a single tensor, not an (X, y) pair)
|
|
177
|
+
if y is None:
|
|
178
|
+
for transform in self.transforms:
|
|
179
|
+
X = transform(X)
|
|
180
|
+
return X
|
|
175
181
|
for transform in self.transforms:
|
|
176
182
|
X, y = transform(X, y)
|
|
177
183
|
return X, y
|
|
@@ -19,7 +19,22 @@ from mne.filter import notch_filter
|
|
|
19
19
|
from scipy.interpolate import Rbf
|
|
20
20
|
from sklearn.utils import check_random_state
|
|
21
21
|
from torch.fft import fft, ifft
|
|
22
|
-
from torch.nn.functional import pad
|
|
22
|
+
from torch.nn.functional import one_hot, pad
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _max_float_dtype(device: torch.device | str) -> torch.dtype:
|
|
26
|
+
"""float64, or float32 on Apple MPS, which has no float64."""
|
|
27
|
+
return torch.float32 if torch.device(device).type == "mps" else torch.float64
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _to_device(t: torch.Tensor, device: torch.device | str) -> torch.Tensor:
|
|
31
|
+
"""Move ``t`` to ``device``, in single precision on MPS (no float64 there)."""
|
|
32
|
+
if torch.device(device).type == "mps":
|
|
33
|
+
if t.dtype == torch.float64:
|
|
34
|
+
return t.float().to(device)
|
|
35
|
+
if t.dtype == torch.complex128:
|
|
36
|
+
return t.to(torch.complex64).to(device)
|
|
37
|
+
return t.to(device)
|
|
23
38
|
|
|
24
39
|
|
|
25
40
|
def identity(X: torch.Tensor, y: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
|
|
@@ -92,10 +107,11 @@ def _new_random_fft_phase_odd(
|
|
|
92
107
|
rng = check_random_state(random_state)
|
|
93
108
|
random_phase = torch.from_numpy(
|
|
94
109
|
2j * np.pi * rng.random((batch_size, c, (n - 1) // 2))
|
|
95
|
-
)
|
|
110
|
+
)
|
|
111
|
+
random_phase = _to_device(random_phase, device)
|
|
96
112
|
return torch.cat(
|
|
97
113
|
[
|
|
98
|
-
torch.zeros((batch_size, c, 1), device=device),
|
|
114
|
+
torch.zeros((batch_size, c, 1), device=device, dtype=random_phase.dtype),
|
|
99
115
|
random_phase,
|
|
100
116
|
-torch.flip(random_phase, [-1]),
|
|
101
117
|
],
|
|
@@ -113,12 +129,13 @@ def _new_random_fft_phase_even(
|
|
|
113
129
|
rng = check_random_state(random_state)
|
|
114
130
|
random_phase = torch.from_numpy(
|
|
115
131
|
2j * np.pi * rng.random((batch_size, c, n // 2 - 1))
|
|
116
|
-
)
|
|
132
|
+
)
|
|
133
|
+
random_phase = _to_device(random_phase, device)
|
|
117
134
|
return torch.cat(
|
|
118
135
|
[
|
|
119
|
-
torch.zeros((batch_size, c, 1), device=device),
|
|
136
|
+
torch.zeros((batch_size, c, 1), device=device, dtype=random_phase.dtype),
|
|
120
137
|
random_phase,
|
|
121
|
-
torch.zeros((batch_size, c, 1), device=device),
|
|
138
|
+
torch.zeros((batch_size, c, 1), device=device, dtype=random_phase.dtype),
|
|
122
139
|
-torch.flip(random_phase, [-1]),
|
|
123
140
|
],
|
|
124
141
|
dim=-1,
|
|
@@ -178,7 +195,7 @@ def ft_surrogate(
|
|
|
178
195
|
and 0 <= phase_noise_magnitude <= 1
|
|
179
196
|
), f"eps must be a float between 0 and 1. Got {phase_noise_magnitude}."
|
|
180
197
|
|
|
181
|
-
f = fft(X.
|
|
198
|
+
f = fft(X.to(_max_float_dtype(X.device)), dim=-1)
|
|
182
199
|
device = X.device
|
|
183
200
|
|
|
184
201
|
n = f.shape[-1]
|
|
@@ -580,6 +597,7 @@ def _frequency_shift(X: torch.Tensor, fs: float, f_shift: float) -> torch.Tensor
|
|
|
580
597
|
_f_shift = torch.as_tensor(f_shift).float()
|
|
581
598
|
else:
|
|
582
599
|
raise ValueError(f"Invalid f_shift type: {type(f_shift)}")
|
|
600
|
+
_f_shift = _f_shift.to(X.device)
|
|
583
601
|
f_shift_stack = _f_shift.repeat(N_padded, n_channels, 1)
|
|
584
602
|
reshaped_f_shift = f_shift_stack.permute(
|
|
585
603
|
*torch.arange(f_shift_stack.ndim - 1, -1, -1)
|
|
@@ -911,7 +929,15 @@ def _rotate_signals(
|
|
|
911
929
|
sensors_positions_matrix: torch.Tensor,
|
|
912
930
|
spherical: bool = True,
|
|
913
931
|
) -> torch.Tensor:
|
|
914
|
-
|
|
932
|
+
if X.device.type == "mps":
|
|
933
|
+
# MPS has no float64: compute the small (n_chans x n_chans) spherical
|
|
934
|
+
# spline matrices on CPU in double precision, only move the result
|
|
935
|
+
# (two separate steps: a combined device + dtype .to() from MPS
|
|
936
|
+
# returns zeros with some torch versions)
|
|
937
|
+
sensors_positions_matrix = sensors_positions_matrix.cpu().double()
|
|
938
|
+
rotations = [rotation.cpu().double() for rotation in rotations]
|
|
939
|
+
else:
|
|
940
|
+
sensors_positions_matrix = sensors_positions_matrix.to(X.device)
|
|
915
941
|
rot_sensors_matrices = [
|
|
916
942
|
rotation.matmul(sensors_positions_matrix) for rotation in rotations
|
|
917
943
|
]
|
|
@@ -921,9 +947,10 @@ def _rotate_signals(
|
|
|
921
947
|
torch.as_tensor(
|
|
922
948
|
_torch_make_interpolation_matrix(
|
|
923
949
|
sensors_positions_matrix.T, rot_sensors_matrix.T
|
|
924
|
-
)
|
|
925
|
-
|
|
926
|
-
|
|
950
|
+
)
|
|
951
|
+
)
|
|
952
|
+
.float()
|
|
953
|
+
.to(X.device)
|
|
927
954
|
for rot_sensors_matrix in rot_sensors_matrices
|
|
928
955
|
]
|
|
929
956
|
)
|
|
@@ -1062,10 +1089,12 @@ def mixup(
|
|
|
1062
1089
|
Online: https://arxiv.org/abs/1710.09412
|
|
1063
1090
|
.. [2] https://github.com/facebookresearch/mixup-cifar10/blob/master/train.py
|
|
1064
1091
|
"""
|
|
1065
|
-
device = X.device
|
|
1066
1092
|
batch_size, n_channels, n_times = X.shape
|
|
1067
1093
|
|
|
1068
|
-
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
|
+
)
|
|
1069
1098
|
y_a = y.clone()
|
|
1070
1099
|
y_b = y[idx_perm].clone()
|
|
1071
1100
|
|
|
@@ -1123,6 +1152,97 @@ def cutmix(
|
|
|
1123
1152
|
return X_mix, (y.clone(), y[idx_perm].clone(), lam)
|
|
1124
1153
|
|
|
1125
1154
|
|
|
1155
|
+
def label_smoothing(
|
|
1156
|
+
X: torch.Tensor,
|
|
1157
|
+
y: torch.Tensor,
|
|
1158
|
+
epsilon: float,
|
|
1159
|
+
num_classes: int | None = None,
|
|
1160
|
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
|
1161
|
+
"""Smooth targets toward the uniform distribution over the classes.
|
|
1162
|
+
|
|
1163
|
+
See [1]_ for details.
|
|
1164
|
+
|
|
1165
|
+
Parameters
|
|
1166
|
+
----------
|
|
1167
|
+
X : torch.Tensor
|
|
1168
|
+
EEG data in form ``batch_size, n_channels, n_times``. Returned
|
|
1169
|
+
unchanged.
|
|
1170
|
+
y : torch.Tensor
|
|
1171
|
+
Target of length ``batch_size`` holding class indices (float values
|
|
1172
|
+
are accepted when they are integral), or a floating-point tensor of
|
|
1173
|
+
shape ``batch_size, num_classes`` holding target distributions.
|
|
1174
|
+
epsilon : float
|
|
1175
|
+
Smoothing parameter between 0 and 1: the weight of the uniform
|
|
1176
|
+
distribution mixed into the targets. ``0`` returns the unsmoothed
|
|
1177
|
+
targets.
|
|
1178
|
+
num_classes : int | None, optional
|
|
1179
|
+
Number of classes. Required when ``y`` holds class indices; when
|
|
1180
|
+
``y`` already holds distributions, it must match the size of the
|
|
1181
|
+
last dimension of ``y``. Defaults to None.
|
|
1182
|
+
|
|
1183
|
+
Returns
|
|
1184
|
+
-------
|
|
1185
|
+
tuple
|
|
1186
|
+
``X``, ``y``. Where ``X`` is unchanged and ``y`` is a
|
|
1187
|
+
floating-point tensor of shape ``batch_size, num_classes`` whose
|
|
1188
|
+
rows sum to one.
|
|
1189
|
+
|
|
1190
|
+
References
|
|
1191
|
+
----------
|
|
1192
|
+
.. [1] Christian Szegedy, Vincent Vanhoucke, Jonathon Shlens and
|
|
1193
|
+
Zbigniew Wojna (2016). Rethinking the Inception Architecture for
|
|
1194
|
+
Computer Vision. In 2016 IEEE Conference on Computer Vision and
|
|
1195
|
+
Pattern Recognition (CVPR), pp. 2818-2826.
|
|
1196
|
+
Online: https://arxiv.org/abs/1512.00567
|
|
1197
|
+
"""
|
|
1198
|
+
if not isinstance(epsilon, Real) or not 0.0 <= float(epsilon) <= 1.0:
|
|
1199
|
+
raise ValueError(
|
|
1200
|
+
f"epsilon should be a real number between 0 and 1. Got {epsilon!r}."
|
|
1201
|
+
)
|
|
1202
|
+
if num_classes is not None and (
|
|
1203
|
+
not isinstance(num_classes, int)
|
|
1204
|
+
or isinstance(num_classes, bool)
|
|
1205
|
+
or num_classes < 2
|
|
1206
|
+
):
|
|
1207
|
+
raise ValueError(
|
|
1208
|
+
f"num_classes should be an integer of at least 2. Got {num_classes!r}."
|
|
1209
|
+
)
|
|
1210
|
+
|
|
1211
|
+
if y.dim() == 1:
|
|
1212
|
+
# class-index targets: smooth their one-hot encoding
|
|
1213
|
+
if num_classes is None:
|
|
1214
|
+
raise ValueError("num_classes is required when y holds class indices.")
|
|
1215
|
+
if not torch.all(y == y.floor()):
|
|
1216
|
+
raise ValueError(
|
|
1217
|
+
"y holds non-integral values; class-index targets should be "
|
|
1218
|
+
"integers or integral floats."
|
|
1219
|
+
)
|
|
1220
|
+
if y.numel() > 0 and (y.min() < 0 or y.max() >= num_classes):
|
|
1221
|
+
raise ValueError(f"y holds class indices outside [0, {num_classes}).")
|
|
1222
|
+
one_hot_y = one_hot(y.long(), num_classes).to(dtype=X.dtype)
|
|
1223
|
+
return X, one_hot_y * (1.0 - epsilon) + epsilon / num_classes
|
|
1224
|
+
|
|
1225
|
+
if y.is_floating_point() and y.dim() >= 2:
|
|
1226
|
+
# target distributions: interpolate them toward the uniform one
|
|
1227
|
+
n_classes = y.shape[-1]
|
|
1228
|
+
if num_classes is not None and num_classes != n_classes:
|
|
1229
|
+
raise ValueError(
|
|
1230
|
+
f"num_classes ({num_classes}) does not match the size of the "
|
|
1231
|
+
f"last dimension of y ({n_classes})."
|
|
1232
|
+
)
|
|
1233
|
+
if n_classes < 2:
|
|
1234
|
+
raise ValueError(
|
|
1235
|
+
f"y should hold distributions over at least 2 classes. Got {n_classes}."
|
|
1236
|
+
)
|
|
1237
|
+
return X, y * (1.0 - epsilon) + epsilon / n_classes
|
|
1238
|
+
|
|
1239
|
+
raise ValueError(
|
|
1240
|
+
"y should hold class indices or floating-point target distributions "
|
|
1241
|
+
f"with a class dimension; got dtype {y.dtype} and shape "
|
|
1242
|
+
f"{tuple(y.shape)}."
|
|
1243
|
+
)
|
|
1244
|
+
|
|
1245
|
+
|
|
1126
1246
|
def segmentation_reconstruction(
|
|
1127
1247
|
X: torch.Tensor,
|
|
1128
1248
|
y: torch.Tensor,
|
|
@@ -18,6 +18,7 @@ from braindecode.util import resolve_montage_name
|
|
|
18
18
|
|
|
19
19
|
from .base import Transform
|
|
20
20
|
from .functional import (
|
|
21
|
+
_max_float_dtype,
|
|
21
22
|
amplitude_scale,
|
|
22
23
|
band_rotation,
|
|
23
24
|
bandstop_filter,
|
|
@@ -29,6 +30,7 @@ from .functional import (
|
|
|
29
30
|
frequency_shift,
|
|
30
31
|
ft_surrogate,
|
|
31
32
|
gaussian_noise,
|
|
33
|
+
label_smoothing,
|
|
32
34
|
mask_encoding,
|
|
33
35
|
mixup,
|
|
34
36
|
segmentation_reconstruction,
|
|
@@ -494,6 +496,7 @@ class SmoothTimeMask(Transform):
|
|
|
494
496
|
size=X.shape[0],
|
|
495
497
|
),
|
|
496
498
|
device=X.device,
|
|
499
|
+
dtype=_max_float_dtype(X.device),
|
|
497
500
|
) * (seq_length - mask_len_samples)
|
|
498
501
|
return {
|
|
499
502
|
"mask_start_per_sample": mask_start,
|
|
@@ -675,7 +678,11 @@ class FrequencyShift(Transform):
|
|
|
675
678
|
return super().get_augmentation_params(*batch)
|
|
676
679
|
X = batch[0]
|
|
677
680
|
|
|
678
|
-
u = torch.as_tensor(
|
|
681
|
+
u = torch.as_tensor(
|
|
682
|
+
self.rng.uniform(size=X.shape[0]),
|
|
683
|
+
device=X.device,
|
|
684
|
+
dtype=_max_float_dtype(X.device),
|
|
685
|
+
)
|
|
679
686
|
max_delta_freq = self.max_delta_freq
|
|
680
687
|
if isinstance(max_delta_freq, torch.Tensor):
|
|
681
688
|
max_delta_freq = max_delta_freq.to(X.device)
|
|
@@ -833,7 +840,10 @@ class SensorsRotation(Transform):
|
|
|
833
840
|
if isinstance(max_degrees, torch.Tensor):
|
|
834
841
|
max_degrees = max_degrees.to(X.device)
|
|
835
842
|
random_angles = (
|
|
836
|
-
torch.as_tensor(u, device=X.device)
|
|
843
|
+
torch.as_tensor(u, device=X.device, dtype=_max_float_dtype(X.device))
|
|
844
|
+
* 2
|
|
845
|
+
* max_degrees
|
|
846
|
+
- max_degrees
|
|
837
847
|
)
|
|
838
848
|
return {
|
|
839
849
|
"sensors_positions_matrix": self.sensors_positions_matrix,
|
|
@@ -1146,6 +1156,98 @@ class CutMix(Mixup):
|
|
|
1146
1156
|
return dict(params, cut_t_start=start, cut_t_len=end - start)
|
|
1147
1157
|
|
|
1148
1158
|
|
|
1159
|
+
class LabelSmoothing(Transform):
|
|
1160
|
+
"""Label smoothing from Szegedy et al. (2016) [1]_.
|
|
1161
|
+
|
|
1162
|
+
Replaces each target with its convex combination with the uniform
|
|
1163
|
+
distribution over the classes, penalizing over-confident predictions.
|
|
1164
|
+
The signals are returned unchanged; only the targets change.
|
|
1165
|
+
|
|
1166
|
+
The smoothed targets are floating-point distributions of shape
|
|
1167
|
+
``batch_size, num_classes`` (each row sums to one), so the training
|
|
1168
|
+
loss must accept target distributions, e.g. soft cross-entropy
|
|
1169
|
+
``-(y * torch.log_softmax(logits, dim=-1)).sum(-1).mean()`` or
|
|
1170
|
+
``torch.nn.KLDivLoss``. The transform composes before target-mixing
|
|
1171
|
+
transforms such as :class:`braindecode.augmentation.Mixup`, whose
|
|
1172
|
+
fractional-target path then mixes the smoothed distributions. The
|
|
1173
|
+
fixed-expansion mode (``n_augmentation > 0``) of
|
|
1174
|
+
:class:`braindecode.augmentation.AugmentedDataLoader` is not supported:
|
|
1175
|
+
it cannot concatenate the unsmoothed original targets with the reshaped
|
|
1176
|
+
smoothed copies.
|
|
1177
|
+
|
|
1178
|
+
Parameters
|
|
1179
|
+
----------
|
|
1180
|
+
epsilon : float
|
|
1181
|
+
Smoothing parameter between 0 and 1: the weight of the uniform
|
|
1182
|
+
distribution mixed into the targets. ``0`` disables smoothing.
|
|
1183
|
+
num_classes : int | None, optional
|
|
1184
|
+
Number of classes. Required when the targets are class indices;
|
|
1185
|
+
when the targets are already distributions of shape
|
|
1186
|
+
``batch_size, num_classes``, it must match their last dimension.
|
|
1187
|
+
Defaults to None.
|
|
1188
|
+
random_state : int | numpy.random.Generator, optional
|
|
1189
|
+
Seed to be used to instantiate numpy random number generator
|
|
1190
|
+
instance. The transform is deterministic, so the seed only feeds
|
|
1191
|
+
the application-probability machinery, which is inactive here.
|
|
1192
|
+
Defaults to None.
|
|
1193
|
+
|
|
1194
|
+
References
|
|
1195
|
+
----------
|
|
1196
|
+
.. [1] Christian Szegedy, Vincent Vanhoucke, Jonathon Shlens and
|
|
1197
|
+
Zbigniew Wojna (2016). Rethinking the Inception Architecture for
|
|
1198
|
+
Computer Vision. In 2016 IEEE Conference on Computer Vision and
|
|
1199
|
+
Pattern Recognition (CVPR), pp. 2818-2826.
|
|
1200
|
+
Online: https://arxiv.org/abs/1512.00567
|
|
1201
|
+
"""
|
|
1202
|
+
|
|
1203
|
+
operation = staticmethod(label_smoothing) # type: ignore[assignment]
|
|
1204
|
+
|
|
1205
|
+
def __init__(self, epsilon, num_classes=None, random_state=None):
|
|
1206
|
+
super().__init__(
|
|
1207
|
+
probability=1.0, # LabelSmoothing has to be applied to whole batches
|
|
1208
|
+
random_state=random_state,
|
|
1209
|
+
)
|
|
1210
|
+
if not isinstance(epsilon, Real) or not 0.0 <= float(epsilon) <= 1.0:
|
|
1211
|
+
raise ValueError(
|
|
1212
|
+
f"epsilon should be a real number between 0 and 1. Got {epsilon!r}."
|
|
1213
|
+
)
|
|
1214
|
+
if num_classes is not None and (
|
|
1215
|
+
not isinstance(num_classes, int)
|
|
1216
|
+
or isinstance(num_classes, bool)
|
|
1217
|
+
or num_classes < 2
|
|
1218
|
+
):
|
|
1219
|
+
raise ValueError(
|
|
1220
|
+
f"num_classes should be an integer of at least 2. Got {num_classes!r}."
|
|
1221
|
+
)
|
|
1222
|
+
self.epsilon = epsilon
|
|
1223
|
+
self.num_classes = num_classes
|
|
1224
|
+
|
|
1225
|
+
def get_augmentation_params(self, *batch):
|
|
1226
|
+
"""Return transform parameters.
|
|
1227
|
+
|
|
1228
|
+
Parameters
|
|
1229
|
+
----------
|
|
1230
|
+
X : tensor.Tensor
|
|
1231
|
+
The data.
|
|
1232
|
+
y : tensor.Tensor
|
|
1233
|
+
The labels.
|
|
1234
|
+
|
|
1235
|
+
Returns
|
|
1236
|
+
-------
|
|
1237
|
+
params : dict
|
|
1238
|
+
Contains
|
|
1239
|
+
|
|
1240
|
+
* epsilon : float
|
|
1241
|
+
Smoothing parameter between 0 and 1.
|
|
1242
|
+
* num_classes : int | None
|
|
1243
|
+
The number of classes.
|
|
1244
|
+
"""
|
|
1245
|
+
return {
|
|
1246
|
+
"epsilon": self.epsilon,
|
|
1247
|
+
"num_classes": self.num_classes,
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
|
|
1149
1251
|
class SegmentationReconstruction(Transform):
|
|
1150
1252
|
"""Segmentation Reconstruction from Lotte (2015) [Lotte2015]_.
|
|
1151
1253
|
|
{braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/base.py
RENAMED
|
@@ -634,7 +634,9 @@ class RecordDataset(Dataset[tuple[np.ndarray, int | str, tuple[int, int, int]]])
|
|
|
634
634
|
f"'{key}' already in description. Please "
|
|
635
635
|
f"rename or set overwrite to True."
|
|
636
636
|
)
|
|
637
|
-
|
|
637
|
+
# drop on a copy: windows datasets share the description
|
|
638
|
+
# Series of the dataset they were created from
|
|
639
|
+
self._description = self._description.drop(key)
|
|
638
640
|
self._description = pd.concat([self.description, description])
|
|
639
641
|
|
|
640
642
|
@property
|
{braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/mne.py
RENAMED
|
@@ -159,6 +159,11 @@ def create_from_mne_epochs(
|
|
|
159
159
|
|
|
160
160
|
list_of_windows_ds = []
|
|
161
161
|
for i, epochs in enumerate(list_of_epochs):
|
|
162
|
+
# drop rejected epochs first (on a copy) so that iterating over the
|
|
163
|
+
# epochs stays aligned with ``epochs.events``; preloaded epochs have
|
|
164
|
+
# already dropped them, so skip copying their data
|
|
165
|
+
if not epochs.preload:
|
|
166
|
+
epochs = epochs.copy().drop_bad()
|
|
162
167
|
event_descriptions = epochs.events[:, 2]
|
|
163
168
|
original_trial_starts = epochs.events[:, 0]
|
|
164
169
|
stop = len(epochs.times) - window_size_samples
|
{braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/datasets/tuh.py
RENAMED
|
@@ -122,7 +122,8 @@ class TUH(BaseConcatDataset):
|
|
|
122
122
|
# Assume it is an integer specifying number
|
|
123
123
|
# of recordings to load
|
|
124
124
|
recording_ids = range(recording_ids)
|
|
125
|
-
|
|
125
|
+
# select by chronological position, not by (file listing) label
|
|
126
|
+
descriptions = descriptions.iloc[:, list(recording_ids)]
|
|
126
127
|
|
|
127
128
|
# workaround to ensure warnings are suppressed when running in parallel
|
|
128
129
|
def create_dataset(*args, **kwargs):
|
|
@@ -140,15 +140,19 @@ def _load_signals(fif_file, preload, is_raw):
|
|
|
140
140
|
with open(pkl_file, "rb") as f:
|
|
141
141
|
signals = pickle.load(f)
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
# The pickle stores absolute paths: check that they exist and point to
|
|
144
|
+
# this fif file, not to the folder the dataset was copied from.
|
|
145
|
+
if all(Path(f).exists() for f in signals.filenames) and (
|
|
146
|
+
Path(signals.filenames[0]).resolve() == fif_file.resolve()
|
|
147
|
+
):
|
|
144
148
|
if preload:
|
|
145
149
|
signals.load_data()
|
|
146
150
|
return _compact_fif_tags(signals)
|
|
147
151
|
else: # This may happen if the file has been moved together with the pickle file.
|
|
148
152
|
warnings.warn(
|
|
149
153
|
f"Pickle file {pkl_file} exists, but the referenced fif "
|
|
150
|
-
"file(s) do not exist. Will read the
|
|
151
|
-
"and re-create the pickle file.",
|
|
154
|
+
"file(s) do not exist or are not next to it. Will read the "
|
|
155
|
+
"fif file(s) directly and re-create the pickle file.",
|
|
152
156
|
UserWarning,
|
|
153
157
|
)
|
|
154
158
|
|
|
@@ -220,7 +224,10 @@ def load_concat_dataset(path, preload, ids_to_load=None, target_name=None, n_job
|
|
|
220
224
|
# target_name.json, raw_preproc_kwargs.json, window_kwargs.json,
|
|
221
225
|
# window_preproc_kwargs.json
|
|
222
226
|
if ids_to_load is None:
|
|
223
|
-
|
|
227
|
+
# skip stray entries such as .DS_Store or a README next to the datasets
|
|
228
|
+
ids_to_load = [
|
|
229
|
+
p.name for p in path.iterdir() if p.is_dir() and p.name.isdigit()
|
|
230
|
+
]
|
|
224
231
|
ids_to_load = sorted(ids_to_load, key=lambda i: int(i))
|
|
225
232
|
ids_to_load = [str(i) for i in ids_to_load]
|
|
226
233
|
first_raw_fif_path = path / ids_to_load[0] / f"{ids_to_load[0]}-raw.fif"
|
|
@@ -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.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/atcnet.py
RENAMED
|
@@ -444,8 +444,10 @@ class ATCNet(EEGModuleMixin, nn.Module):
|
|
|
444
444
|
# ----- Sliding window -----
|
|
445
445
|
sw_concat: list[torch.Tensor] = [] # to store sliding window outputs
|
|
446
446
|
# for w in range(self.n_windows):
|
|
447
|
-
|
|
448
|
-
|
|
447
|
+
# (final_layer is not zipped in: with concat=True it holds a single
|
|
448
|
+
# layer, which would stop the loop after the first window)
|
|
449
|
+
for idx, (attention, tcn_module) in enumerate(
|
|
450
|
+
zip(self.attention_blocks, self.temporal_conv_nets)
|
|
449
451
|
):
|
|
450
452
|
conv_feat_w = conv_feat[..., idx : idx + self.Tw]
|
|
451
453
|
# Dimension: (batch_size, F2, Tw)
|
|
@@ -458,14 +460,15 @@ class ATCNet(EEGModuleMixin, nn.Module):
|
|
|
458
460
|
tcn_feat = tcn_module(att_feat)[..., -1]
|
|
459
461
|
# Dimension: (batch_size, F2)
|
|
460
462
|
|
|
461
|
-
# Outputs of sliding window can be either averaged after being
|
|
462
|
-
# mapped by dense layer or concatenated then mapped by a dense
|
|
463
|
-
# layer
|
|
464
|
-
if not self.concat:
|
|
465
|
-
tcn_feat = final_layer(tcn_feat)
|
|
466
|
-
|
|
467
463
|
sw_concat.append(tcn_feat)
|
|
468
464
|
|
|
465
|
+
# Outputs of sliding window can be either averaged after being
|
|
466
|
+
# mapped by dense layer or concatenated then mapped by a dense
|
|
467
|
+
# layer
|
|
468
|
+
if not self.concat:
|
|
469
|
+
for idx, final_layer in enumerate(self.final_layer):
|
|
470
|
+
sw_concat[idx] = final_layer(sw_concat[idx])
|
|
471
|
+
|
|
469
472
|
# ----- Aggregation and prediction -----
|
|
470
473
|
if self.concat:
|
|
471
474
|
sw_concat_agg = torch.cat(sw_concat, dim=1)
|
{braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/base.py
RENAMED
|
@@ -521,6 +521,11 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
521
521
|
output_shape : tuple[int, ...]
|
|
522
522
|
shape of the network output for `batch_size==1` (1, ...)
|
|
523
523
|
"""
|
|
524
|
+
# Run in eval mode, so that the probe input does not update BatchNorm
|
|
525
|
+
# running stats or draw dropout masks; restore each module's own mode
|
|
526
|
+
# afterwards (some may have been put in eval mode on purpose).
|
|
527
|
+
modes = {module: module.training for module in self.modules()}
|
|
528
|
+
self.eval()
|
|
524
529
|
with torch.inference_mode():
|
|
525
530
|
try:
|
|
526
531
|
return tuple(
|
|
@@ -540,6 +545,9 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
540
545
|
if error is None:
|
|
541
546
|
raise
|
|
542
547
|
raise error from exc
|
|
548
|
+
finally:
|
|
549
|
+
for module, training in modes.items():
|
|
550
|
+
module.training = training
|
|
543
551
|
|
|
544
552
|
def get_config(self) -> dict:
|
|
545
553
|
"""Return a JSON-serializable dict of all ``__init__`` parameters.
|
|
@@ -623,7 +631,11 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
|
|
|
623
631
|
``"pad"``.
|
|
624
632
|
"""
|
|
625
633
|
legacy = getattr(cls, "_legacy_on_non_divisible", None)
|
|
626
|
-
if legacy is
|
|
634
|
+
if legacy is None or "on_non_divisible" in kwargs:
|
|
635
|
+
return
|
|
636
|
+
# A subclass with its own signature may not take the argument.
|
|
637
|
+
params = inspect.signature(cls.__init__).parameters.values()
|
|
638
|
+
if any(p.name == "on_non_divisible" or p.kind is p.VAR_KEYWORD for p in params):
|
|
627
639
|
kwargs["on_non_divisible"] = legacy
|
|
628
640
|
|
|
629
641
|
def _set_n_outputs(self, n_outputs: int) -> None:
|
{braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/biot.py
RENAMED
|
@@ -186,10 +186,12 @@ class BIOT(EEGModuleMixin, nn.Module):
|
|
|
186
186
|
warn(
|
|
187
187
|
"The hop length is larger than the sampling frequency. "
|
|
188
188
|
+ "This may cause aliasing. Consider using a smaller "
|
|
189
|
-
"hop length.",
|
|
189
|
+
"hop length. Using sfreq // 2 instead.",
|
|
190
190
|
UserWarning,
|
|
191
191
|
)
|
|
192
|
-
|
|
192
|
+
# torch.stft needs an int, and sfreq is usually a float
|
|
193
|
+
hop_length = int(self.sfreq // 2)
|
|
194
|
+
self.hop_length = hop_length
|
|
193
195
|
|
|
194
196
|
if self.input_window_seconds < 1.0:
|
|
195
197
|
warning_msg = (
|
{braindecode-1.8.1.dev170153392 → braindecode-1.8.1.dev170208067}/braindecode/models/ctnet.py
RENAMED
|
@@ -181,6 +181,7 @@ class CTNet(EEGModuleMixin, nn.Module, license="mit"):
|
|
|
181
181
|
drop_prob=self.att_positional_drop_prob,
|
|
182
182
|
n_times=self.n_times,
|
|
183
183
|
pool_size=self.pool_size_1,
|
|
184
|
+
sequence_length=self.sequence_length,
|
|
184
185
|
)
|
|
185
186
|
|
|
186
187
|
self.trans = _TransformerEncoder(
|
|
@@ -220,7 +221,7 @@ class CTNet(EEGModuleMixin, nn.Module, license="mit"):
|
|
|
220
221
|
cnn = self.position(cnn)
|
|
221
222
|
trans = self.trans(cnn)
|
|
222
223
|
features = cnn + trans
|
|
223
|
-
flatten_feature = self.
|
|
224
|
+
flatten_feature = self.flatten_drop_layer(features)
|
|
224
225
|
out = self.final_layer(flatten_feature)
|
|
225
226
|
return out
|
|
226
227
|
|
|
@@ -516,18 +517,23 @@ class _PositionalEncoding(nn.Module):
|
|
|
516
517
|
length: int = 100,
|
|
517
518
|
drop_prob: float = 0.1,
|
|
518
519
|
pool_size: int = 8,
|
|
520
|
+
sequence_length: int | None = None,
|
|
519
521
|
):
|
|
520
522
|
super().__init__()
|
|
521
523
|
self.pool_size = pool_size
|
|
522
524
|
self.n_times = n_times
|
|
523
525
|
|
|
524
|
-
|
|
526
|
+
# n_times / pool_size**2 is the sequence length only when both pooling
|
|
527
|
+
# sizes are equal; also cover the actual length (e.g. pool_size_2 <
|
|
528
|
+
# pool_size_1), so that the encoding is never shorter than the input
|
|
529
|
+
needed = max(int(n_times / (pool_size * pool_size)), sequence_length or 0)
|
|
530
|
+
if needed > length:
|
|
525
531
|
warn(
|
|
526
532
|
"the temporal dimensional is too long for this default length. "
|
|
527
533
|
"The length parameter will be automatically adjusted to "
|
|
528
534
|
"avoid inference issues."
|
|
529
535
|
)
|
|
530
|
-
length =
|
|
536
|
+
length = needed
|
|
531
537
|
|
|
532
538
|
self.dropout = nn.Dropout(drop_prob)
|
|
533
539
|
self.encoding = nn.Parameter(torch.randn(1, length, emb_size))
|