braindecode 1.7.0.dev182244820__tar.gz → 1.7.0.dev182553025__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 (179) hide show
  1. {braindecode-1.7.0.dev182244820/braindecode.egg-info → braindecode-1.7.0.dev182553025}/PKG-INFO +1 -1
  2. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/functional/__init__.py +4 -0
  3. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/functional/functions.py +34 -0
  4. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/__init__.py +2 -0
  5. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/bendr.py +8 -1
  6. braindecode-1.7.0.dev182553025/braindecode/models/dance.py +368 -0
  7. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/fblightconvnet.py +31 -4
  8. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/summary.csv +1 -0
  9. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/tcn.py +5 -2
  10. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/util.py +22 -0
  11. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/__init__.py +5 -2
  12. braindecode-1.7.0.dev182553025/braindecode/modules/dance_modules.py +333 -0
  13. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/training/__init__.py +4 -1
  14. braindecode-1.7.0.dev182553025/braindecode/training/losses.py +284 -0
  15. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/training/scoring.py +39 -0
  16. braindecode-1.7.0.dev182553025/braindecode/version.py +1 -0
  17. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025/braindecode.egg-info}/PKG-INFO +1 -1
  18. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode.egg-info/SOURCES.txt +2 -0
  19. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/api.rst +2 -0
  20. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/whats_new.rst +28 -0
  21. braindecode-1.7.0.dev182244820/braindecode/training/losses.py +0 -105
  22. braindecode-1.7.0.dev182244820/braindecode/version.py +0 -1
  23. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/LICENSE.txt +0 -0
  24. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/MANIFEST.in +0 -0
  25. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/NOTICE.txt +0 -0
  26. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/README.rst +0 -0
  27. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/__init__.py +0 -0
  28. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/augmentation/__init__.py +0 -0
  29. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/augmentation/base.py +0 -0
  30. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/augmentation/functional.py +0 -0
  31. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/augmentation/transforms.py +0 -0
  32. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/classifier.py +0 -0
  33. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/__init__.py +0 -0
  34. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/base.py +0 -0
  35. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/bbci.py +0 -0
  36. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/bcicomp.py +0 -0
  37. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/bids/__init__.py +0 -0
  38. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/bids/datasets.py +0 -0
  39. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/bids/format.py +0 -0
  40. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/bids/hub.py +0 -0
  41. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/bids/hub_format.py +0 -0
  42. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/bids/hub_io.py +0 -0
  43. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/bids/hub_validation.py +0 -0
  44. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/bids/iterable.py +0 -0
  45. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/chb_mit.py +0 -0
  46. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/collate.py +0 -0
  47. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/mne.py +0 -0
  48. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/moabb.py +0 -0
  49. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/nmt.py +0 -0
  50. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/registry.py +0 -0
  51. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/siena.py +0 -0
  52. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  53. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/sleep_physionet.py +0 -0
  54. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/tuh.py +0 -0
  55. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/utils.py +0 -0
  56. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datasets/xy.py +0 -0
  57. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datautil/__init__.py +0 -0
  58. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datautil/channel_utils.py +0 -0
  59. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datautil/hub_formats.py +0 -0
  60. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datautil/serialization.py +0 -0
  61. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/datautil/util.py +0 -0
  62. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/eegneuralnet.py +0 -0
  63. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/functional/initialization.py +0 -0
  64. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/atcnet.py +0 -0
  65. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/attentionbasenet.py +0 -0
  66. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/attn_sleep.py +0 -0
  67. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/base.py +0 -0
  68. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/biot.py +0 -0
  69. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/brainmodule.py +0 -0
  70. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/cbramod.py +0 -0
  71. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/codebrain.py +0 -0
  72. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/config.py +0 -0
  73. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/contrawr.py +0 -0
  74. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/ctnet.py +0 -0
  75. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/deep4.py +0 -0
  76. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/deepsleepnet.py +0 -0
  77. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/dgcnn.py +0 -0
  78. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eegconformer.py +0 -0
  79. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eegdino.py +0 -0
  80. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eeginception_erp.py +0 -0
  81. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eeginception_mi.py +0 -0
  82. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eegitnet.py +0 -0
  83. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eegminer.py +0 -0
  84. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eegnet.py +0 -0
  85. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eegnex.py +0 -0
  86. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eegpt.py +0 -0
  87. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eegsimpleconv.py +0 -0
  88. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eegsym.py +0 -0
  89. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/eegtcnet.py +0 -0
  90. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/emg2qwerty.py +0 -0
  91. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/fbcnet.py +0 -0
  92. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/fbmsnet.py +0 -0
  93. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/hybrid.py +0 -0
  94. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/ifnet.py +0 -0
  95. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/interpolated.py +0 -0
  96. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/labram.py +0 -0
  97. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/luna.py +0 -0
  98. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/medformer.py +0 -0
  99. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/meta_neuromotor.py +0 -0
  100. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/msvtnet.py +0 -0
  101. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/mvpformer.py +0 -0
  102. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/patchedtransformer.py +0 -0
  103. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/reve.py +0 -0
  104. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/sccnet.py +0 -0
  105. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/shallow_fbcsp.py +0 -0
  106. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/signal_jepa.py +0 -0
  107. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/sinc_shallow.py +0 -0
  108. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  109. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  110. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/sparcnet.py +0 -0
  111. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/sstdpn.py +0 -0
  112. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/steegformer.py +0 -0
  113. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/syncnet.py +0 -0
  114. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/tcformer.py +0 -0
  115. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/tidnet.py +0 -0
  116. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/tsinception.py +0 -0
  117. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/models/usleep.py +0 -0
  118. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/activation.py +0 -0
  119. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/attention.py +0 -0
  120. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/blocks.py +0 -0
  121. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/convolution.py +0 -0
  122. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/filter.py +0 -0
  123. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/interpolation.py +0 -0
  124. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/layers.py +0 -0
  125. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/linear.py +0 -0
  126. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/parametrization.py +0 -0
  127. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/stats.py +0 -0
  128. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/util.py +0 -0
  129. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/modules/wrapper.py +0 -0
  130. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/preprocessing/__init__.py +0 -0
  131. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  132. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/preprocessing/mne_preprocess.py +0 -0
  133. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/preprocessing/preprocess.py +0 -0
  134. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/preprocessing/util.py +0 -0
  135. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/preprocessing/windowers.py +0 -0
  136. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/regressor.py +0 -0
  137. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/samplers/__init__.py +0 -0
  138. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/samplers/base.py +0 -0
  139. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/samplers/ssl.py +0 -0
  140. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/training/callbacks.py +0 -0
  141. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/util.py +0 -0
  142. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/visualization/__init__.py +0 -0
  143. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/visualization/attribution.py +0 -0
  144. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/visualization/confusion_matrices.py +0 -0
  145. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/visualization/frequency.py +0 -0
  146. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/visualization/metrics.py +0 -0
  147. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/visualization/sanity.py +0 -0
  148. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode/visualization/topology.py +0 -0
  149. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode.egg-info/dependency_links.txt +0 -0
  150. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode.egg-info/requires.txt +0 -0
  151. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/braindecode.egg-info/top_level.txt +0 -0
  152. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/Makefile +0 -0
  153. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/_templates/autosummary/class.rst +0 -0
  154. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  155. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/_templates/autosummary/function.rst +0 -0
  156. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  157. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/cite.rst +0 -0
  158. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/conf.py +0 -0
  159. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/help.rst +0 -0
  160. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/index.rst +0 -0
  161. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/install/install.rst +0 -0
  162. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/install/install_pip.rst +0 -0
  163. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/install/install_source.rst +0 -0
  164. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/categorization/attention.rst +0 -0
  165. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/categorization/channel.rst +0 -0
  166. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/categorization/convolution.rst +0 -0
  167. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/categorization/filterbank.rst +0 -0
  168. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/categorization/gnn.rst +0 -0
  169. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/categorization/interpretable.rst +0 -0
  170. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/categorization/lbm.rst +0 -0
  171. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/categorization/recurrent.rst +0 -0
  172. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/categorization/spd.rst +0 -0
  173. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/models.rst +0 -0
  174. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/models_categorization.rst +0 -0
  175. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/models_table.rst +0 -0
  176. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/models/models_visualization.rst +0 -0
  177. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/docs/sg_execution_times.rst +0 -0
  178. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/pyproject.toml +0 -0
  179. {braindecode-1.7.0.dev182244820 → braindecode-1.7.0.dev182553025}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.7.0.dev182244820
