Braindecode 1.5.0.dev179275821__tar.gz → 1.5.0.dev182195895__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 (174) hide show
  1. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/NOTICE.txt +0 -5
  2. {braindecode-1.5.0.dev179275821/braindecode.egg-info → braindecode-1.5.0.dev182195895}/PKG-INFO +2 -6
  3. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/base.py +1 -119
  4. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/sleep_physionet.py +1 -15
  5. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/__init__.py +3 -16
  6. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/base.py +4 -16
  7. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/bendr.py +28 -92
  8. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/biot.py +1 -61
  9. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/config.py +4 -5
  10. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/labram.py +266 -208
  11. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/reve.py +1 -1
  12. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/signal_jepa.py +38 -463
  13. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/summary.csv +0 -7
  14. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/util.py +20 -151
  15. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/__init__.py +0 -2
  16. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/eegprep_preprocess.py +6 -51
  17. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/preprocess.py +17 -38
  18. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/windowers.py +4 -13
  19. braindecode-1.5.0.dev182195895/braindecode/version.py +1 -0
  20. braindecode-1.5.0.dev182195895/braindecode/visualization/__init__.py +8 -0
  21. braindecode-1.5.0.dev182195895/braindecode/visualization/gradients.py +62 -0
  22. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895/braindecode.egg-info}/PKG-INFO +2 -6
  23. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode.egg-info/SOURCES.txt +1 -10
  24. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode.egg-info/requires.txt +1 -6
  25. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/api.rst +4 -106
  26. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/cite.rst +2 -2
  27. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/conf.py +2 -34
  28. braindecode-1.5.0.dev182195895/docs/index.rst +48 -0
  29. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/whats_new.rst +0 -142
  30. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/pyproject.toml +1 -4
  31. braindecode-1.5.0.dev179275821/braindecode/models/codebrain.py +0 -977
  32. braindecode-1.5.0.dev179275821/braindecode/models/emg2qwerty.py +0 -714
  33. braindecode-1.5.0.dev179275821/braindecode/models/interpolated.py +0 -182
  34. braindecode-1.5.0.dev179275821/braindecode/models/meta_neuromotor.py +0 -1774
  35. braindecode-1.5.0.dev179275821/braindecode/modules/interpolation.py +0 -201
  36. braindecode-1.5.0.dev179275821/braindecode/version.py +0 -1
  37. braindecode-1.5.0.dev179275821/braindecode/visualization/__init__.py +0 -45
  38. braindecode-1.5.0.dev179275821/braindecode/visualization/attribution.py +0 -152
  39. braindecode-1.5.0.dev179275821/braindecode/visualization/frequency.py +0 -89
  40. braindecode-1.5.0.dev179275821/braindecode/visualization/metrics.py +0 -414
  41. braindecode-1.5.0.dev179275821/braindecode/visualization/sanity.py +0 -117
  42. braindecode-1.5.0.dev179275821/braindecode/visualization/topology.py +0 -64
  43. braindecode-1.5.0.dev179275821/docs/index.rst +0 -749
  44. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/LICENSE.txt +0 -0
  45. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/MANIFEST.in +0 -0
  46. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/README.rst +0 -0
  47. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/__init__.py +0 -0
  48. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/augmentation/__init__.py +0 -0
  49. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/augmentation/base.py +0 -0
  50. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/augmentation/functional.py +0 -0
  51. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/augmentation/transforms.py +0 -0
  52. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/classifier.py +0 -0
  53. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/__init__.py +0 -0
  54. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bbci.py +0 -0
  55. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bcicomp.py +0 -0
  56. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/__init__.py +0 -0
  57. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/datasets.py +0 -0
  58. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/format.py +0 -0
  59. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/hub.py +0 -0
  60. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/hub_format.py +0 -0
  61. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/hub_io.py +0 -0
  62. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/hub_validation.py +0 -0
  63. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/bids/iterable.py +0 -0
  64. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/chb_mit.py +0 -0
  65. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/mne.py +0 -0
  66. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/moabb.py +0 -0
  67. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/nmt.py +0 -0
  68. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/registry.py +0 -0
  69. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/siena.py +0 -0
  70. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  71. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/tuh.py +0 -0
  72. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/utils.py +0 -0
  73. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datasets/xy.py +0 -0
  74. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datautil/__init__.py +0 -0
  75. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datautil/channel_utils.py +0 -0
  76. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datautil/hub_formats.py +0 -0
  77. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datautil/serialization.py +0 -0
  78. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/datautil/util.py +0 -0
  79. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/eegneuralnet.py +0 -0
  80. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/functional/__init__.py +0 -0
  81. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/functional/functions.py +0 -0
  82. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/functional/initialization.py +0 -0
  83. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/atcnet.py +0 -0
  84. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/attentionbasenet.py +0 -0
  85. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/attn_sleep.py +0 -0
  86. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/brainmodule.py +0 -0
  87. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/cbramod.py +0 -0
  88. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/contrawr.py +0 -0
  89. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/ctnet.py +0 -0
  90. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/deep4.py +0 -0
  91. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/deepsleepnet.py +0 -0
  92. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/dgcnn.py +0 -0
  93. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegconformer.py +0 -0
  94. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eeginception_erp.py +0 -0
  95. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eeginception_mi.py +0 -0
  96. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegitnet.py +0 -0
  97. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegminer.py +0 -0
  98. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegnet.py +0 -0
  99. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegnex.py +0 -0
  100. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegpt.py +0 -0
  101. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegsimpleconv.py +0 -0
  102. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegsym.py +0 -0
  103. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/eegtcnet.py +0 -0
  104. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/fbcnet.py +0 -0
  105. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/fblightconvnet.py +0 -0
  106. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/fbmsnet.py +0 -0
  107. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/hybrid.py +0 -0
  108. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/ifnet.py +0 -0
  109. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/luna.py +0 -0
  110. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/medformer.py +0 -0
  111. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/msvtnet.py +0 -0
  112. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/patchedtransformer.py +0 -0
  113. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sccnet.py +0 -0
  114. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/shallow_fbcsp.py +0 -0
  115. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sinc_shallow.py +0 -0
  116. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  117. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  118. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sparcnet.py +0 -0
  119. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/sstdpn.py +0 -0
  120. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/syncnet.py +0 -0
  121. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/tcn.py +0 -0
  122. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/tidnet.py +0 -0
  123. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/tsinception.py +0 -0
  124. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/models/usleep.py +0 -0
  125. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/activation.py +0 -0
  126. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/attention.py +0 -0
  127. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/blocks.py +0 -0
  128. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/convolution.py +0 -0
  129. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/filter.py +0 -0
  130. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/layers.py +0 -0
  131. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/linear.py +0 -0
  132. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/parametrization.py +0 -0
  133. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/stats.py +0 -0
  134. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/util.py +0 -0
  135. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/modules/wrapper.py +0 -0
  136. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/__init__.py +0 -0
  137. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/mne_preprocess.py +0 -0
  138. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/preprocessing/util.py +0 -0
  139. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/regressor.py +0 -0
  140. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/samplers/__init__.py +0 -0
  141. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/samplers/base.py +0 -0
  142. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/samplers/ssl.py +0 -0
  143. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/training/__init__.py +0 -0
  144. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/training/callbacks.py +0 -0
  145. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/training/losses.py +0 -0
  146. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/training/scoring.py +0 -0
  147. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/util.py +0 -0
  148. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode/visualization/confusion_matrices.py +0 -0
  149. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode.egg-info/dependency_links.txt +0 -0
  150. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/braindecode.egg-info/top_level.txt +0 -0
  151. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/Makefile +0 -0
  152. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/_templates/autosummary/class.rst +0 -0
  153. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  154. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/_templates/autosummary/function.rst +0 -0
  155. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  156. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/help.rst +0 -0
  157. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/install/install.rst +0 -0
  158. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/install/install_pip.rst +0 -0
  159. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/install/install_source.rst +0 -0
  160. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/attention.rst +0 -0
  161. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/channel.rst +0 -0
  162. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/convolution.rst +0 -0
  163. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/filterbank.rst +0 -0
  164. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/gnn.rst +0 -0
  165. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/interpretable.rst +0 -0
  166. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/lbm.rst +0 -0
  167. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/recurrent.rst +0 -0
  168. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/categorization/spd.rst +0 -0
  169. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/models.rst +0 -0
  170. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/models_categorization.rst +0 -0
  171. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/models_table.rst +0 -0
  172. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/models/models_visualization.rst +0 -0
  173. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/docs/sg_execution_times.rst +0 -0
  174. {braindecode-1.5.0.dev179275821 → braindecode-1.5.0.dev182195895}/setup.cfg +0 -0
