Braindecode 1.8.0.dev180935432__tar.gz → 1.8.0.dev181115527__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.0.dev180935432/braindecode.egg-info → braindecode-1.8.0.dev181115527}/PKG-INFO +1 -1
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/augmentation/base.py +1 -25
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/augmentation/functional.py +4 -2
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/augmentation/transforms.py +3 -5
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/base.py +0 -15
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bids/hub.py +25 -90
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bids/hub_io.py +5 -67
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/sleep_physionet.py +3 -9
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/atcnet.py +2 -2
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/attn_sleep.py +28 -87
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/base.py +1 -40
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/ctnet.py +6 -9
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eegsimpleconv.py +6 -8
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/ifnet.py +5 -8
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/sleep_stager_blanco_2020.py +9 -5
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/sleep_stager_chambon_2018.py +7 -1
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/sparcnet.py +2 -2
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/tidnet.py +7 -1
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/preprocessing/eegprep_preprocess.py +1 -1
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/preprocessing/windowers.py +30 -126
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/samplers/base.py +2 -40
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/training/losses.py +4 -7
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/util.py +10 -16
- braindecode-1.8.0.dev181115527/braindecode/version.py +1 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527/braindecode.egg-info}/PKG-INFO +1 -1
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/whats_new.rst +3 -118
- braindecode-1.8.0.dev180935432/braindecode/version.py +0 -1
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/LICENSE.txt +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/MANIFEST.in +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/NOTICE.txt +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/README.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/augmentation/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/classifier.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bbci.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bcicomp.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bids/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bids/datasets.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bids/format.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bids/hub_format.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bids/hub_validation.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bids/iterable.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/chb_mit.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/collate.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/mne.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/moabb.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/nmt.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/registry.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/siena.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/tuh.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/utils.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/xy.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datautil/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datautil/channel_utils.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datautil/hub_formats.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datautil/serialization.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datautil/util.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/eegneuralnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/functional/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/functional/functions.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/functional/initialization.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/attentionbasenet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/bendr.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/biot.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/brainmodule.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/cbramod.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/codebrain.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/config.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/contrawr.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/dance.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/deep4.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/deepsleepnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/dgcnn.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eegconformer.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eegdino.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eeginception_erp.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eeginception_mi.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eegitnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eegminer.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eegnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eegnex.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eegpt.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eegsym.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/eegtcnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/emg2qwerty.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/fbcnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/fblightconvnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/fbmsnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/hybrid.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/interpolated.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/labram.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/luna.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/medformer.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/meta_neuromotor.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/msvtnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/mvpformer.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/patchedtransformer.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/reve.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/sccnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/shallow_fbcsp.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/signal_jepa.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/sinc_shallow.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/sstdpn.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/steegformer.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/summary.csv +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/syncnet.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/tcformer.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/tcn.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/tsinception.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/usleep.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/util.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/zuna.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/activation.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/attention.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/blocks.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/convolution.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/dance_modules.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/filter.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/interpolation.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/layers.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/linear.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/parametrization.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/stats.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/util.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/modules/wrapper.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/preprocessing/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/preprocessing/mne_preprocess.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/preprocessing/preprocess.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/preprocessing/util.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/regressor.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/samplers/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/samplers/ssl.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/training/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/training/callbacks.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/training/scoring.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/visualization/__init__.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/visualization/attribution.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/visualization/confusion_matrices.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/visualization/frequency.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/visualization/metrics.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/visualization/sanity.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/visualization/topology.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode.egg-info/SOURCES.txt +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode.egg-info/dependency_links.txt +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode.egg-info/requires.txt +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode.egg-info/top_level.txt +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/Makefile +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/_templates/autosummary/class.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/_templates/autosummary/function.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/api.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/cite.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/conf.py +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/help.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/index.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/install/install.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/install/install_pip.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/install/install_source.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/categorization/attention.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/categorization/channel.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/categorization/convolution.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/categorization/filterbank.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/categorization/gnn.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/categorization/interpretable.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/categorization/lbm.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/categorization/recurrent.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/categorization/spd.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/models.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/models_categorization.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/models_table.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/models/models_visualization.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/docs/sg_execution_times.rst +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/pyproject.toml +0 -0
- {braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/setup.cfg +0 -0
{braindecode-1.8.0.dev180935432/braindecode.egg-info → braindecode-1.8.0.dev181115527}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: braindecode
|
|
3
|
-
Version: 1.8.0.
|
|
3
|
+
Version: 1.8.0.dev181115527
|
|
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>
|
{braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/augmentation/base.py
RENAMED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
# Bruno Aristimunha <b.aristimunha@gmail.com>
|
|
4
4
|
# Martin Wimpff <martin.wimpff@iss.uni-stuttgart.de>
|
|
5
5
|
# Valentin Iovene <val@too.gy>
|
|
6
|
-
# Sarthak Tayal <sarthaktayal2@gmail.com>
|
|
7
6
|
# License: BSD (3-clause)
|
|
8
7
|
|
|
9
8
|
from numbers import Real
|
|
@@ -177,14 +176,6 @@ class Compose(Transform):
|
|
|
177
176
|
return X, y
|
|
178
177
|
|
|
179
178
|
|
|
180
|
-
def _as_mixed_target(y, lam_dtype):
|
|
181
|
-
# an untouched target is the same as being mixed with itself with lam of one
|
|
182
|
-
if isinstance(y, (tuple, list)) and len(y) == 3:
|
|
183
|
-
return tuple(y)
|
|
184
|
-
lam = torch.ones(y.shape[0], device=y.device, dtype=lam_dtype)
|
|
185
|
-
return y, y, lam
|
|
186
|
-
|
|
187
|
-
|
|
188
179
|
class _AugmentationCollate:
|
|
189
180
|
"""Collate that applies a transform to each batch, with optional expansion.
|
|
190
181
|
|
|
@@ -202,10 +193,7 @@ class _AugmentationCollate:
|
|
|
202
193
|
``0`` (default) applies the transform in place (batch size unchanged).
|
|
203
194
|
``> 0`` keeps the clean originals and appends ``n_augmentation``
|
|
204
195
|
independently transformed copies, returning ``(X, y)`` of
|
|
205
|
-
``(1 + n_augmentation)`` times the original size.
|
|
206
|
-
mixes targets, as :class:`braindecode.augmentation.Mixup` does, ``y``
|
|
207
|
-
stays the ``(y_a, y_b, lam)`` triple and the clean originals get a
|
|
208
|
-
mixing coefficient of one.
|
|
196
|
+
``(1 + n_augmentation)`` times the original size.
|
|
209
197
|
"""
|
|
210
198
|
|
|
211
199
|
def __init__(self, transform, device=None, n_augmentation=0):
|
|
@@ -228,18 +216,6 @@ class _AugmentationCollate:
|
|
|
228
216
|
aug_X, aug_y = self.transform(X, y)
|
|
229
217
|
xs.append(aug_X)
|
|
230
218
|
ys.append(aug_y)
|
|
231
|
-
mixed_ys = [
|
|
232
|
-
aug_y
|
|
233
|
-
for aug_y in ys
|
|
234
|
-
if isinstance(aug_y, (tuple, list)) and len(aug_y) == 3
|
|
235
|
-
]
|
|
236
|
-
if mixed_ys:
|
|
237
|
-
# a target-mixing transform such as Mixup returns (y_a, y_b, lam),
|
|
238
|
-
# so the parts are concatenated one by one and the untouched copies
|
|
239
|
-
# are given a mixing coefficient of one
|
|
240
|
-
lam_dtype = mixed_ys[0][2].dtype
|
|
241
|
-
ys = [_as_mixed_target(aug_y, lam_dtype) for aug_y in ys]
|
|
242
|
-
return torch.cat(xs), tuple(torch.cat(part) for part in zip(*ys))
|
|
243
219
|
return torch.cat(xs), torch.cat(ys)
|
|
244
220
|
|
|
245
221
|
|
|
@@ -1065,11 +1065,13 @@ def mixup(
|
|
|
1065
1065
|
batch_size, n_channels, n_times = X.shape
|
|
1066
1066
|
|
|
1067
1067
|
X_mix = torch.zeros((batch_size, n_channels, n_times)).to(device)
|
|
1068
|
-
y_a =
|
|
1069
|
-
y_b =
|
|
1068
|
+
y_a = torch.arange(batch_size).to(device)
|
|
1069
|
+
y_b = torch.arange(batch_size).to(device)
|
|
1070
1070
|
|
|
1071
1071
|
for idx in range(batch_size):
|
|
1072
1072
|
X_mix[idx] = lam[idx] * X[idx] + (1 - lam[idx]) * X[idx_perm[idx]]
|
|
1073
|
+
y_a[idx] = y[idx]
|
|
1074
|
+
y_b[idx] = y[idx_perm[idx]]
|
|
1073
1075
|
|
|
1074
1076
|
return X_mix, (y_a, y_b, lam)
|
|
1075
1077
|
|
|
@@ -1068,18 +1068,16 @@ class Mixup(Transform):
|
|
|
1068
1068
|
device = X.device
|
|
1069
1069
|
batch_size, _, _ = X.shape
|
|
1070
1070
|
|
|
1071
|
-
# lam follows the dtype of X, numpy draws float64 and that would leak
|
|
1072
|
-
# into the mixed signal and into the loss returned by mixup_criterion
|
|
1073
1071
|
if self.alpha > 0:
|
|
1074
1072
|
if self.beta_per_sample:
|
|
1075
1073
|
lam = torch.as_tensor(
|
|
1076
1074
|
self.rng.beta(self.alpha, self.alpha, batch_size)
|
|
1077
|
-
).to(device
|
|
1075
|
+
).to(device)
|
|
1078
1076
|
else:
|
|
1079
|
-
lam = torch.ones(batch_size
|
|
1077
|
+
lam = torch.ones(batch_size).to(device)
|
|
1080
1078
|
lam *= self.rng.beta(self.alpha, self.alpha)
|
|
1081
1079
|
else:
|
|
1082
|
-
lam = torch.ones(batch_size
|
|
1080
|
+
lam = torch.ones(batch_size).to(device)
|
|
1083
1081
|
|
|
1084
1082
|
idx_perm = torch.as_tensor(
|
|
1085
1083
|
self.rng.permutation(
|
{braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/base.py
RENAMED
|
@@ -59,7 +59,6 @@ def _html_row(label, value):
|
|
|
59
59
|
|
|
60
60
|
_METADATA_INTERNAL_COLS = {
|
|
61
61
|
"i_window_in_trial",
|
|
62
|
-
"i_trial_in_dataset",
|
|
63
62
|
"i_start_in_trial",
|
|
64
63
|
"i_stop_in_trial",
|
|
65
64
|
"target",
|
|
@@ -1375,20 +1374,6 @@ class BaseConcatDataset(ConcatDataset, HubDatasetMixin, Generic[T]):
|
|
|
1375
1374
|
"datasets are WindowsDataset."
|
|
1376
1375
|
)
|
|
1377
1376
|
|
|
1378
|
-
for ds in self.datasets:
|
|
1379
|
-
if hasattr(ds, "_windows") and ds._windows is not None:
|
|
1380
|
-
df = ds._windows.metadata
|
|
1381
|
-
else:
|
|
1382
|
-
df = ds.metadata
|
|
1383
|
-
if (
|
|
1384
|
-
"i_trial_in_dataset" in df.columns
|
|
1385
|
-
and "i_trial_in_dataset" in ds.description
|
|
1386
|
-
):
|
|
1387
|
-
raise ValueError(
|
|
1388
|
-
"Dataset descriptions cannot contain the reserved window "
|
|
1389
|
-
"metadata key 'i_trial_in_dataset'."
|
|
1390
|
-
)
|
|
1391
|
-
|
|
1392
1377
|
all_dfs = list()
|
|
1393
1378
|
for ds in self.datasets:
|
|
1394
1379
|
if hasattr(ds, "_windows") and ds._windows is not None:
|
{braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/datasets/bids/hub.py
RENAMED
|
@@ -28,7 +28,6 @@ The format follows a BIDS-inspired sourcedata structure:
|
|
|
28
28
|
# License: BSD (3-clause)
|
|
29
29
|
|
|
30
30
|
import contextlib
|
|
31
|
-
import copy
|
|
32
31
|
import json
|
|
33
32
|
import logging
|
|
34
33
|
import tempfile
|
|
@@ -57,7 +56,6 @@ from .hub_io import (
|
|
|
57
56
|
_load_eegwindows_from_zarr,
|
|
58
57
|
_load_raw_from_zarr,
|
|
59
58
|
_load_windows_from_zarr,
|
|
60
|
-
_prepare_info_for_json,
|
|
61
59
|
_save_eegwindows_to_zarr,
|
|
62
60
|
_save_raw_to_zarr,
|
|
63
61
|
_save_windows_to_zarr,
|
|
@@ -74,33 +72,6 @@ log = logging.getLogger(__name__)
|
|
|
74
72
|
_LOCK_FILE = "format_info.json"
|
|
75
73
|
|
|
76
74
|
|
|
77
|
-
def _normalize_kwargs_for_json(value, field_name):
|
|
78
|
-
"""Return one preprocessing-kwargs value as native strict JSON."""
|
|
79
|
-
|
|
80
|
-
def _convert(obj):
|
|
81
|
-
if isinstance(obj, np.ndarray):
|
|
82
|
-
return _convert(obj.tolist())
|
|
83
|
-
if isinstance(obj, dict):
|
|
84
|
-
return {key: _convert(item) for key, item in obj.items()}
|
|
85
|
-
if isinstance(obj, (list, tuple)):
|
|
86
|
-
return [_convert(item) for item in obj]
|
|
87
|
-
if isinstance(obj, np.generic):
|
|
88
|
-
return _convert(obj.item())
|
|
89
|
-
return obj
|
|
90
|
-
|
|
91
|
-
try:
|
|
92
|
-
converted = _convert(value)
|
|
93
|
-
if isinstance(converted, str):
|
|
94
|
-
raise ValueError(
|
|
95
|
-
"a root string is ambiguous with the legacy encoded format"
|
|
96
|
-
)
|
|
97
|
-
return json.loads(json.dumps(converted, allow_nan=False))
|
|
98
|
-
except (OverflowError, RecursionError, TypeError, ValueError) as error:
|
|
99
|
-
raise ValueError(
|
|
100
|
-
f"{field_name} must contain only finite JSON-serializable values"
|
|
101
|
-
) from error
|
|
102
|
-
|
|
103
|
-
|
|
104
75
|
class HubDatasetMixin:
|
|
105
76
|
"""
|
|
106
77
|
Mixin class for Hugging Face Hub integration with EEG datasets.
|
|
@@ -714,57 +685,14 @@ class HubDatasetMixin:
|
|
|
714
685
|
f"{output_path} already exists. Set overwrite=True to replace it."
|
|
715
686
|
)
|
|
716
687
|
|
|
688
|
+
# Create zarr store (zarr v3 API)
|
|
689
|
+
root = zarr.open(str(output_path), mode="w")
|
|
690
|
+
|
|
717
691
|
# Validate uniformity across all datasets using shared validation
|
|
718
692
|
dataset_type, _, _ = hub_validation.validate_dataset_uniformity(self.datasets)
|
|
719
693
|
|
|
720
|
-
#
|
|
721
|
-
|
|
722
|
-
prepared_infos = []
|
|
723
|
-
for ds in self.datasets:
|
|
724
|
-
if dataset_type == "WindowsDataset":
|
|
725
|
-
info = ds.windows.info
|
|
726
|
-
elif dataset_type in ("EEGWindowsDataset", "RawDataset"):
|
|
727
|
-
info = ds.raw.info
|
|
728
|
-
prepared_infos.append(_prepare_info_for_json(info.to_json_dict()))
|
|
729
|
-
|
|
730
|
-
prepared_kwargs = {}
|
|
731
|
-
for kwarg_name in [
|
|
732
|
-
"raw_preproc_kwargs",
|
|
733
|
-
"window_kwargs",
|
|
734
|
-
"window_preproc_kwargs",
|
|
735
|
-
]:
|
|
736
|
-
expected_present = hasattr(self.datasets[0], kwarg_name)
|
|
737
|
-
expected_value = None
|
|
738
|
-
expected_token = None
|
|
739
|
-
for i_ds, ds in enumerate(self.datasets):
|
|
740
|
-
present = hasattr(ds, kwarg_name)
|
|
741
|
-
if present != expected_present:
|
|
742
|
-
raise ValueError(
|
|
743
|
-
f"{kwarg_name} on dataset {i_ds} has inconsistent presence; "
|
|
744
|
-
"the Zarr format stores one global value"
|
|
745
|
-
)
|
|
746
|
-
if not present:
|
|
747
|
-
continue
|
|
748
|
-
value = _normalize_kwargs_for_json(
|
|
749
|
-
getattr(ds, kwarg_name), f"{kwarg_name} on dataset {i_ds}"
|
|
750
|
-
)
|
|
751
|
-
value_token = json.dumps(
|
|
752
|
-
value, sort_keys=True, separators=(",", ":"), allow_nan=False
|
|
753
|
-
)
|
|
754
|
-
if i_ds == 0:
|
|
755
|
-
expected_value = value
|
|
756
|
-
expected_token = value_token
|
|
757
|
-
elif value_token != expected_token:
|
|
758
|
-
raise ValueError(
|
|
759
|
-
f"{kwarg_name} on dataset {i_ds} differs from dataset 0; "
|
|
760
|
-
"the Zarr format stores one global value"
|
|
761
|
-
)
|
|
762
|
-
if expected_present:
|
|
763
|
-
prepared_kwargs[kwarg_name] = expected_value
|
|
764
|
-
|
|
765
|
-
# Create compressor and zarr store (zarr v3 API) only after preflight.
|
|
766
|
-
compressor = _create_compressor(compression, compression_level)
|
|
767
|
-
root = zarr.open(str(output_path), mode="w")
|
|
694
|
+
# Keep reference to first dataset for preprocessing kwargs
|
|
695
|
+
first_ds = self.datasets[0]
|
|
768
696
|
|
|
769
697
|
# Store global metadata
|
|
770
698
|
root.attrs["n_datasets"] = len(self.datasets)
|
|
@@ -778,10 +706,21 @@ class HubDatasetMixin:
|
|
|
778
706
|
root.attrs["zarr_version"] = zarr.__version__
|
|
779
707
|
root.attrs["scipy_version"] = scipy.__version__
|
|
780
708
|
|
|
781
|
-
# Save preprocessing kwargs
|
|
782
|
-
# typically set by windowing functions on individual datasets
|
|
783
|
-
for kwarg_name
|
|
784
|
-
|
|
709
|
+
# Save preprocessing kwargs (check first dataset, assuming uniform preprocessing)
|
|
710
|
+
# These are typically set by windowing functions on individual datasets
|
|
711
|
+
for kwarg_name in [
|
|
712
|
+
"raw_preproc_kwargs",
|
|
713
|
+
"window_kwargs",
|
|
714
|
+
"window_preproc_kwargs",
|
|
715
|
+
]:
|
|
716
|
+
# Check first dataset for these attributes
|
|
717
|
+
if hasattr(first_ds, kwarg_name):
|
|
718
|
+
kwargs = getattr(first_ds, kwarg_name)
|
|
719
|
+
if kwargs:
|
|
720
|
+
root.attrs[kwarg_name] = json.dumps(kwargs)
|
|
721
|
+
|
|
722
|
+
# Create compressor
|
|
723
|
+
compressor = _create_compressor(compression, compression_level)
|
|
785
724
|
|
|
786
725
|
# Save each recording
|
|
787
726
|
for i_ds, ds in enumerate(self.datasets):
|
|
@@ -792,7 +731,7 @@ class HubDatasetMixin:
|
|
|
792
731
|
data = ds.windows.get_data()
|
|
793
732
|
metadata = ds.windows.metadata
|
|
794
733
|
description = ds.description
|
|
795
|
-
info_dict =
|
|
734
|
+
info_dict = ds.windows.info.to_json_dict()
|
|
796
735
|
target_name = ds.target_name if hasattr(ds, "target_name") else None
|
|
797
736
|
|
|
798
737
|
# Save using inlined function
|
|
@@ -811,7 +750,7 @@ class HubDatasetMixin:
|
|
|
811
750
|
raw = ds.raw
|
|
812
751
|
metadata = ds.metadata
|
|
813
752
|
description = ds.description
|
|
814
|
-
info_dict =
|
|
753
|
+
info_dict = ds.raw.info.to_json_dict()
|
|
815
754
|
targets_from = ds.targets_from
|
|
816
755
|
last_target_only = ds.last_target_only
|
|
817
756
|
|
|
@@ -832,7 +771,7 @@ class HubDatasetMixin:
|
|
|
832
771
|
# Get continuous raw data from RawDataset
|
|
833
772
|
raw = ds.raw
|
|
834
773
|
description = ds.description
|
|
835
|
-
info_dict =
|
|
774
|
+
info_dict = ds.raw.info.to_json_dict()
|
|
836
775
|
target_name = ds.target_name if hasattr(ds, "target_name") else None
|
|
837
776
|
|
|
838
777
|
# Save using inlined function
|
|
@@ -1017,14 +956,10 @@ class HubDatasetMixin:
|
|
|
1017
956
|
"window_preproc_kwargs",
|
|
1018
957
|
]:
|
|
1019
958
|
if kwarg_name in root.attrs:
|
|
1020
|
-
kwargs = root.attrs[kwarg_name]
|
|
1021
|
-
if isinstance(kwargs, str):
|
|
1022
|
-
# Stores written by older braindecode versions kept
|
|
1023
|
-
# these attributes as double-encoded JSON strings.
|
|
1024
|
-
kwargs = json.loads(kwargs)
|
|
959
|
+
kwargs = json.loads(root.attrs[kwarg_name])
|
|
1025
960
|
# Set on each individual dataset (where they were originally stored)
|
|
1026
961
|
for ds in datasets:
|
|
1027
|
-
setattr(ds, kwarg_name,
|
|
962
|
+
setattr(ds, kwarg_name, kwargs)
|
|
1028
963
|
|
|
1029
964
|
return concat_ds
|
|
1030
965
|
|
|
@@ -8,7 +8,6 @@ These functions keep the Zarr serialization details isolated from hub.py.
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
10
|
import json
|
|
11
|
-
from numbers import Real
|
|
12
11
|
from pathlib import Path
|
|
13
12
|
|
|
14
13
|
import numpy as np
|
|
@@ -18,78 +17,17 @@ from mne.utils import _soft_import
|
|
|
18
17
|
zarr = _soft_import("zarr", purpose="hugging face integration", strict=False)
|
|
19
18
|
|
|
20
19
|
|
|
21
|
-
def _is_non_bool_real(value):
|
|
22
|
-
return not isinstance(value, (bool, np.bool_)) and isinstance(
|
|
23
|
-
value, (Real, np.integer, np.floating)
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def _prepare_info_for_json(obj, path="info", *, _in_numeric_sequence=False):
|
|
28
|
-
"""Normalize an MNE Info value to strict JSON without losing sequence NaNs."""
|
|
29
|
-
if isinstance(obj, np.ndarray):
|
|
30
|
-
obj = obj.tolist()
|
|
31
|
-
|
|
32
|
-
if isinstance(obj, dict):
|
|
33
|
-
return {
|
|
34
|
-
key: _prepare_info_for_json(value, f"{path}.{key}")
|
|
35
|
-
for key, value in obj.items()
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if isinstance(obj, (list, tuple)):
|
|
39
|
-
values = list(obj)
|
|
40
|
-
has_none = any(value is None for value in values)
|
|
41
|
-
has_number = any(_is_non_bool_real(value) for value in values)
|
|
42
|
-
all_none = bool(values) and all(value is None for value in values)
|
|
43
|
-
if all_none or (has_none and has_number):
|
|
44
|
-
raise ValueError(
|
|
45
|
-
f"{path} is ambiguous: numeric sequences cannot contain JSON null"
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
is_numeric_sequence = bool(values) and all(
|
|
49
|
-
_is_non_bool_real(value) for value in values
|
|
50
|
-
)
|
|
51
|
-
return [
|
|
52
|
-
_prepare_info_for_json(
|
|
53
|
-
value,
|
|
54
|
-
f"{path}[{index}]",
|
|
55
|
-
_in_numeric_sequence=is_numeric_sequence,
|
|
56
|
-
)
|
|
57
|
-
for index, value in enumerate(values)
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
if isinstance(obj, (bool, np.bool_)):
|
|
61
|
-
return bool(obj)
|
|
62
|
-
if isinstance(obj, (int, np.integer)):
|
|
63
|
-
return int(obj)
|
|
64
|
-
if _is_non_bool_real(obj):
|
|
65
|
-
value = float(obj)
|
|
66
|
-
if np.isnan(value):
|
|
67
|
-
if _in_numeric_sequence:
|
|
68
|
-
return None
|
|
69
|
-
raise ValueError(f"{path} contains unsupported NaN")
|
|
70
|
-
if np.isposinf(value):
|
|
71
|
-
raise ValueError(f"{path} contains positive infinity")
|
|
72
|
-
if np.isneginf(value):
|
|
73
|
-
raise ValueError(f"{path} contains negative infinity")
|
|
74
|
-
return value
|
|
75
|
-
if obj is None or isinstance(obj, str):
|
|
76
|
-
return obj
|
|
77
|
-
raise ValueError(f"{path} contains a non-JSON-serializable value")
|
|
78
|
-
|
|
79
|
-
|
|
80
20
|
def _restore_nan_from_json(obj):
|
|
81
|
-
"""Restore NaN values from None in
|
|
21
|
+
"""Restore NaN values from None in legacy zarr stores.
|
|
82
22
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
23
|
+
Datasets saved before zarr v3 native NaN support used
|
|
24
|
+
``_sanitize_for_json`` to convert NaN/Inf → None. This restores them
|
|
25
|
+
on load so ``mne.Info.from_json_dict`` gets proper NaN arrays.
|
|
86
26
|
"""
|
|
87
27
|
if isinstance(obj, dict):
|
|
88
28
|
return {k: _restore_nan_from_json(v) for k, v in obj.items()}
|
|
89
29
|
if isinstance(obj, list):
|
|
90
|
-
if len(obj) > 0 and all(
|
|
91
|
-
value is None or _is_non_bool_real(value) for value in obj
|
|
92
|
-
):
|
|
30
|
+
if len(obj) > 0 and all(isinstance(x, (int, float, type(None))) for x in obj):
|
|
93
31
|
return [np.nan if x is None else x for x in obj]
|
|
94
32
|
return [_restore_nan_from_json(v) for v in obj]
|
|
95
33
|
return obj
|
|
@@ -117,15 +117,9 @@ class SleepPhysionet(BaseConcatDataset):
|
|
|
117
117
|
sleep_event_inds = np.where(mask)[0]
|
|
118
118
|
|
|
119
119
|
# Crop raw
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
tmin
|
|
123
|
-
tmax = a_tmax["onset"] + a_tmax["duration"] + crop_wake_mins * 60
|
|
124
|
-
raw.crop(
|
|
125
|
-
tmin=max(tmin, raw.times[0]),
|
|
126
|
-
tmax=min(tmax, raw.times[-1] + 1 / raw.info["sfreq"]),
|
|
127
|
-
include_tmax=False,
|
|
128
|
-
)
|
|
120
|
+
tmin = annots[int(sleep_event_inds[0])]["onset"] - crop_wake_mins * 60
|
|
121
|
+
tmax = annots[int(sleep_event_inds[-1])]["onset"] + crop_wake_mins * 60
|
|
122
|
+
raw.crop(tmin=max(tmin, raw.times[0]), tmax=min(tmax, raw.times[-1]))
|
|
129
123
|
|
|
130
124
|
# Rename EEG channels
|
|
131
125
|
ch_names = {i: i.replace("EEG ", "") for i in raw.ch_names if "EEG" in i}
|
{braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/atcnet.py
RENAMED
|
@@ -196,7 +196,7 @@ class ATCNet(EEGModuleMixin, nn.Module):
|
|
|
196
196
|
num_heads : int
|
|
197
197
|
Number of attention heads, denoted H in table 1 of the paper [1]_.
|
|
198
198
|
Defaults to 2 as in [1]_.
|
|
199
|
-
|
|
199
|
+
att_dropout : float
|
|
200
200
|
Dropout probability used in the attention block, denoted pa in table 1
|
|
201
201
|
of the paper [1]_. Defaults to 0.5 as in [1]_.
|
|
202
202
|
tcn_depth : int
|
|
@@ -206,7 +206,7 @@ class ATCNet(EEGModuleMixin, nn.Module):
|
|
|
206
206
|
tcn_kernel_size : int
|
|
207
207
|
Temporal kernel size used in TCN block, denoted Kt in table 1 of the
|
|
208
208
|
paper [1]_. Defaults to 4 as in [1]_.
|
|
209
|
-
|
|
209
|
+
tcn_dropout : float
|
|
210
210
|
Dropout probability used in the TCN block, denoted pt in table 1
|
|
211
211
|
of the paper [1]_. Defaults to 0.3 as in [1]_.
|
|
212
212
|
tcn_activation : torch.nn.Module
|
{braindecode-1.8.0.dev180935432 → braindecode-1.8.0.dev181115527}/braindecode/models/attn_sleep.py
RENAMED
|
@@ -1,36 +1,10 @@
|
|
|
1
1
|
# Authors: Divyesh Narayanan <divyesh.narayanan@gmail.com>
|
|
2
|
-
# Sarthak Tayal <sarthaktayal2@gmail.com>
|
|
3
2
|
#
|
|
4
3
|
# License: BSD (3-clause)
|
|
5
|
-
#
|
|
6
|
-
# This implementation derives from https://github.com/emadeldeen24/AttnSleep:
|
|
7
|
-
#
|
|
8
|
-
# MIT License
|
|
9
|
-
#
|
|
10
|
-
# Copyright (c) 2020 Emadeldeen Eldele
|
|
11
|
-
#
|
|
12
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
14
|
-
# in the Software without restriction, including without limitation the rights
|
|
15
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
17
|
-
# furnished to do so, subject to the following conditions:
|
|
18
|
-
#
|
|
19
|
-
# The above copyright notice and this permission notice shall be included in all
|
|
20
|
-
# copies or substantial portions of the Software.
|
|
21
|
-
#
|
|
22
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
-
# SOFTWARE.
|
|
29
4
|
|
|
30
5
|
import math
|
|
31
6
|
import warnings
|
|
32
7
|
from copy import deepcopy
|
|
33
|
-
from numbers import Integral
|
|
34
8
|
|
|
35
9
|
import torch
|
|
36
10
|
import torch.nn.functional as F
|
|
@@ -59,8 +33,7 @@ class AttnSleep(EEGModuleMixin, nn.Module):
|
|
|
59
33
|
|
|
60
34
|
Warning - This model was designed for signals of 30 seconds at 100Hz or 125Hz (in which case
|
|
61
35
|
the reference architecture from [1]_ which was validated on SHHS dataset [2]_ will be used)
|
|
62
|
-
to use any other input is likely to make the model perform in unintended ways.
|
|
63
|
-
window length also needs a ``d_model`` of its own, see the parameter below.
|
|
36
|
+
to use any other input is likely to make the model perform in unintended ways.
|
|
64
37
|
|
|
65
38
|
Parameters
|
|
66
39
|
----------
|
|
@@ -71,10 +44,7 @@ class AttnSleep(EEGModuleMixin, nn.Module):
|
|
|
71
44
|
Also the input dimension of the first FC layer in the feed forward
|
|
72
45
|
and the output of the second FC layer in the same.
|
|
73
46
|
Increase for higher sampling rate/signal length.
|
|
74
|
-
It should be divisible by n_attn_heads
|
|
75
|
-
of time steps returned by the feature extractor: 80 for 30 seconds at
|
|
76
|
-
100 Hz and 100 for 30 seconds at 125 Hz. A construction error reports
|
|
77
|
-
the value needed for other window lengths.
|
|
47
|
+
It should be divisible by n_attn_heads
|
|
78
48
|
d_ff : int
|
|
79
49
|
Output dimension of the first FC layer in the feed forward and the
|
|
80
50
|
input dimension of the second FC layer in the same.
|
|
@@ -88,12 +58,15 @@ class AttnSleep(EEGModuleMixin, nn.Module):
|
|
|
88
58
|
If True, return the features, i.e. the output of the feature extractor
|
|
89
59
|
(before the final linear layer). If False, pass the features through
|
|
90
60
|
the final linear layer.
|
|
61
|
+
n_classes : int
|
|
62
|
+
Alias for `n_outputs`.
|
|
63
|
+
input_size_s : float
|
|
64
|
+
Alias for `input_window_seconds`.
|
|
91
65
|
activation : nn.Module, default=nn.ReLU
|
|
92
|
-
Activation function class to apply
|
|
93
|
-
feed-forward block. Should be a PyTorch activation
|
|
66
|
+
Activation function class to apply. Should be a PyTorch activation
|
|
94
67
|
module class like ``nn.ReLU`` or ``nn.ELU``. Default is ``nn.ReLU``.
|
|
95
|
-
activation_mrcnn : nn.Module, default=nn.
|
|
96
|
-
Activation function class to apply in the
|
|
68
|
+
activation_mrcnn : nn.Module, default=nn.ReLU
|
|
69
|
+
Activation function class to apply in the Mask R-CNN layer.
|
|
97
70
|
Should be a PyTorch activation module class like ``nn.ReLU`` or
|
|
98
71
|
``nn.GELU``. Default is ``nn.GELU``.
|
|
99
72
|
|
|
@@ -126,14 +99,6 @@ class AttnSleep(EEGModuleMixin, nn.Module):
|
|
|
126
99
|
n_chans=None,
|
|
127
100
|
n_times=None,
|
|
128
101
|
):
|
|
129
|
-
if (
|
|
130
|
-
sum(value is not None for value in (n_times, sfreq, input_window_seconds))
|
|
131
|
-
< 2
|
|
132
|
-
):
|
|
133
|
-
raise ValueError(
|
|
134
|
-
"AttnSleep requires at least two of n_times, sfreq, and "
|
|
135
|
-
"input_window_seconds."
|
|
136
|
-
)
|
|
137
102
|
super().__init__(
|
|
138
103
|
n_outputs=n_outputs,
|
|
139
104
|
n_chans=n_chans,
|
|
@@ -175,14 +140,6 @@ class AttnSleep(EEGModuleMixin, nn.Module):
|
|
|
175
140
|
activation=activation_mrcnn,
|
|
176
141
|
activation_se=activation,
|
|
177
142
|
)
|
|
178
|
-
feature_length = self._feature_length(mrcnn, self.n_times)
|
|
179
|
-
if feature_length != d_model:
|
|
180
|
-
raise ValueError(
|
|
181
|
-
f"d_model is {d_model} but the feature extractor returns "
|
|
182
|
-
f"{feature_length} time steps for an input of {self.n_times} "
|
|
183
|
-
f"samples at {self.sfreq} Hz. Set d_model={feature_length}, with "
|
|
184
|
-
"an n_attn_heads that divides it."
|
|
185
|
-
)
|
|
186
143
|
attn = _MultiHeadedAttention(n_attn_heads, d_model, after_reduced_cnn_size)
|
|
187
144
|
ff = _PositionwiseFeedForward(d_model, d_ff, drop_prob, activation=activation)
|
|
188
145
|
tce = _TCE(
|
|
@@ -193,26 +150,23 @@ class AttnSleep(EEGModuleMixin, nn.Module):
|
|
|
193
150
|
)
|
|
194
151
|
|
|
195
152
|
self.feature_extractor = nn.Sequential(mrcnn, tce)
|
|
196
|
-
self.len_last_layer =
|
|
153
|
+
self.len_last_layer = self._len_last_layer(self.n_times)
|
|
197
154
|
self.return_feats = return_feats
|
|
198
155
|
|
|
199
156
|
# TODO: Add new way to handle return features
|
|
200
157
|
"""if return_feats:
|
|
201
158
|
raise ValueError("return_feat == True is not accepted anymore")"""
|
|
202
159
|
if not return_feats:
|
|
203
|
-
self.final_layer = nn.Linear(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
for module, was_training in training_states:
|
|
214
|
-
module.training = was_training
|
|
215
|
-
return out.shape[-1]
|
|
160
|
+
self.final_layer = nn.Linear(
|
|
161
|
+
d_model * after_reduced_cnn_size, self.n_outputs
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def _len_last_layer(self, input_size):
|
|
165
|
+
self.feature_extractor.eval()
|
|
166
|
+
with torch.no_grad():
|
|
167
|
+
out = self.feature_extractor(torch.Tensor(1, 1, input_size))
|
|
168
|
+
self.feature_extractor.train()
|
|
169
|
+
return len(out.flatten())
|
|
216
170
|
|
|
217
171
|
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
218
172
|
"""
|
|
@@ -241,7 +195,7 @@ class _SELayer(nn.Module):
|
|
|
241
195
|
self.avg_pool = nn.AdaptiveAvgPool1d(1)
|
|
242
196
|
self.fc = nn.Sequential(
|
|
243
197
|
nn.Linear(channel, channel // reduction, bias=False),
|
|
244
|
-
activation(),
|
|
198
|
+
activation(inplace=True),
|
|
245
199
|
nn.Linear(channel // reduction, channel, bias=False),
|
|
246
200
|
nn.Sigmoid(),
|
|
247
201
|
)
|
|
@@ -282,10 +236,10 @@ class _SEBasicBlock(nn.Module):
|
|
|
282
236
|
super(_SEBasicBlock, self).__init__()
|
|
283
237
|
self.conv1 = nn.Conv1d(inplanes, planes, stride)
|
|
284
238
|
self.bn1 = nn.BatchNorm1d(planes)
|
|
285
|
-
self.relu = activation()
|
|
239
|
+
self.relu = activation(inplace=True)
|
|
286
240
|
self.conv2 = nn.Conv1d(planes, planes, 1)
|
|
287
241
|
self.bn2 = nn.BatchNorm1d(planes)
|
|
288
|
-
self.se = _SELayer(planes, reduction
|
|
242
|
+
self.se = _SELayer(planes, reduction)
|
|
289
243
|
self.downsample = downsample
|
|
290
244
|
self.stride = stride
|
|
291
245
|
self.features = nn.Sequential(
|
|
@@ -366,11 +320,11 @@ class _MRCNN(nn.Module):
|
|
|
366
320
|
self.dropout = nn.Dropout(drate)
|
|
367
321
|
self.inplanes = 128
|
|
368
322
|
self.AFR = self._make_layer(
|
|
369
|
-
_SEBasicBlock, after_reduced_cnn_size, 1,
|
|
323
|
+
_SEBasicBlock, after_reduced_cnn_size, 1, activate=activation_se
|
|
370
324
|
)
|
|
371
325
|
|
|
372
326
|
def _make_layer(
|
|
373
|
-
self, block, planes, blocks, stride=1,
|
|
327
|
+
self, block, planes, blocks, stride=1, activate: type[nn.Module] = nn.ReLU
|
|
374
328
|
): # makes residual SE block
|
|
375
329
|
downsample = None
|
|
376
330
|
if stride != 1 or self.inplanes != planes * block.expansion:
|
|
@@ -386,12 +340,10 @@ class _MRCNN(nn.Module):
|
|
|
386
340
|
)
|
|
387
341
|
|
|
388
342
|
layers = []
|
|
389
|
-
layers.append(
|
|
390
|
-
block(self.inplanes, planes, stride, downsample, activation=activation)
|
|
391
|
-
)
|
|
343
|
+
layers.append(block(self.inplanes, planes, stride, downsample))
|
|
392
344
|
self.inplanes = planes * block.expansion
|
|
393
345
|
for i in range(1, blocks):
|
|
394
|
-
layers.append(block(self.inplanes, planes,
|
|
346
|
+
layers.append(block(self.inplanes, planes, activate=activate))
|
|
395
347
|
|
|
396
348
|
return nn.Sequential(*layers)
|
|
397
349
|
|
|
@@ -423,20 +375,9 @@ class _MultiHeadedAttention(nn.Module):
|
|
|
423
375
|
def __init__(self, h, d_model, after_reduced_cnn_size, dropout=0.1):
|
|
424
376
|
"""Take in model size and number of heads."""
|
|
425
377
|
super().__init__()
|
|
426
|
-
|
|
427
|
-
isinstance(h, bool)
|
|
428
|
-
or not isinstance(h, Integral)
|
|
429
|
-
or h <= 0
|
|
430
|
-
or d_model % h != 0
|
|
431
|
-
):
|
|
432
|
-
raise ValueError(
|
|
433
|
-
"n_attn_heads must be a positive integer that divides d_model, "
|
|
434
|
-
f"got n_attn_heads={h!r} and d_model={d_model}."
|
|
435
|
-
)
|
|
436
|
-
h = int(h)
|
|
378
|
+
assert d_model % h == 0
|
|
437
379
|
self.d_per_head = d_model // h
|
|
438
380
|
self.h = h
|
|
439
|
-
self.attn = torch.empty(0)
|
|
440
381
|
|
|
441
382
|
base_conv = CausalConv1d(
|
|
442
383
|
in_channels=after_reduced_cnn_size,
|