Braindecode 1.3.2.dev181313884__tar.gz → 1.3.2.dev182544824__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. {braindecode-1.3.2.dev181313884/braindecode.egg-info → braindecode-1.3.2.dev182544824}/PKG-INFO +1 -1
  2. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/base.py +6 -101
  3. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/bendr.py +6 -17
  4. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/biot.py +5 -23
  5. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/cbramod.py +11 -19
  6. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eegpt.py +2 -15
  7. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/labram.py +1 -15
  8. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/reve.py +20 -36
  9. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/signal_jepa.py +13 -52
  10. braindecode-1.3.2.dev182544824/braindecode/version.py +1 -0
  11. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824/braindecode.egg-info}/PKG-INFO +1 -1
  12. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/conf.py +7 -0
  13. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/whats_new.rst +0 -26
  14. braindecode-1.3.2.dev181313884/braindecode/version.py +0 -1
  15. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/LICENSE.txt +0 -0
  16. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/MANIFEST.in +0 -0
  17. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/NOTICE.txt +0 -0
  18. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/README.rst +0 -0
  19. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/__init__.py +0 -0
  20. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/augmentation/__init__.py +0 -0
  21. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/augmentation/base.py +0 -0
  22. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/augmentation/functional.py +0 -0
  23. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/augmentation/transforms.py +0 -0
  24. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/classifier.py +0 -0
  25. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/__init__.py +0 -0
  26. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/base.py +0 -0
  27. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/bbci.py +0 -0
  28. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/bcicomp.py +0 -0
  29. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/bids/__init__.py +0 -0
  30. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/bids/datasets.py +0 -0
  31. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/bids/format.py +0 -0
  32. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/bids/hub.py +0 -0
  33. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/bids/hub_format.py +0 -0
  34. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/bids/hub_io.py +0 -0
  35. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/bids/hub_validation.py +0 -0
  36. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/bids/iterable.py +0 -0
  37. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/chb_mit.py +0 -0
  38. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/mne.py +0 -0
  39. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/moabb.py +0 -0
  40. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/nmt.py +0 -0
  41. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/registry.py +0 -0
  42. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/siena.py +0 -0
  43. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  44. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/sleep_physionet.py +0 -0
  45. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/tuh.py +0 -0
  46. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/utils.py +0 -0
  47. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datasets/xy.py +0 -0
  48. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datautil/__init__.py +0 -0
  49. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datautil/channel_utils.py +0 -0
  50. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datautil/hub_formats.py +0 -0
  51. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datautil/serialization.py +0 -0
  52. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/datautil/util.py +0 -0
  53. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/eegneuralnet.py +0 -0
  54. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/functional/__init__.py +0 -0
  55. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/functional/functions.py +0 -0
  56. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/functional/initialization.py +0 -0
  57. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/__init__.py +0 -0
  58. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/atcnet.py +0 -0
  59. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/attentionbasenet.py +0 -0
  60. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/attn_sleep.py +0 -0
  61. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/brainmodule.py +0 -0
  62. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/config.py +0 -0
  63. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/contrawr.py +0 -0
  64. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/ctnet.py +0 -0
  65. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/deep4.py +0 -0
  66. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/deepsleepnet.py +0 -0
  67. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/dgcnn.py +0 -0
  68. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eegconformer.py +0 -0
  69. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eeginception_erp.py +0 -0
  70. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eeginception_mi.py +0 -0
  71. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eegitnet.py +0 -0
  72. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eegminer.py +0 -0
  73. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eegnet.py +0 -0
  74. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eegnex.py +0 -0
  75. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eegsimpleconv.py +0 -0
  76. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eegsym.py +0 -0
  77. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/eegtcnet.py +0 -0
  78. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/fbcnet.py +0 -0
  79. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/fblightconvnet.py +0 -0
  80. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/fbmsnet.py +0 -0
  81. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/hybrid.py +0 -0
  82. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/ifnet.py +0 -0
  83. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/luna.py +0 -0
  84. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/medformer.py +0 -0
  85. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/msvtnet.py +0 -0
  86. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/patchedtransformer.py +0 -0
  87. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/sccnet.py +0 -0
  88. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/shallow_fbcsp.py +0 -0
  89. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/sinc_shallow.py +0 -0
  90. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  91. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  92. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/sparcnet.py +0 -0
  93. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/sstdpn.py +0 -0
  94. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/summary.csv +0 -0
  95. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/syncnet.py +0 -0
  96. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/tcn.py +0 -0
  97. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/tidnet.py +0 -0
  98. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/tsinception.py +0 -0
  99. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/usleep.py +0 -0
  100. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/models/util.py +0 -0
  101. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/__init__.py +0 -0
  102. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/activation.py +0 -0
  103. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/attention.py +0 -0
  104. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/blocks.py +0 -0
  105. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/convolution.py +0 -0
  106. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/filter.py +0 -0
  107. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/layers.py +0 -0
  108. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/linear.py +0 -0
  109. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/parametrization.py +0 -0
  110. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/stats.py +0 -0
  111. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/util.py +0 -0
  112. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/modules/wrapper.py +0 -0
  113. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/preprocessing/__init__.py +0 -0
  114. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  115. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/preprocessing/mne_preprocess.py +0 -0
  116. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/preprocessing/preprocess.py +0 -0
  117. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/preprocessing/util.py +0 -0
  118. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/preprocessing/windowers.py +0 -0
  119. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/regressor.py +0 -0
  120. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/samplers/__init__.py +0 -0
  121. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/samplers/base.py +0 -0
  122. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/samplers/ssl.py +0 -0
  123. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/training/__init__.py +0 -0
  124. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/training/callbacks.py +0 -0
  125. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/training/losses.py +0 -0
  126. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/training/scoring.py +0 -0
  127. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/util.py +0 -0
  128. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/visualization/__init__.py +0 -0
  129. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/visualization/confusion_matrices.py +0 -0
  130. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode/visualization/gradients.py +0 -0
  131. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode.egg-info/SOURCES.txt +0 -0
  132. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode.egg-info/dependency_links.txt +0 -0
  133. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode.egg-info/requires.txt +0 -0
  134. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/braindecode.egg-info/top_level.txt +0 -0
  135. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/Makefile +0 -0
  136. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/_templates/autosummary/class.rst +0 -0
  137. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  138. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/_templates/autosummary/function.rst +0 -0
  139. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  140. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/api.rst +0 -0
  141. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/cite.rst +0 -0
  142. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/help.rst +0 -0
  143. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/index.rst +0 -0
  144. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/install/install.rst +0 -0
  145. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/install/install_pip.rst +0 -0
  146. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/install/install_source.rst +0 -0
  147. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/categorization/attention.rst +0 -0
  148. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/categorization/channel.rst +0 -0
  149. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/categorization/convolution.rst +0 -0
  150. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/categorization/filterbank.rst +0 -0
  151. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/categorization/gnn.rst +0 -0
  152. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/categorization/interpretable.rst +0 -0
  153. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/categorization/lbm.rst +0 -0
  154. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/categorization/recurrent.rst +0 -0
  155. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/categorization/spd.rst +0 -0
  156. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/models.rst +0 -0
  157. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/models_categorization.rst +0 -0
  158. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/models_table.rst +0 -0
  159. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/models/models_visualization.rst +0 -0
  160. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/docs/sg_execution_times.rst +0 -0
  161. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/pyproject.toml +0 -0
  162. {braindecode-1.3.2.dev181313884 → braindecode-1.3.2.dev182544824}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.3.2.dev181313884
