Braindecode 1.3.2.dev168310904__tar.gz → 1.3.2.dev168583761__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.
Files changed (162) hide show
  1. {braindecode-1.3.2.dev168310904/braindecode.egg-info → braindecode-1.3.2.dev168583761}/PKG-INFO +3 -3
  2. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/bids/hub.py +2 -7
  3. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/__init__.py +0 -2
  4. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/base.py +78 -123
  5. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/cbramod.py +5 -19
  6. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/config.py +29 -29
  7. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/luna.py +7 -8
  8. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/patchedtransformer.py +3 -5
  9. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/reve.py +3 -23
  10. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/shallow_fbcsp.py +8 -16
  11. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/util.py +2 -133
  12. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/__init__.py +1 -2
  13. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/activation.py +0 -20
  14. braindecode-1.3.2.dev168583761/braindecode/version.py +1 -0
  15. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761/braindecode.egg-info}/PKG-INFO +3 -3
  16. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode.egg-info/requires.txt +2 -2
  17. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/conf.py +7 -0
  18. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/models_categorization.rst +54 -55
  19. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/whats_new.rst +2 -27
  20. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/pyproject.toml +2 -11
  21. braindecode-1.3.2.dev168310904/braindecode/version.py +0 -1
  22. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/LICENSE.txt +0 -0
  23. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/MANIFEST.in +0 -0
  24. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/NOTICE.txt +0 -0
  25. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/README.rst +0 -0
  26. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/__init__.py +0 -0
  27. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/augmentation/__init__.py +0 -0
  28. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/augmentation/base.py +0 -0
  29. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/augmentation/functional.py +0 -0
  30. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/augmentation/transforms.py +0 -0
  31. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/classifier.py +0 -0
  32. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/__init__.py +0 -0
  33. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/base.py +0 -0
  34. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/bbci.py +0 -0
  35. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/bcicomp.py +0 -0
  36. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/bids/__init__.py +0 -0
  37. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/bids/datasets.py +0 -0
  38. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/bids/format.py +0 -0
  39. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/bids/hub_format.py +0 -0
  40. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/bids/hub_io.py +0 -0
  41. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/bids/hub_validation.py +0 -0
  42. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/bids/iterable.py +0 -0
  43. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/chb_mit.py +0 -0
  44. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/mne.py +0 -0
  45. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/moabb.py +0 -0
  46. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/nmt.py +0 -0
  47. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/registry.py +0 -0
  48. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/siena.py +0 -0
  49. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  50. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/sleep_physionet.py +0 -0
  51. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/tuh.py +0 -0
  52. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/utils.py +0 -0
  53. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datasets/xy.py +0 -0
  54. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datautil/__init__.py +0 -0
  55. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datautil/channel_utils.py +0 -0
  56. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datautil/hub_formats.py +0 -0
  57. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datautil/serialization.py +0 -0
  58. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/datautil/util.py +0 -0
  59. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/eegneuralnet.py +0 -0
  60. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/functional/__init__.py +0 -0
  61. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/functional/functions.py +0 -0
  62. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/functional/initialization.py +0 -0
  63. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/atcnet.py +0 -0
  64. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/attentionbasenet.py +0 -0
  65. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/attn_sleep.py +0 -0
  66. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/bendr.py +0 -0
  67. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/biot.py +0 -0
  68. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/brainmodule.py +0 -0
  69. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/contrawr.py +0 -0
  70. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/ctnet.py +0 -0
  71. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/deep4.py +0 -0
  72. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/deepsleepnet.py +0 -0
  73. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/dgcnn.py +0 -0
  74. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eegconformer.py +0 -0
  75. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eeginception_erp.py +0 -0
  76. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eeginception_mi.py +0 -0
  77. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eegitnet.py +0 -0
  78. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eegminer.py +0 -0
  79. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eegnet.py +0 -0
  80. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eegnex.py +0 -0
  81. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eegpt.py +0 -0
  82. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eegsimpleconv.py +0 -0
  83. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eegsym.py +0 -0
  84. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/eegtcnet.py +0 -0
  85. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/fbcnet.py +0 -0
  86. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/fblightconvnet.py +0 -0
  87. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/fbmsnet.py +0 -0
  88. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/hybrid.py +0 -0
  89. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/ifnet.py +0 -0
  90. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/labram.py +0 -0
  91. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/medformer.py +0 -0
  92. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/msvtnet.py +0 -0
  93. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/sccnet.py +0 -0
  94. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/signal_jepa.py +0 -0
  95. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/sinc_shallow.py +0 -0
  96. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  97. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  98. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/sparcnet.py +0 -0
  99. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/sstdpn.py +0 -0
  100. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/summary.csv +0 -0
  101. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/syncnet.py +0 -0
  102. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/tcn.py +0 -0
  103. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/tidnet.py +0 -0
  104. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/tsinception.py +0 -0
  105. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/models/usleep.py +0 -0
  106. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/attention.py +0 -0
  107. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/blocks.py +0 -0
  108. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/convolution.py +0 -0
  109. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/filter.py +0 -0
  110. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/layers.py +0 -0
  111. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/linear.py +0 -0
  112. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/parametrization.py +0 -0
  113. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/stats.py +0 -0
  114. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/util.py +0 -0
  115. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/modules/wrapper.py +0 -0
  116. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/preprocessing/__init__.py +0 -0
  117. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  118. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/preprocessing/mne_preprocess.py +0 -0
  119. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/preprocessing/preprocess.py +0 -0
  120. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/preprocessing/util.py +0 -0
  121. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/preprocessing/windowers.py +0 -0
  122. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/regressor.py +0 -0
  123. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/samplers/__init__.py +0 -0
  124. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/samplers/base.py +0 -0
  125. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/samplers/ssl.py +0 -0
  126. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/training/__init__.py +0 -0
  127. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/training/callbacks.py +0 -0
  128. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/training/losses.py +0 -0
  129. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/training/scoring.py +0 -0
  130. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/util.py +0 -0
  131. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/visualization/__init__.py +0 -0
  132. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/visualization/confusion_matrices.py +0 -0
  133. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode/visualization/gradients.py +0 -0
  134. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode.egg-info/SOURCES.txt +0 -0
  135. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode.egg-info/dependency_links.txt +0 -0
  136. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/braindecode.egg-info/top_level.txt +0 -0
  137. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/Makefile +0 -0
  138. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/_templates/autosummary/class.rst +0 -0
  139. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  140. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/_templates/autosummary/function.rst +0 -0
  141. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  142. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/api.rst +0 -0
  143. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/cite.rst +0 -0
  144. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/help.rst +0 -0
  145. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/index.rst +0 -0
  146. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/install/install.rst +0 -0
  147. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/install/install_pip.rst +0 -0
  148. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/install/install_source.rst +0 -0
  149. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/categorization/attention.rst +0 -0
  150. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/categorization/channel.rst +0 -0
  151. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/categorization/convolution.rst +0 -0
  152. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/categorization/filterbank.rst +0 -0
  153. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/categorization/gnn.rst +0 -0
  154. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/categorization/interpretable.rst +0 -0
  155. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/categorization/lbm.rst +0 -0
  156. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/categorization/recurrent.rst +0 -0
  157. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/categorization/spd.rst +0 -0
  158. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/models.rst +0 -0
  159. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/models_table.rst +0 -0
  160. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/models/models_visualization.rst +0 -0
  161. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/docs/sg_execution_times.rst +0 -0
  162. {braindecode-1.3.2.dev168310904 → braindecode-1.3.2.dev168583761}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.3.2.dev168310904