@@ -11,14 +11,9 @@ All files within the `src/` directory are licensed under the BSD-3-Clause Licens
11
11
  The following components are licensed under the Creative Commons Attribution-NonCommercial 4.0 International License:
12
12
 
13
13
  - `braindecode/models/eegminer.py`
14
- - `braindecode/models/meta_neuromotor.py`
15
14
 
16
15
  As well as class later imported into the `braindecode.models.module` named as GeneralizedGaussianFilter.
17
16
 
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
17
  ## License Links
23
18
 
24
19
  - [BSD-3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.5.0.dev179275821
3
+ Version: 1.5.0.dev182195895
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>
@@ -43,8 +43,6 @@ Requires-Dist: eegprep[eeglabio]>=0.2.23; extra == "eegprep"
43
43
  Provides-Extra: hub
44
44
  Requires-Dist: huggingface_hub[torch]>=0.20.0; extra == "hub"
45
45
  Requires-Dist: zarr>=3.0; extra == "hub"
46
- Provides-Extra: viz
47
- Requires-Dist: captum>=0.7.0; extra == "viz"
48
46
  Provides-Extra: tests
49
47
  Requires-Dist: pytest; extra == "tests"
50
48
  Requires-Dist: pytest-cov; extra == "tests"
@@ -63,7 +61,6 @@ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
63
61
  Requires-Dist: sphinx-autobuild; extra == "docs"
64
62
  Requires-Dist: sphinxcontrib-bibtex; extra == "docs"
65
63
  Requires-Dist: sphinx_sitemap; extra == "docs"
66
- Requires-Dist: sphinxext-opengraph; extra == "docs"
67
64
  Requires-Dist: pydata_sphinx_theme; extra == "docs"
68
65
  Requires-Dist: numpydoc; extra == "docs"
69
66
  Requires-Dist: memory_profiler; extra == "docs"
@@ -73,7 +70,7 @@ Requires-Dist: sphinx_design; extra == "docs"
73
70
  Requires-Dist: lightning; extra == "docs"
74
71
  Requires-Dist: seaborn; extra == "docs"
75
72
  Requires-Dist: pre-commit; extra == "docs"
76
- Requires-Dist: openneuro-py>=2026.4.0; extra == "docs"
73
+ Requires-Dist: openneuro-py; extra == "docs"
77
74
  Requires-Dist: plotly; extra == "docs"
78
75
  Requires-Dist: shap; extra == "docs"
79
76
  Requires-Dist: nbformat; extra == "docs"
@@ -85,7 +82,6 @@ Requires-Dist: braindecode[docs]; extra == "all"
85
82
  Requires-Dist: braindecode[hub]; extra == "all"
86
83
  Requires-Dist: braindecode[eegprep]; extra == "all"
87
84
  Requires-Dist: braindecode[typing]; extra == "all"
88
- Requires-Dist: braindecode[viz]; extra == "all"
89
85
  Dynamic: license-file
90
86
 
91
87
  .. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.17699192.svg
@@ -18,7 +18,7 @@ import shutil
18
18
  import warnings
19
19
  from abc import abstractmethod
20
20
  from collections import Counter
21
- from collections.abc import Callable, Hashable
21
+ from collections.abc import Callable
22
22
  from glob import glob
23
23
  from pathlib import Path
24
24
  from typing import Any, Generic, Iterable, no_type_check
@@ -1340,124 +1340,6 @@ class BaseConcatDataset(ConcatDataset, HubDatasetMixin, Generic[T]):
1340
1340
  raise TypeError("target_transform must be a callable.")
1341
1341
  self._target_transform = fn
1342
1342
 
1343
- def set_target(self, column: Hashable) -> "BaseConcatDataset":
1344
- """Use ``column`` as the target ``y`` for every subdataset.
1345
-
1346
- Dispatches on the subdataset type:
1347
-
1348
- * For :class:`WindowsDataset` / :class:`EEGWindowsDataset`,
1349
- ``column`` is looked up in per-window ``metadata`` first, then in
1350
- the per-record ``description`` (broadcast to every window). The
1351
- resolved values overwrite ``ds.metadata['target']`` and ``ds.y``.
1352
- For :class:`WindowsDataset`, the underlying ``ds.windows.metadata``
1353
- is kept in sync so ``get_metadata()`` and the repr reflect the
1354
- new target.
1355
- * For :class:`RawDataset`, ``column`` must exist on the
1356
- ``description``. ``ds.target_name`` is set to ``column`` so
1357
- ``__getitem__`` reads ``description[column]`` as ``y`` on every
1358
- access — no rebuild needed.
1359
-
1360
- Parameters
1361
- ----------
1362
- column : Hashable
1363
- Name of a metadata column or description field (BIDS entity,
1364
- participants.tsv extra, ...). Typically a string, but any
1365
- hashable that pandas accepts as a column label is allowed.
1366
-
1367
- Returns
1368
- -------
1369
- self : BaseConcatDataset
1370
-
1371
- Raises
1372
- ------
1373
- TypeError
1374
- If any subdataset is not a :class:`WindowsDataset`,
1375
- :class:`EEGWindowsDataset`, or :class:`RawDataset`, or if a
1376
- windowed subdataset has lazy (non-DataFrame) metadata.
1377
- ValueError
1378
- If ``column`` is not present on a subdataset's metadata or
1379
- description, or if a windowed subdataset has
1380
- ``targets_from='channels'`` (which would make this a silent
1381
- no-op since ``__getitem__`` reads y from misc channels, not
1382
- from ``metadata['target']``).
1383
- """
1384
- for i, ds in enumerate(self.datasets):
1385
- if isinstance(ds, (WindowsDataset, EEGWindowsDataset)):
1386
- if not isinstance(ds.metadata, pd.DataFrame):
1387
- # _LazyDataFrame (lazy_metadata=True) does not implement
1388
- # .copy()/__setitem__, so the in-place write below would
1389
- # raise AttributeError. Surface the precondition cleanly.
1390
- raise TypeError(
1391
- "set_target requires a materialized metadata "
1392
- f"DataFrame; datasets[{i}].metadata is "
1393
- f"{type(ds.metadata).__name__}. Re-window with "
1394
- "lazy_metadata=False to use set_target."
1395
- )
1396
- if getattr(ds, "targets_from", "metadata") != "metadata":
1397
- # __getitem__ would read y from misc channels; writing
1398
- # metadata['target']/ds.y would be a silent no-op.
1399
- raise ValueError(
1400
- f"datasets[{i}] has targets_from="
1401
- f"{ds.targets_from!r}; set_target only applies when "
1402
- "targets_from='metadata' (otherwise __getitem__ "
1403
- "derives y from misc channels and would ignore the "
1404
- "rewritten target column)."
1405
- )
1406
- n = len(ds)
1407
- md = ds.metadata
1408
- if column in md.columns:
1409
- values = md[column].iloc[:n].to_list()
1410
- elif (
1411
- isinstance(ds.description, pd.Series)
1412
- and column in ds.description.index
1413
- ):
1414
- values = [ds.description[column]] * n
1415
- else:
1416
- desc_keys = (
1417
- list(ds.description.index)
1418
- if isinstance(ds.description, pd.Series)
1419
- else []
1420
- )
1421
- raise ValueError(
1422
- f"Column {column!r} not found on datasets[{i}]: "
1423
- f"metadata cols={list(md.columns)}, "
1424
- f"description keys={desc_keys}."
1425
- )
1426
- # In-place write so the WindowsDataset's metadata and the
1427
- # underlying mne.Epochs.metadata (which start as the same
1428
- # object reference) both reflect the new target. Defensive
1429
- # second write covers the case where they got de-aliased
1430
- # earlier by a caller-side reassignment.
1431
- md["target"] = values
1432
- windows_obj = getattr(ds, "_windows", None)
1433
- if windows_obj is not None and windows_obj.metadata is not md:
1434
- windows_obj.metadata["target"] = values
1435
- # values is already a fresh list (Series.to_list() / [x] * n);
1436
- # no defensive copy needed — pandas keeps its own representation
1437
- # for md["target"] so mutating ds.y won't reach back into it.
1438
- ds.y = values
1439
- elif isinstance(ds, RawDataset):
1440
- if (
1441
- not isinstance(ds.description, pd.Series)
1442
- or column not in ds.description.index
1443
- ):
1444
- desc_keys = (
1445
- list(ds.description.index)
1446
- if isinstance(ds.description, pd.Series)
1447
- else []
1448
- )
1449
- raise ValueError(
1450
- f"Column {column!r} not found on datasets[{i}] "
1451
- f"description (keys={desc_keys})."
1452
- )
1453
- ds.target_name = column
1454
- else:
1455
- raise TypeError(
1456
- "set_target requires WindowsDataset, EEGWindowsDataset, "
1457
- f"or RawDataset; datasets[{i}] is {type(ds).__name__}."
1458
- )
1459
- return self
1460
-
1461
1343
  def _outdated_save(self, path, overwrite=False):
1462
1344
  """This is a copy of the old saving function, that had inconsistent.
1463
1345
 
@@ -6,12 +6,10 @@
6
6
  from __future__ import annotations
7
7
 
8
8
  import os
9
- import time
10
9
 
11
10
  import mne
12
11
  import numpy as np
13
12
  import pandas as pd
14
- import requests
15
13
  from mne.datasets.sleep_physionet.age import fetch_data
16
14
 
17
15
  from .base import BaseConcatDataset, RawDataset
@@ -61,19 +59,7 @@ class SleepPhysionet(BaseConcatDataset):
61
59
  if recording_ids is None:
62
60
  recording_ids = [1, 2]
63
61
 
64
- max_attempts = 5
65
- retry_delay_s = 10
66
-
67
- for attempt in range(max_attempts):
68
- try:
69
- paths = fetch_data(
70
- subject_ids, recording=recording_ids, on_missing="warn"
71
- )
72
- break
73
- except requests.exceptions.RequestException:
74
- if attempt == max_attempts - 1:
75
- raise
76
- time.sleep(retry_delay_s)
62
+ paths = fetch_data(subject_ids, recording=recording_ids, on_missing="warn")
77
63
 
78
64
  all_base_ds = list()
79
65
  for p in paths:
@@ -4,11 +4,10 @@ from .atcnet import ATCNet
4
4
  from .attentionbasenet import AttentionBaseNet
5
5
  from .attn_sleep import AttnSleep
6
6
  from .base import EEGModuleMixin
7
- from .bendr import BENDR, InterpolatedBENDR
8
- from .biot import BIOT, InterpolatedBIOT
7
+ from .bendr import BENDR
8
+ from .biot import BIOT
9
9
  from .brainmodule import BrainModule
10
10
  from .cbramod import CBraMod
11
- from .codebrain import CodeBrain
12
11
  from .contrawr import ContraWR
13
12
  from .ctnet import CTNet
14
13
  from .deep4 import Deep4Net
@@ -25,24 +24,20 @@ from .eegpt import EEGPT
25
24
  from .eegsimpleconv import EEGSimpleConv
26
25
  from .eegsym import EEGSym
27
26
  from .eegtcnet import EEGTCNet
28
- from .emg2qwerty import EMG2QwertyNet
29
27
  from .fbcnet import FBCNet
30
28
  from .fblightconvnet import FBLightConvNet
31
29
  from .fbmsnet import FBMSNet
32
30
  from .hybrid import HybridNet
33
31
  from .ifnet import IFNet
34
- from .interpolated import InterpolatedModel
35
- from .labram import InterpolatedLaBraM, Labram
32
+ from .labram import Labram
36
33
  from .luna import LUNA
37
34
  from .medformer import MEDFormer
38
- from .meta_neuromotor import MetaNeuromotorHand
39
35
  from .msvtnet import MSVTNet
40
36
  from .patchedtransformer import PBT
41
37
  from .reve import REVE
42
38
  from .sccnet import SCCNet
43
39
  from .shallow_fbcsp import ShallowFBCSPNet
44
40
  from .signal_jepa import (
45
- InterpolatedSignalJEPA,
46
41
  SignalJEPA,
47
42
  SignalJEPA_Contextual,
48
43
  SignalJEPA_PostLocal,
@@ -77,7 +72,6 @@ __all__ = [
77
72
  "BIOT",
78
73
  "BENDR",
79
74
  "CBraMod",
80
- "CodeBrain",
81
75
  "ContraWR",
82
76
  "CTNet",
83
77
  "Deep4Net",
@@ -96,18 +90,11 @@ __all__ = [
96
90
  "EEGSimpleConv",
97
91
  "EEGTCNet",
98
92
  "DGCNN",
99
- "EMG2QwertyNet",
100
93
  "FBCNet",
101
94
  "FBLightConvNet",
102
95
  "FBMSNet",
103
- "MetaNeuromotorHand",
104
96
  "HybridNet",
105
97
  "IFNet",
106
- "InterpolatedBENDR",
107
- "InterpolatedBIOT",
108
- "InterpolatedLaBraM",
109
- "InterpolatedModel",
110
- "InterpolatedSignalJEPA",
111
98
  "Labram",
112
99
  "LUNA",
113
100
  "extract_channel_locations_from_chs_info",
@@ -33,25 +33,13 @@ huggingface_hub = _soft_import(
33
33
  HAS_HF_HUB = huggingface_hub is not False
34
34
 
35
35
 
36
- _HF_INSTALL_HINT = (
37
- "requires the `huggingface_hub` package. "
38
- "Install with: pip install 'braindecode[hub]'"
39
- )
40
-
41
-
42
- class _BaseHubMixinStub:
43
- @classmethod
44
- def from_pretrained(cls, *args, **kwargs):
45
- raise ImportError(f"{cls.__name__}.from_pretrained() {_HF_INSTALL_HINT}")
46
-
47
- def push_to_hub(self, *args, **kwargs):
48
- raise ImportError(f"{type(self).__name__}.push_to_hub() {_HF_INSTALL_HINT}")
36
+ class _BaseHubMixin:
37
+ pass
49
38
 
50
39
 
51
40
  # Define base class for hub mixin
52
- _BaseHubMixin: Type = (
53
- huggingface_hub.PyTorchModelHubMixin if HAS_HF_HUB else _BaseHubMixinStub
54
- )
41
+ if HAS_HF_HUB:
42
+ _BaseHubMixin: Type = huggingface_hub.PyTorchModelHubMixin # type: ignore
55
43
 
56
44
 
57
45
  def deprecated_args(obj, *old_new_args):
@@ -1,60 +1,12 @@
1
1
  import copy
2
2
 
3
- import numpy as np
4
3
  import torch
5
4
  from einops.layers.torch import Rearrange
6
5
  from torch import nn
6
+ from torch.nn.utils.parametrize import register_parametrization
7
7
 
8
8
  from braindecode.models.base import EEGModuleMixin
9
-
10
- # The 20 channels used to pre-train BENDR, in the order expected by the
11
- # `braindecode/braindecode-bendr` checkpoint. The first 19 entries are the
12
- # EEG channels taken verbatim from `dn3.transforms.instance.To1020.EEG_20_div`
13
- # (https://github.com/SPOClab-ca/dn3/blob/master/dn3/transforms/instance.py).
14
- # Their positions come from MNE's ``standard_1005`` montage (T5/T6 are
15
- # legacy names that share positions with P7/P8 there).
16
- #
17
- # The 20th entry is ``SCALE``, a relative-amplitude statistic (not an
18
- # electrode) appended by ``To1020(include_scale_ch=True)`` during
19
- # pre-training. Since it has no physical position, the ``loc`` below is
20
- # the centroid of the 19 EEG positions — purely a placeholder so that
21
- # :class:`~braindecode.modules.ChannelInterpolationLayer` (used by
22
- # :class:`InterpolatedBENDR`) can build a valid spline interpolation
23
- # matrix. It is NOT the SCALE the pre-training pipeline computes
24
- # (which is an RMS-like amplitude via ``dn3.MappingDeep1010``); users
25
- # who need a faithful SCALE must compute it themselves and feed 20
26
- # channels to :class:`BENDR` directly.
27
- _BENDR_TARGET_CHS_TUPLES: list[tuple[str, tuple[float, float, float]]] = [
28
- ("FP1", (-0.0294367, +0.0839171, -0.0069900)), # standard_1005
29
- ("FP2", (+0.0298723, +0.0848959, -0.0070800)), # standard_1005
30
- ("F7", (-0.0702629, +0.0424743, -0.0114200)), # standard_1005
31
- ("F3", (-0.0502438, +0.0531112, +0.0421920)), # standard_1005
32
- ("FZ", (+0.0003122, +0.0585120, +0.0664620)), # standard_1005
33
- ("F4", (+0.0518362, +0.0543048, +0.0408140)), # standard_1005
34
- ("F8", (+0.0730431, +0.0444217, -0.0120000)), # standard_1005
35
- ("T7", (-0.0841611, -0.0160187, -0.0093460)), # standard_1005
36
- ("C3", (-0.0653581, -0.0116317, +0.0643580)), # standard_1005
37
- ("CZ", (+0.0004009, -0.0091670, +0.1002440)), # standard_1005
38
- ("C4", (+0.0671179, -0.0109003, +0.0635800)), # standard_1005
39
- ("T8", (+0.0850799, -0.0150203, -0.0094900)), # standard_1005
40
- ("T5", (-0.0724343, -0.0734527, -0.0024870)), # standard_1005 (= P7)
41
- ("P3", (-0.0530073, -0.0787878, +0.0559400)), # standard_1005
42
- ("PZ", (+0.0003247, -0.0811150, +0.0826150)), # standard_1005
43
- ("P4", (+0.0556667, -0.0785602, +0.0565610)), # standard_1005
44
- ("T6", (+0.0730557, -0.0730683, -0.0025400)), # standard_1005 (= P8)
45
- ("O1", (-0.0294134, -0.1124490, +0.0088390)), # standard_1005
46
- ("O2", (+0.0298426, -0.1121560, +0.0088000)), # standard_1005
47
- (
48
- "SCALE",
49
- (+0.0006439, -0.0131942, +0.0278448),
50
- ), # centroid of the 19 EEG positions (placeholder; see comment above)
51
- ]
52
-
53
- _BENDR_TARGET_CHS_INFO: list[dict] = [
54
- {"ch_name": ch, "kind": "eeg", "loc": np.asarray(loc, dtype=float)}
55
- for ch, loc in _BENDR_TARGET_CHS_TUPLES
56
- ]
57
- BENDR_CHANNEL_ORDER: list[str] = [ch for ch, _ in _BENDR_TARGET_CHS_TUPLES]
9
+ from braindecode.modules.parametrization import MaxNormParametrize
58
10
 
59
11
 
60
12
  class BENDR(EEGModuleMixin, nn.Module):
@@ -243,6 +195,15 @@ class BENDR(EEGModuleMixin, nn.Module):
243
195
  The contextualizer is still created (to allow loading pretrained weights) but is not
244
196
  used in the forward pass. Requires input length of at least
245
197
  ``4 * product(enc_downsample)`` samples (384 with default downsampling of 96x).
198
+ n_chans_pretrained : int or None, default=None
199
+ Number of input channels the pretrained weights expect (20 for the official BENDR
200
+ checkpoint). When set and ``n_chans != n_chans_pretrained``, a 1x1 Conv1d with
201
+ max-norm constraint projects from ``n_chans`` to ``n_chans_pretrained`` before the
202
+ encoder. This allows fine-tuning pretrained BENDR on datasets with arbitrary channel
203
+ counts. When using ``from_pretrained``, pass ``strict=False`` since the checkpoint
204
+ will not contain ``channel_projection`` weights.
205
+ chan_proj_max_norm : float, default=1.0
206
+ Max-norm constraint value for the channel projection weights.
246
207
  """
247
208
 
248
209
  def __init__(
@@ -270,6 +231,8 @@ class BENDR(EEGModuleMixin, nn.Module):
270
231
  start_token=-5, # Value for start token embedding
271
232
  final_layer=True, # Whether to include the final linear layer
272
233
  encoder_only=False, # If True, bypass contextualizer and use 4-chunk pooling
234
+ n_chans_pretrained=None, # Expected input channels of pretrained weights
235
+ chan_proj_max_norm=1.0, # Max-norm for channel projection weights
273
236
  ):
274
237
  super().__init__(
275
238
  n_outputs=n_outputs,
@@ -283,34 +246,25 @@ class BENDR(EEGModuleMixin, nn.Module):
283
246
  # Keep these parameters if needed later, otherwise they are captured by the mixin
284
247
  del n_outputs, n_chans, chs_info, n_times, input_window_seconds, sfreq
285
248
 
286
- # If the user supplies chs_info, require it to match BENDR_CHANNEL_ORDER
287
- # exactly (case-insensitive). Arbitrary channel sets should go through
288
- # InterpolatedBENDR — same pattern as Labram / InterpolatedLaBraM.
289
- # When chs_info is absent (the usual n_chans=20 path, incl.
290
- # from_pretrained), no check is performed.
291
- try:
292
- _chs_info = self.chs_info
293
- except ValueError:
294
- _chs_info = None
295
- if _chs_info is not None:
296
- user_names = [ch["ch_name"] for ch in _chs_info] # type: ignore[index]
297
- canonical = BENDR_CHANNEL_ORDER
298
- if [n.lower() for n in user_names] != [n.lower() for n in canonical]:
299
- raise ValueError(
300
- f"BENDR requires chs_info to match BENDR_CHANNEL_ORDER exactly "
301
- f"({len(canonical)} channels, specific order; last is 'SCALE'). "
302
- f"Got {len(user_names)} channel(s). For arbitrary channel sets, "
303
- f"use InterpolatedBENDR "
304
- f"(from braindecode.models import InterpolatedBENDR)."
305
- )
306
-
307
249
  self.encoder_h = encoder_h
308
250
  self.contextualizer_hidden = contextualizer_hidden
309
251
  self.include_final_layer = final_layer
310
252
  self.encoder_only = encoder_only
311
253
 
254
+ # Channel projection for pretrained weight compatibility
255
+ encoder_n_chans = self.n_chans
256
+ if n_chans_pretrained is not None and self.n_chans != n_chans_pretrained:
257
+ conv = nn.Conv1d(self.n_chans, n_chans_pretrained, 1, bias=False)
258
+ register_parametrization(
259
+ conv, "weight", MaxNormParametrize(chan_proj_max_norm)
260
+ )
261
+ self.channel_projection = conv
262
+ encoder_n_chans = n_chans_pretrained
263
+ else:
264
+ self.channel_projection = None
265
+
312
266
  self.encoder = _ConvEncoderBENDR(
313
- in_features=self.n_chans,
267
+ in_features=encoder_n_chans,
314
268
  encoder_h=encoder_h,
315
269
  dropout=drop_prob,
316
270
  projection_head=projection_head,
@@ -354,6 +308,8 @@ class BENDR(EEGModuleMixin, nn.Module):
354
308
  self._build_head(n_outputs)
355
309
 
356
310
  def forward(self, x, return_features=False):
311
+ if self.channel_projection is not None:
312
+ x = self.channel_projection(x)
357
313
  encoded = self.encoder(x)
358
314
  # encoded: [batch_size, encoder_h, n_encoded_times]
359
315
 
@@ -596,23 +552,3 @@ class _BENDRContextualizer(nn.Module):
596
552
  # x: [batch_size, in_features, seq_len + 1]
597
553
 
598
554
  return x
599
-
600
-
601
- # -----------------------------------------------------------------------------
602
- # InterpolatedBENDR — experimental channel-interpolation variant of BENDR
603
- # -----------------------------------------------------------------------------
604
- # Wraps :class:`BENDR` with an MNE-backed channel-interpolation layer that
605
- # projects arbitrary user ``chs_info`` to the canonical 20-channel BENDR
606
- # input (:data:`_BENDR_TARGET_CHS_INFO` — the 19 pre-training EEG channels
607
- # plus a ``SCALE`` placeholder at the centroid of those 19 positions).
608
- # Frozen by default; set ``trainable=True`` to fine-tune the projection.
609
- #
610
- # NOTE: the ``SCALE`` target has no physical position, so the row of the
611
- # interpolation matrix that produces it is a spatial spline of the user's
612
- # EEG channels — *not* the dn3 ``MappingDeep1010`` RMS statistic the
613
- # checkpoint saw during pre-training. Expect degraded zero-shot transfer
614
- # from the SCALE channel; downstream fine-tuning should still work.
615
-
616
- from braindecode.models.interpolated import InterpolatedModel # noqa: E402
617
-
618
- InterpolatedBENDR = InterpolatedModel(BENDR, _BENDR_TARGET_CHS_INFO)
@@ -1,57 +1,12 @@
1
1
  import math
2
2
  from warnings import warn
3
3
 
4
- import numpy as np
5
4
  import torch
6
5
  import torch.nn as nn
7
6
  from linear_attention_transformer import LinearAttentionTransformer
8
7
 
9
8
  from braindecode.models.base import EEGModuleMixin
10
9
 
11
- # -----------------------------------------------------------------------------
12
- # Canonical channel order for InterpolatedBIOT — the 18-channel TCP bipolar
13
- # montage used by BIOT's shhs-prest and six-datasets pretrained checkpoints.
14
- # Source: https://github.com/ycq091044/BIOT (README + datasets/TUAB/process.py
15
- # + datasets/SHHS/process.py). Indices 0-15 are the TCP 16-channel bipolar
16
- # derivations; indices 16-17 are SHHS differential channels.
17
- #
18
- # The `loc` values are only used to build an MNE interpolation matrix for
19
- # InterpolatedBIOT. All entries are bipolar / differential derivations.
20
- # TODO: positions are stored as the midpoint of the two constituent
21
- # electrodes. This is a simplification — a bipolar signal V(A)-V(B) cannot
22
- # be faithfully recovered by spatial interpolation at the midpoint. Revisit
23
- # in a follow-up PR (e.g. a dedicated BipolarDerivationLayer).
24
- # -----------------------------------------------------------------------------
25
-
26
- # fmt: off
27
- _BIOT_TARGET_CHS_TUPLES: list[tuple[str, tuple[float, float, float]]] = [
28
- ("FP1-F7", (-0.04984980, 0.06319570, -0.00920500)),
29
- ("F7-T7", (-0.07721200, 0.01322780, -0.01038300)),
30
- ("T7-P7", (-0.07829770, -0.04473570, -0.00591650)),
31
- ("P7-O1", (-0.05092385, -0.09295085, 0.00317600)),
32
- ("FP2-F8", (0.05145770, 0.06465880, -0.00954000)),
33
- ("F8-T8", (0.07906150, 0.01470070, -0.01074500)),
34
- ("T8-P8", (0.07906780, -0.04404430, -0.00601500)),
35
- ("P8-O2", (0.05144915, -0.09261215, 0.00313000)),
36
- ("FP1-F3", (-0.03984025, 0.06851415, 0.01760100)),
37
- ("F3-C3", (-0.05780095, 0.02073975, 0.05327500)),
38
- ("C3-P3", (-0.05918270, -0.04520975, 0.06014900)),
39
- ("P3-O1", (-0.04121035, -0.09561840, 0.03238950)),
40
- ("FP2-F4", (0.04085425, 0.06960035, 0.01686700)),
41
- ("F4-C4", (0.05947705, 0.02170225, 0.05219700)),
42
- ("C4-P4", (0.06139230, -0.04473025, 0.06007050)),
43
- ("P4-O2", (0.04275465, -0.09535810, 0.03268050)),
44
- ("C3-A2", (0.01021790, -0.01832050, -0.00183650)),
45
- ("C4-A1", (-0.00947910, -0.01794500, -0.00220300)),
46
- ]
47
- # fmt: on
48
-
49
- _BIOT_TARGET_CHS_INFO = [
50
- {"ch_name": ch, "kind": "eeg", "loc": np.asarray(loc, dtype=float)}
51
- for ch, loc in _BIOT_TARGET_CHS_TUPLES
52
- ]
53
- BIOT_CHANNEL_ORDER = [ch for ch, _ in _BIOT_TARGET_CHS_TUPLES]
54
-
55
10
 
56
11
  class BIOT(EEGModuleMixin, nn.Module):
57
12
  r"""BIOT from Yang et al (2023) [Yang2023]_
@@ -484,9 +439,7 @@ class _BIOTEncoder(nn.Module):
484
439
  self.channel_tokens = nn.Embedding(
485
440
  num_embeddings=n_chans, embedding_dim=emb_size
486
441
  )
487
- self.register_buffer(
488
- "index", torch.arange(n_chans, dtype=torch.long), persistent=False
489
- )
442
+ self.register_buffer("index", torch.arange(n_chans, dtype=torch.long))
490
443
 
491
444
  def stft(self, sample):
492
445
  """
@@ -600,16 +553,3 @@ class _BIOTEncoder(nn.Module):
600
553
  # (batch_size, emb)
601
554
  emb = self.transformer(emb).mean(dim=1)
602
555
  return emb
603
-
604
-
605
- # -----------------------------------------------------------------------------
606
- # InterpolatedBIOT — experimental channel-interpolation variant of BIOT
607
- # -----------------------------------------------------------------------------
608
- # Wraps :class:`BIOT` with an MNE-backed channel-interpolation layer that
609
- # projects arbitrary user ``chs_info`` to the canonical 18-channel BIOT
610
- # montage (:data:`_BIOT_TARGET_CHS_INFO`). Frozen by default; set
611
- # ``trainable=True`` to fine-tune the projection matrix.
612
-
613
- from braindecode.models.interpolated import InterpolatedModel # noqa: E402
614
-
615
- InterpolatedBIOT = InterpolatedModel(BIOT, _BIOT_TARGET_CHS_INFO)
@@ -1,4 +1,3 @@
1
- # Authors: Sarthak Tayal <sarthaktayal2@gmail.com>
2
1
  from collections.abc import Callable
3
2
  from inspect import signature
4
3
  from types import UnionType
@@ -18,10 +17,10 @@ from braindecode.models.util import (
18
17
 
19
18
  try:
20
19
  from numpydantic import NDArray, Shape
21
-
22
- _loc_type = NDArray[Shape["12"], np.float64]
23
20
  except ImportError:
24
- _loc_type = np.ndarray # type: ignore[misc]
21
+ # we can't use soft import for numpydantic because numpydantic does not define its version in __init__
22
+ NDArray = Any # type: ignore
23
+ Shape = Any # type: ignore
25
24
 
26
25
 
27
26
  class ChsInfoType(TypedDict, total=False, closed=True): # type: ignore[call-arg]
@@ -30,7 +29,7 @@ class ChsInfoType(TypedDict, total=False, closed=True): # type: ignore[call-arg
30
29
  coil_type: int
31
30
  coord_frame: int
32
31
  kind: str
33
- loc: _loc_type # type: ignore[valid-type,misc]
32
+ loc: NDArray[Shape["12"], np.float64] # type: ignore[misc]
34
33
  logno: int
35
34
  range: float
36
35
  scanno: int