3
+ Version: 1.3.2.dev182544824
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>
@@ -59,25 +59,7 @@ def deprecated_args(obj, *old_new_args):
59
59
  return out_args
60
60
 
61
61
 
62
- class _BraindecodeDocstringMeta(NumpyDocstringInheritanceInitMeta):
63
- """Defer ``__init__`` wrapping until after docstring inheritance.
64
-
65
- ``NumpyDocstringInheritanceInitMeta`` uses ``inspect.unwrap()``
66
- internally, which bypasses ``@wraps`` wrappers. By wrapping
67
- ``__init__`` *after* docstring processing, the metaclass sees the
68
- unwrapped function and correctly inherits ``cls.__doc__``.
69
- """
70
-
71
- def __init__(cls, class_name, class_bases, class_dict):
72
- super().__init__(class_name, class_bases, class_dict)
73
- # Only wrap subclass __init__s, not EEGModuleMixin itself.
74
- # Wrapping the mixin would cause super().__init__() calls to
75
- # overwrite _braindecode_init_kwargs captured by the subclass.
76
- if any(isinstance(b, _BraindecodeDocstringMeta) for b in class_bases):
77
- track_model_init_kwargs(cls)
78
-
79
-
80
- class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
62
+ class EEGModuleMixin(_BaseHubMixin, metaclass=NumpyDocstringInheritanceInitMeta):
81
63
  """
82
64
  Mixin class for all EEG models in braindecode.
83
65
 
@@ -162,8 +144,8 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
162
144
 
163
145
  def __init_subclass__(cls, **kwargs):
164
146
  # Append model-specific Hub integration notes to the docstring.
165
- # This runs before the metaclass __init__, so the Hub notes will
166
- # be included in the docstring that the metaclass processes.
147
+ # This runs after the metaclass, so we concatenate rather than
148
+ # override any existing Notes section in the subclass.
167
149
  if cls.__doc__ is not None:
168
150
  hub_notes = cls._HUB_NOTES_TEMPLATE.format(
169
151
  name=cls.__name__,
@@ -173,6 +155,7 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
173
155
 
174
156
  if not HAS_HF_HUB:
175
157
  super().__init_subclass__(**kwargs)
158
+ track_model_init_kwargs(cls)
176
159
  return
177
160
 
178
161
  base_tags = ["braindecode", cls.__name__]
@@ -212,6 +195,7 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
212
195
  coders=coders,
213
196
  **kwargs,
214
197
  )
198
+ track_model_init_kwargs(cls)
215
199
 
216
200
  def __init__(
217
201
  self,
@@ -442,34 +426,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
442
426
  resolve_type_kwargs(cls, config)
443
427
  return cls(**config)
444
428
 
445
- def reset_head(self, n_outputs):
446
- """Replace the classification head for a new number of outputs.
447
-
448
- This is called automatically by :meth:`from_pretrained` when the
449
- user passes an ``n_outputs`` that differs from the saved config.
450
- Override in subclasses that need a model-specific head structure.
451
-
452
- Parameters
453
- ----------
454
- n_outputs : int
455
- New number of output classes.
456
-
457
- Examples
458
- --------
459
- >>> from braindecode.models import BENDR
460
- >>> model = BENDR(n_chans=22, n_times=1000, n_outputs=4)
461
- >>> model.reset_head(10)
462
- >>> model.n_outputs
463
- 10
464
-
465
- .. versionadded:: 1.4
466
- """
467
- raise NotImplementedError(
468
- f"{type(self).__name__} does not implement reset_head(). "
469
- "Override this method to support changing n_outputs after "
470
- "loading pretrained weights."
471
- )
472
-
473
429
  mapping: Optional[Dict[str, str]] = None
474
430
 
475
431
  def load_state_dict(self, state_dict, *args, **kwargs):
@@ -670,41 +626,7 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
670
626
  ):
671
627
  model_kwargs.pop("braindecode_version", None)
672
628
  resolve_type_kwargs(cls, model_kwargs)
673
-
674
- # Read saved n_outputs from config.json to detect when the
675
- # user wants a different number of outputs. Works for both
676
- # local directories and Hub repo IDs.
677
- saved_n_outputs = None
678
- try:
679
- if Path(model_id).is_dir():
680
- config_file = Path(model_id) / "config.json"
681
- else:
682
- config_file = huggingface_hub.hf_hub_download(
683
- repo_id=model_id,
684
- filename="config.json",
685
- revision=revision,
686
- cache_dir=cache_dir,
687
- force_download=force_download,
688
- token=token,
689
- local_files_only=local_files_only,
690
- )
691
- with open(config_file, "r") as f:
692
- saved_n_outputs = json.load(f).get("n_outputs")
693
- except (OSError, json.JSONDecodeError, KeyError):
694
- pass # config unavailable; skip reset_head logic
695
-
696
- requested_n_outputs = model_kwargs.get("n_outputs")
697
-
698
- # If the user requests different n_outputs, load with the
699
- # saved value first (so weights match), then swap the head.
700
- if (
701
- saved_n_outputs is not None
702
- and requested_n_outputs is not None
703
- and requested_n_outputs != saved_n_outputs
704
- ):
705
- model_kwargs["n_outputs"] = saved_n_outputs
706
-
707
- model = super()._from_pretrained( # type: ignore
629
+ return super()._from_pretrained( # type: ignore
708
630
  model_id=model_id,
709
631
  revision=revision,
710
632
  cache_dir=cache_dir,
@@ -715,20 +637,3 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
715
637
  strict=strict,
716
638
  **model_kwargs,
717
639
  )
718
-
719
- if (
720
- saved_n_outputs is not None
721
- and requested_n_outputs is not None
722
- and requested_n_outputs != saved_n_outputs
723
- ):
724
- try:
725
- model.reset_head(requested_n_outputs)
726
- except NotImplementedError:
727
- raise ValueError(
728
- f"{type(model).__name__} does not support changing "
729
- f"n_outputs after loading. Saved model has "
730
- f"n_outputs={saved_n_outputs}, but "
731
- f"n_outputs={requested_n_outputs} was requested."
732
- ) from None
733
-
734
- return model
@@ -291,23 +291,15 @@ class BENDR(EEGModuleMixin, nn.Module):
291
291
  else:
292
292
  in_features = encoder_h
293
293
 
294
- self._head_in_features = in_features
295
294
  self.final_layer = None
296
295
  if self.include_final_layer:
297
- self._build_head(self.n_outputs)
298
-
299
- def _build_head(self, n_outputs):
300
- linear = nn.Linear(in_features=self._head_in_features, out_features=n_outputs)
301
- self.final_layer = nn.utils.parametrizations.weight_norm(
302
- linear, name="weight", dim=1
303
- )
304
-
305
- def reset_head(self, n_outputs):
306
- self._n_outputs = n_outputs
307
- self.include_final_layer = True
308
- self._build_head(n_outputs)
296
+ # in_features: encoder_h*4 (encoder_only) or encoder_h (full model)
297
+ linear = nn.Linear(in_features=in_features, out_features=self.n_outputs)
298
+ self.final_layer = nn.utils.parametrizations.weight_norm(
299
+ linear, name="weight", dim=1
300
+ )
309
301
 
310
- def forward(self, x, return_features=False):
302
+ def forward(self, x):
311
303
  if self.channel_projection is not None:
312
304
  x = self.channel_projection(x)
313
305
  encoded = self.encoder(x)
@@ -336,9 +328,6 @@ class BENDR(EEGModuleMixin, nn.Module):
336
328
  feature = context[:, :, 0]
337
329
  # feature: [batch_size, encoder_h]
338
330
 
339
- if return_features:
340
- return {"features": feature, "cls_token": None}
341
-
342
331
  if self.final_layer is not None:
343
332
  feature = self.final_layer(feature)
344
333
  # feature: [batch_size, n_outputs]
@@ -183,22 +183,13 @@ class BIOT(EEGModuleMixin, nn.Module):
183
183
  attn_layer_dropout=att_layer_drop_prob,
184
184
  )
185
185
 
186
- self._head_activation = activation
187
186
  self.final_layer = _ClassificationHead(
188
187
  emb_size=self.embed_dim,
189
188
  n_outputs=self.n_outputs,
190
189
  activation=activation,
191
190
  )
192
191
 
193
- def reset_head(self, n_outputs):
194
- self._n_outputs = n_outputs
195
- self.final_layer = _ClassificationHead(
196
- emb_size=self.embed_dim,
197
- n_outputs=n_outputs,
198
- activation=self._head_activation,
199
- )
200
-
201
- def forward(self, x, return_features=False):
192
+ def forward(self, x):
202
193
  """