3
+ Version: 1.3.2.dev168583761
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>
@@ -22,7 +22,7 @@ Requires-Python: >=3.11
22
22
  Description-Content-Type: text/x-rst
23
23
  License-File: LICENSE.txt
24
24
  License-File: NOTICE.txt
25
- Requires-Dist: torch>=2.0
25
+ Requires-Dist: torch>=2.2
26
26
  Requires-Dist: torchaudio>=2.0
27
27
  Requires-Dist: mne>=1.11.0
28
28
  Requires-Dist: pandas<3.0.0
@@ -35,7 +35,7 @@ Requires-Dist: wfdb
35
35
  Requires-Dist: linear_attention_transformer
36
36
  Requires-Dist: docstring_inheritance
37
37
  Requires-Dist: rotary_embedding_torch
38
- Requires-Dist: pydantic>=2.0
38
+ Requires-Dist: pandas<3.0.0
39
39
  Provides-Extra: moabb
40
40
  Requires-Dist: moabb>=1.4.3; extra == "moabb"
41
41
  Provides-Extra: eegprep
@@ -845,16 +845,11 @@ class HubDatasetMixin:
845
845
 
846
846
  # Convert to MNE objects and create dataset
847
847
  info = Info.from_json_dict(info_dict)
848
- targets = metadata["target"].values
849
- if np.issubdtype(targets.dtype, np.integer):
850
- event_ids = targets
851
- else:
852
- event_ids = np.ones(len(metadata), dtype=int)
853
848
  events = np.column_stack(
854
849
  [
855
- metadata["i_start_in_trial"].values.astype(int),
850
+ metadata["i_start_in_trial"].values,
856
851
  np.zeros(len(metadata), dtype=int),
857
- event_ids,
852
+ metadata["target"].values,
858
853
  ]
859
854
  )
