Braindecode 1.7.0__tar.gz → 1.7.0.dev174519142__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. {braindecode-1.7.0/braindecode.egg-info → braindecode-1.7.0.dev174519142}/PKG-INFO +1 -1
  2. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/classifier.py +7 -7
  3. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/functional/__init__.py +0 -4
  4. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/functional/functions.py +2 -39
  5. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/__init__.py +0 -2
  6. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/bendr.py +1 -8
  7. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eegminer.py +62 -38
  8. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/summary.csv +0 -1
  9. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/tcn.py +2 -5
  10. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/util.py +0 -22
  11. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/__init__.py +2 -5
  12. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/filter.py +10 -16
  13. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/regressor.py +7 -7
  14. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/training/__init__.py +1 -4
  15. braindecode-1.7.0.dev174519142/braindecode/training/losses.py +105 -0
  16. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/training/scoring.py +5 -46
  17. braindecode-1.7.0.dev174519142/braindecode/version.py +1 -0
  18. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142/braindecode.egg-info}/PKG-INFO +1 -1
  19. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode.egg-info/SOURCES.txt +0 -2
  20. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/api.rst +0 -2
  21. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/whats_new.rst +1 -26
  22. braindecode-1.7.0/braindecode/models/dance.py +0 -368
  23. braindecode-1.7.0/braindecode/modules/dance_modules.py +0 -333
  24. braindecode-1.7.0/braindecode/training/losses.py +0 -284
  25. braindecode-1.7.0/braindecode/version.py +0 -1
  26. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/LICENSE.txt +0 -0
  27. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/MANIFEST.in +0 -0
  28. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/NOTICE.txt +0 -0
  29. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/README.rst +0 -0
  30. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/__init__.py +0 -0
  31. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/augmentation/__init__.py +0 -0
  32. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/augmentation/base.py +0 -0
  33. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/augmentation/functional.py +0 -0
  34. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/augmentation/transforms.py +0 -0
  35. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/__init__.py +0 -0
  36. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/base.py +0 -0
  37. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/bbci.py +0 -0
  38. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/bcicomp.py +0 -0
  39. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/bids/__init__.py +0 -0
  40. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/bids/datasets.py +0 -0
  41. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/bids/format.py +0 -0
  42. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/bids/hub.py +0 -0
  43. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/bids/hub_format.py +0 -0
  44. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/bids/hub_io.py +0 -0
  45. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/bids/hub_validation.py +0 -0
  46. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/bids/iterable.py +0 -0
  47. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/chb_mit.py +0 -0
  48. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/collate.py +0 -0
  49. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/mne.py +0 -0
  50. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/moabb.py +0 -0
  51. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/nmt.py +0 -0
  52. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/registry.py +0 -0
  53. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/siena.py +0 -0
  54. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  55. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/sleep_physionet.py +0 -0
  56. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/tuh.py +0 -0
  57. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/utils.py +0 -0
  58. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datasets/xy.py +0 -0
  59. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datautil/__init__.py +0 -0
  60. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datautil/channel_utils.py +0 -0
  61. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datautil/hub_formats.py +0 -0
  62. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datautil/serialization.py +0 -0
  63. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/datautil/util.py +0 -0
  64. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/eegneuralnet.py +0 -0
  65. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/functional/initialization.py +0 -0
  66. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/atcnet.py +0 -0
  67. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/attentionbasenet.py +0 -0
  68. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/attn_sleep.py +0 -0
  69. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/base.py +0 -0
  70. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/biot.py +0 -0
  71. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/brainmodule.py +0 -0
  72. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/cbramod.py +0 -0
  73. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/codebrain.py +0 -0
  74. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/config.py +0 -0
  75. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/contrawr.py +0 -0
  76. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/ctnet.py +0 -0
  77. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/deep4.py +0 -0
  78. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/deepsleepnet.py +0 -0
  79. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/dgcnn.py +0 -0
  80. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eegconformer.py +0 -0
  81. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eegdino.py +0 -0
  82. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eeginception_erp.py +0 -0
  83. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eeginception_mi.py +0 -0
  84. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eegitnet.py +0 -0
  85. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eegnet.py +0 -0
  86. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eegnex.py +0 -0
  87. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eegpt.py +0 -0
  88. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eegsimpleconv.py +0 -0
  89. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eegsym.py +0 -0
  90. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/eegtcnet.py +0 -0
  91. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/emg2qwerty.py +0 -0
  92. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/fbcnet.py +0 -0
  93. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/fblightconvnet.py +0 -0
  94. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/fbmsnet.py +0 -0
  95. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/hybrid.py +0 -0
  96. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/ifnet.py +0 -0
  97. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/interpolated.py +0 -0
  98. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/labram.py +0 -0
  99. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/luna.py +0 -0
  100. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/medformer.py +0 -0
  101. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/meta_neuromotor.py +0 -0
  102. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/msvtnet.py +0 -0
  103. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/mvpformer.py +0 -0
  104. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/patchedtransformer.py +0 -0
  105. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/reve.py +0 -0
  106. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/sccnet.py +0 -0
  107. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/shallow_fbcsp.py +0 -0
  108. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/signal_jepa.py +0 -0
  109. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/sinc_shallow.py +0 -0
  110. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  111. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  112. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/sparcnet.py +0 -0
  113. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/sstdpn.py +0 -0
  114. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/steegformer.py +0 -0
  115. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/syncnet.py +0 -0
  116. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/tcformer.py +0 -0
  117. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/tidnet.py +0 -0
  118. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/tsinception.py +0 -0
  119. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/models/usleep.py +0 -0
  120. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/activation.py +0 -0
  121. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/attention.py +0 -0
  122. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/blocks.py +0 -0
  123. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/convolution.py +0 -0
  124. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/interpolation.py +0 -0
  125. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/layers.py +0 -0
  126. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/linear.py +0 -0
  127. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/parametrization.py +0 -0
  128. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/stats.py +0 -0
  129. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/util.py +0 -0
  130. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/modules/wrapper.py +0 -0
  131. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/preprocessing/__init__.py +0 -0
  132. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  133. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/preprocessing/mne_preprocess.py +0 -0
  134. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/preprocessing/preprocess.py +0 -0
  135. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/preprocessing/util.py +0 -0
  136. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/preprocessing/windowers.py +0 -0
  137. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/samplers/__init__.py +0 -0
  138. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/samplers/base.py +0 -0
  139. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/samplers/ssl.py +0 -0
  140. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/training/callbacks.py +0 -0
  141. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/util.py +0 -0
  142. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/visualization/__init__.py +0 -0
  143. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/visualization/attribution.py +0 -0
  144. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/visualization/confusion_matrices.py +0 -0
  145. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/visualization/frequency.py +0 -0
  146. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/visualization/metrics.py +0 -0
  147. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/visualization/sanity.py +0 -0
  148. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode/visualization/topology.py +0 -0
  149. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode.egg-info/dependency_links.txt +0 -0
  150. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode.egg-info/requires.txt +0 -0
  151. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/braindecode.egg-info/top_level.txt +0 -0
  152. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/Makefile +0 -0
  153. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/_templates/autosummary/class.rst +0 -0
  154. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  155. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/_templates/autosummary/function.rst +0 -0
  156. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  157. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/cite.rst +0 -0
  158. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/conf.py +0 -0
  159. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/help.rst +0 -0
  160. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/index.rst +0 -0
  161. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/install/install.rst +0 -0
  162. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/install/install_pip.rst +0 -0
  163. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/install/install_source.rst +0 -0
  164. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/categorization/attention.rst +0 -0
  165. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/categorization/channel.rst +0 -0
  166. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/categorization/convolution.rst +0 -0
  167. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/categorization/filterbank.rst +0 -0
  168. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/categorization/gnn.rst +0 -0
  169. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/categorization/interpretable.rst +0 -0
  170. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/categorization/lbm.rst +0 -0
  171. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/categorization/recurrent.rst +0 -0
  172. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/categorization/spd.rst +0 -0
  173. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/models.rst +0 -0
  174. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/models_categorization.rst +0 -0
  175. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/models_table.rst +0 -0
  176. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/models/models_visualization.rst +0 -0
  177. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/docs/sg_execution_times.rst +0 -0
  178. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/pyproject.toml +0 -0
  179. {braindecode-1.7.0 → braindecode-1.7.0.dev174519142}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.7.0