203
194
  Pass the input through the BIOT encoder, and then through the
204
195
  classification head.
@@ -207,24 +198,15 @@ class BIOT(EEGModuleMixin, nn.Module):
207
198
  ----------
208
199
  x: Tensor
209
200
  (batch_size, n_channels, n_times)
210
- return_features : bool
211
- If True, return a dict with ``"features"`` and ``"cls_token"``
212
- instead of the classification output.
213
201
 
214
202
  Returns
215
203
  -------
216
- torch.Tensor or tuple or dict
217
- Default: ``torch.Tensor`` of shape ``(batch_size, n_outputs)``.
218
- If ``return_features=True``: ``dict`` with ``"features"``
219
- ``(batch_size, emb_size)`` and ``"cls_token"`` (``None``).
220
- If legacy ``return_feature=True`` (init param):
221
- ``(out, emb)`` tuple (ignored when ``return_features=True``).
204
+ out: Tensor
205
+ (batch_size, n_outputs)
206
+ (out, emb): tuple Tensor
207
+ (batch_size, n_outputs), (batch_size, emb_size)
222
208
  """
223
209
  emb = self.encoder(x)
224
-
225
- if return_features:
226
- return {"features": emb, "cls_token": None}
227
-
228
210
  x = self.final_layer(emb)
229
211
 
230
212
  if self.return_feature:
@@ -205,15 +205,20 @@ class CBraMod(EEGModuleMixin, nn.Module):
205
205
  self.encoder = _TransformerEncoder(encoder_layer, num_layers=n_layer)
206
206
  self.proj_out = nn.Sequential(nn.Linear(d_model, emb_dim))
207
207
 
208
- self._emb_dim = emb_dim
209
- self._patch_size = patch_size
210
208
  self._weights_init()
211
209
 
210
+ try:
211
+ n_times = self.n_times
212
+ n_chans = self.n_chans
213
+ except ValueError:
214
+ n_times = None
215
+ n_chans = None
216
+
212
217
  if return_encoder_output:
213
218
  self.final_layer = nn.Identity()
214
- elif self._n_times is not None and self._n_chans is not None:
215
- n_patch = self._n_times // patch_size
216
- flat_dim = self._n_chans * n_patch * emb_dim
219
+ elif n_times is not None and n_chans is not None:
220
+ n_patch = n_times // patch_size
221
+ flat_dim = n_chans * n_patch * emb_dim
217
222
  self.final_layer = nn.Sequential(
218
223
  nn.Flatten(), nn.Linear(flat_dim, self.n_outputs)
219
224
  )
@@ -222,17 +227,6 @@ class CBraMod(EEGModuleMixin, nn.Module):
222
227
  nn.Flatten(), nn.LazyLinear(self.n_outputs)
223
228
  )
224
229
 
225
- def reset_head(self, n_outputs):
226
- self._n_outputs = n_outputs
227
- if self._n_times is not None and self._n_chans is not None:
228
- n_patch = self._n_times // self._patch_size
229
- flat_dim = self._n_chans * n_patch * self._emb_dim
230
- self.final_layer = nn.Sequential(
231
- nn.Flatten(), nn.Linear(flat_dim, n_outputs)
232
- )
233
- else:
234
- self.final_layer = nn.Sequential(nn.Flatten(), nn.LazyLinear(n_outputs))
235
-
236
230
  def _weights_init(self):
237
231
  for m in self.modules():
238
232
  if isinstance(m, nn.Linear):
@@ -243,13 +237,11 @@ class CBraMod(EEGModuleMixin, nn.Module):
243
237
  nn.init.constant_(m.weight, 1)
244
238
  nn.init.constant_(m.bias, 0)
245
239
 
246
- def forward(self, x, mask=None, return_features=False):
240
+ def forward(self, x, mask=None):
247
241
  x = self.rearrange(x)
248
242
  patch_emb = self.patch_embedding(x, mask)
249
243
  feats = self.encoder(patch_emb)
250
244
  out = self.proj_out(feats)
251
- if return_features:
252
- return {"features": out, "cls_token": None}
253
245
  return self.final_layer(out)
254
246
 
255
247
 
@@ -368,13 +368,6 @@ class EEGPT(EEGModuleMixin, nn.Module):
368
368
  """Number of temporal patches from encoder."""
369
369
  return self.target_encoder.num_patches[1]
370
370
 
371
- def reset_head(self, n_outputs):
372
- self._n_outputs = n_outputs
373
- self.final_layer = _LinearConstraintProbe(
374
- **self.get_probe_params(),
375
- n_outputs=n_outputs,
376
- )
377
-
378
371
  def get_probe_params(self) -> dict:
379
372
  """Get parameters needed to create a _LinearConstraintProbe.