860
855
  epochs = mne.EpochsArray(data, info, events=events, metadata=metadata)
@@ -55,7 +55,6 @@ from .tsinception import TSception
55
55
  from .usleep import USleep
56
56
  from .util import (
57
57
  _init_models_dict,
58
- build_model_config,
59
58
  extract_channel_locations_from_chs_info,
60
59
  models_mandatory_parameters,
61
60
  )
@@ -119,7 +118,6 @@ __all__ = [
119
118
  "TIDNet",
120
119
  "TSception",
121
120
  "USleep",
122
- "build_model_config",
123
121
  "_init_models_dict",
124
122
  "models_mandatory_parameters",
125
123
  ]
@@ -17,13 +17,6 @@ from docstring_inheritance import NumpyDocstringInheritanceInitMeta
17
17
  from mne.utils import _soft_import
18
18
  from torchinfo import ModelStatistics, summary
19
19
 
20
- from braindecode.models.util import (
21
- _EEG_PARAMS,
22
- _IMPORT_ADAPTER,
23
- build_model_config,
24
- resolve_type_kwargs,
25
- track_model_init_kwargs,
26
- )
27
20
  from braindecode.version import __version__
28
21
 
29
22
  huggingface_hub = _soft_import(
@@ -137,9 +130,13 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta)
137
130
  the model weights. This ensures that loaded models are correctly configured
138
131
  for their original data specifications.
139
132
 
