Braindecode 1.6.1.dev1014__tar.gz → 1.6.1.dev1034__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.6.1.dev1014/braindecode.egg-info → braindecode-1.6.1.dev1034}/PKG-INFO +2 -2
  2. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/bids/hub.py +1 -41
  3. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/moabb.py +10 -0
  4. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/eegneuralnet.py +0 -41
  5. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/__init__.py +2 -5
  6. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/atcnet.py +1 -118
  7. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/attn_sleep.py +10 -0
  8. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eegnet.py +10 -1
  9. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eegtcnet.py +27 -62
  10. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/sstdpn.py +4 -10
  11. braindecode-1.6.1.dev1034/braindecode/models/summary.csv +58 -0
  12. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/tsinception.py +11 -1
  13. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/util.py +2 -2
  14. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/__init__.py +1 -2
  15. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/blocks.py +0 -82
  16. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/preprocessing/mne_preprocess.py +1 -28
  17. braindecode-1.6.1.dev1034/braindecode/version.py +1 -0
  18. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034/braindecode.egg-info}/PKG-INFO +2 -2
  19. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode.egg-info/SOURCES.txt +0 -2
  20. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode.egg-info/requires.txt +1 -1
  21. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/api.rst +0 -3
  22. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/index.rst +4 -5
  23. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/models_table.rst +2 -4
  24. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/whats_new.rst +2 -90
  25. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/pyproject.toml +1 -7
  26. braindecode-1.6.1.dev1014/braindecode/models/eegdino.py +0 -533
  27. braindecode-1.6.1.dev1014/braindecode/models/summary.csv +0 -60
  28. braindecode-1.6.1.dev1014/braindecode/models/tcformer.py +0 -643
  29. braindecode-1.6.1.dev1014/braindecode/version.py +0 -1
  30. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/LICENSE.txt +0 -0
  31. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/MANIFEST.in +0 -0
  32. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/NOTICE.txt +0 -0
  33. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/README.rst +0 -0
  34. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/__init__.py +0 -0
  35. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/augmentation/__init__.py +0 -0
  36. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/augmentation/base.py +0 -0
  37. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/augmentation/functional.py +0 -0
  38. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/augmentation/transforms.py +0 -0
  39. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/classifier.py +0 -0
  40. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/__init__.py +0 -0
  41. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/base.py +0 -0
  42. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/bbci.py +0 -0
  43. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/bcicomp.py +0 -0
  44. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/bids/__init__.py +0 -0
  45. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/bids/datasets.py +0 -0
  46. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/bids/format.py +0 -0
  47. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/bids/hub_format.py +0 -0
  48. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/bids/hub_io.py +0 -0
  49. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/bids/hub_validation.py +0 -0
  50. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/bids/iterable.py +0 -0
  51. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/chb_mit.py +0 -0
  52. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/mne.py +0 -0
  53. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/nmt.py +0 -0
  54. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/registry.py +0 -0
  55. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/siena.py +0 -0
  56. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  57. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/sleep_physionet.py +0 -0
  58. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/tuh.py +0 -0
  59. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/utils.py +0 -0
  60. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datasets/xy.py +0 -0
  61. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datautil/__init__.py +0 -0
  62. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datautil/channel_utils.py +0 -0
  63. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datautil/hub_formats.py +0 -0
  64. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datautil/serialization.py +0 -0
  65. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/datautil/util.py +0 -0
  66. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/functional/__init__.py +0 -0
  67. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/functional/functions.py +0 -0
  68. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/functional/initialization.py +0 -0
  69. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/attentionbasenet.py +0 -0
  70. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/base.py +0 -0
  71. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/bendr.py +0 -0
  72. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/biot.py +0 -0
  73. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/brainmodule.py +0 -0
  74. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/cbramod.py +0 -0
  75. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/codebrain.py +0 -0
  76. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/config.py +0 -0
  77. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/contrawr.py +0 -0
  78. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/ctnet.py +0 -0
  79. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/deep4.py +0 -0
  80. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/deepsleepnet.py +0 -0
  81. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/dgcnn.py +0 -0
  82. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eegconformer.py +0 -0
  83. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eeginception_erp.py +0 -0
  84. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eeginception_mi.py +0 -0
  85. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eegitnet.py +0 -0
  86. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eegminer.py +0 -0
  87. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eegnex.py +0 -0
  88. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eegpt.py +0 -0
  89. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eegsimpleconv.py +0 -0
  90. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/eegsym.py +0 -0
  91. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/emg2qwerty.py +0 -0
  92. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/fbcnet.py +0 -0
  93. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/fblightconvnet.py +0 -0
  94. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/fbmsnet.py +0 -0
  95. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/hybrid.py +0 -0
  96. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/ifnet.py +0 -0
  97. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/interpolated.py +0 -0
  98. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/labram.py +0 -0
  99. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/luna.py +0 -0
  100. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/medformer.py +0 -0
  101. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/meta_neuromotor.py +0 -0
  102. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/msvtnet.py +0 -0
  103. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/patchedtransformer.py +0 -0
  104. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/reve.py +0 -0
  105. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/sccnet.py +0 -0
  106. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/shallow_fbcsp.py +0 -0
  107. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/signal_jepa.py +0 -0
  108. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/sinc_shallow.py +0 -0
  109. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  110. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  111. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/sparcnet.py +0 -0
  112. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/syncnet.py +0 -0
  113. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/tcn.py +0 -0
  114. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/tidnet.py +0 -0
  115. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/models/usleep.py +0 -0
  116. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/activation.py +0 -0
  117. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/attention.py +0 -0
  118. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/convolution.py +0 -0
  119. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/filter.py +0 -0
  120. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/interpolation.py +0 -0
  121. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/layers.py +0 -0
  122. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/linear.py +0 -0
  123. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/parametrization.py +0 -0
  124. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/stats.py +0 -0
  125. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/util.py +0 -0
  126. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/modules/wrapper.py +0 -0
  127. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/preprocessing/__init__.py +0 -0
  128. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  129. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/preprocessing/preprocess.py +0 -0
  130. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/preprocessing/util.py +0 -0
  131. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/preprocessing/windowers.py +0 -0
  132. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/regressor.py +0 -0
  133. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/samplers/__init__.py +0 -0
  134. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/samplers/base.py +0 -0
  135. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/samplers/ssl.py +0 -0
  136. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/training/__init__.py +0 -0
  137. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/training/callbacks.py +0 -0
  138. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/training/losses.py +0 -0
  139. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/training/scoring.py +0 -0
  140. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/util.py +0 -0
  141. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/visualization/__init__.py +0 -0
  142. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/visualization/attribution.py +0 -0
  143. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/visualization/confusion_matrices.py +0 -0
  144. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/visualization/frequency.py +0 -0
  145. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/visualization/metrics.py +0 -0
  146. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/visualization/sanity.py +0 -0
  147. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode/visualization/topology.py +0 -0
  148. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode.egg-info/dependency_links.txt +0 -0
  149. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/braindecode.egg-info/top_level.txt +0 -0
  150. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/Makefile +0 -0
  151. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/_templates/autosummary/class.rst +0 -0
  152. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  153. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/_templates/autosummary/function.rst +0 -0
  154. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  155. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/cite.rst +0 -0
  156. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/conf.py +0 -0
  157. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/help.rst +0 -0
  158. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/install/install.rst +0 -0
  159. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/install/install_pip.rst +0 -0
  160. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/install/install_source.rst +0 -0
  161. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/categorization/attention.rst +0 -0
  162. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/categorization/channel.rst +0 -0
  163. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/categorization/convolution.rst +0 -0
  164. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/categorization/filterbank.rst +0 -0
  165. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/categorization/gnn.rst +0 -0
  166. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/categorization/interpretable.rst +0 -0
  167. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/categorization/lbm.rst +0 -0
  168. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/categorization/recurrent.rst +0 -0
  169. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/categorization/spd.rst +0 -0
  170. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/models.rst +0 -0
  171. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/models_categorization.rst +0 -0
  172. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/models/models_visualization.rst +0 -0
  173. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/docs/sg_execution_times.rst +0 -0
  174. {braindecode-1.6.1.dev1014 → braindecode-1.6.1.dev1034}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.6.1.dev1014
