Braindecode 1.3.2.dev183566201__tar.gz → 1.3.2.dev183987088__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.dev183566201/braindecode.egg-info → braindecode-1.3.2.dev183987088}/PKG-INFO +1 -1
  2. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/base.py +15 -132
  3. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/bendr.py +6 -17
  4. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/biot.py +5 -23
  5. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/cbramod.py +11 -19
  6. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eeginception_mi.py +1 -2
  7. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegitnet.py +3 -4
  8. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegpt.py +2 -15
  9. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/labram.py +1 -15
  10. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/luna.py +16 -5
  11. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/reve.py +20 -36
  12. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/signal_jepa.py +13 -63
  13. braindecode-1.3.2.dev183987088/braindecode/version.py +1 -0
  14. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088/braindecode.egg-info}/PKG-INFO +1 -1
  15. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/whats_new.rst +0 -22
  16. braindecode-1.3.2.dev183566201/braindecode/version.py +0 -1
  17. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/LICENSE.txt +0 -0
  18. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/MANIFEST.in +0 -0
  19. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/NOTICE.txt +0 -0
  20. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/README.rst +0 -0
  21. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/__init__.py +0 -0
  22. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/augmentation/__init__.py +0 -0
  23. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/augmentation/base.py +0 -0
  24. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/augmentation/functional.py +0 -0
  25. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/augmentation/transforms.py +0 -0
  26. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/classifier.py +0 -0
  27. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/__init__.py +0 -0
  28. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/base.py +0 -0
  29. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bbci.py +0 -0
  30. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bcicomp.py +0 -0
  31. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/__init__.py +0 -0
  32. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/datasets.py +0 -0
  33. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/format.py +0 -0
  34. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/hub.py +0 -0
  35. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/hub_format.py +0 -0
  36. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/hub_io.py +0 -0
  37. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/hub_validation.py +0 -0
  38. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/bids/iterable.py +0 -0
  39. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/chb_mit.py +0 -0
  40. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/mne.py +0 -0
  41. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/moabb.py +0 -0
  42. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/nmt.py +0 -0
  43. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/registry.py +0 -0
  44. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/siena.py +0 -0
  45. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  46. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/sleep_physionet.py +0 -0
  47. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/tuh.py +0 -0
  48. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/utils.py +0 -0
  49. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datasets/xy.py +0 -0
  50. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datautil/__init__.py +0 -0
  51. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datautil/channel_utils.py +0 -0
  52. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datautil/hub_formats.py +0 -0
  53. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datautil/serialization.py +0 -0
  54. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/datautil/util.py +0 -0
  55. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/eegneuralnet.py +0 -0
  56. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/functional/__init__.py +0 -0
  57. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/functional/functions.py +0 -0
  58. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/functional/initialization.py +0 -0
  59. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/__init__.py +0 -0
  60. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/atcnet.py +0 -0
  61. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/attentionbasenet.py +0 -0
  62. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/attn_sleep.py +0 -0
  63. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/brainmodule.py +0 -0
  64. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/config.py +0 -0
  65. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/contrawr.py +0 -0
  66. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/ctnet.py +0 -0
  67. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/deep4.py +0 -0
  68. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/deepsleepnet.py +0 -0
  69. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/dgcnn.py +0 -0
  70. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegconformer.py +0 -0
  71. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eeginception_erp.py +0 -0
  72. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegminer.py +0 -0
  73. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegnet.py +0 -0
  74. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegnex.py +0 -0
  75. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegsimpleconv.py +0 -0
  76. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegsym.py +0 -0
  77. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/eegtcnet.py +0 -0
  78. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/fbcnet.py +0 -0
  79. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/fblightconvnet.py +0 -0
  80. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/fbmsnet.py +0 -0
  81. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/hybrid.py +0 -0
  82. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/ifnet.py +0 -0
  83. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/medformer.py +0 -0
  84. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/msvtnet.py +0 -0
  85. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/patchedtransformer.py +0 -0
  86. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sccnet.py +0 -0
  87. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/shallow_fbcsp.py +0 -0
  88. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sinc_shallow.py +0 -0
  89. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  90. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  91. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sparcnet.py +0 -0
  92. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/sstdpn.py +0 -0
  93. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/summary.csv +0 -0
  94. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/syncnet.py +0 -0
  95. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/tcn.py +0 -0
  96. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/tidnet.py +0 -0
  97. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/tsinception.py +0 -0
  98. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/usleep.py +0 -0
  99. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/models/util.py +0 -0
  100. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/__init__.py +0 -0
  101. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/activation.py +0 -0
  102. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/attention.py +0 -0
  103. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/blocks.py +0 -0
  104. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/convolution.py +0 -0
  105. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/filter.py +0 -0
  106. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/layers.py +0 -0
  107. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/linear.py +0 -0
  108. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/parametrization.py +0 -0
  109. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/stats.py +0 -0
  110. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/util.py +0 -0
  111. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/modules/wrapper.py +0 -0
  112. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/__init__.py +0 -0
  113. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  114. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/mne_preprocess.py +0 -0
  115. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/preprocess.py +0 -0
  116. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/util.py +0 -0
  117. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/preprocessing/windowers.py +0 -0
  118. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/regressor.py +0 -0
  119. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/samplers/__init__.py +0 -0
  120. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/samplers/base.py +0 -0
  121. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/samplers/ssl.py +0 -0
  122. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/training/__init__.py +0 -0
  123. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/training/callbacks.py +0 -0
  124. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/training/losses.py +0 -0
  125. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/training/scoring.py +0 -0
  126. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/util.py +0 -0
  127. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/visualization/__init__.py +0 -0
  128. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/visualization/confusion_matrices.py +0 -0
  129. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode/visualization/gradients.py +0 -0
  130. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode.egg-info/SOURCES.txt +0 -0
  131. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode.egg-info/dependency_links.txt +0 -0
  132. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode.egg-info/requires.txt +0 -0
  133. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/braindecode.egg-info/top_level.txt +0 -0
  134. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/Makefile +0 -0
  135. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/_templates/autosummary/class.rst +0 -0
  136. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  137. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/_templates/autosummary/function.rst +0 -0
  138. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  139. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/api.rst +0 -0
  140. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/cite.rst +0 -0
  141. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/conf.py +0 -0
  142. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/help.rst +0 -0
  143. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/index.rst +0 -0
  144. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/install/install.rst +0 -0
  145. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/install/install_pip.rst +0 -0
  146. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/install/install_source.rst +0 -0
  147. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/attention.rst +0 -0
  148. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/channel.rst +0 -0
  149. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/convolution.rst +0 -0
  150. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/filterbank.rst +0 -0
  151. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/gnn.rst +0 -0
  152. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/interpretable.rst +0 -0
  153. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/lbm.rst +0 -0
  154. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/recurrent.rst +0 -0
  155. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/categorization/spd.rst +0 -0
  156. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/models.rst +0 -0
  157. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/models_categorization.rst +0 -0
  158. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/models_table.rst +0 -0
  159. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/models/models_visualization.rst +0 -0
  160. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/docs/sg_execution_times.rst +0 -0
  161. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/pyproject.toml +0 -0
  162. {braindecode-1.3.2.dev183566201 → braindecode-1.3.2.dev183987088}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.3.2.dev183566201
