Braindecode 1.8.0.dev179993000__tar.gz → 1.8.0.dev180935432__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 (181) hide show
  1. braindecode-1.8.0.dev180935432/NOTICE.txt +25 -0
  2. {braindecode-1.8.0.dev179993000/braindecode.egg-info → braindecode-1.8.0.dev180935432}/PKG-INFO +5 -8
  3. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/README.rst +3 -6
  4. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/base.py +0 -3
  5. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/functional/functions.py +3 -4
  6. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/base.py +3 -28
  7. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/brainmodule.py +1 -1
  8. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/ctnet.py +1 -1
  9. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/dance.py +10 -2
  10. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegconformer.py +1 -1
  11. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegminer.py +1 -2
  12. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegsimpleconv.py +1 -1
  13. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/emg2qwerty.py +133 -9
  14. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/ifnet.py +1 -2
  15. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/luna.py +5 -31
  16. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/medformer.py +1 -1
  17. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/meta_neuromotor.py +1 -1
  18. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/mvpformer.py +1 -1
  19. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sstdpn.py +1 -1
  20. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/summary.csv +1 -1
  21. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/tcformer.py +1 -1
  22. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/usleep.py +7 -3
  23. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/zuna.py +12 -26
  24. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/__init__.py +2 -14
  25. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/blocks.py +0 -213
  26. braindecode-1.8.0.dev180935432/braindecode/version.py +1 -0
  27. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432/braindecode.egg-info}/PKG-INFO +5 -8
  28. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode.egg-info/SOURCES.txt +0 -1
  29. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode.egg-info/requires.txt +1 -1
  30. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/whats_new.rst +1 -31
  31. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/pyproject.toml +1 -1
  32. braindecode-1.8.0.dev179993000/NOTICE.txt +0 -65
  33. braindecode-1.8.0.dev179993000/braindecode/datasets/_notebook_viewer.py +0 -255
  34. braindecode-1.8.0.dev179993000/braindecode/version.py +0 -1
  35. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/LICENSE.txt +0 -0
  36. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/MANIFEST.in +0 -0
  37. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/__init__.py +0 -0
  38. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/augmentation/__init__.py +0 -0
  39. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/augmentation/base.py +0 -0
  40. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/augmentation/functional.py +0 -0
  41. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/augmentation/transforms.py +0 -0
  42. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/classifier.py +0 -0
  43. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/__init__.py +0 -0
  44. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bbci.py +0 -0
  45. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bcicomp.py +0 -0
  46. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/__init__.py +0 -0
  47. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/datasets.py +0 -0
  48. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/format.py +0 -0
  49. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/hub.py +0 -0
  50. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/hub_format.py +0 -0
  51. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/hub_io.py +0 -0
  52. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/hub_validation.py +0 -0
  53. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/bids/iterable.py +0 -0
  54. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/chb_mit.py +0 -0
  55. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/collate.py +0 -0
  56. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/mne.py +0 -0
  57. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/moabb.py +0 -0
  58. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/nmt.py +0 -0
  59. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/registry.py +0 -0
  60. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/siena.py +0 -0
  61. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  62. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/sleep_physionet.py +0 -0
  63. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/tuh.py +0 -0
  64. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/utils.py +0 -0
  65. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datasets/xy.py +0 -0
  66. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datautil/__init__.py +0 -0
  67. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datautil/channel_utils.py +0 -0
  68. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datautil/hub_formats.py +0 -0
  69. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datautil/serialization.py +0 -0
  70. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/datautil/util.py +0 -0
  71. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/eegneuralnet.py +0 -0
  72. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/functional/__init__.py +0 -0
  73. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/functional/initialization.py +0 -0
  74. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/__init__.py +0 -0
  75. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/atcnet.py +0 -0
  76. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/attentionbasenet.py +0 -0
  77. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/attn_sleep.py +0 -0
  78. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/bendr.py +0 -0
  79. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/biot.py +0 -0
  80. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/cbramod.py +0 -0
  81. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/codebrain.py +0 -0
  82. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/config.py +0 -0
  83. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/contrawr.py +0 -0
  84. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/deep4.py +0 -0
  85. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/deepsleepnet.py +0 -0
  86. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/dgcnn.py +0 -0
  87. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegdino.py +0 -0
  88. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eeginception_erp.py +0 -0
  89. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eeginception_mi.py +0 -0
  90. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegitnet.py +0 -0
  91. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegnet.py +0 -0
  92. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegnex.py +0 -0
  93. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegpt.py +0 -0
  94. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegsym.py +0 -0
  95. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/eegtcnet.py +0 -0
  96. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/fbcnet.py +0 -0
  97. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/fblightconvnet.py +0 -0
  98. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/fbmsnet.py +0 -0
  99. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/hybrid.py +0 -0
  100. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/interpolated.py +0 -0
  101. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/labram.py +0 -0
  102. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/msvtnet.py +0 -0
  103. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/patchedtransformer.py +0 -0
  104. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/reve.py +0 -0
  105. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sccnet.py +0 -0
  106. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/shallow_fbcsp.py +0 -0
  107. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/signal_jepa.py +0 -0
  108. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sinc_shallow.py +0 -0
  109. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  110. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  111. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/sparcnet.py +0 -0
  112. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/steegformer.py +0 -0
  113. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/syncnet.py +0 -0
  114. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/tcn.py +0 -0
  115. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/tidnet.py +0 -0
  116. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/tsinception.py +0 -0
  117. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/models/util.py +0 -0
  118. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/activation.py +0 -0
  119. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/attention.py +0 -0
  120. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/convolution.py +0 -0
  121. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/dance_modules.py +0 -0
  122. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/filter.py +0 -0
  123. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/interpolation.py +0 -0
  124. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/layers.py +0 -0
  125. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/linear.py +0 -0
  126. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/parametrization.py +0 -0
  127. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/stats.py +0 -0
  128. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/util.py +0 -0
  129. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/modules/wrapper.py +0 -0
  130. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/__init__.py +0 -0
  131. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  132. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/mne_preprocess.py +0 -0
  133. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/preprocess.py +0 -0
  134. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/util.py +0 -0
  135. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/preprocessing/windowers.py +0 -0
  136. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/regressor.py +0 -0
  137. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/samplers/__init__.py +0 -0
  138. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/samplers/base.py +0 -0
  139. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/samplers/ssl.py +0 -0
  140. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/training/__init__.py +0 -0
  141. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/training/callbacks.py +0 -0
  142. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/training/losses.py +0 -0
  143. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/training/scoring.py +0 -0
  144. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/util.py +0 -0
  145. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/__init__.py +0 -0
  146. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/attribution.py +0 -0
  147. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/confusion_matrices.py +0 -0
  148. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/frequency.py +0 -0
  149. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/metrics.py +0 -0
  150. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/sanity.py +0 -0
  151. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode/visualization/topology.py +0 -0
  152. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode.egg-info/dependency_links.txt +0 -0
  153. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/braindecode.egg-info/top_level.txt +0 -0
  154. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/Makefile +0 -0
  155. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/_templates/autosummary/class.rst +0 -0
  156. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  157. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/_templates/autosummary/function.rst +0 -0
  158. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  159. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/api.rst +0 -0
  160. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/cite.rst +0 -0
  161. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/conf.py +0 -0
  162. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/help.rst +0 -0
  163. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/index.rst +0 -0
  164. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/install/install.rst +0 -0
  165. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/install/install_pip.rst +0 -0
  166. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/install/install_source.rst +0 -0
  167. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/attention.rst +0 -0
  168. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/channel.rst +0 -0
  169. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/convolution.rst +0 -0
  170. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/filterbank.rst +0 -0
  171. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/gnn.rst +0 -0
  172. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/interpretable.rst +0 -0
  173. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/lbm.rst +0 -0
  174. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/recurrent.rst +0 -0
  175. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/categorization/spd.rst +0 -0
  176. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/models.rst +0 -0
  177. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/models_categorization.rst +0 -0
  178. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/models_table.rst +0 -0
  179. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/models/models_visualization.rst +0 -0
  180. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/docs/sg_execution_times.rst +0 -0
  181. {braindecode-1.8.0.dev179993000 → braindecode-1.8.0.dev180935432}/setup.cfg +0 -0