3
+ Version: 1.6.1.dev1034
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>
@@ -46,7 +46,7 @@ Requires-Dist: zarr>=3.0; extra == "hub"
46
46
  Provides-Extra: viz
47
47
  Requires-Dist: captum>=0.7.0; extra == "viz"
48
48
  Provides-Extra: tests
49
- Requires-Dist: pytest<9.1; extra == "tests"
49
+ Requires-Dist: pytest; extra == "tests"
50
50
  Requires-Dist: pytest-cov; extra == "tests"
51
51
  Requires-Dist: codecov; extra == "tests"
52
52
  Requires-Dist: pytest_cases; extra == "tests"
@@ -327,7 +327,6 @@ class HubDatasetMixin:
327
327
 
328
328
  n_recordings = len(self.datasets)
329
329
  first_ds = self.datasets[0]
330
- descriptions = [ds.description for ds in self.datasets]
331
330
 
332
331
  # Get dataset-specific info based on type using registry
333
332
  dataset_type = get_dataset_type(first_ds)
@@ -359,9 +358,6 @@ class HubDatasetMixin:
359
358
  raise TypeError(f"Unsupported dataset type: {dataset_type}")
360
359
 
361
360
  # Create README content and save
362
- license_value, license_needs_update = _infer_license_from_descriptions(
363
- descriptions
364
- )
365
361
  readme_content = _generate_readme_content(
366
362
  format_info=format_info,
367
363
  n_recordings=n_recordings,
@@ -370,8 +366,6 @@ class HubDatasetMixin:
370
366
  data_type=data_type,
371
367
  n_windows=n_windows,
372
368
  total_duration=total_duration,
373
- license=license_value,
374
- license_needs_update=license_needs_update,
375
369
  )