3
+ Version: 1.3.2.dev183987088
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>
@@ -150,40 +150,14 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
150
150
  # Load pretrained model
151
151
  model = {name}.from_pretrained("username/my-{name_lower}-model")
152
152
 
153
- # Load with a different number of outputs (head is rebuilt automatically)
154
- model = {name}.from_pretrained("username/my-{name_lower}-model", n_outputs=4)
155
-
156
- **Extracting features and replacing the head:**
157
-
158
- .. code-block::
159
-
160
- import torch
161
-
162
- x = torch.randn(1, model.n_chans, model.n_times)
163
- # Extract encoder features (consistent dict across all models)
164
- out = model(x, return_features=True)
165
- features = out["features"]
166
-
167
- # Replace the classification head
168
- model.reset_head(n_outputs=10)
169
-
170
- **Saving and restoring full configuration:**
171
-
172
- .. code-block::
173
-
174
- import json
175
-
176
- config = model.get_config() # all __init__ params
177
- with open("config.json", "w") as f:
178
- json.dump(config, f)
179
-
180
- model2 = {name}.from_config(config) # reconstruct (no weights)
153
+ The integration automatically handles EEG-specific parameters (n_chans,
154
+ n_times, sfreq, chs_info, etc.) by saving them in a config file alongside
155
+ the model weights. This ensures that loaded models are correctly configured
156
+ for their original data specifications.
181
157
 
182
158
  All model parameters (both EEG-specific and model-specific such as
183
159
  dropout rates, activation functions, number of filters) are automatically