@@ -0,0 +1,25 @@
1
+ # BRAINDECODE Notice
2
+
3
+ ## Licensed Components
4
+
5
+ ### BSD-3-Clause Licensed Files
6
+
7
+ All files within the `src/` directory are licensed under the BSD-3-Clause License.
8
+
9
+ ### CC BY-NC 4.0 Licensed Files
10
+
11
+ The following components are licensed under the Creative Commons Attribution-NonCommercial 4.0 International License:
12
+
13
+ - `braindecode/models/eegminer.py`
14
+ - `braindecode/models/meta_neuromotor.py`
15
+
16
+ As well as class later imported into the `braindecode.models.module` named as GeneralizedGaussianFilter.
17
+
18
+ The `meta_neuromotor.py` file is a derivative of
19
+ `facebookresearch/generic-neuromotor-interface`, released by Meta Platforms,
20
+ Inc. under CC BY-NC 4.0, and inherits the same noncommercial terms.
21
+
22
+ ## License Links
23
+
24
+ - [BSD-3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
25
+ - [CC BY-NC 4.0 License](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.8.0.dev179993000
3
+ Version: 1.8.0.dev180935432
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>
@@ -34,6 +34,7 @@ Requires-Dist: pandas
34
34
  Requires-Dist: wfdb>=4.3.1
35
35
  Requires-Dist: linear_attention_transformer
36
36
  Requires-Dist: docstring_inheritance
37
+ Requires-Dist: rotary_embedding_torch
37
38
  Requires-Dist: pydantic>=2.0
38
39
  Provides-Extra: moabb
39
40
  Requires-Dist: moabb>=1.4.3; extra == "moabb"
@@ -50,7 +51,6 @@ Requires-Dist: pytest-cov; extra == "tests"
50
51
  Requires-Dist: codecov; extra == "tests"
51
52
  Requires-Dist: pytest_cases; extra == "tests"
52
53
  Requires-Dist: mypy; extra == "tests"
53
- Requires-Dist: ipython; extra == "tests"
54
54
  Requires-Dist: transformers>=4.57.0; extra == "tests"
55
55
  Requires-Dist: bids_validator; extra == "tests"
56
56
  Provides-Extra: typing
@@ -260,10 +260,7 @@ This project is primarily licensed under the BSD-3-Clause License.
260
260
  Additional Components
261
261
  =====================
262
262
 
263
- Some components within this repository are licensed under other licenses, including
264
- Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0), Creative
265
- Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0), MIT
266
- and Apache-2.0.
263
+ Some components within this repository are licensed under the Creative Commons
264
+ Attribution-NonCommercial 4.0 International License.
267
265
 