376
370
 
377
371
  # Save README
@@ -973,8 +967,6 @@ def _generate_readme_content(
973
967
  n_windows: int,
974
968
  total_duration: float | None = None,
975
969
  format: str = "zarr",
976
- license: str = "please-specify",
977
- license_needs_update: bool = True,
978
970
  ):
979
971
  """Generate README.md content for a dataset uploaded to the Hub.
980
972
 
@@ -996,10 +988,6 @@ def _generate_readme_content(
996
988
  Total duration in seconds across all recordings.
997
989
  format : str
998
990
  Storage format (default: "zarr").
999
- license : str
1000
- Dataset license string to write in YAML front matter.
1001
- license_needs_update : bool
1002
- Whether to append a reminder comment next to the license field.
1003
991
 
1004
992
  Returns
1005
993
  -------
@@ -1015,10 +1003,6 @@ def _generate_readme_content(
1015
1003
  str(timedelta(seconds=int(total_duration))) if total_duration else "N/A"
1016
1004
  )
1017
1005
 
1018
- license_line = f"license: {license}"
1019
- if license_needs_update:
1020
- license_line += " # Please update this field to reflect your dataset's license"
1021
-
1022
1006
  return f"""---
1023
1007
  tags:
1024
1008
  - braindecode
@@ -1026,7 +1010,7 @@ tags:
1026
1010
  - neuroscience
1027
1011
  - brain-computer-interface
1028
1012
  - deep-learning
1029
- {license_line}
1013
+ license: unknown
1030
1014
  ---
1031
1015
 
1032
1016
  # EEG Dataset
@@ -1122,27 +1106,3 @@ if hasattr(dataset.datasets[0], "bids_channels"):
1122
1106
 