380
373
 
@@ -389,7 +382,7 @@ class EEGPT(EEGModuleMixin, nn.Module):
389
382
  "embed_dim": self.embed_dim,
390
383
  }
391
384
 
392
- def forward(self, x, return_features=False):
385
+ def forward(self, x):
393
386
  """
394
387
  Forward pass.
395
388
 
@@ -397,13 +390,10 @@ class EEGPT(EEGModuleMixin, nn.Module):
397
390
  ----------
398
391
  x : torch.Tensor
399
392
  EEG data of shape (batch, n_chans, n_times).
400
- return_features : bool
401
- If True, return a dict with ``"features"`` and ``"cls_token"``
402
- instead of the classification output.
403
393
 
404
394
  Returns
405
395
  -------
406
- torch.Tensor or dict
396
+ torch.Tensor
407
397
  Model output. Shape depends on `n_outputs` and `return_encoder_output`.
408
398
  """
409
399
  # Channel projection (if configured)
@@ -412,9 +402,6 @@ class EEGPT(EEGModuleMixin, nn.Module):
412
402
  # z shape: (batch, n_patches, embed_num, embed_dim)
413
403
  z = self.target_encoder(x, self.chans_id)
414
404
 
415
- if return_features:
416
- return {"features": z.flatten(2), "cls_token": None}
417
-
418
405
  if self.return_encoder_output:
419
406
  return z
420
407
 
@@ -790,7 +790,6 @@ class Labram(EEGModuleMixin, nn.Module):
790
790
  ch_names: list[str] | None = None,
791
791
  return_patch_tokens=False,
792
792
  return_all_tokens=False,
793
- return_features=False,
794
793
  ):
795
794
  """
796
795
  Forward the input EEG data through the model.
@@ -806,9 +805,6 @@ class Labram(EEGModuleMixin, nn.Module):
806
805
  If not provided, the channels provided during model initialization
807
806
  (via ``chs_info``), channels will be used instead
808
807
  If neither is provided, an error will be raised.
809
- return_features : bool
810
- If True, return a dict with ``"features"`` (patch tokens) and
811
- ``"cls_token"`` instead of the classification output.
812
808
  return_patch_tokens: bool
813
809
  Return the patch tokens
814
810
  return_all_tokens: bool
@@ -816,18 +812,12 @@ class Labram(EEGModuleMixin, nn.Module):
816
812
 
817
813
  Returns
818
814
  -------
819
- torch.Tensor or dict
815
+ torch.Tensor
820
816
  The output of the model with dimensions (batch, n_outputs)
821
817
  """
822
818
  # Apply automatic channel reordering if configured and input_chans not provided
823
819
  x, input_chans = self._select_channels(x, ch_names=ch_names)