268
- Please refer to the ``LICENSE`` and ``NOTICE`` files for the per-file list and more
269
- detailed information.
266
+ Please refer to the ``LICENSE`` and ``NOTICE`` files for more detailed information.
@@ -170,10 +170,7 @@ This project is primarily licensed under the BSD-3-Clause License.
170
170
  Additional Components
171
171
  =====================
172
172
 
173
- Some components within this repository are licensed under other licenses, including
174
- Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0), Creative
175
- Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0), MIT
176
- and Apache-2.0.
173
+ Some components within this repository are licensed under the Creative Commons
174
+ Attribution-NonCommercial 4.0 International License.
177
175
 
178
- Please refer to the ``LICENSE`` and ``NOTICE`` files for the per-file list and more
179
- detailed information.
176
+ Please refer to the ``LICENSE`` and ``NOTICE`` files for more detailed information.
@@ -32,7 +32,6 @@ from mne.utils.docs import deprecated
32
32
  from torch.utils.data import ConcatDataset, Dataset, IterableDataset
33
33
  from typing_extensions import TypeVar
34
34
 
35
- from ._notebook_viewer import plot as _viewer_plot
36
35
  from .bids.hub import HubDatasetMixin
37
36
  from .bids.hub_io import _restore_nan_from_json
38
37
  from .registry import register_dataset
@@ -1175,8 +1174,6 @@ class BaseConcatDataset(ConcatDataset, HubDatasetMixin, Generic[T]):
1175
1174
  If True, defer computing cumulative sizes until length or item access.
1176
1175
  """
1177
1176
 
1178
- plot = _viewer_plot # eegdash-viewer embed; a direct member so the API docs list it
1179
-
1180
1177
  datasets: list[T]
1181
1178
 
1182
1179
  def __init__(
@@ -40,7 +40,7 @@ def drop_path(
40
40
  x : torch.Tensor
41
41
  input tensor
42
42
  drop_prob : float, optional
43
- probability of dropping a path, by default 0.0
43
+ survival rate (i.e. probability of being kept), by default 0.0
44
44
  training : bool, optional
45
45
  whether the model is in training mode, by default False
46
46
  scale_by_keep : bool, optional
@@ -68,10 +68,9 @@ def drop_path(
68
68
  shape = (x.shape[0],) + (1,) * (
69
69
  x.ndim - 1
70
70
  ) # work with diff dim tensors, not just 2D ConvNets
71
- probabilities = torch.full(shape, keep_prob, dtype=torch.float32, device=x.device)
72
- random_tensor = torch.bernoulli(probabilities).to(dtype=x.dtype)
71
+ random_tensor = x.new_empty(shape).bernoulli_(keep_prob)
73
72
  if keep_prob > 0.0 and scale_by_keep:
74
- random_tensor = random_tensor / keep_prob
73
+ random_tensor.div_(keep_prob)
75
74
  return x * random_tensor
76
75
 
77
76
 
@@ -80,7 +80,7 @@ class _BraindecodeDocstringMeta(NumpyDocstringInheritanceInitMeta):
80
80
  unwrapped function and correctly inherits ``cls.__doc__``.
81
81
  """
82
82
 
83
- def __init__(cls, class_name, class_bases, class_dict, **kwargs):
83
+ def __init__(cls, class_name, class_bases, class_dict):
84
84
  super().__init__(class_name, class_bases, class_dict)
85
85
  # Only wrap subclass __init__s, not EEGModuleMixin itself.
86
86
  # Wrapping the mixin would cause super().__init__() calls to
@@ -214,8 +214,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
214
214
  __jit_unused_properties__ = ["chs_info"]
215
215
 
216
216
  def __init_subclass__(cls, **kwargs):
217
- license = kwargs.pop("license", "bsd-3-clause")
218
-
219
217
  # TorchScript only honours ``__jit_ignored_attributes__`` for
220
218
  # properties defined directly on the concrete class: it collects them
221
219
  # with ``vars(type(module))``, which skips inherited ones. Rebinding
@@ -255,6 +253,8 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
255
253
  )
256
254
  repo_url = kwargs.pop("repo_url", "https://braindecode.org")
257
255
  library_name = kwargs.pop("library_name", "braindecode")
256
+ license = kwargs.pop("license", "bsd-3-clause")
257
+
258
258
  # Register a coder so that type[nn.Module] parameters
259
259
  # (e.g. activation=nn.ELU) are serialized as importable
260
260
  # strings in config.json and decoded back on load.
@@ -519,31 +519,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
519
519
  resolve_type_kwargs(cls, config)
520
520
  return cls(**config)
521
521
 