3
+ Version: 1.7.0.dev174519142
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>
@@ -3,7 +3,6 @@
3
3
  # Lukas Gemein <l.gemein@gmail.com>
4
4
  # Bruno Aristimunha <b.aristimunha@gmail.com>
5
5
  # Pierre Guetschel <pierre.guetschel@gmail.com>
6
- # Sarthak Tayal <sarthaktayal2@gmail.com>
7
6
  #
8
7
  # License: BSD (3-clause)
9
8
 
@@ -196,7 +195,9 @@ class EEGClassifier(_EEGNeuralNet, NeuralNetClassifier):
196
195
  return self.predict_proba(X).argmax(1)
197
196
 
198
197
  def predict_trials(self, X, return_targets=True):
199
- """Create trialwise predictions from a cropped dataset.
198
+ """Create trialwise predictions and optionally also return trialwise.
199
+
200
+ labels from cropped dataset.
200
201
 
201
202
  Parameters
202
203
  ----------
@@ -211,11 +212,10 @@ class EEGClassifier(_EEGNeuralNet, NeuralNetClassifier):
211
212
  3-dimensional array (n_trials x n_classes x n_predictions), where
212
213
  the number of predictions depend on the chosen window size and the
213
214
  receptive field of the network.
214
- trial_targets : np.ndarray
215
- Ground-truth targets from the dataset in a 2-dimensional array
216
- (n_trials x n_targets). Only returned when ``return_targets=True``.
217
- The number of targets depends on the decoding paradigm and can be
218
- either a single value, multiple values, or a sequence.
215
+ trial_labels : np.ndarray
216
+ 2-dimensional array (n_trials x n_targets) where the number of
217
+ targets depends on the decoding paradigm and can be either a single
218
+ value, multiple values, or a sequence.
219
219
  """
220
220
  if not self.cropped:
221
221
  warnings.warn(
@@ -5,8 +5,6 @@ from .functions import (
5
5
  dwt_max_level,
6
6
  hilbert_freq,
7
7
  identity,
8
- iou_1d,
9
- pairwise_iou_1d,
10
8
  plv_time,
11
9
  safe_log,
12
10
  sinusoidal_positional_encoding,
@@ -22,8 +20,6 @@ __all__ = [
22
20
  "dwt_max_level",
23
21
  "hilbert_freq",
24
22
  "identity",
25
- "iou_1d",
26
- "pairwise_iou_1d",
27
23
  "plv_time",
28
24
  "safe_log",
29
25
  "sinusoidal_positional_encoding",
@@ -1,6 +1,5 @@
1
1
  # Authors: Robin Schirrmeister <robintibor@gmail.com>
2
2
  # Bruno Aristimunha <b.aristimunha@gmail.com>
3
- # Sarthak Tayal <sarthaktayal2@gmail.com>
4
3
  #
5
4
  # License: BSD (3-clause)
6
5
 
@@ -110,7 +109,7 @@ def _get_gaussian_kernel1d(kernel_size: int, sigma: float) -> torch.Tensor:
110
109
  return kernel1d
111
110
 
112
111
 
113
- def hilbert_freq(x: torch.Tensor, forward_fourier: bool = True) -> torch.Tensor:
112
+ def hilbert_freq(x, forward_fourier=True):
114
113
  r"""