1123
1107
  *Created with [braindecode](https://braindecode.org)*
1124
1108
  """
1125
-
1126
-
1127
- def _infer_license_from_descriptions(
1128
- descriptions: list[pd.Series | None],
1129
- ) -> tuple[str, bool]:
1130
- """Infer a single dataset license from descriptions.
1131
-
1132
- Returns inferred license and whether a manual update reminder is needed.
1133
- """
1134
- licenses = set()
1135
- for description in descriptions:
1136
- if description is None:
1137
- continue
1138
- raw_license = description.get("license", None)
1139
- if raw_license is None:
1140
- continue
1141
- normalized = str(raw_license).strip()
1142
- if normalized and normalized.lower() != "nan":
1143
- licenses.add(normalized)
1144
-
1145
- if len(licenses) == 1:
1146
- return next(iter(licenses)), False
1147
-
1148
- return "please-specify", True
@@ -15,6 +15,7 @@ from typing import Any
15
15
 
16
16
  import mne
17
17
  import pandas as pd
18
+ from mne.utils import deprecated
18
19
 
19
20
  from braindecode.util import _update_moabb_docstring
20
21
 
@@ -207,3 +208,12 @@ class HGD(MOABBDataset):
207
208
 
208
209
  def __init__(self, subject_ids):
209
210
  super().__init__("Schirrmeister2017", subject_ids=subject_ids)
211
+
212
+
213
+ @deprecated(
214
+ "`BNCI2014001` was renamed to `BNCI2014_001` in v1.13; this alias will be removed in v1.14."
215
+ )
216
+ class BNCI2014001(BNCI2014_001):
217
+ """Deprecated alias for BNCI2014001."""
218
+
219
+ pass
@@ -7,7 +7,6 @@
7
7
  import abc
8
8
  import inspect
9
9
  import logging
10
- import warnings
11
10
  from typing import Literal
12
11
 
13
12
  import mne
@@ -42,7 +41,6 @@ def _get_model(model: str):
42
41
 
43
42
  class _EEGNeuralNet(NeuralNet, abc.ABC):
44
43
  signal_args_set_ = False
45
- _warned_drop_last_ = False
46
44
 
47
45
  @property
48
46
  def log(self):
@@ -269,44 +267,6 @@ class _EEGNeuralNet(NeuralNet, abc.ABC):
269
267
  X = X.get_data(units="uV")
270
268
  return super().get_dataset(X, y)
271
269
 
272
- def get_iterator(self, dataset, training=False):
273
- iterator = super().get_iterator(dataset, training=training)
274
- # Warn (once per fit) if drop_last would discard every training batch,
275
- # e.g. a training set smaller than batch_size. This silently skips
276
- # training without raising any error, which is hard to diagnose.
277
- if training and not self._warned_drop_last_:
278
- self._warn_if_training_batches_dropped(iterator)
279
- return iterator
280
-
281
- def _warn_if_training_batches_dropped(self, loader):
282
- """Warn if ``drop_last`` discards all training batches.
283
-
284
- With ``iterator_train__drop_last=True`` (the braindecode default), a
285
- training set smaller than ``batch_size`` yields zero batches, so no
286
- forward/backward pass runs and the model is left untrained without any
287
- error. We inspect the resolved training ``DataLoader`` (after
288
- ``train_split`` has been applied), so the count reflects the actual
289
- number of training examples.
290
- """
291
- self._warned_drop_last_ = True
292
- if not getattr(loader, "drop_last", False):
293
- return
294
- batch_size = getattr(loader, "batch_size", None)
295
- try:
296
- n_train = len(loader.dataset)
297
- except TypeError:
298
- return # e.g. an IterableDataset whose length is unknown
299
- if not batch_size or n_train == 0 or n_train >= batch_size:
300
- return
301
- warnings.warn(
302
- f"The training set has {n_train} example(s), which is smaller than "
303
- f"batch_size={batch_size}. With iterator_train__drop_last=True "
304
- f"(the braindecode default), all training batches are dropped and "
305
- f"the model is not trained. Reduce batch_size to at most {n_train}, "
306
- f"or pass iterator_train__drop_last=False.",
307
- UserWarning,
308
- )
309
-
310
270
  def partial_fit(self, X, y=None, classes=None, **fit_params):
311
271
  """Fit the module.
312
272
 
@@ -406,7 +366,6 @@ class _EEGNeuralNet(NeuralNet, abc.ABC):
406
366
  the module and to the ``self.train_split`` call.
407
367
  """
408
368
  # this needs to be executed before the net is initialized:
409
- self._warned_drop_last_ = False # re-check on every fresh fit
410
369
  if not self.signal_args_set_:
411
370
  self._set_signal_args(X, y, classes=None)
412
371
  self.signal_args_set_ = True
@@ -15,12 +15,11 @@ from .deep4 import Deep4Net
15
15
  from .deepsleepnet import DeepSleepNet
16
16
  from .dgcnn import DGCNN
17
17
  from .eegconformer import EEGConformer
18
- from .eegdino import EEGDINO
19
18
  from .eeginception_erp import EEGInceptionERP
20
19
  from .eeginception_mi import EEGInceptionMI
21
20
  from .eegitnet import EEGITNet
22
21
  from .eegminer import EEGMiner
23
- from .eegnet import EEGNet
22
+ from .eegnet import EEGNet, EEGNetv4
24
23
  from .eegnex import EEGNeX
25
24
  from .eegpt import EEGPT, InterpolatedEEGPT
26
25
  from .eegsimpleconv import EEGSimpleConv
@@ -55,7 +54,6 @@ from .sleep_stager_chambon_2018 import SleepStagerChambon2018
55
54
  from .sparcnet import SPARCNet
56
55
  from .sstdpn import SSTDPN
57
56
  from .syncnet import SyncNet
58
- from .tcformer import TCFormer
59
57
  from .tcn import BDTCN, TCN
60
58
  from .tidnet import TIDNet
61
59
  from .tsinception import TSception
@@ -86,7 +84,6 @@ __all__ = [
86
84
  "DeepSleepNet",
87
85
  "BrainModule",
88
86
  "EEGConformer",
89
- "EEGDINO",
90
87
  "EEGPT",
91
88
  "InterpolatedEEGPT",
92
89
  "EEGInceptionERP",
@@ -94,6 +91,7 @@ __all__ = [
94
91
  "EEGITNet",
95
92
  "EEGMiner",
96
93
  "EEGNet",
94
+ "EEGNetv4",
97
95
  "EEGNeX",
98
96
  "EEGSym",
99
97
  "EEGSimpleConv",
@@ -131,7 +129,6 @@ __all__ = [
131
129
  "SPARCNet",
132
130
  "SyncNet",
133
131
  "BDTCN",
134
- "TCFormer",
135
132
  "TCN",
136
133
  "TIDNet",
137
134
  "TSception",
@@ -2,21 +2,14 @@
2
2
  #
3
3
  # License: BSD (3-clause)
4
4
  import math
5
- from typing import Optional
6
5
 
7
6
  import torch
8
7
  from einops.layers.torch import Rearrange
9
8
  from mne.utils import warn
10
9
  from torch import nn
11
- from torch.nn.utils.parametrize import is_parametrized, register_parametrization
12
10
 
13
11
  from braindecode.models.base import EEGModuleMixin
14
- from braindecode.modules import (
15
- CausalConv1d,
16
- Ensure4d,
17
- MaxNormLinear,
18
- MaxNormParametrize,
19
- )
12
+ from braindecode.modules import CausalConv1d, Ensure4d, MaxNormLinear
20
13
 
21
14
 
22
15
  class ATCNet(EEGModuleMixin, nn.Module):
@@ -220,16 +213,6 @@ class ATCNet(EEGModuleMixin, nn.Module):
220
213
  max_norm_const : float
221
214
  Maximum L2-norm constraint imposed on weights of the last
222
215
  fully-connected layer. Defaults to 0.25.
223
- conv_max_norm_const : float | None
224
- If not ``None``, applies a max-norm constraint (via a weight
225
- parametrization) to the convolution kernels of :class:`_ConvBlock` and
226
- :class:`_TCNResidualBlock`, matching the official implementation which
227
- uses ``0.6``. When ``None`` (default), no constraint is applied to those
228
- layers, preserving the previous behavior. The complementary ``L2``
229
- weight decay of the official code can be obtained from
230
- :meth:`source_optimizer_param_groups`.
231
-
232
- .. versionadded:: 1.6.1
233
216
 
234
217
  Notes
235
218
  -----
@@ -274,7 +257,6 @@ class ATCNet(EEGModuleMixin, nn.Module):
274
257
  tcn_activation: type[nn.Module] = nn.ELU,
275
258
  concat=False,
276
259
  max_norm_const=0.25,
277
- conv_max_norm_const: Optional[float] = None,
278
260
  chs_info=None,
279
261
  n_times=None,
280
262
  ):
@@ -343,7 +325,6 @@ class ATCNet(EEGModuleMixin, nn.Module):
343
325
  self.tcn_activation = tcn_activation
344
326
  self.concat = concat
345
327
  self.max_norm_const = max_norm_const
346
- self.conv_max_norm_const = conv_max_norm_const
347
328
  self.tcn_n_filters = int(self.conv_block_depth_mult * self.conv_block_n_filters)
348
329
  map = dict()
349
330
  for w in range(self.n_windows):
@@ -365,7 +346,6 @@ class ATCNet(EEGModuleMixin, nn.Module):
365
346
  pool_size_2=conv_block_pool_size_2,
366
347
  depth_mult=conv_block_depth_mult,
367
348
  dropout=conv_block_dropout,
368
- conv_max_norm=self.conv_max_norm_const,
369
349
  )
370
350
 
371
351
  self.F2 = int(conv_block_depth_mult * conv_block_n_filters)
@@ -395,7 +375,6 @@ class ATCNet(EEGModuleMixin, nn.Module):
395
375
  dropout=self.tcn_dropout,
396
376
  activation=self.tcn_activation,
397
377
  dilation=2**i,
398
- conv_max_norm=self.conv_max_norm_const,
399
378
  )
400
379
  for i in range(self.tcn_depth)
401
380
  ]
@@ -479,93 +458,6 @@ class ATCNet(EEGModuleMixin, nn.Module):
479
458
 
480
459
  return self.out_fun(sw_concat_agg)
481
460
 
482
- def source_optimizer_param_groups(
483
- self,
484
- conv_weight_decay: float = 0.009,
485
- dense_weight_decay: float = 0.5,
486
- ) -> list[dict]:
487
- r"""Source-faithful optimizer parameter groups for ATCNet.
488
-
489
- The official Keras implementation applies ``L2`` weight decay only to the
490
- convolution / TCN kernels (``conv_weightDecay = 0.009``) and to the final
491
- dense layer (``dense_weightDecay = 0.5``); biases, BatchNorm and attention
492
- weights are left undecayed. This reproduces the Keras ``L2`` kernel penalty
493
- only for optimizers that implement ``weight_decay`` as a coupled L2 term,
494
- e.g. :class:`torch.optim.SGD` or :class:`torch.optim.Adam` (as used by the
495
- official code). For decoupled-weight-decay optimizers such as
496
- :class:`torch.optim.AdamW`, ``weight_decay`` is *not* equivalent to a Keras
497
- ``L2`` penalty.
498
-
499
- Parameters
500
- ----------
501
- conv_weight_decay : float
502
- Weight decay applied to the convolution and TCN kernels. Defaults to
503
- ``0.009`` as in the official code.
504
- dense_weight_decay : float
505
- Weight decay applied to the final (dense) layer weights. Defaults to
506
- ``0.5`` as in the official code.
507
-
508
- Returns
509
- -------
510
- list of dict
511
- Parameter groups ready to be passed to a ``torch.optim`` optimizer:
512
- convolution/TCN kernels, final dense weights, and everything else
513
- (no decay).
514
-
515
- Examples
516
- --------
517
- >>> model = ATCNet(n_chans=22, n_outputs=4, n_times=1125) # doctest: +SKIP
518
- >>> opt = torch.optim.Adam(model.source_optimizer_param_groups()) # doctest: +SKIP
519
- """
520
-
521
- def weight_leaf(module):
522
- # Return the leaf weight Parameter, accounting for a registered
523
- # max-norm parametrization (``conv_max_norm_const`` / MaxNormLinear).
524
- if is_parametrized(module, "weight"):
525
- return module.parametrizations.weight.original
526
- return module.weight
527
-
528
- conv_weights: list[nn.Parameter] = []
529
- dense_weights: list[nn.Parameter] = []
530
- decayed_ids: set[int] = set()
531
-
532
- # Convolution / TCN kernels (Keras L2 = 0.009).
533
- for parent in (self.conv_block, self.temporal_conv_nets):
534
- for module in parent.modules():
535
- if isinstance(module, (nn.Conv1d, nn.Conv2d)):
536
- weight = weight_leaf(module)
537
- conv_weights.append(weight)
538
- decayed_ids.add(id(weight))
539
-
540
- # Final dense / readout weights (Keras L2 = 0.5).
541
- for module in self.final_layer.modules():
542
- if isinstance(module, nn.Linear):
543
- weight = weight_leaf(module)
544
- dense_weights.append(weight)
545
- decayed_ids.add(id(weight))
546
-
547
- # Everything else (biases, BatchNorm, attention) is left undecayed.
548
- other = [p for p in self.parameters() if id(p) not in decayed_ids]
549
-
550
- return [
551
- {"params": conv_weights, "weight_decay": conv_weight_decay},
552
- {"params": dense_weights, "weight_decay": dense_weight_decay},
553
- {"params": other, "weight_decay": 0.0},
554
- ]
555
-
556
-
557
- def _register_max_norm(max_norm, *convs):
558
- """Register a max-norm weight parametrization on each given convolution.
559
-
560
- No-op when ``max_norm`` is ``None`` or a passed layer is not a convolution
561
- (e.g. an ``nn.Identity`` residual shortcut).
562
- """
563
- if max_norm is None:
564
- return
565
- for conv in convs:
566
- if isinstance(conv, (nn.Conv1d, nn.Conv2d)):
567
- register_parametrization(conv, "weight", MaxNormParametrize(max_norm))
568
-
569
461
 
570
462
  class _ConvBlock(nn.Module):
571
463
  r"""Convolutional block proposed in ATCNet [1]_, inspired by the EEGNet.
@@ -595,7 +487,6 @@ class _ConvBlock(nn.Module):
595
487
  pool_size_2=7,
596
488
  depth_mult=2,
597
489
  dropout=0.3,
598
- conv_max_norm: Optional[float] = None,
599
490
  ):