522
- def _set_n_outputs(self, n_outputs: int) -> None:
523
- """Record a new ``n_outputs`` on the model and its saved configs.
524
-
525
- Helper for :meth:`reset_head` implementations: validates the value,
526
- then keeps the ``n_outputs`` property, the braindecode init kwargs
527
- and the Hugging Face hub config in sync, so a re-serialized model
528
- reports the head it actually has.
529
-
530
- Parameters
531
- ----------
532
- n_outputs : int
533
- New number of outputs. Must be positive.
534
-
535
- .. versionadded:: 1.8
536
- """
537
- if n_outputs <= 0:
538
- raise ValueError(f"n_outputs must be positive; got {n_outputs}.")
539
- self._n_outputs = n_outputs
540
- for config in (
541
- getattr(self, "_braindecode_init_kwargs", None),
542
- getattr(self, "_hub_mixin_config", None),
543
- ):
544
- if config is not None and "n_outputs" in config:
545
- config["n_outputs"] = n_outputs
546
-
547
522
  def reset_head(self, n_outputs):
548
523
  """Replace the classification head for a new number of outputs.
549
524
 
@@ -25,7 +25,7 @@ from braindecode.modules.layers import SubjectLayers
25
25
  __all__ = ["BrainModule"]
26
26
 
27
27
 
28
- class BrainModule(EEGModuleMixin, nn.Module, license="cc-by-nc-4.0"):
28
+ class BrainModule(EEGModuleMixin, nn.Module):
29
29
  r"""BrainModule from [brainmagick]_, also known as SimpleConv.
30
30
 
31
31
  A dilated convolutional encoder for EEG decoding, using residual
@@ -24,7 +24,7 @@ from braindecode.modules import (
24
24
  )
25
25
 
26
26
 
27
- class CTNet(EEGModuleMixin, nn.Module, license="mit"):
27
+ class CTNet(EEGModuleMixin, nn.Module):
28
28
  r"""CTNet from Zhao, W et al (2024) [ctnet]_.
29
29
 
30
30
  :bdg-success:`Convolution` :bdg-info:`Attention/Transformer`
@@ -22,7 +22,7 @@ from braindecode.modules import ChannelMerger, Perceiver, SimpleConv
22
22
  from braindecode.modules.dance_modules import DanceDetrDecoder
23
23
 
24
24
 
25
- class DANCE(EEGModuleMixin, nn.Module, license="mit"):
25
+ class DANCE(EEGModuleMixin, nn.Module):
26
26
  r"""DANCE from Lévy et al (2026) [dance]_.
27
27
 
28
28
  :bdg-success:`Convolution` :bdg-info:`Attention/Transformer` :bdg-dark-line:`Channel`
@@ -349,7 +349,8 @@ class DANCE(EEGModuleMixin, nn.Module, license="mit"):
349
349
 
350
350
  def reset_head(self, n_outputs: int) -> None:
351
351
  """Replace the dense head and the DETR class head for a new ``n_outputs``."""
352
- self._set_n_outputs(n_outputs)
352
+ if n_outputs <= 0:
353
+ raise ValueError(f"n_outputs must be positive; got {n_outputs}.")
353
354
  old = self.final_layer