115
114
  Compute the Hilbert transform using PyTorch, separating the real and
116
115
  imaginary parts.
@@ -179,9 +178,7 @@ def hilbert_freq(x: torch.Tensor, forward_fourier: bool = True) -> torch.Tensor:
179
178
  return x
180
179
 
181
180
 
182
- def plv_time(
183
- x: torch.Tensor, forward_fourier: bool = True, epsilon: float = 1e-6
184
- ) -> torch.Tensor:
181
+ def plv_time(x, forward_fourier=True, epsilon: float = 1e-6):
185
182
  """Compute the Phase Locking Value (PLV) metric in the time domain.
186
183
 
187
184
  The Phase Locking Value (PLV) is a measure of the synchronization between
@@ -260,40 +257,6 @@ def plv_time(
260
257
  return plv_matrix
261
258
 
262
259
 
263
- # -----------------------------------------------------------------------------
264
- # DANCE functional helpers
265
- #
266
- # Authors: Bruno Aristimunha <b.aristimunha@gmail.com>
267
- #
268
- # License: MIT
269
- #
270
- # Ported from the DANCE event-detection model (facebookresearch/dance, MIT).
271
- # -----------------------------------------------------------------------------
272
-
273
-
274
- def iou_1d(s1, e1, s2, e2, eps: float = 1e-7):
275
- """ELEMENTWISE 1-D temporal IoU. All four inputs share the same shape S
276
- (e.g. ``(B, Q)``); returns IoU of shape S. Used by ``DanceLoss`` on the
277
- matched ``(B, Q)`` spans. For (Q,)x(T,) pairwise IoU use ``pairwise_iou_1d``.
278
- """
279
- inter = (torch.minimum(e1, e2) - torch.maximum(s1, s2)).clamp(min=0)
280
- union = (e1 - s1) + (e2 - s2) - inter
281
- return inter / (union + eps)
282
-
283
-
284
- def pairwise_iou_1d(s1, e1, s2, e2, eps: float = 1e-7):
285
- """PAIRWISE 1-D temporal IoU. ``s1,e1`` shape ``(Q,)``, ``s2,e2`` shape
286
- ``(T,)``; returns ``(Q, T)`` (broadcast ``[:, None]`` x ``[None, :]``).
287
- Transcribed from ``dance/matcher.py:33-39`` (``_pairwise_iou``). Used by
288
- ``HungarianMatcher`` to build the ``(Q, n_targets)`` cost matrix.
289
- """
290
- inter_start = torch.maximum(s1[:, None], s2[None, :])
291
- inter_end = torch.minimum(e1[:, None], e2[None, :])
292
- inter = (inter_end - inter_start).clamp(min=0)
293
- union = (e1 - s1)[:, None] + (e2 - s2)[None, :] - inter
294
- return inter / (union + eps)
295
-
296
-
297
260
  def daubechies_filters(n_vanishing: int) -> torch.Tensor:
298
261
  r"""Daubechies ``db<n_vanishing>`` wavelet decomposition filters.