600
491
  super().__init__()
601
492
 
@@ -643,9 +534,6 @@ class _ConvBlock(nn.Module):
643
534
 
644
535
  self.drop3 = nn.Dropout2d(dropout)
645
536
 
646
- # Optional source-faithful max-norm constraint on the conv kernels.
647
- _register_max_norm(conv_max_norm, self.conv1, self.conv2, self.conv3)
648
-
649
537
  def forward(self, X):
650
538
  # ----- Temporal convolution -----
651
539
  # Dimension: (batch_size, 1, T, C)
@@ -774,7 +662,6 @@ class _TCNResidualBlock(nn.Module):
774
662
  dropout=0.3,
775
663
  activation: type[nn.Module] = nn.ELU,
776
664
  dilation=1,
777
- conv_max_norm: Optional[float] = None,
778
665
  ):
779
666
  super().__init__()
780
667
  self.activation = activation()
@@ -819,10 +706,6 @@ class _TCNResidualBlock(nn.Module):
819
706
  else:
820
707
  self.reshaping_conv = nn.Identity()
821
708
 
822
- # Optional source-faithful max-norm constraint on the conv kernels
823
- # (reshaping_conv may be nn.Identity, which the helper skips).
824
- _register_max_norm(conv_max_norm, self.conv1, self.conv2, self.reshaping_conv)
825
-
826
709
  def forward(self, X):