140
- All model parameters (both EEG-specific and model-specific such as
141
- dropout rates, activation functions, number of filters) are automatically
142
- saved to the Hub and restored when loading.
133
+ .. important::
134
+ Currently, only EEG-specific parameters (n_outputs, n_chans, n_times,
135
+ input_window_seconds, sfreq, chs_info) are saved to the Hub.
136
+ Model-specific parameters (e.g., dropout rates, activation functions,
137
+ number of filters) are not preserved and will use their default values
138
+ when loading from the Hub.
139
+ Full parameter serialization will be addressed in a future update.
143
140
  """
144
141
 
145
142
  def __init_subclass__(cls, **kwargs):
@@ -155,7 +152,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta)
155
152
 
156
153
  if not HAS_HF_HUB:
157
154
  super().__init_subclass__(**kwargs)
158
- track_model_init_kwargs(cls)
159
155
  return
160
156
 
161
157
  base_tags = ["braindecode", cls.__name__]
@@ -172,19 +168,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta)
172
168
  repo_url = kwargs.pop("repo_url", "https://braindecode.org")
173
169
  library_name = kwargs.pop("library_name", "braindecode")
174
170
  license = kwargs.pop("license", "bsd-3-clause")
175
-
176
- # Register a coder so that type[nn.Module] parameters
177
- # (e.g. activation=nn.ELU) are serialized as importable
178
- # strings in config.json and decoded back on load.
179
- coders = kwargs.pop("coders", None) or {}
180
- coders.setdefault(
181
- type,
182
- (
183
- lambda t: f"{t.__module__}.{t.__qualname__}",
184
- lambda data: _IMPORT_ADAPTER.validate_python(data),
185
- ),
186
- )
187
-
188
171
  # TODO: model_card_template can be added in the future for custom model cards
189
172
  super().__init_subclass__(
190
173
  tags=tags,
@@ -192,10 +175,8 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta)
192
175
  repo_url=repo_url,
193
176
  library_name=library_name,
194
177
  license=license,
195
- coders=coders,
196
178
  **kwargs,
197
179
  )
198
- track_model_init_kwargs(cls)
199
180
 
200
181
  def __init__(
201
182
  self,
@@ -235,17 +216,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta)
235
216
  self._n_times = n_times # type: ignore[assignment]
236
217
  self._sfreq = sfreq # type: ignore[assignment]
237
218
 
238
- # Back-fill instance attributes from _hub_mixin_config for any
239
- # params the subclass didn't store on self. Skip EEG params
240
- # (stored as self._*) and descriptors (properties).
241
- for key, val in getattr(self, "_hub_mixin_config", {}).items():
242
- if key in _EEG_PARAMS:
243
- continue
244
- if hasattr(getattr(type(self), key, None), "__get__"):
245
- continue
246
- if not hasattr(self, key):
247
- setattr(self, key, val)
248
-
249
219
  super().__init__()
250
220
 
251
221
  @property
@@ -356,76 +326,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta)
356
326
  raise ValueError(msg) from exc
357
327
  raise exc
358
328
 
359
- def get_config(self) -> dict:
360
- """Return a JSON-serializable dict of all ``__init__`` parameters.
361
-
362
- The returned dictionary can be saved to a JSON file and later
363
- used with :meth:`from_config` to reconstruct the model (without
364
- weights). It is also used internally by :meth:`push_to_hub` to
365
- persist the full model configuration.
366
-
367
- Returns
368
- -------
369
- dict
370
- All ``__init__`` parameters, JSON-serializable.
371
- ``type[nn.Module]`` parameters (e.g. ``activation``) are
372
- encoded as importable dotted-path strings.
373
-
374
- Examples
375
- --------
376
- >>> import json
377
- >>> from braindecode.models import EEGNet
378
- >>> model = EEGNet(n_chans=22, n_times=1000, n_outputs=4, F1=16)
379
- >>> config = model.get_config()
380
- >>> config["F1"]
381
- 16
382
- >>> # Save to disk
383
- >>> with open("config.json", "w") as f:
384
- ... json.dump(config, f)
385
-
386
- .. versionadded:: 1.4
387
- """
388
- return build_model_config(self)
389
-
390
- @classmethod
391
- def from_config(cls, config: dict) -> "EEGModuleMixin":
392
- """Create a model instance from a configuration dict.
393
-
394
- This is the inverse of :meth:`get_config`. Weights are **not**
395
- loaded -- use :meth:`from_pretrained` for that.
396
-
397
- Parameters
398
- ----------
399
- config : dict
400
- Configuration dict as returned by :meth:`get_config`.
401
-
402
- Returns
403
- -------
404
- EEGModuleMixin
405
- A new model instance.
406
-
407
- Examples
408
- --------
409
- >>> import json
410
- >>> from braindecode.models import EEGNet
411
- >>> model = EEGNet(n_chans=22, n_times=1000, n_outputs=4, F1=16)
412
- >>> config = model.get_config()
413
- >>> # Reconstruct (without weights)
414
- >>> model2 = EEGNet.from_config(config)
415
- >>> model2.F1
416
- 16
417
- >>> # Or from a JSON file
418
- >>> with open("config.json") as f:
419
- ... config = json.load(f)
420
- >>> model3 = EEGNet.from_config(config)
421
-
422
- .. versionadded:: 1.4
423
- """
424
- config = dict(config) # shallow copy
425
- config.pop("braindecode_version", None)
426
- resolve_type_kwargs(cls, config)
427
- return cls(**config)
428
-
429
329
  mapping: Optional[Dict[str, str]] = None
430
330
 
431
331
  def load_state_dict(self, state_dict, *args, **kwargs):
@@ -530,22 +430,54 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta)
530
430
 
531
431
  @staticmethod
532
432
  def _serialize_chs_info(chs_info):
533
- """Serialize MNE channel info (``info["chs"]``) to JSON-compatible dicts."""
433
+ """
434
+ Serialize MNE channel info to JSON-compatible format.
435
+
436
+ Parameters
437
+ ----------
438
+ chs_info : list of dict or None
439
+ Channel information from MNE Info object.
440
+
441
+ Returns
442
+ -------
443
+ list of dict or None
444
+ Serialized channel information that can be saved to JSON.
445
+ """
534
446
  if chs_info is None:
535
447
  return None
536
- _INT_FIELDS = ("kind", "coil_type", "unit")
537
- _FLOAT_FIELDS = ("cal", "range")
448
+
538
449
  serialized = []
539
450
  for ch in chs_info:
540
- ch_dict = {"ch_name": ch.get("ch_name", "")}
541
- for key in _INT_FIELDS:
542
- val = ch.get(key)
543
- if val is not None:
544
- ch_dict[key] = val if isinstance(val, str) else int(val)
545
- for key in _FLOAT_FIELDS:
546
- val = ch.get(key)
547
- if val is not None:
548
- ch_dict[key] = float(val)
451
+ # Extract serializable fields from MNE channel info
452
+ ch_dict = {
453
+ "ch_name": ch.get("ch_name", ""),
454
+ }
455
+
456
+ # Handle kind field - can be either string or integer
457
+ kind_val = ch.get("kind")
458
+ if kind_val is not None:
459
+ ch_dict["kind"] = (
460
+ kind_val if isinstance(kind_val, str) else int(kind_val)
461
+ )
462
+
463
+ # Add numeric fields with safe conversion
464
+ coil_type = ch.get("coil_type")
465
+ if coil_type is not None:
466
+ ch_dict["coil_type"] = int(coil_type)
467
+
468
+ unit = ch.get("unit")
469
+ if unit is not None:
470
+ ch_dict["unit"] = int(unit)
471
+
472
+ cal = ch.get("cal")
473
+ if cal is not None:
474
+ ch_dict["cal"] = float(cal)
475
+
476
+ range_val = ch.get("range")
477
+ if range_val is not None:
478
+ ch_dict["range"] = float(range_val)
479
+
480
+ # Serialize location array if present
549
481
  if "loc" in ch and ch["loc"] is not None:
550
482
  ch_dict["loc"] = (
551
483
  ch["loc"].tolist()
@@ -553,19 +485,35 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta)
553
485
  else list(ch["loc"])
554
486
  )
555
487
  serialized.append(ch_dict)
488
+
556
489
  return serialized
557
490
 
558
491
  @staticmethod
559
492
  def _deserialize_chs_info(chs_info_dict):
560
- """Deserialize JSON channel dicts back to MNE-compatible format."""
493
+ """
494
+ Deserialize channel info from JSON-compatible format to MNE-like structure.
495
+
496
+ Parameters
497
+ ----------
498
+ chs_info_dict : list of dict or None
499
+ Serialized channel information.
500
+
501
+ Returns
502
+ -------
503
+ list of dict or None
504
+ Deserialized channel information compatible with MNE.
505
+ """
561
506
  if chs_info_dict is None:
562
507
  return None
508
+
563
509
  deserialized = []
564
510
  for ch_dict in chs_info_dict:
565
511
  ch = ch_dict.copy()
512
+ # Convert location back to numpy array if present
566
513
  if "loc" in ch and ch["loc"] is not None:
567
514
  ch["loc"] = np.array(ch["loc"])
568
515
  deserialized.append(ch)
516
+
569
517
  return deserialized
570
518
 
571
519
  def _save_pretrained(self, save_directory):
@@ -585,8 +533,16 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta)
585
533
 
586
534
  save_directory = Path(save_directory)
587
535
 
588
- config = build_model_config(self)
589
- config["braindecode_version"] = __version__
536
+ # Collect EEG-specific configuration
537
+ config = {
538
+ "n_outputs": self._n_outputs,
539
+ "n_chans": self._n_chans,
540
+ "n_times": self._n_times,
541
+ "input_window_seconds": self._input_window_seconds,
542
+ "sfreq": self._sfreq,
543
+ "chs_info": self._serialize_chs_info(self._chs_info),
544
+ "braindecode_version": __version__,
545
+ }
590
546
 
591
547
  # Save to config.json
592
548
  config_path = save_directory / "config.json"
@@ -625,7 +581,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta)
625
581
  **model_kwargs,
626
582
  ):
627
583
  model_kwargs.pop("braindecode_version", None)
628
- resolve_type_kwargs(cls, model_kwargs)
629
584
  return super()._from_pretrained( # type: ignore
630
585
  model_id=model_id,
631
586
  revision=revision,
@@ -207,25 +207,11 @@ class CBraMod(EEGModuleMixin, nn.Module):
207
207
 
208
208
  self._weights_init()
209
209
 
210
- try:
211
- n_times = self.n_times
212
- n_chans = self.n_chans
213
- except ValueError:
214
- n_times = None
215
- n_chans = None
216
-
217
- if return_encoder_output:
218
- self.final_layer = nn.Identity()
219
- elif n_times is not None and n_chans is not None:
220
- n_patch = n_times // patch_size
221
- flat_dim = n_chans * n_patch * emb_dim
222
- self.final_layer = nn.Sequential(
223
- nn.Flatten(), nn.Linear(flat_dim, self.n_outputs)
224
- )
225
- else:
226
- self.final_layer = nn.Sequential(
227
- nn.Flatten(), nn.LazyLinear(self.n_outputs)
228
- )
210
+ self.final_layer = (
211
+ nn.Identity()
212
+ if return_encoder_output
213
+ else nn.Sequential(nn.Flatten(), nn.LazyLinear(self.n_outputs))
214
+ )
229
215
 
230
216
  def _weights_init(self):
231
217
  for m in self.modules():
@@ -4,16 +4,13 @@ from types import UnionType
4
4
  from typing import Annotated, Any, Literal, Union, get_args, get_origin
5
5
 
6
6
  import numpy as np
7
- import pydantic
7
+ from mne.utils import _soft_import
8
8
  from typing_extensions import TypedDict
9
9
 
10
10
  from braindecode.models.base import EEGModuleMixin
11
- from braindecode.models.util import (
12
- SigArgName,
13
- _init_models_dict,
14
- models_dict,
15
- models_mandatory_parameters,
16
- )
11
+ from braindecode.models.util import SigArgName, models_dict, models_mandatory_parameters
12
+
13
+ pydantic = _soft_import(name="pydantic", purpose="model configuration", strict=False)
17
14
 
18
15
  try:
19
16
  from numpydantic import NDArray, Shape
@@ -60,12 +57,8 @@ SIGNAL_ARGS_TYPES = {
60
57
  }
61
58
 
62
59
 
63
- class BaseBraindecodeModelConfig(pydantic.BaseModel):
64
- """Base class for braindecode model pydantic configs."""
65
-
60
+ class BaseBraindecodeModelConfig(pydantic.BaseModel): # type: ignore
66
61
  def create_instance(self) -> EEGModuleMixin:
67
- if self.model_name_ not in models_dict:
68
- _init_models_dict()
69
62
  model_cls = models_dict[self.model_name_]
70
63
  kwargs = self.model_dump(mode="python", exclude={"model_name_"})
71
64
  if kwargs.get("n_chans") is not None and kwargs.get("chs_info") is not None:
@@ -97,6 +90,13 @@ def make_model_config(
97
90
  type
98
91
  A pydantic BaseModel subclass representing the model config.
99
92
  """