299
262
 
@@ -11,7 +11,6 @@ from .cbramod import CBraMod
11
11
  from .codebrain import CodeBrain
12
12
  from .contrawr import ContraWR
13
13
  from .ctnet import CTNet
14
- from .dance import DANCE
15
14
  from .deep4 import Deep4Net
16
15
  from .deepsleepnet import DeepSleepNet
17
16
  from .dgcnn import DGCNN
@@ -87,7 +86,6 @@ __all__ = [
87
86
  "CodeBrain",
88
87
  "ContraWR",
89
88
  "CTNet",
90
- "DANCE",
91
89
  "Deep4Net",
92
90
  "DeepSleepNet",
93
91
  "BrainModule",
@@ -1,8 +1,3 @@
1
- # Authors: Bruno Aristimunha <b.aristimunha@gmail.com>
2
- # Sarthak Tayal <sarthaktayal2@gmail.com>
3
- #
4
- # License: BSD (3-clause)
5
-
6
1
  import copy
7
2
 
8
3
  import numpy as np
@@ -440,9 +435,7 @@ class _ConvEncoderBENDR(nn.Module):
440
435
  padding=width
441
436
  // 2, # Correct padding for 'same' output length before stride
442
437
  ),
443
- # channel-wise dropout (matches paper specification), on
444
- # (batch, channels, times) activations
445
- nn.Dropout1d(dropout),
438
+ nn.Dropout2d(dropout), # 2D dropout (matches paper specification)
446
439
  nn.GroupNorm(
447
440
  encoder_h // 2, encoder_h
448
441
  ), # Consider making num_groups configurable or ensure encoder_h is divisible by 2
@@ -5,9 +5,10 @@
5
5
  * https://www.ipo.gov.uk/p-ipsum/Case/ApplicationNumber/GB2113420.0
6
6
  """
7
7
 
8
- # Authors: Sarthak Tayal <sarthaktayal2@gmail.com>
8
+ from functools import partial
9
9
 
10
10
  import torch
11
+ from einops.layers.torch import Rearrange
11
12
  from torch import nn
12
13
 
13
14
  import braindecode.functional as F
@@ -18,36 +19,6 @@ from braindecode.modules import GeneralizedGaussianFilter
18
19
  _eeg_miner_methods = ["mag", "corr", "plv"]
19
20
 
20
21
 
21
- class _EEGMinerFeatures(nn.Module):
22
- def __init__(self, method, n_chans, n_filters, n_times):
23
- super().__init__()
24
- self.method = method
25
- self.n_chans = n_chans
26
- self.n_filters = n_filters
27
- self.n_times = n_times
28
- triu = torch.triu_indices(n_chans, n_chans, 1)
29
- self.register_buffer("triu_row", triu[0], persistent=False)
30
- self.register_buffer("triu_col", triu[1], persistent=False)
31
-
32
- def forward(self, x):
33
- if self.method == "mag":
34
- return torch.sqrt((x * x).mean(dim=-1))
35
- if self.method == "corr":
36
- x = x.reshape(
37
- x.shape[0], self.n_chans, self.n_filters, self.n_times
38
- ).transpose(-3, -2)
39
- x = (x - x.mean(dim=-1, keepdim=True)) / torch.sqrt(
40
- x.var(dim=-1, keepdim=True) + 1e-6
41
- )
42
- x = torch.matmul(x, x.transpose(-2, -1)) / x.shape[-1]
43
- x = x.permute(0, 2, 3, 1).abs()
44
- else:
45
- x = x.transpose(-4, -3)
46
- x = F.plv_time(x, forward_fourier=False)
47
- x = x.permute(0, 2, 3, 1)
48
- return x[:, self.triu_row, self.triu_col, :]
49
-
50
-
51
22
  class EEGMiner(EEGModuleMixin, nn.Module):
52
23
  r"""EEGMiner from Ludwig et al (2024) [eegminer]_.
53
24
 
@@ -197,18 +168,24 @@ class EEGMiner(EEGModuleMixin, nn.Module):
197
168
  )
198
169
 
199
170
  # Forward method
200
- self.ensure_dim = nn.Identity()
201
171
  if self.method == "mag":
172
+ self.method_forward = self._apply_mag_forward
202
173
  self.n_features = self.n_chans * self.n_filters
174
+ self.ensure_dim = nn.Identity()
203
175
  elif self.method == "corr":
176
+ self.method_forward = partial(
177
+ self._apply_corr_forward,
178
+ n_chans=self.n_chans,
179
+ n_filters=self.n_filters,
180
+ n_times=self.n_times,
181
+ )
204
182
  self.n_features = self.n_filters * self.n_chans * (self.n_chans - 1) // 2