354
355
  self.final_layer = nn.Linear(old.in_features, n_outputs).to(
355
356
  device=old.weight.device, dtype=old.weight.dtype
@@ -358,3 +359,10 @@ class DANCE(EEGModuleMixin, nn.Module, license="mit"):
358
359
  self.decoder.class_head = nn.Linear(ch.in_features, n_outputs).to(
359
360
  device=ch.weight.device, dtype=ch.weight.dtype
360
361
  )
362
+ self._n_outputs = n_outputs
363
+ init_kwargs = getattr(self, "_braindecode_init_kwargs", None)
364
+ if init_kwargs is not None and "n_outputs" in init_kwargs:
365
+ init_kwargs["n_outputs"] = n_outputs
366
+ hub_config = getattr(self, "_hub_mixin_config", None)
367
+ if hub_config is not None and "n_outputs" in hub_config:
368
+ hub_config["n_outputs"] = n_outputs
@@ -185,7 +185,7 @@ class EEGConformer(EEGModuleMixin, nn.Module):
185
185
  31, pp.710-719. https://ieeexplore.ieee.org/document/9991178
186
186
  .. [ConformerCode] Song, Y., Zheng, Q., Liu, B. and Gao, X., 2022. EEG
187
187
  conformer: Convolutional transformer for EEG decoding and visualization.
188
- https://github.com/eeyhsong/EEG-Conformer
188
+ https://github.com/eeyhsong/EEG-Conformer.
189
189
  """
190
190
 
191
191
  def __init__(
@@ -6,7 +6,6 @@
6
6
  """
7
7
 
8
8
  # Authors: Sarthak Tayal <sarthaktayal2@gmail.com>
9
- # License: Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
10
9
 
11
10
  import torch
12
11
  from torch import nn
@@ -49,7 +48,7 @@ class _EEGMinerFeatures(nn.Module):
49
48
  return x[:, self.triu_row, self.triu_col, :]
50
49
 
51
50
 
52
- class EEGMiner(EEGModuleMixin, nn.Module, license="cc-by-nc-4.0"):
51
+ class EEGMiner(EEGModuleMixin, nn.Module):
53
52
  r"""EEGMiner from Ludwig et al (2024) [eegminer]_.
54
53
 
55
54
  :bdg-success:`Convolution` :bdg-warning:`Interpretability`
@@ -93,7 +93,7 @@ class EEGSimpleConv(EEGModuleMixin, torch.nn.Module):
93
93
  .. [Yassine2023Code] Yassine El Ouahidi, V. Gripon, B. Pasdeloup, G. Bouallegue
94
94
  N. Farrugia, G. Lioi, 2023. A Strong and Simple Deep Learning Baseline for
95
95
  BCI Motor Imagery Decoding. GitHub repository.
96
- https://github.com/elouayas/EEGSimpleConv
96
+ https://github.com/elouayas/EEGSimpleConv.
97
97
 
98
98
  """
99
99
 
@@ -1,10 +1,9 @@
1
1
  # Authors: Meta Platforms, Inc. and affiliates (original emg2qwerty)
2
2
  # Bruno Aristimunha <b.aristimunha@gmail.com> (Braindecode adaptation)
3
3
  #
4
- # License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0
5
- # International (CC BY-NC-SA 4.0)
4
+ # License: Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
6
5
  # Adapted from https://github.com/facebookresearch/emg2qwerty (NeurIPS 2024).
7
- # Inherits CC BY-NC-SA 4.0; not covered by braindecode's BSD-3 license.
6
+ # Inherits CC BY-NC 4.0; not covered by braindecode's BSD-3 license.
8
7
  """``EMG2QwertyNet``: TDS-Conv-CTC for sEMG-to-keystroke decoding."""
9
8
 
10
9
  from __future__ import annotations
@@ -17,10 +16,9 @@ import torchaudio.transforms as ta_transforms
17
16
  from torch import nn
18
17
 
19
18
  from braindecode.models.base import EEGModuleMixin
20
- from braindecode.modules import TDSConvEncoder
21
19
 
22
20
 
23
- class EMG2QwertyNet(EEGModuleMixin, nn.Module, license="cc-by-nc-sa-4.0"):
21
+ class EMG2QwertyNet(EEGModuleMixin, nn.Module):
24
22
  r"""Decoder mapping surface electromyography (sEMG) to keystrokes
25
23
  (emg2qwerty) [emg2qwerty2024]_.
26
24
 
@@ -91,7 +89,7 @@ class EMG2QwertyNet(EEGModuleMixin, nn.Module, license="cc-by-nc-sa-4.0"):
91
89
  .. warning::
92
90
  **License: noncommercial use only.** This module is a derivative
93
91
  of Meta's reference implementation released under
94
- `CC BY-NC-SA 4.0 <https://creativecommons.org/licenses/by-nc-sa/4.0/>`_,
92
+ `CC BY-NC 4.0 <https://creativecommons.org/licenses/by-nc/4.0/>`_,
95
93
  the same license as the upstream repository. Not covered by
96
94
  braindecode's BSD-3 license. Must not be used in commercial
97
95
  products or services. Pretrained weights from the upstream release
@@ -347,7 +345,7 @@ class EMG2QwertyNet(EEGModuleMixin, nn.Module, license="cc-by-nc-sa-4.0"):
347
345
  activation=activation,
348
346
  ),
349
347
  nn.Flatten(start_dim=2),
350
- TDSConvEncoder(
348
+ _TDSConvEncoder(
351
349
  num_features=num_features,
352
350
  block_channels=list(block_channels),
353
351
  kernel_width=kernel_width,
@@ -358,7 +356,9 @@ class EMG2QwertyNet(EEGModuleMixin, nn.Module, license="cc-by-nc-sa-4.0"):
358
356
 
359
357
  self.final_layer = nn.Linear(num_features, self.n_outputs)
360
358
 
361
- self._n_conv_blocks = len(block_channels)
359
+ self._n_conv_blocks = sum(
360
+ isinstance(m, _TDSConv2dBlock) for m in self.model[3].tds_conv_blocks
361
+ )
362
362
 
363
363
  def forward(
364
364
  self, x: torch.Tensor, return_features: bool = False
@@ -452,11 +452,22 @@ class EMG2QwertyNet(EEGModuleMixin, nn.Module, license="cc-by-nc-sa-4.0"):
452
452
  captured init config (``get_config()``) is also kept in sync so
453
453
  save/load round-trips rebuild the new head.
454
454
  """
455
- self._set_n_outputs(n_outputs)
455
+ if n_outputs <= 0:
456
+ raise ValueError(f"n_outputs must be positive; got {n_outputs}.")
456
457
  old_head = self.final_layer
457
458
  self.final_layer = nn.Linear(old_head.in_features, n_outputs).to(
458
459
  device=old_head.weight.device, dtype=old_head.weight.dtype
459
460
  )
461
+ self._n_outputs = n_outputs
462
+ # Keep the init-kwargs snapshot used by ``get_config()`` aligned with
463
+ # the live head, so ``EMG2QwertyNet.from_config(m.get_config())``
464
+ # rebuilds the head with the new vocab size.
465
+ init_kwargs = getattr(self, "_braindecode_init_kwargs", None)
466
+ if init_kwargs is not None and "n_outputs" in init_kwargs:
467
+ init_kwargs["n_outputs"] = n_outputs
468
+ hub_config = getattr(self, "_hub_mixin_config", None)
469
+ if hub_config is not None and "n_outputs" in hub_config:
470
+ hub_config["n_outputs"] = n_outputs
460
471
 
461
472
  def compute_output_lengths(self, input_lengths: torch.Tensor) -> torch.Tensor:
462
473
  """Map per-sample input lengths to CTC emission lengths.
@@ -788,3 +799,116 @@ class _MultiBandRotationInvariantMLP(nn.Module):
788
799
  for band_idx, mlp in enumerate(self.mlps):
789
800
  band_outputs.append(mlp(per_band_inputs[band_idx]))
790
801
  return torch.stack(band_outputs, dim=self.stack_dim)
802
+
803
+
804
+ class _TDSConv2dBlock(nn.Module):
805
+ r"""Time-Depth-Separable 2-D conv block ([hannun2019tds]_).
806
+
807
+ 1×``kernel_width`` conv + activation + residual + LayerNorm. No
808
+ temporal padding: strips ``kernel_width - 1`` frames per block.
809
+ """
810
+
811
+ def __init__(
812
+ self,
813
+ channels: int,
814
+ width: int,
815
+ kernel_width: int,
816
+ activation: type[nn.Module] = nn.ReLU,
817
+ ) -> None:
818
+ super().__init__()
819
+ self.channels = channels
820
+ self.width = width
821
+ self.conv2d = nn.Conv2d(
822
+ in_channels=channels,
823
+ out_channels=channels,
824
+ kernel_size=(1, kernel_width),
825
+ )
826
+ self.activation = activation()
827
+ self.layer_norm = nn.LayerNorm(channels * width)
828
+
829
+ def forward(self, inputs: torch.Tensor) -> torch.Tensor:
830
+ n_in_frames, batch_size, n_features = inputs.shape
831
+ folded = inputs.movedim(0, -1).reshape(
832
+ batch_size, self.channels, self.width, n_in_frames
833
+ )
834
+ conv_out = self.activation(self.conv2d(folded))
835
+ conv_out = conv_out.reshape(batch_size, n_features, -1).movedim(-1, 0)
836
+ n_out_frames = conv_out.shape[0]
837
+ # Output frame i aligns with input frame i+(kernel_width-1), so
838
+ # the residual is the LAST n_out_frames input frames.
839
+ residual_added = conv_out + inputs[-n_out_frames:]
840
+ return self.layer_norm(residual_added)
841
+
842
+
843
+ class _TDSFullyConnectedBlock(nn.Module):
844
+ r"""Two-layer FFN with residual skip, LayerNorm, and optional dropout."""
845
+
846
+ def __init__(
847
+ self,
848
+ num_features: int,
849
+ activation: type[nn.Module] = nn.ReLU,
850
+ drop_prob: float = 0.0,
851
+ ) -> None:
852
+ super().__init__()
853
+ layers: list[nn.Module] = [
854
+ nn.Linear(num_features, num_features),
855
+ activation(),
856
+ ]
857
+ if drop_prob > 0:
858
+ layers.append(nn.Dropout(drop_prob))
859
+ layers.append(nn.Linear(num_features, num_features))
860
+ if drop_prob > 0:
861
+ layers.append(nn.Dropout(drop_prob))
862
+ self.fc_block = nn.Sequential(*layers)
863
+ self.layer_norm = nn.LayerNorm(num_features)
864
+
865
+ def forward(self, inputs: torch.Tensor) -> torch.Tensor:
866
+ return self.layer_norm(self.fc_block(inputs) + inputs)
867
+
868
+
869
+ class _TDSConvEncoder(nn.Module):
870
+ r"""``_TDSConv2dBlock`` + ``_TDSFullyConnectedBlock`` stack.
871
+
872
+ With ``K = len(block_channels)`` blocks and no temporal padding, the
873
+ encoder strips ``K * (kernel_width - 1)`` frames in total. Each ``ch``
874
+ must evenly divide ``num_features`` so the conv block can fold features
875
+ as ``(channels=ch, width=num_features // ch)``.
876
+ """
877
+
878
+ def __init__(
879
+ self,
880
+ num_features: int,
881
+ block_channels: Sequence[int] = (24, 24, 24, 24),
882
+ kernel_width: int = 32,
883
+ activation: type[nn.Module] = nn.ReLU,
884
+ drop_prob: float = 0.0,
885
+ ) -> None:
886
+ super().__init__()
887
+ if not block_channels:
888
+ raise ValueError("block_channels must be non-empty.")
889
+ blocks: list[nn.Module] = []
890
+ for n_block_channels in block_channels:
891
+ if num_features % n_block_channels != 0:
892
+ raise ValueError(
893
+ f"block_channels entry {n_block_channels} does not evenly "
894
+ f"divide num_features={num_features}."
895
+ )
896
+ blocks.extend(
897
+ [
898
+ _TDSConv2dBlock(
899
+ n_block_channels,
900
+ num_features // n_block_channels,
901
+ kernel_width,
902
+ activation=activation,
903
+ ),
904
+ _TDSFullyConnectedBlock(
905
+ num_features,
906
+ activation=activation,
907
+ drop_prob=drop_prob,
908
+ ),
909
+ ]
910
+ )
911
+ self.tds_conv_blocks = nn.Sequential(*blocks)
912
+
913
+ def forward(self, inputs: torch.Tensor) -> torch.Tensor:
914
+ return self.tds_conv_blocks(inputs)
@@ -1,4 +1,3 @@
1
- # License: MIT
2
1
  """IFNet Neural Network.
3
2
 
4
3
  Authors: Jiaheng Wang
@@ -29,7 +28,7 @@ from braindecode.modules import (
29
28
  )
30
29
 
31
30
 
32
- class IFNet(EEGModuleMixin, nn.Module, license="mit"):
31
+ class IFNet(EEGModuleMixin, nn.Module):
33
32
  r"""IFNetV2 from Wang J et al (2023) [ifnet]_.
34
33
 
35
34
  :bdg-success:`Convolution` :bdg-primary:`Filterbank`
@@ -1,4 +1,3 @@
1
- # License: Apache-2.0
2
1
  """This implementation is adapted from ETH Zurich's BioFoundation repository.
3
2
 
4
3
  Döner, B., Ingolfsson, T. M., Benini, L., & Li, Y. (2025).
@@ -21,13 +20,14 @@ import torch.fft as fft
21
20
  import torch.nn as nn
22
21
  import torch.nn.functional as F
23
22
  from einops import rearrange
23
+ from rotary_embedding_torch import RotaryEmbedding
24
24
 
25
25
  from braindecode.models.base import EEGModuleMixin
26
26
  from braindecode.models.util import extract_channel_locations_from_chs_info
27
27
  from braindecode.modules.layers import DropPath
28
28
 
29
29
 
30
- class LUNA(EEGModuleMixin, nn.Module, license="apache-2.0"):
30
+ class LUNA(EEGModuleMixin, nn.Module):
31
31
  r"""LUNA from Döner et al [LUNA]_.
32
32
 
33
33
  :bdg-success:`Convolution` :bdg-danger:`Foundation Model` :bdg-dark-line:`Channel`
@@ -535,7 +535,7 @@ class _RotarySelfAttentionBlock(nn.Module):
535
535
  self.dim = dim
536
536
  self.num_heads = num_heads
537
537
  head_dim = dim // num_heads
538
- self.rotary_emb = _RotaryEmbedding(head_dim)
538
+ self.rotary_emb = RotaryEmbedding(dim=head_dim, learned_freq=False)
539
539
 
540
540
  self.scale = qk_scale or head_dim**-0.5
541
541
 
@@ -545,17 +545,6 @@ class _RotarySelfAttentionBlock(nn.Module):
545
545
  self.proj = nn.Linear(dim, dim)
546
546
  self.proj_drop = nn.Dropout(proj_drop)
547
547
 
548
- def _rotate_queries_or_keys(self, tensor: torch.Tensor) -> torch.Tensor:
549
- """Apply full-head RoPE without concatenating empty boundary views."""
550
- seq_len = tensor.shape[-2]
551
- positions = torch.arange(seq_len, device=tensor.device, dtype=tensor.dtype)
552
- freqs = self.rotary_emb(positions)
553
-
554
- pairs = tensor.reshape(*tensor.shape[:-1], -1, 2)
555
- rotated = torch.stack((-pairs[..., 1], pairs[..., 0]), dim=-1).flatten(-2)
556
- transformed = tensor * freqs.cos() + rotated * freqs.sin()
557
- return transformed.to(tensor.dtype)
558
-
559
548
  def forward(self, x: torch.Tensor) -> torch.Tensor:
560
549
  B, N, C = x.shape
561
550
  qkv = (
@@ -564,8 +553,8 @@ class _RotarySelfAttentionBlock(nn.Module):
564
553
  .permute(2, 0, 3, 1, 4)
565
554
  ) # (K, B, H, N, D)
566
555
  q, k, v = qkv[0], qkv[1], qkv[2]
567
- q = self._rotate_queries_or_keys(q)
568
- k = self._rotate_queries_or_keys(k)
556
+ q = self.rotary_emb.rotate_queries_or_keys(q)
557
+ k = self.rotary_emb.rotate_queries_or_keys(k)
569
558
  # Calculate attention scores
570
559
  attn_weights = (q @ k.transpose(-2, -1)) * self.scale # (B, H, N, N)
571
560
 
@@ -581,21 +570,6 @@ class _RotarySelfAttentionBlock(nn.Module):
581
570
  return self.proj_drop(self.proj(attn))
582
571
 
583
572
 
584
- class _RotaryEmbedding(nn.Module):
585
- """Minimal language RoPE frequency generator used by LUNA."""
586
-
587
- def __init__(self, dim: int, theta: float = 10000.0) -> None:
588
- super().__init__()
589
- frequencies = 1.0 / (
590
- theta ** (torch.arange(0, dim, 2, dtype=torch.float32) / dim)
591
- )
592
- self.freqs = nn.Parameter(frequencies, requires_grad=False)
593
-
594
- def forward(self, positions: torch.Tensor) -> torch.Tensor:
595
- angles = positions.to(self.freqs.dtype).unsqueeze(-1) * self.freqs
596
- return angles.repeat_interleave(2, dim=-1)
597
-
598
-
599
573
  class _FeedForwardBlock(nn.Module):
600
574
  def __init__(self, dim: int, hidden_dim: int, dropout: float = 0.0) -> None:
601
575
  super().__init__()
@@ -17,7 +17,7 @@ from braindecode.functional import sinusoidal_positional_encoding
17
17
  from braindecode.models.base import EEGModuleMixin
18
18
 
19
19
 
20
- class MEDFormer(EEGModuleMixin, nn.Module, license="mit"):
20
+ class MEDFormer(EEGModuleMixin, nn.Module):
21
21
  r"""
22
22
  Medformer from Wang et al (2024) [Medformer2024]_.
23
23
 
@@ -31,7 +31,7 @@ _LPadType = int | Literal["none", "steady", "full"]
31
31
  # ---------------------------------------------------------------------------
32
32
 
33
33
 
34
- class MetaNeuromotorHand(EEGModuleMixin, nn.Module, license="cc-by-nc-4.0"):
34
+ class MetaNeuromotorHand(EEGModuleMixin, nn.Module):
35
35
  r"""Generic neuromotor interface for handwriting from Meta (2025) [gni2025]_.
36
36
 
37
37
  :bdg-info:`Attention/Transformer` :bdg-success:`Convolution`
@@ -26,7 +26,7 @@ from braindecode.models.base import EEGModuleMixin
26
26
  from braindecode.modules import PatchTokenizer
27
27
 
28
28
 
29
- class MVPFormer(EEGModuleMixin, nn.Module, license="apache-2.0"):
29
+ class MVPFormer(EEGModuleMixin, nn.Module):
30
30
  r"""MVPFormer from Carzaniga et al. (2026) [Carzaniga2026]_.
31
31
 
32
32
  :bdg-danger:`Foundation Model` :bdg-info:`Attention/Transformer`
@@ -216,7 +216,7 @@ class SSTDPN(EEGModuleMixin, nn.Module):
216
216
  temporal dual prototype network for motor imagery
217
217
  brain–computer interface. Knowledge-Based Systems,
218
218
  315, 113315. GitHub repository.
219
- https://github.com/hancan16/SST-DPN
219
+ https://github.com/hancan16/SST-DPN.
220
220
  """
221
221
 
222
222
  def __init__(
@@ -31,7 +31,7 @@ SincShallowNet,Motor Imagery,Prediction,250,"n_chans, n_outputs, n_times, sfreq"
31
31
  ShallowFBCSPNet,General,Prediction,250,"n_chans, n_outputs, n_times",46084,"ShallowFBCSPNet(n_chans=22, n_outputs=4, n_times=1000, sfreq=250)","Convolution",EEG
32
32
  SleepStagerBlanco2020,Sleep Staging,Prediction,100,"n_chans, n_outputs, n_times",2845,"SleepStagerBlanco2020(n_chans=2, n_outputs=5, n_times=3000, sfreq=100)","Convolution",EEG
33
33
  SleepStagerChambon2018,Sleep Staging,Prediction,128,"n_chans, n_outputs, n_times, sfreq",5835,"SleepStagerChambon2018(n_chans=2, n_outputs=5, n_times=3840, sfreq=128)","Convolution",EEG
34
- AttnSleep,Sleep Staging,Prediction,100,"n_chans, n_outputs, n_times, sfreq",522805,"AttnSleep(n_chans=1, n_outputs=5, n_times=3000, sfreq=100)","Convolution, Attention/Transformer",EEG
34
+ AttnSleep,Sleep Staging,Prediction,100,"n_chans, n_outputs, n_times, sfreq",719925,"AttnSleep(n_chans=2, n_outputs=5, n_times=3000, sfreq=100)","Convolution, Attention/Transformer",EEG
35
35
  SPARCNet,Epilepsy,Prediction,200,"n_chans, n_outputs, n_times",1141921,"SPARCNet(n_chans=16, n_outputs=6, n_times=2000, sfreq=200)","Convolution",EEG
36
36
  SyncNet,"Emotion Recognition, Alcoholism",Prediction,256,"n_chans, n_outputs, n_times",554,"SyncNet(n_chans=62, n_outputs=3, n_times=5120, sfreq=256)","Interpretability",EEG
37
37
  TSception,Emotion Recognition,Prediction,256,"n_chans, n_outputs, n_times, sfreq",2187206,"TSception(n_chans=62, n_outputs=3, n_times=5120, sfreq=256)","Convolution",EEG
@@ -14,7 +14,7 @@ from braindecode.models.base import EEGModuleMixin
14
14
  from braindecode.modules import CausalConv1d, Conv1dWithConstraint, DropPath
15
15
 
16
16
 
17
- class TCFormer(EEGModuleMixin, nn.Module, license="mit"):
17
+ class TCFormer(EEGModuleMixin, nn.Module):
18
18
  r"""TCFormer from Altaheri et al (2025) [tcformer]_.
19
19
 
20
20
  :bdg-success:`Convolution` :bdg-info:`Attention/Transformer`
@@ -431,7 +431,11 @@ class _DecoderBlock(nn.Module):
431
431
  ) -> tuple[torch.Tensor, torch.Tensor]:
432
432
  """Crops two tensors to their lowest-common-dimension along an axis."""
433
433
  dim_cropped = min(x1.shape[axis], x2.shape[axis])
434
- return (
435
- x1.narrow(axis, 0, dim_cropped),
436
- x2.narrow(axis, 0, dim_cropped),
434
+
435
+ x1_cropped = torch.index_select(
436
+ x1, dim=axis, index=torch.arange(dim_cropped).to(device=x1.device)
437
+ )
438
+ x2_cropped = torch.index_select(
439
+ x2, dim=axis, index=torch.arange(dim_cropped).to(device=x1.device)
437
440
  )
441
+ return x1_cropped, x2_cropped