184
160
  saved to the Hub and restored when loading.
185
-
186
- See :ref:`load-pretrained-models` for a complete tutorial.
187
161
  """
188
162
 
189
163
  def __init_subclass__(cls, **kwargs):
@@ -468,34 +442,6 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
468
442
  resolve_type_kwargs(cls, config)
469
443
  return cls(**config)
470
444
 
471
- def reset_head(self, n_outputs):
472
- """Replace the classification head for a new number of outputs.
473
-
474
- This is called automatically by :meth:`from_pretrained` when the
475
- user passes an ``n_outputs`` that differs from the saved config.
476
- Override in subclasses that need a model-specific head structure.
477
-
478
- Parameters
479
- ----------
480
- n_outputs : int
481
- New number of output classes.
482
-
483
- Examples
484
- --------
485
- >>> from braindecode.models import BENDR
486
- >>> model = BENDR(n_chans=22, n_times=1000, n_outputs=4)
487
- >>> model.reset_head(10)
488
- >>> model.n_outputs
489
- 10
490
-
491
- .. versionadded:: 1.4
492
- """
493
- raise NotImplementedError(
494
- f"{type(self).__name__} does not implement reset_head(). "
495
- "Override this method to support changing n_outputs after "
496
- "loading pretrained weights."
497
- )
498
-
499
445
  mapping: Optional[Dict[str, str]] = None
500
446
 
501
447
  def load_state_dict(self, state_dict, *args, **kwargs):
@@ -695,78 +641,15 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
695
641
  **model_kwargs,
696
642
  ):
697
643
  model_kwargs.pop("braindecode_version", None)
698
- filename = model_kwargs.pop("filename", None)
699
644
  resolve_type_kwargs(cls, model_kwargs)
700
-
701
- # Read saved n_outputs from config.json to detect when the
702
- # user wants a different number of outputs. Works for both
703
- # local directories and Hub repo IDs.
704
- saved_n_outputs = None
705
- try:
706
- if Path(model_id).is_dir():
707
- config_file = Path(model_id) / "config.json"
708
- else:
709
- config_file = huggingface_hub.hf_hub_download(
710
- repo_id=model_id,
711
- filename="config.json",
712
- revision=revision,
713
- cache_dir=cache_dir,
714
- force_download=force_download,
715
- token=token,
716
- local_files_only=local_files_only,
717
- )
718
- with open(config_file, "r") as f:
719
- saved_n_outputs = json.load(f).get("n_outputs")
720
- except (OSError, json.JSONDecodeError, KeyError):
721
- pass # config unavailable; skip reset_head logic
722
-
723
- requested_n_outputs = model_kwargs.get("n_outputs")
724
-
725
- # If the user requests different n_outputs, load with the
726
- # saved value first (so weights match), then swap the head.
727
- if (
728
- saved_n_outputs is not None
729
- and requested_n_outputs is not None
730
- and requested_n_outputs != saved_n_outputs
731
- ):
732
- model_kwargs["n_outputs"] = saved_n_outputs
733
-
734
- # If a custom filename is provided, temporarily override the
735
- # HuggingFace constant so the parent class downloads the
736
- # correct file (e.g. "LUNA_base.safetensors" instead of
737
- # "model.safetensors").
738
- hf_constants = huggingface_hub.constants
739
- _orig_safetensors = hf_constants.SAFETENSORS_SINGLE_FILE
740
- if filename is not None:
741
- hf_constants.SAFETENSORS_SINGLE_FILE = filename
742
- try:
743
- model = super()._from_pretrained( # type: ignore
744
- model_id=model_id,
745
- revision=revision,
746
- cache_dir=cache_dir,
747
- force_download=force_download,
748
- local_files_only=local_files_only,
749
- token=token,
750
- map_location=map_location,
751
- strict=strict,
752
- **model_kwargs,
753
- )
754
- finally:
755
- hf_constants.SAFETENSORS_SINGLE_FILE = _orig_safetensors
756
-
757
- if (
758
- saved_n_outputs is not None
759
- and requested_n_outputs is not None
760
- and requested_n_outputs != saved_n_outputs
761
- ):
762
- try:
763
- model.reset_head(requested_n_outputs)
764
- except NotImplementedError:
765
- raise ValueError(
766
- f"{type(model).__name__} does not support changing "
767
- f"n_outputs after loading. Saved model has "
768
- f"n_outputs={saved_n_outputs}, but "
769
- f"n_outputs={requested_n_outputs} was requested."
770
- ) from None
771
-
772
- return model
645
+ return super()._from_pretrained( # type: ignore
646
+ model_id=model_id,
647
+ revision=revision,
648
+ cache_dir=cache_dir,
649
+ force_download=force_download,
650
+ local_files_only=local_files_only,
651
+ token=token,
652
+ map_location=map_location,
653
+ strict=strict,
654
+ **model_kwargs,
655
+ )
@@ -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
 
@@ -1,5 +1,4 @@
1
1
  # Authors: Cedric Rommel <cedric.rommel@inria.fr>
2
- # Sarthak Tayal <sarthaktayal2@gmail.com>
3
2
  #
4
3
  # License: BSD (3-clause)
5
4
 
@@ -96,7 +95,7 @@ class EEGInceptionMI(EEGModuleMixin, nn.Module):
96
95
 
97
96
  self.mapping = {
98
97
  "fc.weight": "final_layer.fc.weight",
99
- "fc.bias": "final_layer.fc.bias",
98
+ "tc.bias": "final_layer.fc.bias",
100
99
  }
101
100
 
102
101
  # ======== Inception branches ========================
@@ -1,5 +1,4 @@
1
1
  # Authors: Ghaith Bouallegue <ghaithbouallegue@gmail.com>
2
- # Sarthak Tayal <sarthaktayal2@gmail.com>
3
2
  #
4
3
  # License: BSD-3
5
4
  from einops.layers.torch import Rearrange
@@ -95,8 +94,8 @@ class EEGITNet(EEGModuleMixin, nn.Sequential):
95
94
  sfreq=sfreq,
96
95
  )
97
96
  self.mapping = {
98
- "classification.1.weight": "final_layer.weight",
99
- "classification.1.bias": "final_layer.bias",
97
+ "classification.1.weight": "final_layer.clf.weight",
98
+ "classification.1.bias": "final_layer.clf.weight",
100
99
  }
101
100
 
102
101
  del n_outputs, n_chans, chs_info, n_times, input_window_seconds, sfreq
@@ -122,7 +121,7 @@ class EEGITNet(EEGModuleMixin, nn.Sequential):
122
121
  block13 = self._get_inception_branch(
123
122
  in_channels=self.n_chans,
124
123
  out_channels=n_filters_time * 4,
125
- kernel_length=kernel_length * 4,
124
+ kernel_length=n_filters_time * 4,
126
125
  activation=activation,
127
126
  )
128
127
  self.add_module("inception_block", InceptionBlock((block11, block12, block13)))
@@ -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
@@ -49,7 +49,7 @@ class LUNA(EEGModuleMixin, nn.Module):
49
49
  **Pre-trained Weights Available**
50
50
 
51
51
  This model has pre-trained weights available on the Hugging Face Hub
52
- at `PulpBio/LUNA <https://huggingface.co/PulpBio/LUNA>`_.
52
+ at `thorir/LUNA <https://huggingface.co/thorir/LUNA>`_.
53
53
 
54
54
  Available model variants:
55
55
 
@@ -61,13 +61,19 @@ class LUNA(EEGModuleMixin, nn.Module):
61
61
 
62
62
  .. code-block:: python
63
63
 
64
+ from huggingface_hub import hf_hub_download
65
+ from safetensors.torch import load_file
64
66
  from braindecode.models import LUNA
65
67
 
66
- # Load pre-trained base model from Hugging Face Hub
67
- model = LUNA.from_pretrained(
68
- "PulpBio/LUNA",
68
+ # Download pre-trained weights
69
+ model_path = hf_hub_download(
70
+ repo_id="thorir/LUNA",
69
71
  filename="LUNA_base.safetensors",
70
- n_outputs=2,
72
+ )
73
+
74
+ # Create model for classification (fine-tuning)
75
+ model = LUNA(
76
+ n_outputs=2, # Number of classes for your task
71
77
  n_chans=22,
72
78
  n_times=1000,
73
79
  embed_dim=64,
@@ -75,6 +81,11 @@ class LUNA(EEGModuleMixin, nn.Module):
75
81
  depth=8,
76
82
  )
77
83
 
84
+ # Load pre-trained encoder weights
85
+ state_dict = load_file(model_path)
86
+ # load_state_dict applies model.mapping automatically
87
+ model.load_state_dict(state_dict, strict=False)
88
+
78
89
  To push your own trained model to the Hub:
79
90
 
80
91
  .. code-block:: python
@@ -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