824
820
 
825
- if return_features:
826
- x = self.forward_features(
827
- x, input_chans=input_chans, return_all_tokens=True
828
- )
829
- return {"features": x[:, 1:, :], "cls_token": x[:, 0, :]}
830
-
831
821
  x = self.forward_features(
832
822
  x,
833
823
  input_chans=input_chans,
@@ -861,10 +851,6 @@ class Labram(EEGModuleMixin, nn.Module):
861
851
  nn.Linear(self.embed_dim, n_outputs) if n_outputs > 0 else nn.Identity()
862
852
  )
863
853
 
864
- def reset_head(self, n_outputs):
865
- self._n_outputs = n_outputs
866
- self.reset_classifier(n_outputs)
867
-
868
854
  def _adj_temporal_embedding(self, num_ch, batch_size, dim_embed=None):
869
855
  """
870
856
  Adjust the dimensions of the time embedding to match the
@@ -311,7 +311,19 @@ class REVE(EEGModuleMixin, nn.Module):
311
311
  geglu=self.use_geglu,
312
312
  )
313
313
 
314
- self._build_head(self.n_outputs)
314
+ final_dim = self._get_flattened_output_dim()
315
+
316
+ if self.use_attention_pooling:
317
+ self.final_layer = nn.Sequential(
318
+ nn.LayerNorm(self.embed_dim),
319
+ nn.Linear(self.embed_dim, self.n_outputs),
320
+ )
321
+ else:
322
+ self.final_layer = nn.Sequential(
323
+ nn.Flatten(),
324
+ nn.LayerNorm(final_dim),
325
+ nn.Linear(final_dim, self.n_outputs),
326
+ )
315
327
 
316
328
  if self.use_attention_pooling:
317
329
  self.cls_query_token = nn.Parameter(torch.randn(1, 1, self.embed_dim))
@@ -340,24 +352,6 @@ class REVE(EEGModuleMixin, nn.Module):
340
352
  flat_dim = self.n_chans * n_patches * self.embed_dim
341
353
  return flat_dim
342
354
 
343
- def _build_head(self, n_outputs):
344
- if self.use_attention_pooling:
345
- self.final_layer = nn.Sequential(
346
- nn.LayerNorm(self.embed_dim),
347
- nn.Linear(self.embed_dim, n_outputs),
348
- )
349
- else:
350
- final_dim = self._get_flattened_output_dim()
351
- self.final_layer = nn.Sequential(
352
- nn.Flatten(),
353
- nn.LayerNorm(final_dim),
354
- nn.Linear(final_dim, n_outputs),
355
- )
356
-
357
- def reset_head(self, n_outputs):
358
- self._n_outputs = n_outputs
359
- self._build_head(n_outputs)
360
-
361
355
  def get_positions(self, channel_names: list[str]) -> torch.Tensor:
362
356
  """Fetch channel positions from the position bank. The position bank is downloaded when the model is instantiated.
363
357
 
@@ -379,8 +373,7 @@ class REVE(EEGModuleMixin, nn.Module):
379
373
  eeg: torch.Tensor,
380
374
  pos: Optional[torch.Tensor] = None,
381
375
  return_output: bool = False,
382
- return_features: bool = False,
383
- ) -> Union[torch.Tensor, list[torch.Tensor], dict]:
376
+ ) -> Union[torch.Tensor, list[torch.Tensor]]:
384
377
  """
385
378
  Forward pass of the model.
386
379
 
@@ -399,22 +392,16 @@ class REVE(EEGModuleMixin, nn.Module):
399
392
  return_output : bool, optional
400
393
  If True, returns the output from the transformer directly.
401
394
  If False, applies the final layer and returns the processed output. Default is False.
402
- return_features : bool, optional
403
- If True, returns a dict ``{"features": Tensor, "cls_token": None}``
404
- with encoder features before the final layer. Default is False.
405
395
 
406
396
  Returns
407
397
  -------
408
- torch.Tensor or list[torch.Tensor] or dict
409
- Default: ``torch.Tensor`` after the final layer.
410
- If ``return_output=True``: ``list[torch.Tensor]`` from transformer layers.
411
- If ``return_features=True``: ``dict`` with ``"features"`` and ``"cls_token"`` keys.
412
- """
398
+ Union[torch.Tensor, list[torch.Tensor]]
399
+ - If `return_output` is False: Returns a single `torch.Tensor` (output after final layer).
400
+ - If `return_output` is True: Returns a `list[torch.Tensor]` (outputs from transformer layers).
413
401
 