93
+ if not pydantic:
94
+ raise ImportError(
95
+ "pydantic is required to use make_model_config. "
96
+ "Please install braindecode[typing]."
97
+ )
98
+
99
+ # ironically, we need to ignore the type here to have the soft dependency.
100
100
 
101
101
  @pydantic.model_validator(mode="before")
102
102
  def validate_signal_params(cls, data: Any):
@@ -207,23 +207,23 @@ def make_model_config(
207
207
  # and define __all__ based on generated classes
208
208
  __all__ = ["make_model_config"]
209
209
 
210
- if not models_dict:
211
- _init_models_dict()
212
-
213
- models_configs: list[type[BaseBraindecodeModelConfig]] = []
214
- for model_name, req, _ in models_mandatory_parameters:
215
- model_cls = models_dict[model_name]
216
- model_cfg = make_model_config(model_cls, req)
217
- globals()[model_cfg.__name__] = model_cfg
218
- __all__.append(model_cfg.__name__)
219
- models_configs.append(model_cfg)
220
-
221
- BraindecodeModelConfig = Annotated[ # type: ignore[valid-type]
222
- Union[tuple(models_configs)],
223
- pydantic.Field(
224
- discriminator="model_name_", description="Braindecode model configuration"
225
- ),
226
- ]
210
+ if not pydantic:
211
+ pass
212
+ else:
213
+ models_configs: list[type[BaseBraindecodeModelConfig]] = []
214
+ for model_name, req, _ in models_mandatory_parameters:
215
+ model_cls = models_dict[model_name]
216
+ model_cfg = make_model_config(model_cls, req)
217
+ globals()[model_cfg.__name__] = model_cfg
218
+ __all__.append(model_cfg.__name__)
219
+ models_configs.append(model_cfg)
220
+
221
+ BraindecodeModelConfig = Annotated[ # type: ignore
222
+ Union[tuple(models_configs)],
223
+ pydantic.Field(
224
+ discriminator="model_name_", description="Braindecode model configuration"
225
+ ),
226
+ ]
227
227
 
228
228
  # # Example usage:
229
229
  #
@@ -7,7 +7,6 @@ Retrieved from https://openreview.net/forum?id=uazfjnFL0G
7
7
 
8
8
  Original Authors: Berkay Döner, Thorir Mar Ingolfsson
9
9
  Braindecode Adaptation: Bruno Aristimunha
10
- Contributions: Sarthak Tayal <sarthaktayal2@gmail.com>
11
10
 
12
11
  the LICENSE Of this file is APACHE-2.0.
13
12
  """
@@ -83,8 +82,11 @@ class LUNA(EEGModuleMixin, nn.Module):
83
82
 
84
83
  # Load pre-trained encoder weights
85
84
  state_dict = load_file(model_path)
86
- # load_state_dict applies model.mapping automatically
87
- model.load_state_dict(state_dict, strict=False)
85
+ # Apply key mapping for pretrained weights
86
+ mapping = model.mapping.copy()
87
+ mapping["cross_attn.temparature"] = "cross_attn.temperature"
88
+ mapped_state_dict = {mapping.get(k, k): v for k, v in state_dict.items()}
89
+ model.load_state_dict(mapped_state_dict, strict=False)
88
90
 
89
91
  To push your own trained model to the Hub:
90
92
 
@@ -168,7 +170,6 @@ class LUNA(EEGModuleMixin, nn.Module):
168
170
  "channel_location_embedder.0.fc2.bias": "channel_location_embedder.fc2.bias",
169
171
  "channel_location_embedder.0.norm.weight": "channel_location_embedder.norm.weight",
170
172
  "channel_location_embedder.0.norm.bias": "channel_location_embedder.norm.bias",
171
- "cross_attn.temparature": "cross_attn.temperature", # typo in pretrained weights
172
173
  }
173
174
 
174
175
  # Model parameters
@@ -314,10 +315,8 @@ class LUNA(EEGModuleMixin, nn.Module):
314
315
  channel_locations_emb = self.channel_location_embedder(channel_locations)
315
316
 
316
317
  x_tokenized = rearrange(x_masked, "B (C t) D -> (B t) C D", C=num_channels)
317
- channel_locations_emb = (
318
- channel_locations_emb.repeat_interleave( # was repeat(), wrong dim ordering
319
- num_patches_per_channel, dim=0
320
- )
318
+ channel_locations_emb = channel_locations_emb.repeat(
319
+ num_patches_per_channel, 1, 1
321
320
  )
322
321
  x_tokenized = x_tokenized + channel_locations_emb
323
322
 
@@ -4,7 +4,6 @@
4
4
  from __future__ import annotations
5
5
 
6
6
  import math
7
- import warnings
8
7
  from typing import Optional, Tuple
9
8
 
10
9
  import torch
@@ -497,10 +496,9 @@ class _TransformerEncoderLayer(nn.Module):
497
496
 
498
497
  if dim_feedforward is None:
499
498
  dim_feedforward = 4 * embed_dim
500
- warnings.warn(
501
- "dim_feedforward is set to 4*embed_dim, the default in "
502
- "Vaswani et al. (Attention is all you need)",
503
- stacklevel=2,
499
+ # note: preserve the original behaviour (print) from the provided code
500
+ print(
501
+ "dim_feedforward is set to 4*embed_dim, the default in Vaswani et al. (Attention is all you need)"
504
502
  )
505
503
 
506
504
  self.layer_norm_att = _LayerNorm(embed_dim, bias=bias)
@@ -16,16 +16,7 @@ import torch
16
16
  import torch.nn.functional as F
17
17
  from einops import rearrange
18
18
  from torch import nn
19
-
20
- # Safe import for older PyTorch versions (Support for Intel-based Macs)
21
- try:
22
- from torch.nn.attention import SDPBackend, sdpa_kernel
23
-
24
- HAS_SDPA = True
25
- except ImportError:
26
- HAS_SDPA = False
27
- SDPBackend = None
28
- sdpa_kernel = None
19
+ from torch.nn.attention import SDPBackend, sdpa_kernel
29
20
 
30
21
  from braindecode.models.base import EEGModuleMixin
31
22
 
@@ -539,22 +530,11 @@ class FeedForward(nn.Module):
539
530
 
540
531
 
541
532
  class ClassicalAttention(nn.Module):
542
- def __init__(self, heads: int, use_sdpa: bool | None = None):
533
+ def __init__(self, heads: int, use_sdpa: bool = True):
543
534
  super().__init__()
535
+ self.use_sdpa = use_sdpa
544
536
  self.heads = heads
545
537
 
546
- if use_sdpa is None:
547
- self.use_sdpa = HAS_SDPA
548
- elif use_sdpa is True and not HAS_SDPA:
549
- logger.warning(
550
- "SDPA (Scaled Dot Product Attention) was requested, but it is not "
551
- "available in your current PyTorch version. Falling back to naive "
552
- "implementation. Please upgrade to PyTorch >= 2.2 for SDPA support."
553
- )
554
- self.use_sdpa = False
555
- else:
556
- self.use_sdpa = use_sdpa
557
-
558
538
  def forward(self, qkv: torch.Tensor) -> torch.Tensor:
559
539
  # Split concatenated QKV into separate tensors
560
540
  # qkv shape: (batch, seq_len, 3 * heads * head_dim)
@@ -2,21 +2,19 @@
2
2
  #
3
3
  # License: BSD (3-clause)
4
4
 
5
- from __future__ import annotations
6
-
7
- from collections.abc import Callable
5
+ from typing import Callable
8
6
 
9
7
  from einops.layers.torch import Rearrange
10
8
  from torch import nn
11
9
  from torch.nn import init
12
10
 
11
+ from braindecode.functional import square
13
12
  from braindecode.models.base import EEGModuleMixin
14
13
  from braindecode.modules import (
15
14
  CombinedConv,
16
15
  Ensure4d,
17
16
  Expression,
18
17
  SafeLog,
19
- Square,
20
18
  SqueezeFinalOutput,
21
19
  )
22
20
 
@@ -47,14 +45,12 @@ class ShallowFBCSPNet(EEGModuleMixin, nn.Sequential):
47
45
  final_conv_length: int | str
48
46
  Length of the final convolution layer.
49
47
  If set to "auto", length of the input signal must be specified.
50
- conv_nonlin: type[nn.Module] | Callable
51
- Non-linear module class to be used after convolution layers.
52
- For backward compatibility, callables are also accepted and wrapped
53
- with :class:`~braindecode.modules.Expression`.
48
+ conv_nonlin: callable
49
+ Non-linear function to be used after convolution layers.
54
50
  pool_mode: str
55
51
  Method to use on pooling layers. "max" or "mean".
56
- activation_pool_nonlin: type[nn.Module]
57
- Non-linear module class to be used after pooling layers.
52
+ activation_pool_nonlin: callable
53
+ Non-linear function to be used after pooling layers.
58
54
  split_first_layer: bool
59
55
  Split first layer into temporal and spatial layers (True) or just use temporal (False).
60
56
  There would be no non-linearity between the split layers.
@@ -87,7 +83,7 @@ class ShallowFBCSPNet(EEGModuleMixin, nn.Sequential):
87
83
  pool_time_length=75,
88
84
  pool_time_stride=15,
89
85
  final_conv_length="auto",
90
- conv_nonlin: type[nn.Module] | Callable = Square,
86
+ conv_nonlin: Callable = square,
91
87
  pool_mode="mean",
92
88
  activation_pool_nonlin: type[nn.Module] = SafeLog,
93
89
  split_first_layer=True,
@@ -167,11 +163,7 @@ class ShallowFBCSPNet(EEGModuleMixin, nn.Sequential):
167
163
  n_filters_conv, momentum=self.batch_norm_alpha, affine=True
168
164
  ),
169
165
  )
170
- if isinstance(self.conv_nonlin, type):
171
- self.add_module("conv_nonlin_exp", self.conv_nonlin())
172
- else:
173
- # Backward compat: accept a callable (e.g. square function)
174
- self.add_module("conv_nonlin_exp", Expression(self.conv_nonlin))
166
+ self.add_module("conv_nonlin_exp", Expression(self.conv_nonlin))
175
167
  self.add_module(
176
168
  "pool",
177
169
  pool_class(