183
+ self.ensure_dim = nn.Identity()
205
184
  elif self.method == "plv":
206
- self.ensure_dim = nn.Unflatten(-1, (1, self.n_times))
185
+ self.method_forward = partial(self._apply_plv, n_chans=self.n_chans)
186
+ self.ensure_dim = Rearrange("... d -> ... 1 d")
207
187
  self.n_features = (self.n_filters * self.n_chans * (self.n_chans - 1)) // 2
208
188
 
209
- self.feature_layer = _EEGMinerFeatures(
210
- self.method, self.n_chans, self.n_filters, self.n_times
211
- )
212
189
  self.flatten_layer = nn.Flatten()
213
190
  # Classifier
214
191
  self.batch_layer = nn.BatchNorm1d(self.n_features, affine=False)
@@ -218,17 +195,64 @@ class EEGMiner(EEGModuleMixin, nn.Module):
218
195
  @_disable_batch_norm_training_if_batch_size_one
219
196
  def forward(self, x):
220
197
  """x: (batch, electrodes, time)"""
198
+ batch = x.shape[0]
221
199
  x = self.ensure_dim(x)
222
200
  # Apply Gaussian filters in frequency domain
223
201
  # x -> (batch, electrodes * filters, time)
224
202
  x = self.filter(x)
225
203
 
226
- x = self.feature_layer(x)
204
+ x = self.method_forward(x=x, batch=batch)
227
205
  # Classifier
228
206
  # Note that the order of dimensions before flattening the feature vector is important
229
207
  # for attributing feature weights during interpretation.
230
- x = x.reshape(x.shape[0], self.n_features)
208
+ x = x.reshape(batch, self.n_features)
231
209
  x = self.batch_layer(x)
232
210
  x = self.final_layer(x)
233
211
 
234
212
  return x
213
+
214
+ @staticmethod
215
+ def _apply_mag_forward(x, batch=None):
216
+ # Signal magnitude
217
+ x = x * x
218
+ x = x.mean(dim=-1)
219
+ x = torch.sqrt(x)
220
+ return x
221
+
222
+ @staticmethod
223
+ def _apply_corr_forward(
224
+ x, batch, n_chans, n_filters, n_times, epilson: float = 1e-6
225
+ ):
226
+ x = x.reshape(batch, n_chans, n_filters, n_times).transpose(-3, -2)
227
+ x = (x - x.mean(dim=-1, keepdim=True)) / torch.sqrt(
228
+ x.var(dim=-1, keepdim=True) + epilson
229
+ )
230
+ x = torch.matmul(x, x.transpose(-2, -1)) / x.shape[-1]
231
+ # Original tensor shape: [batch, n_filters, chans, chans]
232
+ x = x.permute(0, 2, 3, 1)
233
+ # New tensor shape: [batch, chans, chans, n_filters]
234
+ # move filter channels to the end
235
+ x = x.abs()
236
+
237
+ # Get upper triu of symmetric connectivity matrix
238
+ triu = torch.triu_indices(n_chans, n_chans, 1)
239
+ x = x[:, triu[0], triu[1], :]
240
+
241
+ return x
242
+
243
+ @staticmethod
244
+ def _apply_plv(x, n_chans, batch=None):
245
+ # Compute PLV connectivity
246
+ # x -> (batch, electrodes, electrodes, filters)
247
+ x = x.transpose(-4, -3) # swap electrodes and filters
248
+ # adjusting to compute the plv
249
+ x = F.plv_time(x, forward_fourier=False)
250
+ # batch, number of filters, connectivity matrix
251
+ # [batch, n_filters, chans, chans]
252
+ x = x.permute(0, 2, 3, 1)
253
+ # [batch, chans, chans, n_filters]
254
+
255
+ # Get upper triu of symmetric connectivity matrix
256
+ triu = torch.triu_indices(n_chans, n_chans, 1)
257
+ x = x[:, triu[0], triu[1], :]
258
+ return x
@@ -58,6 +58,5 @@ InterpolatedLaBraM,General,"Prediction, Embedding",200,"chs_info, n_outputs, n_t
58
58
  InterpolatedSignalJEPA,"Motor Imagery, ERP, SSVEP",Embedding,128,"chs_info",3456882,"InterpolatedSignalJEPA(chs_info=<user>)","Convolution,Channel,Foundation Model",EEG
59
59
  TCFormer,Motor Imagery,Classification,250,"n_chans, n_outputs, n_times",77820,"TCFormer(n_chans=22, n_outputs=4, n_times=1000)","Convolution,Attention/Transformer",EEG
60
60
  EEGDINO,General,Classification,200,"n_chans, n_outputs, n_times",4539698,"EEGDINO(n_chans=19, n_outputs=4, n_times=1000)","Foundation Model,Attention/Transformer",EEG