414
- if return_output and return_features:
415
- raise ValueError(
416
- "return_output and return_features are mutually exclusive."
417
- )
402
+ The output tensor(s) from the model. If `return_output` is True,
403
+ returns the transformer output; otherwise, returns the output after the final layer.
404
+ """
418
405
 
419
406
  patches = eeg.unfold(
420
407
  dimension=2,
@@ -466,9 +453,6 @@ class REVE(EEGModuleMixin, nn.Module):
466
453
  emb=self.embed_dim,
467
454
  )
468
455
 
469
- if return_features:
470
- return {"features": x, "cls_token": None}
471
-
472
456
  if self.use_attention_pooling:
473
457
  x = self._attention_pooling(x)
474
458
 
@@ -222,13 +222,11 @@ class SignalJEPA(_BaseSignalJEPA):
222
222
  del n_outputs, n_chans, chs_info, n_times, input_window_seconds, sfreq
223
223
  self.final_layer = nn.Identity()
224
224
 
225
- def forward(self, X, ch_idxs: torch.Tensor | None = None, return_features=False): # type: ignore
225
+ def forward(self, X, ch_idxs: torch.Tensor | None = None): # type: ignore
226
226
  local_features = self.feature_encoder(X) # type: ignore
227
227
  pos_encoding = self.pos_encoder(local_features, ch_idxs=ch_idxs) # type: ignore
228
228
  local_features += pos_encoding # type: ignore
229
229
  contextual_features = self.transformer.encoder(local_features) # type: ignore
230
- if return_features:
231
- return {"features": contextual_features, "cls_token": None}
232
230
  y = self.final_layer(contextual_features) # type: ignore
233
231
  return y # type: ignore
234
232
 
@@ -315,8 +313,6 @@ class SignalJEPA_Contextual(_BaseSignalJEPA):
315
313
  _init_transformer=_init_transformer,
316
314
  )
317
315
  del n_outputs, n_chans, chs_info, n_times, input_window_seconds, sfreq
318
- self._clf_conv_layers_spec = feature_encoder__conv_layers_spec
319
- self._clf_n_spat_filters = n_spat_filters
320
316
  self.final_layer = _get_separable_clf_layer(
321
317
  conv_layers_spec=feature_encoder__conv_layers_spec,
322
318
  n_chans=self.n_chans,
@@ -325,26 +321,6 @@ class SignalJEPA_Contextual(_BaseSignalJEPA):
325
321
  n_spat_filters=n_spat_filters,
326
322
  )
327
323
 
328
- def reset_head(self, n_outputs):
329
- self._n_outputs = n_outputs
330
- self.final_layer = _get_separable_clf_layer(
331
- conv_layers_spec=self._clf_conv_layers_spec,
332
- n_chans=self.n_chans,
333
- n_times=self.n_times,
334
- n_classes=n_outputs,
335
- n_spat_filters=self._clf_n_spat_filters,
336
- )
337
-
338
- def forward(self, X, ch_idxs: torch.Tensor | None = None, return_features=False): # type: ignore
339
- local_features = self.feature_encoder(X) # type: ignore
340
- pos_encoding = self.pos_encoder(local_features, ch_idxs=ch_idxs) # type: ignore
341
- local_features += pos_encoding # type: ignore
342
- contextual_features = self.transformer.encoder(local_features) # type: ignore
343
- if return_features:
344
- return {"features": contextual_features, "cls_token": None}
345
- y = self.final_layer(contextual_features) # type: ignore
346
- return y # type: ignore
347
-
348
324
  @classmethod
349
325
  def from_pretrained(
350
326
  cls,
@@ -419,6 +395,14 @@ class SignalJEPA_Contextual(_BaseSignalJEPA):
419
395
 
420
396
  return new_model
421
397
 
398
+ def forward(self, X, ch_idxs: torch.Tensor | None = None): # type: ignore
399
+ local_features = self.feature_encoder(X) # type: ignore
400
+ pos_encoding = self.pos_encoder(local_features, ch_idxs=ch_idxs) # type: ignore
401
+ local_features += pos_encoding # type: ignore
402
+ contextual_features = self.transformer.encoder(local_features) # type: ignore
403
+ y = self.final_layer(contextual_features) # type: ignore
404
+ return y # type: ignore
405
+
422
406
 
423
407
  class SignalJEPA_PostLocal(_BaseSignalJEPA):
424
408
  r"""Post-local downstream architecture introduced in signal-JEPA Guetschel, P et al (2024) [1]_.