827
710
  # Dimension: (batch_size, F2, Tw)
828
711
  # ----- Double dilated convolutions -----
@@ -8,6 +8,7 @@ from copy import deepcopy
8
8
 
9
9
  import torch
10
10
  import torch.nn.functional as F
11
+ from mne.utils import deprecated
11
12
  from torch import nn
12
13
 
13
14
  from braindecode.models.base import EEGModuleMixin
@@ -537,3 +538,12 @@ class _PositionwiseFeedForward(nn.Module):
537
538
  def forward(self, x: torch.Tensor) -> torch.Tensor:
538
539
  """Implements FFN equation."""
539
540
  return self.w_2(self.dropout(self.activate(self.w_1(x))))
541
+
542
+
543
+ @deprecated(
544
+ "`SleepStagerEldele2021` was renamed to `AttnSleep` in v1.12 to follow original author's name; this alias will be removed in v1.14."
545
+ )
546
+ class SleepStagerEldele2021(AttnSleep):
547
+ r"""Deprecated alias for SleepStagerEldele2021."""
548
+
549
+ pass
@@ -6,7 +6,7 @@ from __future__ import annotations
6
6
  from typing import Dict, Optional
7
7
 
8
8
  from einops.layers.torch import Rearrange
9
- from mne.utils import warn
9
+ from mne.utils import deprecated, warn
10
10
  from torch import nn