3
+ Version: 1.7.0.dev182553025
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>
@@ -5,6 +5,8 @@ from .functions import (
5
5
  dwt_max_level,
6
6
  hilbert_freq,
7
7
  identity,
8
+ iou_1d,
9
+ pairwise_iou_1d,
8
10
  plv_time,
9
11
  safe_log,
10
12
  sinusoidal_positional_encoding,
@@ -20,6 +22,8 @@ __all__ = [
20
22
  "dwt_max_level",
21
23
  "hilbert_freq",
22
24
  "identity",
25
+ "iou_1d",
26
+ "pairwise_iou_1d",
23
27
  "plv_time",
24
28
  "safe_log",
25
29
  "sinusoidal_positional_encoding",
@@ -260,6 +260,40 @@ def plv_time(
260
260
  return plv_matrix
261
261
 
262
262
 
263
+ # -----------------------------------------------------------------------------
264
+ # DANCE functional helpers
265
+ #
266
+ # Authors: Bruno Aristimunha <b.aristimunha@gmail.com>
267
+ #
268
+ # License: MIT
269
+ #
270
+ # Ported from the DANCE event-detection model (facebookresearch/dance, MIT).
271
+ # -----------------------------------------------------------------------------
272
+
273
+
274
+ def iou_1d(s1, e1, s2, e2, eps: float = 1e-7):
275
+ """ELEMENTWISE 1-D temporal IoU. All four inputs share the same shape S
276
+ (e.g. ``(B, Q)``); returns IoU of shape S. Used by ``DanceLoss`` on the
277
+ matched ``(B, Q)`` spans. For (Q,)x(T,) pairwise IoU use ``pairwise_iou_1d``.
278
+ """
279
+ inter = (torch.minimum(e1, e2) - torch.maximum(s1, s2)).clamp(min=0)
280
+ union = (e1 - s1) + (e2 - s2) - inter
281
+ return inter / (union + eps)
282
+
283
+
284
+ def pairwise_iou_1d(s1, e1, s2, e2, eps: float = 1e-7):
285
+ """PAIRWISE 1-D temporal IoU. ``s1,e1`` shape ``(Q,)``, ``s2,e2`` shape
286
+ ``(T,)``; returns ``(Q, T)`` (broadcast ``[:, None]`` x ``[None, :]``).
287
+ Transcribed from ``dance/matcher.py:33-39`` (``_pairwise_iou``). Used by
288
+ ``HungarianMatcher`` to build the ``(Q, n_targets)`` cost matrix.
289
+ """
290
+ inter_start = torch.maximum(s1[:, None], s2[None, :])
291
+ inter_end = torch.minimum(e1[:, None], e2[None, :])
292
+ inter = (inter_end - inter_start).clamp(min=0)
293
+ union = (e1 - s1)[:, None] + (e2 - s2)[None, :] - inter
294
+ return inter / (union + eps)
295
+
296
+
263
297
  def daubechies_filters(n_vanishing: int) -> torch.Tensor:
264
298
  r"""Daubechies ``db<n_vanishing>`` wavelet decomposition filters.
265
299
 
@@ -11,6 +11,7 @@ from .cbramod import CBraMod
11
11
  from .codebrain import CodeBrain
12
12
  from .contrawr import ContraWR
13
13
  from .ctnet import CTNet
14
+ from .dance import DANCE
14
15
  from .deep4 import Deep4Net
15
16
  from .deepsleepnet import DeepSleepNet
16
17
  from .dgcnn import DGCNN
@@ -86,6 +87,7 @@ __all__ = [
86
87
  "CodeBrain",
87
88
  "ContraWR",
88
89
  "CTNet",
90
+ "DANCE",
89
91
  "Deep4Net",
90
92
  "DeepSleepNet",
91
93
  "BrainModule",
@@ -1,3 +1,8 @@
1
+ # Authors: Bruno Aristimunha <b.aristimunha@gmail.com>
2
+ # Sarthak Tayal <sarthaktayal2@gmail.com>
3
+ #
4
+ # License: BSD (3-clause)
5
+
1
6
  import copy
2
7
 
3
8
  import numpy as np
@@ -435,7 +440,9 @@ class _ConvEncoderBENDR(nn.Module):
435
440
  padding=width
436
441
  // 2, # Correct padding for 'same' output length before stride
437
442
  ),
438
- nn.Dropout2d(dropout), # 2D dropout (matches paper specification)
443
+ # channel-wise dropout (matches paper specification), on
444
+ # (batch, channels, times) activations
445
+ nn.Dropout1d(dropout),
439
446
  nn.GroupNorm(
440
447
  encoder_h // 2, encoder_h
441
448
  ), # Consider making num_groups configurable or ensure encoder_h is divisible by 2
@@ -0,0 +1,368 @@
1
+ # Authors: Bruno Aristimunha <b.aristimunha@gmail.com>
2
+ # Meta Platforms, Inc. and affiliates (original DANCE)
3
+ #
4
+ # License: MIT
5
+ # Adapted from https://github.com/facebookresearch/dance (MIT).
6
+ """``DANCE``: detect-and-classify EEG events (DETR for 1-D EEG)."""
7
+
8
+ from __future__ import annotations
9
+
10
+ import warnings
11
+
12
+ import torch
13
+ from torch import nn
14
+
15
+ from braindecode.models.base import EEGModuleMixin
16
+ from braindecode.models.util import (
17
+ _disable_batch_norm_training_if_batch_size_one, # decorates ``forward``
18
+ )
19
+ from braindecode.models.util import has_valid_locations as _has_valid_locations
20
+ from braindecode.models.util import positions_from_chs_info as _positions_from_chs_info
21
+ from braindecode.modules import ChannelMerger, Perceiver, SimpleConv
22
+ from braindecode.modules.dance_modules import DanceDetrDecoder
23
+
24
+
25
+ class DANCE(EEGModuleMixin, nn.Module):
26
+ r"""DANCE from Lévy et al (2026) [dance]_.
27
+
28
+ :bdg-success:`Convolution` :bdg-info:`Attention/Transformer` :bdg-dark-line:`Channel`
29
+
30
+ DANCE frames EEG decoding as event *set prediction*: a long, unaligned
31
+ window is mapped to a set of events ``(t_start, t_end, class)`` with
32
+ normalized ``[0, 1]`` spans -- DETR for 1-D EEG.
33
+
34
+ .. rubric:: Architecture Overview
35
+
36
+ ``ChannelMerger`` (spatial Fourier attention over electrode positions) ->
37
+ ``SimpleConv`` (dilated conv stack) -> ``Perceiver`` (cross-attention to a
38
+ fixed 256-latent grid) -> a dense head (``forward`` output) and a DETR
39
+ cross-attention decoder (``detect`` output).
40
+
41
+ .. rubric:: Macro Components
42
+
43
+ ``DANCE.conv.merger`` (Spatial ChannelMerger)
44
+ **Operations.** :class:`~braindecode.modules.ChannelMerger` Fourier-embeds
45
+ each electrode's ``(x, y)`` position (:class:`~braindecode.modules.FourierEmb`)
46
+ and computes ``n_virtual_channels`` softmax-attention combinations of the
47
+ input channels, mapping ``(B, n_chans, T) -> (B, n_virtual_channels, T)``.
48
+ Nested inside ``self.conv`` (matching upstream); disabled (``None``) when
49
+ ``chs_info`` has no usable locations. Controlled by ``merger_drop_prob``.
50
+ **Role.** Makes the model montage-agnostic by projecting any electrode
51
+ layout onto a fixed virtual-channel basis.
52
+
53
+ ``DANCE.conv`` (SimpleConv dilated front-end)
54
+ **Operations.** :class:`~braindecode.modules.SimpleConv` runs the nested
55
+ merger, a ``1x1`` ``initial_linear`` projection, then ``conv_depth``
56
+ residual dilated ``Conv1d`` blocks (``nn.ReLU``, dilation accumulating as
57
+ ``int(dilation * conv_dilation_growth)`` per block, same-padding preserves
58
+ ``T``), mapping ``-> (B, embed_dim, T)``.
59
+ **Role.** Builds the temporal feature representation (Défossez lineage).
60
+
61
+ ``DANCE.perceiver`` (Perceiver bottleneck)
62
+ **Operations.** :class:`~braindecode.modules.Perceiver` Fourier-encodes the
63
+ time axis, then cross-attends a fixed ``num_latents``-token learnable grid to
64
+ the conv features over ``perceiver_depth`` blocks, mapping
65
+ ``(B, T, embed_dim) -> (B, num_latents, embed_dim)``.
66
+ **Role.** Makes the model length-agnostic (any ``T`` -> ``num_latents``
67
+ tokens) and forms the detection time-grid (``num_latents / duration``
68
+ tokens/s).
69
+
70
+ ``DANCE.decoder`` (DETR cross-attention decoder)
71
+ **Operations.** ``DanceDetrDecoder`` projects the latents to
72
+ ``decoder_dim``, then ``decoder_depth`` self-/cross-attention layers update
73
+ ``n_queries`` learnable event queries; per-query heads emit class logits and
74
+ sigmoid ``start``/``end`` spans. Used only by :meth:`detect` (not
75
+ :meth:`forward`).
76
+ **Role.** Produces the event-set prediction ``{class, start, end}``.
77
+
78
+ ``DANCE.final_layer`` (dense per-token head)
79
+ **Operations.** ``nn.Linear(embed_dim, n_outputs)`` applied to every latent
80
+ token, mapping ``(B, num_latents, embed_dim) -> (B, num_latents, n_outputs)``.
81
+ **Role.** The :meth:`forward` output (dense per-token class logits) and the
82
+ ``dense`` term consumed by the consistency loss.
83
+
84
+ .. rubric:: Temporal, Spatial, and Spectral Encoding
85
+
86
+ Temporal context comes from the dilated conv stack; spatial structure from
87
+ the Fourier-position channel merge; the Perceiver fourier-encodes the time
88
+ axis before cross-attention.
89
+
90
+ .. rubric:: Additional Mechanisms
91
+
92
+ The DETR decoder uses learnable event queries and emits per-query class
93
+ logits plus sigmoid start/end spans. The dense head provides per-token
94
+ class logits used as ``forward``'s output and for the consistency loss.
95
+
96
+ .. versionadded:: 1.6.1
97
+
98
+ Parameters
99
+ ----------
100
+ n_queries : int, optional
101
+ Number of learnable event queries. The default is ``100``.
102
+ use_channel_merger : bool, optional
103
+ Enable the spatial Fourier ChannelMerger. Auto-disabled if ``chs_info``
104
+ has no usable electrode locations. The default is ``True``.
105
+ n_virtual_channels : int, optional
106
+ Merger output channels. The default is ``270``.
107
+ fourier_emb_dim : int, optional
108
+ Fourier position embedding dim. The default is ``2048``.
109
+ merger_drop_prob : float, optional
110
+ Spatial dropout of the ChannelMerger ONLY (``self.conv.merger``);
111
+ bans whole channels within a random radius during training. The
112
+ default is ``0.2``.
113
+ embed_dim : int, optional
114
+ Conv/Perceiver feature dim. The default is ``128``.
115
+ conv_hidden : int, optional
116
+ SimpleConv hidden width. The default is ``512``.
117
+ conv_depth : int, optional
118
+ Number of dilated conv blocks. The default is ``10``.
119
+ conv_kernel_size : int, optional
120
+ Conv kernel size. The default is ``9``.
121
+ conv_dilation_growth : float, optional
122
+ Per-block dilation growth. The default is ``2.5``.
123
+ conv_initial_linear : int, optional
124
+ 1x1 projection width. The default is ``256``.
125
+ conv_initial_depth : int, optional
126
+ Number of 1x1 projections. The default is ``1``.
127
+ conv_drop_prob : float, optional
128
+ Conv-block dropout knob, exposed for API symmetry. NOTE: the verified
129
+ DANCE config has NO conv dropout, so this maps to no upstream weights
130
+ and does not affect parity; kept for forward-compatibility. The
131
+ default is ``0.2`` (the paper value).
132
+ num_latents : int, optional
133
+ Perceiver latent count (detection token grid). The default is ``256``.
134
+ perceiver_depth : int, optional
135
+ Perceiver cross-attn blocks. The default is ``6``.
136
+ cross_attn_heads : int, optional
137
+ Perceiver cross-attn heads. The default is ``2``.
138
+ latent_attn_heads : int, optional
139
+ Perceiver self-attn heads. The default is ``2``.
140
+ cross_dim_head : int, optional
141
+ Perceiver cross-attn head dim. The default is ``64``.
142
+ latent_dim_head : int, optional
143
+ Perceiver self-attn head dim. The default is ``64``.
144
+ max_freq : float, optional
145
+ Perceiver fourier max frequency. The default is ``10.0``.
146
+ num_freq_bands : int, optional
147
+ Perceiver fourier bands. The default is ``6``.
148
+ decoder_dim : int, optional
149
+ DETR decoder dim. The default is ``256``.
150
+ decoder_depth : int, optional
151
+ DETR decoder layers. The default is ``4``.
152
+ decoder_heads : int, optional
153
+ DETR decoder heads. The default is ``4``.
154
+ activation : type[nn.Module], optional
155
+ Accepted for interface symmetry but currently INERT: it is forwarded to
156
+ ``self.decoder`` yet the decoder feed-forward hardwires GEGLU
157
+ (:class:`~braindecode.modules.dance_modules._FeedForward`), and the
158
+ ``SimpleConv`` front-end hardcodes ``nn.ReLU`` to match upstream. No
159
+ submodule reads it today. The default is ``nn.GELU``.
160
+ drop_prob : float, optional
161
+ Dropout applied to the raw input (``self.input_drop``) and inside the
162
+ DETR decoder (``self.decoder``). Does NOT touch the merger (use
163
+ ``merger_drop_prob``) or the conv stack (no conv dropout upstream).
164
+ The default is ``0.1``.
165
+
166
+ References
167
+ ----------
168
+ .. [dance] Lévy, Banville, Rapin, King, Moreau, d'Ascoli (2026). DANCE:
169
+ Detect and Classify Events in EEG. arXiv:2605.10688.
170
+ .. [defossez2023] Défossez et al. (2023). Decoding speech from
171
+ non-invasive brain recordings.
172
+ .. [perceiver2021] Jaegle et al. (2021). Perceiver: General perception
173
+ with iterative attention.
174
+ .. [detr2020] Carion et al. (2020). End-to-end object detection with
175
+ transformers.
176
+ """
177
+
178
+ def __init__(
179
+ self,
180
+ n_outputs=None,
181
+ n_chans=None,
182
+ chs_info=None,
183
+ n_times=None,
184
+ input_window_seconds=None,
185
+ sfreq=None,
186
+ *,
187
+ n_queries: int = 100,
188
+ use_channel_merger: bool = True,
189
+ n_virtual_channels: int = 270,
190
+ fourier_emb_dim: int = 2048,
191
+ merger_drop_prob: float = 0.2,
192
+ embed_dim: int = 128,
193
+ conv_hidden: int = 512,
194
+ conv_depth: int = 10,
195
+ conv_kernel_size: int = 9,
196
+ conv_dilation_growth: float = 2.5,
197
+ conv_initial_linear: int = 256,
198
+ conv_initial_depth: int = 1,
199
+ conv_drop_prob: float = 0.2,
200
+ num_latents: int = 256,
201
+ perceiver_depth: int = 6,
202
+ cross_attn_heads: int = 2,
203
+ latent_attn_heads: int = 2,
204
+ cross_dim_head: int = 64,
205
+ latent_dim_head: int = 64,
206
+ max_freq: float = 10.0,
207
+ num_freq_bands: int = 6,
208
+ decoder_dim: int = 256,
209
+ decoder_depth: int = 4,
210
+ decoder_heads: int = 4,
211
+ activation: type[nn.Module] = nn.GELU,
212
+ drop_prob: float = 0.1,
213
+ ):
214
+ super().__init__(
215
+ n_outputs=n_outputs,
216
+ n_chans=n_chans,
217
+ chs_info=chs_info,
218
+ n_times=n_times,
219
+ input_window_seconds=input_window_seconds,
220
+ sfreq=sfreq,
221
+ )
222
+ del n_outputs, n_chans, sfreq, n_times, input_window_seconds, chs_info
223
+
224
+ self.num_latents = num_latents
225
+ self.n_queries = n_queries
226
+ self.embed_dim = embed_dim
227
+
228
+ # Decide the merger up front (fall back to no-merger if no locations).
229
+ if use_channel_merger and not _has_valid_locations(self.chs_info):
230
+ warnings.warn(
231
+ "DANCE: chs_info has no usable electrode locations "
232
+ "('loc' missing or all-zero); disabling the ChannelMerger "
233
+ "(use_channel_merger=False).",
234
+ UserWarning,
235
+ )
236
+ use_channel_merger = False
237
+ # Public flag mirroring the fallback decision (``self.conv.merger`` is the
238
+ # source of truth in forward); kept for introspection/tests.
239
+ self.use_channel_merger = use_channel_merger
240
+
241
+ # The merger is NESTED INSIDE SimpleConv (self.conv.merger), matching
242
+ # upstream SimpleConvModel's call path and state_dict layout. There is
243
+ # NO top-level self.channel_merger. The (n_chans, 2) positions buffer is
244
+ # derived from chs_info and broadcast in forward; subject_ids is always
245
+ # None (braindecode has no subjects; per_subject=False).
246
+ merger = None
247
+ if use_channel_merger:
248
+ positions = _positions_from_chs_info(self.chs_info)
249
+ self.register_buffer(
250
+ "channel_positions",
251
+ torch.as_tensor(positions, dtype=torch.float32),
252
+ persistent=False,
253
+ )
254
+ merger = ChannelMerger(
255
+ out_channels=n_virtual_channels,
256
+ pos_dim=fourier_emb_dim,
257
+ dropout=merger_drop_prob,
258
+ )
259
+
260
+ self.input_drop = nn.Dropout(drop_prob)
261
+ self.conv = SimpleConv(
262
+ in_channels=self.n_chans,
263
+ out_channels=embed_dim,
264
+ hidden=conv_hidden,
265
+ depth=conv_depth,
266
+ kernel_size=conv_kernel_size,
267
+ dilation_growth=conv_dilation_growth,
268
+ initial_linear=conv_initial_linear,
269
+ initial_depth=conv_initial_depth,
270
+ drop_prob=conv_drop_prob,
271
+ activation=nn.ReLU,
272
+ merger=merger,
273
+ )
274
+ # The conv stack is SAME-padded, so it preserves length for any T >= 1;
275
+ # the dilated receptive field is not an input-length requirement. The
276
+ # genuine minimum is one first-block kernel (dilation 1), so the guard
277
+ # uses ``conv_kernel_size`` rather than the full receptive field.
278
+ self._min_n_times = conv_kernel_size
279
+ self.perceiver = Perceiver(
280
+ input_dim=embed_dim,
281
+ num_latents=num_latents,
282
+ latent_dim=embed_dim,
283
+ depth=perceiver_depth,
284
+ cross_heads=cross_attn_heads,
285
+ latent_heads=latent_attn_heads,
286
+ cross_dim_head=cross_dim_head,
287
+ latent_dim_head=latent_dim_head,
288
+ max_freq=max_freq,
289
+ num_freq_bands=num_freq_bands,
290
+ )
291
+ self.decoder = DanceDetrDecoder(
292
+ input_dim=embed_dim,
293
+ dim=decoder_dim,
294
+ depth=decoder_depth,
295
+ heads=decoder_heads,
296
+ n_queries=n_queries,
297
+ n_outputs=self.n_outputs,
298
+ drop_prob=drop_prob,
299
+ activation=activation,
300
+ )
301
+ # final_layer LAST so it lands in the last two named_children(); init
302
+ # weights AFTER it exists so the dense head gets the custom init too.
303
+ self.final_layer = nn.Linear(embed_dim, self.n_outputs)
304
+ self.apply(self._init_weights)
305
+
306
+ @staticmethod
307
+ def _init_weights(module: nn.Module) -> None:
308
+ if isinstance(module, nn.Linear):
309
+ nn.init.trunc_normal_(module.weight, std=0.02)
310
+ if module.bias is not None:
311
+ nn.init.zeros_(module.bias)
312
+ elif isinstance(module, nn.LayerNorm):
313
+ nn.init.ones_(module.weight)
314
+ nn.init.zeros_(module.bias)
315
+
316
+ def _encode(self, x: torch.Tensor) -> torch.Tensor:
317
+ if x.ndim != 3 or x.shape[-2] != self.n_chans:
318
+ raise ValueError(
319
+ f"expected (batch, {self.n_chans}, T) input; got {tuple(x.shape)}."
320
+ )
321
+ if x.shape[-1] < self._min_n_times:
322
+ raise ValueError(
323
+ f"n_times={x.shape[-1]} is shorter than the minimum input "
324
+ f"length ({self._min_n_times} samples = one conv kernel)."
325
+ )
326
+ x = self.input_drop(x)
327
+ # The merger is nested inside self.conv; pass positions through it.
328
+ # subject_ids is always None (braindecode has no subjects).
329
+ if self.conv.merger is not None:
330
+ pos = self.channel_positions.unsqueeze(0).expand(x.size(0), -1, -1)
331
+ x = self.conv(x, positions=pos) # merger -> initial_linear -> blocks
332
+ else:
333
+ x = self.conv(x) # (B, embed_dim, T)
334
+ x = x.transpose(2, 1) # (B, T, embed_dim)
335
+ x = self.perceiver(x) # (B, num_latents, embed_dim)
336
+ return x
337
+
338
+ @_disable_batch_norm_training_if_batch_size_one
339
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
340
+ latents = self._encode(x) # (B, num_latents, embed_dim)
341
+ return self.final_layer(latents) # (B, num_latents, n_outputs)
342
+
343
+ @_disable_batch_norm_training_if_batch_size_one
344
+ def detect(self, x: torch.Tensor) -> dict:
345
+ latents = self._encode(x) # (B, num_latents, embed_dim)
346
+ events = self.decoder(latents) # {class, start, end}
347
+ events["dense"] = self.final_layer(latents) # (B, num_latents, n_outputs)
348
+ return events
349
+
350
+ def reset_head(self, n_outputs: int) -> None:
351
+ """Replace the dense head and the DETR class head for a new ``n_outputs``."""
352
+ if n_outputs <= 0:
353
+ raise ValueError(f"n_outputs must be positive; got {n_outputs}.")
354
+ old = self.final_layer
355
+ self.final_layer = nn.Linear(old.in_features, n_outputs).to(
356
+ device=old.weight.device, dtype=old.weight.dtype
357
+ )
358
+ ch = self.decoder.class_head
359
+ self.decoder.class_head = nn.Linear(ch.in_features, n_outputs).to(
360
+ device=ch.weight.device, dtype=ch.weight.dtype
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
@@ -1,3 +1,7 @@
1
+ # Authors: Sarthak Tayal <sarthaktayal2@gmail.com>
2
+ #
3
+ # License: BSD-3
4
+
1
5
  from __future__ import annotations
2
6
 
3
7
  from typing import Optional
@@ -61,15 +65,18 @@ class FBLightConvNet(EEGModuleMixin, nn.Module):
61
65
 
62
66
  Parameters
63
67
  ----------
64
- n_bands : int or None or list of tuple of int, default=8
68
+ n_bands : int or None or list of tuple of int, default=9
65
69
  Number of frequency bands or a list of frequency band tuples. If a list of tuples is provided,
66
70
  each tuple defines the lower and upper bounds of a frequency band.
67
71
  n_filters_spat : int, default=32
68
72
  Number of spatial filters in the depthwise convolutional layer.
69
73
  n_dim : int, default=3
70
74
  Number of dimensions for the temporal reduction layer.
71
- stride_factor : int, default=4
72
- Stride factor used for reshaping the temporal dimension.
75
+ win_len : int, default=250
76
+ Length in samples of the non-overlapping temporal windows the signal is
77
+ split into before the variance based feature extraction. The number of
78
+ windows passed to the attention module is ``n_times // win_len``, so
79
+ ``n_times`` has to be at least ``win_len``.
73
80
  activation : nn.Module, default=nn.ELU
74
81
  Activation function class to apply after convolutional layers.
75
82
  verbose : bool, default=False
@@ -82,6 +89,9 @@ class FBLightConvNet(EEGModuleMixin, nn.Module):
82
89
  If True, applies softmax to the attention weights.
83
90
  bias : bool, default=False
84
91
  If True, includes a bias term in the convolutional layers.
92
+ stride_factor : int or None, default=None
93
+ Deprecated and ignored, it will be removed in a future release. The
94
+ temporal segmentation of this model is controlled by ``win_len``.
85
95
 
86
96
  References
87
97
  ----------
@@ -106,7 +116,7 @@ class FBLightConvNet(EEGModuleMixin, nn.Module):
106
116
  n_bands=9,
107
117
  n_filters_spat: int = 32,
108
118
  n_dim: int = 3,
109
- stride_factor: int = 4,
119
+ stride_factor: Optional[int] = None,
110
120
  win_len: int = 250,
111
121
  heads: int = 8,
112
122
  weight_softmax: bool = True,
@@ -125,6 +135,14 @@ class FBLightConvNet(EEGModuleMixin, nn.Module):
125
135
  )
126
136
  del n_outputs, n_chans, chs_info, n_times, input_window_seconds, sfreq
127
137
 
138
+ if stride_factor is not None:
139
+ warn(
140
+ "The parameter `stride_factor` is deprecated and ignored, it "
141
+ "will be removed in a future release. The temporal "
142
+ "segmentation of FBLightConvNet is set by `win_len`.",
143
+ DeprecationWarning,
144
+ )
145
+
128
146
  # Parameters
129
147
  self.n_bands = n_bands
130
148
  self.n_filters_spat = n_filters_spat
@@ -138,6 +156,13 @@ class FBLightConvNet(EEGModuleMixin, nn.Module):
138
156
  self.filter_parameters = filter_parameters or {}
139
157
 
140
158
  # Checkers
159
+ if self.n_times < self.win_len:
160
+ raise ValueError(
161
+ f"Time dimension ({self.n_times}) is shorter than win_len "
162
+ f"({self.win_len}), so the model cannot build a single "
163
+ f"temporal window. Pass a longer input or lower `win_len`."
164
+ )
165
+
141
166
  self.n_times_truncated = self.n_times
142
167
  if self.n_times % self.win_len != 0:
143
168
  warn(
@@ -194,10 +219,12 @@ class FBLightConvNet(EEGModuleMixin, nn.Module):
194
219
  def forward(self, x: torch.Tensor) -> torch.Tensor:
195
220
  """
196
221
  Forward pass of the FBLightConvNet model.
222
+
197
223
  Parameters
198
224
  ----------
199
225
  x : torch.Tensor
200
226
  Input tensor with shape (batch_size, n_chans, n_times).
227
+
201
228
  Returns
202
229
  -------
203
230
  torch.Tensor
@@ -58,5 +58,6 @@ InterpolatedLaBraM,General,"Prediction, Embedding",200,"chs_info, n_outputs, n_t
58
58
  InterpolatedSignalJEPA,"Motor Imagery, ERP, SSVEP",Embedding,128,"chs_info",3456882,"InterpolatedSignalJEPA(chs_info=<user>)","Convolution,Channel,Foundation Model",EEG
59
59
  TCFormer,Motor Imagery,Classification,250,"n_chans, n_outputs, n_times",77820,"TCFormer(n_chans=22, n_outputs=4, n_times=1000)","Convolution,Attention/Transformer",EEG
60
60
  EEGDINO,General,Classification,200,"n_chans, n_outputs, n_times",4539698,"EEGDINO(n_chans=19, n_outputs=4, n_times=1000)","Foundation Model,Attention/Transformer",EEG
61
+ DANCE,General,Event Detection,200,"n_chans, n_outputs, n_times, sfreq, chs_info",29813542,"DANCE(n_chans=19, n_outputs=4, n_times=6400, sfreq=200, input_window_seconds=32.0, chs_info=[{'ch_name': f'E{i+1}', 'kind': 'eeg', 'loc': numpy.random.default_rng(2024).random(12)} for i in range(19)])","Convolution,Attention/Transformer,Channel",EEG
61
62
  STEEGFormer,General,Classification,250,"n_chans, n_outputs, n_times",25305604,"STEEGFormer(n_chans=22, n_outputs=4, n_times=1000)","Attention/Transformer,Foundation Model",EEG
62
63
  MVPFormer,General,"Prediction, Embedding",512,"n_chans, n_outputs, n_times, sfreq",3356978,"MVPFormer(n_chans=22, n_outputs=4, n_times=2000, sfreq=100)","Foundation Model,Attention/Transformer",EEG
@@ -1,5 +1,6 @@
1
1
  # Authors: Patryk Chrabaszcz
2
2
  # Lukas Gemein <l.gemein@gmail.com>
3
+ # Sarthak Tayal <sarthaktayal2@gmail.com>
3
4
  #
4
5
  # License: BSD-3
5
6
  import torch
@@ -236,7 +237,9 @@ class _TemporalBlock(nn.Module):
236
237
  )
237
238
  self.chomp1 = Chomp1d(padding)
238
239
  self.relu1 = activation()
239
- self.dropout1 = nn.Dropout2d(drop_prob)
240
+ # activations are (batch, channels, times), dropout2d only masks
241
+ # channel-wise there through a deprecated fallback
242
+ self.dropout1 = nn.Dropout1d(drop_prob)
240
243
 
241
244
  self.conv2 = weight_norm(
242
245
  nn.Conv1d(
@@ -250,7 +253,7 @@ class _TemporalBlock(nn.Module):
250
253
  )
251
254
  self.chomp2 = Chomp1d(padding)
252
255
  self.relu2 = activation()
253
- self.dropout2 = nn.Dropout2d(drop_prob)
256
+ self.dropout2 = nn.Dropout1d(drop_prob)
254
257
 
255
258
  self.downsample = (
256
259
  nn.Conv1d(n_inputs, n_outputs, 1) if n_inputs != n_outputs else None
@@ -484,6 +484,25 @@ models_mandatory_parameters: list[
484
484
  ),
485
485
  ("DGCNN", ["n_chans", "n_outputs", "n_times", "chs_info"], None),
486
486
  ("EEGDINO", ["n_chans", "n_outputs", "n_times"], None),
487
+ (
488
+ "DANCE",
489
+ ["n_outputs", "n_chans", "n_times", "sfreq", "chs_info"],
490
+ {
491
+ "n_chans": 19,
492
+ "n_times": 6400, # 32 s @ 200 Hz, above the depth-10 stack minimum
493
+ "sfreq": 200.0,
494
+ "input_window_seconds": 32.0,
495
+ "n_outputs": 4,
496
+ "chs_info": [
497
+ {
498
+ "ch_name": f"E{i + 1}",
499
+ "kind": "eeg",
500
+ "loc": _rng.random(12),
501
+ }
502
+ for i in range(19)
503
+ ],
504
+ },
505
+ ),
487
506
  ]
488
507
 
489
508
  ################################################################
@@ -498,6 +517,9 @@ non_classification_models = [
498
517
  # Emits a (batch, T_out, vocab) sequence for CTC, not class logits.
499
518
  "MetaNeuromotorHand",
500
519
  "EMG2QwertyNet",
520
+ # forward returns (batch, num_latents, n_outputs) dense per-token logits,
521
+ # not class logits.
522
+ "DANCE",
501
523
  ]
502
524
 
503
525
  ################################################################
@@ -23,6 +23,7 @@ from .convolution import (
23
23
  Conv2dWithConstraint,
24
24
  DepthwiseConv2d,
25
25
  )
26
+ from .dance_modules import Perceiver, SimpleConv
26
27
  from .filter import FilterBankLayer, GeneralizedGaussianFilter
27
28
  from .interpolation import ChannelInterpolationLayer
28
29
  from .layers import (
@@ -78,6 +79,10 @@ __all__ = [
78
79
  "Conv1dWithConstraint",
79
80
  "Conv2dWithConstraint",
80
81
  "DepthwiseConv2d",
82
+ "ChannelMerger",
83
+ "FourierEmb",
84
+ "Perceiver",
85
+ "SimpleConv",
81
86
  "FilterBankLayer",
82
87
  "GeneralizedGaussianFilter",
83
88
  "Chomp1d",
@@ -88,8 +93,6 @@ __all__ = [
88
93
  "TimeDistributed",
89
94
  "LinearWithConstraint",
90
95
  "MaxNormLinear",
91
- "ChannelMerger",
92
- "FourierEmb",
93
96
  "MaxNorm",
94
97
  "MaxNormParametrize",
95
98
  "LogPowerLayer",