61
- DANCE,General,Event Detection,200,"n_chans, n_outputs, n_times, sfreq, chs_info",29813542,"DANCE(n_chans=19, n_outputs=4, n_times=6400, sfreq=200, input_window_seconds=32.0, chs_info=[{'ch_name': f'E{i+1}', 'kind': 'eeg', 'loc': numpy.random.default_rng(2024).random(12)} for i in range(19)])","Convolution,Attention/Transformer,Channel",EEG
62
61
  STEEGFormer,General,Classification,250,"n_chans, n_outputs, n_times",25305604,"STEEGFormer(n_chans=22, n_outputs=4, n_times=1000)","Attention/Transformer,Foundation Model",EEG
63
62
  MVPFormer,General,"Prediction, Embedding",512,"n_chans, n_outputs, n_times, sfreq",3356978,"MVPFormer(n_chans=22, n_outputs=4, n_times=2000, sfreq=100)","Foundation Model,Attention/Transformer",EEG
@@ -1,6 +1,5 @@
1
1
  # Authors: Patryk Chrabaszcz
2
2
  # Lukas Gemein <l.gemein@gmail.com>
3
- # Sarthak Tayal <sarthaktayal2@gmail.com>
4
3
  #
5
4
  # License: BSD-3
6
5
  import torch
@@ -237,9 +236,7 @@ class _TemporalBlock(nn.Module):
237
236
  )
238
237
  self.chomp1 = Chomp1d(padding)
239
238
  self.relu1 = activation()
240
- # activations are (batch, channels, times), dropout2d only masks
241
- # channel-wise there through a deprecated fallback
242
- self.dropout1 = nn.Dropout1d(drop_prob)
239
+ self.dropout1 = nn.Dropout2d(drop_prob)
243
240
 