11
11
 
12
12
  from braindecode.functional import glorot_weight_zero_bias
@@ -348,3 +348,12 @@ class EEGNet(EEGModuleMixin, nn.Sequential):
348
348
  self.add_module("final_layer", module)
349
349
 
350
350
  glorot_weight_zero_bias(self)
351
+
352
+
353
+ @deprecated(
354
+ "`EEGNetv4` was renamed to `EEGNet` in v1.12; this alias will be removed in v1.14."
355
+ )
356
+ class EEGNetv4(EEGNet):
357
+ r"""Deprecated alias for EEGNet."""
358
+
359
+ pass
@@ -9,7 +9,6 @@ import torch.nn as nn
9
9
  from einops.layers.torch import Rearrange
10
10
 
11
11
  from braindecode.models.base import EEGModuleMixin
12
- from braindecode.models.util import _disable_batch_norm_training_if_batch_size_one
13
12
  from braindecode.modules import Chomp1d, MaxNormLinear
14
13
 
15
14
 
@@ -34,10 +33,8 @@ class EEGTCNet(EEGModuleMixin, nn.Module):
34
33
  Number of temporal filters in the first convolutional layer. Default is 8.
35
34
  kern_length : int, optional
36
35
  Length of the temporal kernel in the first convolutional layer. Default is 64.
37
- drop_prob : float, optional
38
- Default dropout rate, used for both the EEGNet front-end and the TCN
39
- block unless overridden by ``drop_prob_eeg`` / ``drop_prob_tcn``.
40
- Default is 0.5.
36
+ dropout : float, optional
37
+ Dropout rate. Default is 0.5.
41
38
  depth : int, optional
42
39
  Number of residual blocks in the TCN. Default is 2.
43
40
  kernel_size : int, optional
@@ -47,20 +44,6 @@ class EEGTCNet(EEGModuleMixin, nn.Module):
47
44
  max_norm_const : float
48
45
  Maximum L2-norm constraint imposed on weights of the last
49
46
  fully-connected layer. Defaults to 0.25.
50
- drop_prob_eeg : float | None, optional
51
- Dropout rate for the EEGNet front-end. If ``None`` (default), falls back
52
- to ``drop_prob``. The source/paper uses ``0.2`` for BCI IV 2a.
53
- drop_prob_tcn : float | None, optional
54
- Dropout rate for the TCN block. If ``None`` (default), falls back to
55
- ``drop_prob``. The source/paper uses ``0.3`` for BCI IV 2a.
56
- tcn_batch_norm : bool, optional
57
- If ``True`` (default), insert a :class:`~torch.nn.BatchNorm1d` after each
58
- TCN convolution and use a bias in the residual ``1x1`` downsample, matching
59
- the original Keras source. Set to ``False`` to recover the previous
60
- braindecode architecture (e.g. to load checkpoints trained before this
61
- change). Default is ``True``.
62
-
63
- .. versionadded:: 1.6.1
64
47
 
65
48
  References
66
49
  ----------
@@ -89,9 +72,6 @@ class EEGTCNet(EEGModuleMixin, nn.Module):
89
72
  kernel_size: int = 4,
90
73
  filters: int = 12,
91
74
  max_norm_const: float = 0.25,
92
- drop_prob_eeg: float | None = None,
93
- drop_prob_tcn: float | None = None,
94
- tcn_batch_norm: bool = True,
95
75
  ):
96
76
  super().__init__(
97
77
  n_outputs=n_outputs,
@@ -105,11 +85,6 @@ class EEGTCNet(EEGModuleMixin, nn.Module):
105
85
 
106
86
  self.activation = activation
107
87
  self.drop_prob = drop_prob
108
- # Separate dropout rates for the EEGNet front-end and the TCN block;
109
- # fall back to ``drop_prob`` when not explicitly set.
110
- self.drop_prob_eeg = drop_prob if drop_prob_eeg is None else drop_prob_eeg
111
- self.drop_prob_tcn = drop_prob if drop_prob_tcn is None else drop_prob_tcn
112
- self.tcn_batch_norm = tcn_batch_norm
113
88
  self.depth_multiplier = depth_multiplier
114
89
  self.filter_1 = filter_1
115
90
  self.kern_length = kern_length
@@ -128,7 +103,7 @@ class EEGTCNet(EEGModuleMixin, nn.Module):
128
103
  filter_1=self.filter_1,
129
104
  kern_length=self.kern_length,
130
105
  depth_multiplier=self.depth_multiplier,
131
- drop_prob=self.drop_prob_eeg,
106
+ drop_prob=self.drop_prob,
132
107
  activation=self.activation,
133
108
  )