@@ -501,8 +485,6 @@ class SignalJEPA_PostLocal(_BaseSignalJEPA):
501
485
  _init_transformer=False,
502
486
  )
503
487
  del n_outputs, n_chans, chs_info, n_times, input_window_seconds, sfreq
504
- self._clf_conv_layers_spec = feature_encoder__conv_layers_spec
505
- self._clf_n_spat_filters = n_spat_filters
506
488
  self.final_layer = _get_separable_clf_layer(
507
489
  conv_layers_spec=feature_encoder__conv_layers_spec,
508
490
  n_chans=self.n_chans,
@@ -511,16 +493,6 @@ class SignalJEPA_PostLocal(_BaseSignalJEPA):
511
493
  n_spat_filters=n_spat_filters,
512
494
  )
513
495
 
514
- def reset_head(self, n_outputs):
515
- self._n_outputs = n_outputs
516
- self.final_layer = _get_separable_clf_layer(
517
- conv_layers_spec=self._clf_conv_layers_spec,
518
- n_chans=self.n_chans,
519
- n_times=self.n_times,
520
- n_classes=n_outputs,
521
- n_spat_filters=self._clf_n_spat_filters,
522
- )
523
-
524
496
  @classmethod
525
497
  def from_pretrained(
526
498
  cls,
@@ -577,10 +549,8 @@ class SignalJEPA_PostLocal(_BaseSignalJEPA):
577
549
  new_model.feature_encoder = deepcopy(feature_encoder)
578
550
  return new_model
579
551
 
580
- def forward(self, X, return_features=False):
552
+ def forward(self, X):
581
553
  local_features = self.feature_encoder(X)
582
- if return_features:
583
- return {"features": local_features, "cls_token": None}
584
554
  y = self.final_layer(local_features)
585
555
  return y
586
556
 
@@ -701,21 +671,14 @@ class SignalJEPA_PreLocal(_BaseSignalJEPA):
701
671
  nn.Conv2d(1, n_spat_filters, (self.n_chans, 1)),
702
672
  Rearrange("b spat_filters 1 time -> b spat_filters time"),
703
673
  )
704
- self._out_emb_dim = _get_out_emb_dim(
674
+ out_emb_dim = _get_out_emb_dim(
705
675
  conv_layers_spec=feature_encoder__conv_layers_spec,
706
676
  n_times=self.n_times,
707
677
  n_spat_filters=n_spat_filters,
708
678
  )
709
679
  self.final_layer = nn.Sequential(
710
680
  nn.Flatten(start_dim=1),
711
- nn.Linear(self._out_emb_dim, self.n_outputs),
712
- )
713
-
714
- def reset_head(self, n_outputs):
715
- self._n_outputs = n_outputs
716
- self.final_layer = nn.Sequential(
717
- nn.Flatten(start_dim=1),
718
- nn.Linear(self._out_emb_dim, n_outputs),
681
+ nn.Linear(out_emb_dim, self.n_outputs),
719
682
  )
720
683
 
721
684
  @classmethod
@@ -774,11 +737,9 @@ class SignalJEPA_PreLocal(_BaseSignalJEPA):
774
737
  new_model.feature_encoder = deepcopy(feature_encoder)
775
738
  return new_model
776
739
 
777
- def forward(self, X, return_features=False):
740
+ def forward(self, X):
778
741
  X = self.spatial_conv(X)
779
742
  local_features = self.feature_encoder(X)
780
- if return_features:
781
- return {"features": local_features, "cls_token": None}
782
743
  y = self.final_layer(local_features)
783
744
  return y
784
745
 
@@ -0,0 +1 @@
1
+ __version__ = "1.3.2.dev182544824"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.3.2.dev181313884
3
+ Version: 1.3.2.dev182544824
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>
@@ -349,6 +349,13 @@ html_theme_options = {
349
349
  "footer_start": ["copyright"],
350
350
  # 'pygment_light_style': 'default',
351
351
  "analytics": dict(google_analytics_id="G-7Q43R82K6D"),
352
+ "announcement": (
353
+ "<strong>Using Braindecode in academic work?</strong> "
354
+ "<a class='braindecode-announcement-cta' href='cite.html'>Cite Braindecode</a> "
355
+ "<span class='braindecode-announcement-secondary'>"
356
+ "DOI: <a href='https://doi.org/10.5281/zenodo.17699192'>10.5281/zenodo.17699192</a>"
357
+ "</span>"
358
+ ),
352
359
  }
353
360
 
354
361
  # The name of an image file (relative to this directory) to place at the top