244
241
  self.conv2 = weight_norm(
245
242
  nn.Conv1d(
@@ -253,7 +250,7 @@ class _TemporalBlock(nn.Module):
253
250
  )
254
251
  self.chomp2 = Chomp1d(padding)
255
252
  self.relu2 = activation()
256
- self.dropout2 = nn.Dropout1d(drop_prob)
253
+ self.dropout2 = nn.Dropout2d(drop_prob)
257
254
 
258
255
  self.downsample = (
259
256
  nn.Conv1d(n_inputs, n_outputs, 1) if n_inputs != n_outputs else None
@@ -484,25 +484,6 @@ models_mandatory_parameters: list[
484
484
  ),
485
485
  ("DGCNN", ["n_chans", "n_outputs", "n_times", "chs_info"], None),
486
486
  ("EEGDINO", ["n_chans", "n_outputs", "n_times"], None),
487
- (
488
- "DANCE",
489
- ["n_outputs", "n_chans", "n_times", "sfreq", "chs_info"],
490
- {
491
- "n_chans": 19,
492
- "n_times": 6400, # 32 s @ 200 Hz, above the depth-10 stack minimum
493
- "sfreq": 200.0,
494
- "input_window_seconds": 32.0,
495
- "n_outputs": 4,
496
- "chs_info": [
497
- {
498
- "ch_name": f"E{i + 1}",
499
- "kind": "eeg",
500
- "loc": _rng.random(12),
501
- }
502
- for i in range(19)
503
- ],
504
- },
505
- ),
506
487
  ]
507
488
 
508
489
  ################################################################
@@ -517,9 +498,6 @@ non_classification_models = [
517
498
  # Emits a (batch, T_out, vocab) sequence for CTC, not class logits.
518
499
  "MetaNeuromotorHand",
519
500
  "EMG2QwertyNet",
520
- # forward returns (batch, num_latents, n_outputs) dense per-token logits,
521
- # not class logits.
522
- "DANCE",
523
501
  ]
524
502
 
525
503
  ################################################################
@@ -23,7 +23,6 @@ from .convolution import (
23
23
  Conv2dWithConstraint,
24
24
  DepthwiseConv2d,
25
25
  )
26
- from .dance_modules import Perceiver, SimpleConv
27
26
  from .filter import FilterBankLayer, GeneralizedGaussianFilter
28
27
  from .interpolation import ChannelInterpolationLayer
29
28
  from .layers import (
@@ -79,10 +78,6 @@ __all__ = [
79
78
  "Conv1dWithConstraint",
80
79
  "Conv2dWithConstraint",
81
80
  "DepthwiseConv2d",
82
- "ChannelMerger",
83
- "FourierEmb",
84
- "Perceiver",
85
- "SimpleConv",
86
81
  "FilterBankLayer",
87
82
  "GeneralizedGaussianFilter",
88
83
  "Chomp1d",
@@ -93,6 +88,8 @@ __all__ = [
93
88
  "TimeDistributed",
94
89
  "LinearWithConstraint",
95
90
  "MaxNormLinear",
91
+ "ChannelMerger",
92
+ "FourierEmb",
96
93
  "MaxNorm",
97
94
  "MaxNormParametrize",
98
95
  "LogPowerLayer",
@@ -1,7 +1,3 @@
1
- # Authors: Sarthak Tayal <sarthaktayal2@gmail.com>
2
- #
3
- # License: BSD-3
4
-
5
1
  from __future__ import annotations
6
2
 
7
3
  from typing import Optional
@@ -641,22 +637,20 @@ class GeneralizedGaussianFilter(nn.Module):
641
637
  The constructed filters with shape `(out_channels, freq_bins, 2)`.
642
638
 
643
639
  """
644
- min_f_mean = self.clamp_f_mean[0] / (self.sample_rate / 2)
645
- max_f_mean = self.clamp_f_mean[1] / (self.sample_rate / 2)
646
- f_mean = torch.clamp(self.f_mean, min=min_f_mean, max=max_f_mean)
647
- bandwidth = torch.clamp(
648
- self.bandwidth, min=1.0 / (self.sample_rate / 2), max=1.0
640
+ # Clamp parameters
641
+ self.f_mean.data = torch.clamp(
642
+ self.f_mean.data,
643
+ min=self.clamp_f_mean[0] / (self.sample_rate / 2),
644
+ max=self.clamp_f_mean[1] / (self.sample_rate / 2),
649
645
  )
650
- shape = torch.clamp(self.shape, min=2.0, max=3.0)
651
-
652
- if not torch.jit.is_scripting():
653
- self.f_mean.data = f_mean
654
- self.bandwidth.data = bandwidth
655
- self.shape.data = shape
646
+ self.bandwidth.data = torch.clamp(
647
+ self.bandwidth.data, min=1.0 / (self.sample_rate / 2), max=1.0
648
+ )
649
+ self.shape.data = torch.clamp(self.shape.data, min=2.0, max=3.0)
656
650
 
657
651
  # Create magnitude response with gain=1 -> (channels, freqs)
658
652
  mag_response = self.exponential_power(
659
- self.n_range, f_mean, bandwidth, shape * 8 - 14
653
+ self.n_range, self.f_mean, self.bandwidth, self.shape * 8 - 14
660
654
  )
661
655
  mag_response = mag_response / mag_response.max(dim=-1, keepdim=True)[0]
662
656
 
@@ -3,7 +3,6 @@
3
3
  # Lukas Gemein <l.gemein@gmail.com>
4
4
  # Bruno Aristimunha <b.aristimunha@gmail.com>
5
5
  # Pierre Guetschel <pierre.guetschel@gmail.com>
6
- # Sarthak Tayal <sarthaktayal2@gmail.com>
7
6
  #
8
7
  # License: BSD (3-clause)
9
8
 
@@ -140,7 +139,9 @@ class EEGRegressor(_EEGNeuralNet, NeuralNetRegressor):
140
139
  return y_pred
141
140
 
142
141
  def predict_trials(self, X, return_targets=True):
143
- """Create trialwise predictions from a cropped dataset.
142
+ """Create trialwise predictions and optionally also return trialwise.
143
+
144
+ labels from cropped dataset.
144
145
 
145
146
  Parameters
146
147
  ----------
@@ -155,11 +156,10 @@ class EEGRegressor(_EEGNeuralNet, NeuralNetRegressor):
155
156
  3-dimensional array (n_trials x n_classes x n_predictions), where
156
157
  the number of predictions depend on the chosen window size and the
157
158
  receptive field of the network.
158
- trial_targets : np.ndarray
159
- Ground-truth targets from the dataset in a 2-dimensional array
160
- (n_trials x n_targets). Only returned when ``return_targets=True``.
161
- The number of targets depends on the decoding paradigm and can be
162
- either a single value, multiple values, or a sequence.
159
+ trial_labels : np.ndarray
160
+ 2-dimensional array (n_trials x n_targets) where the number of
161
+ targets depends on the decoding paradigm and can be either a single
162
+ value, multiple values, or a sequence.
163
163
  """
164
164
  if not self.cropped:
165
165
  warnings.warn(
@@ -2,19 +2,17 @@
2
2
  Functionality for skorch-based training.
3
3
  """
4
4
 
5
- from .losses import CroppedLoss, DanceLoss, TimeSeriesLoss, mixup_criterion
5
+ from .losses import CroppedLoss, TimeSeriesLoss, mixup_criterion
6
6
  from .scoring import (
7
7
  CroppedTimeSeriesEpochScoring,
8
8
  CroppedTrialEpochScoring,
9
9
  PostEpochTrainScoring,
10
- f1_event,
11
10
  predict_trials,
12
11
  trial_preds_from_window_preds,
13
12
  )
14
13
 
15
14
  __all__ = [
16
15
  "CroppedLoss",
17
- "DanceLoss",
18
16
  "mixup_criterion",
19
17
  "TimeSeriesLoss",
20
18
  "CroppedTrialEpochScoring",
@@ -22,5 +20,4 @@ __all__ = [
22
20
  "CroppedTimeSeriesEpochScoring",
23
21
  "trial_preds_from_window_preds",
24
22
  "predict_trials",
25
- "f1_event",
26
23
  ]
@@ -0,0 +1,105 @@
1
+ # Authors: Robin Schirrmeister <robintibor@gmail.com>
2
+ # Maciej Sliwowski <maciek.sliwowski@gmail.com>
3
+ # Mohammed Fattouh <mo.fattouh@gmail.com>
4
+ #
5
+ # License: BSD (3-clause)
6
+
7
+ import torch
8
+ from torch import nn
9
+
10
+
11
+ class CroppedLoss(nn.Module):
12
+ """Compute Loss after averaging predictions across time.
13
+ Assumes predictions are in shape:
14
+ n_batch size x n_classes x n_predictions (in time)"""
15
+
16
+ def __init__(self, loss_function):
17
+ super().__init__()
18
+ self.loss_function = loss_function
19
+
20
+ def forward(self, preds, targets):
21
+ """Forward pass.
22
+
23
+ Parameters
24
+ ----------
25
+ preds: torch.Tensor
26
+ Model's prediction with shape (batch_size, n_classes, n_times).
27
+ targets: torch.Tensor
28
+ Target labels with shape (batch_size, n_classes, n_times).
29
+ """
30
+ avg_preds = torch.mean(preds, dim=2)
31
+ avg_preds = avg_preds.squeeze(dim=1)
32
+ return self.loss_function(avg_preds, targets)
33
+
34
+
35
+ class TimeSeriesLoss(nn.Module):
36
+ """Compute Loss between timeseries targets and predictions.
37
+ Assumes predictions are in shape:
38
+ n_batch size x n_classes x n_predictions (in time)
39
+ Assumes targets are in shape:
40
+ n_batch size x n_classes x window_len (in time)
41
+ If the targets contain NaNs, the NaNs will be masked out and the loss will be only computed for
42
+ predictions valid corresponding to valid target values."""
43
+
44
+ def __init__(self, loss_function):
45
+ super().__init__()
46
+ self.loss_function = loss_function
47
+
48
+ def forward(self, preds, targets):
49
+ """Forward pass.
50
+
51
+ Parameters
52
+ ----------
53
+ preds: torch.Tensor
54
+ Model's prediction with shape (batch_size, n_classes, n_times).
55
+ targets: torch.Tensor
56
+ Target labels with shape (batch_size, n_classes, n_times).
57
+ """
58
+ n_preds = preds.shape[-1]
59
+ # slice the targets to fit preds shape
60
+ targets = targets[:, :, -n_preds:]
61
+ # create valid targets mask
62
+ mask = ~torch.isnan(targets)
63
+ # select valid targets that have a matching predictions
64
+ masked_targets = targets[mask]
65
+ masked_preds = preds[mask]
66
+ return self.loss_function(masked_preds, masked_targets)
67
+
68
+
69
+ def mixup_criterion(preds, target):
70
+ """Implements loss for Mixup for EEG data. See [1]_.
71
+
72
+ Implementation based on [2]_.
73
+
74
+ Parameters
75
+ ----------
76
+ preds : torch.Tensor
77
+ Predictions from the model.
78
+ target : torch.Tensor | list of torch.Tensor
79
+ For predictions without mixup, the targets as a tensor. If mixup has
80
+ been applied, a list containing the targets of the two mixed
81
+ samples and the mixing coefficients as tensors.
82
+
83
+ Returns
84
+ -------
85
+ loss : float
86
+ The loss value.
87
+
88
+ References
89
+ ----------
90
+ .. [1] Hongyi Zhang, Moustapha Cisse, Yann N. Dauphin, David Lopez-Paz
91
+ mixup: Beyond Empirical Risk Minimization
92
+ Online: https://arxiv.org/abs/1710.09412
93
+ .. [2] https://github.com/facebookresearch/mixup-cifar10/blob/master/train.py
94
+ """
95
+ if len(target) == 3:
96
+ # unpack target
97
+ y_a, y_b, lam = target
98
+ # compute loss per sample
99
+ loss_a = torch.nn.functional.nll_loss(preds, y_a, reduction="none")
100
+ loss_b = torch.nn.functional.nll_loss(preds, y_b, reduction="none")
101
+ # compute weighted mean
102
+ ret = torch.mul(lam, loss_a) + torch.mul(1 - lam, loss_b)
103
+ return ret.mean()
104
+ else:
105
+ return torch.nn.functional.nll_loss(preds, target)