134
109
  self.arrange_dim_eegnet = Rearrange(
@@ -141,9 +116,8 @@ class EEGTCNet(EEGModuleMixin, nn.Module):
141
116
  depth=self.depth,
142
117
  kernel_size=self.kernel_size,
143
118
  filters=self.filters,
144
- drop_prob=self.drop_prob_tcn,
119
+ drop_prob=self.drop_prob,
145
120
  activation=self.activation,
146
- batch_norm=self.tcn_batch_norm,
147
121
  )
148
122
 
149
123
  # Classification Block
@@ -153,7 +127,6 @@ class EEGTCNet(EEGModuleMixin, nn.Module):
153
127
  max_norm_val=self.max_norm_const,
154
128
  )
155
129
 
156
- @_disable_batch_norm_training_if_batch_size_one
157
130
  def forward(self, x: torch.Tensor) -> torch.Tensor:
158
131
  """
159
132
  Forward pass of the EEGTCNet model.
@@ -304,7 +277,6 @@ class _TCNBlock(nn.Module):
304
277
  filters: int,
305
278
  drop_prob: float,
306
279
  activation: type[nn.Module] = nn.ELU,
307
- batch_norm: bool = True,
308
280
  ):
309
281
  super().__init__()
310
282
  self.activation = activation()
@@ -312,15 +284,10 @@ class _TCNBlock(nn.Module):
312
284
  self.depth = depth
313
285
  self.filters = filters
314
286
  self.kernel_size = kernel_size
315
- self.batch_norm = batch_norm
316
287
 
317
288
  self.layers = nn.ModuleList()
318
- # The Keras source uses a bias on the residual 1x1 downsample, paired
319
- # with the per-conv BatchNorm; the previous braindecode default omitted
320
- # both. Keeping them on the same flag makes ``batch_norm=False`` reproduce
321
- # the legacy architecture exactly.
322
289
  self.downsample = (
323
- nn.Conv1d(input_dimension, filters, kernel_size=1, bias=batch_norm)
290
+ nn.Conv1d(input_dimension, filters, kernel_size=1, bias=False)
324
291
  if input_dimension != filters
325
292
  else None
326
293
  )
@@ -328,34 +295,32 @@ class _TCNBlock(nn.Module):
328
295
  for i in range(depth):
329
296
  dilation = 2**i
330
297
  padding = (kernel_size - 1) * dilation
331
- in_dim = input_dimension if i == 0 else filters
332
298
  conv_block = nn.Sequential(
333
- *self._conv_unit(in_dim, dilation, padding),
334
- *self._conv_unit(filters, dilation, padding),
299
+ nn.Conv1d(
300
+ in_channels=input_dimension if i == 0 else filters,
301
+ out_channels=filters,
302
+ kernel_size=kernel_size,
303
+ dilation=dilation,
304
+ padding=padding,
305
+ bias=False,
306
+ ),
307
+ Chomp1d(padding),
308
+ self.activation,
309
+ nn.Dropout(self.drop_prob),
310
+ nn.Conv1d(
311
+ in_channels=filters,
312
+ out_channels=filters,
313
+ kernel_size=kernel_size,
314
+ dilation=dilation,
315
+ padding=padding,
316
+ bias=False,
317
+ ),
318
+ Chomp1d(padding),
319
+ self.activation,
320
+ nn.Dropout(self.drop_prob),
335
321
  )
336
322
  self.layers.append(conv_block)
337
323
 
338
- def _conv_unit(self, in_channels: int, dilation: int, padding: int):
339
- # Conv -> Chomp -> [BatchNorm] -> activation -> Dropout, as in the
340
- # original EEG-TCNet Keras implementation.
341
- unit = [
342
- nn.Conv1d(
343
- in_channels=in_channels,
344
- out_channels=self.filters,
345
- kernel_size=self.kernel_size,
346
- dilation=dilation,
347
- padding=padding,
348
- bias=False,
349
- ),
350
- Chomp1d(padding),
351
- ]
352
- if self.batch_norm:
353
- # Keras BatchNormalization defaults: momentum=0.99 (-> 0.01 in
354
- # PyTorch convention) and epsilon=1e-3.
355
- unit.append(nn.BatchNorm1d(self.filters, momentum=0.01, eps=1e-3))
356
- unit += [self.activation, nn.Dropout(self.drop_prob)]
357
- return unit
358
-
359
324
  def forward(self, x: torch.Tensor) -> torch.Tensor:
360
325
  # x shape: (batch_size, time_steps, input_dimension)
361
326
  x = x.permute(0, 2, 1) # (batch_size, input_dimension, time_steps)