Braindecode 1.3.0.dev180329405__tar.gz → 1.3.0.dev180851780__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 (136) hide show
  1. {braindecode-1.3.0.dev180329405/braindecode.egg-info → braindecode-1.3.0.dev180851780}/PKG-INFO +1 -1
  2. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/eegneuralnet.py +0 -2
  3. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/attentionbasenet.py +0 -2
  4. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/labram.py +69 -168
  5. braindecode-1.3.0.dev180851780/braindecode/version.py +1 -0
  6. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780/braindecode.egg-info}/PKG-INFO +1 -1
  7. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/whats_new.rst +1 -1
  8. braindecode-1.3.0.dev180329405/braindecode/version.py +0 -1
  9. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/LICENSE.txt +0 -0
  10. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/MANIFEST.in +0 -0
  11. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/NOTICE.txt +0 -0
  12. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/README.rst +0 -0
  13. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/__init__.py +0 -0
  14. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/augmentation/__init__.py +0 -0
  15. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/augmentation/base.py +0 -0
  16. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/augmentation/functional.py +0 -0
  17. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/augmentation/transforms.py +0 -0
  18. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/classifier.py +0 -0
  19. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/__init__.py +0 -0
  20. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/base.py +0 -0
  21. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/bbci.py +0 -0
  22. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/bcicomp.py +0 -0
  23. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/bids.py +0 -0
  24. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/experimental.py +0 -0
  25. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/mne.py +0 -0
  26. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/moabb.py +0 -0
  27. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/nmt.py +0 -0
  28. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  29. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/sleep_physionet.py +0 -0
  30. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/tuh.py +0 -0
  31. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datasets/xy.py +0 -0
  32. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datautil/__init__.py +0 -0
  33. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datautil/serialization.py +0 -0
  34. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/datautil/util.py +0 -0
  35. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/functional/__init__.py +0 -0
  36. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/functional/functions.py +0 -0
  37. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/functional/initialization.py +0 -0
  38. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/__init__.py +0 -0
  39. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/atcnet.py +0 -0
  40. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/attn_sleep.py +0 -0
  41. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/base.py +0 -0
  42. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/biot.py +0 -0
  43. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/contrawr.py +0 -0
  44. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/ctnet.py +0 -0
  45. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/deep4.py +0 -0
  46. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/deepsleepnet.py +0 -0
  47. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/eegconformer.py +0 -0
  48. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/eeginception_erp.py +0 -0
  49. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/eeginception_mi.py +0 -0
  50. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/eegitnet.py +0 -0
  51. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/eegminer.py +0 -0
  52. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/eegnet.py +0 -0
  53. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/eegnex.py +0 -0
  54. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/eegsimpleconv.py +0 -0
  55. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/eegtcnet.py +0 -0
  56. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/fbcnet.py +0 -0
  57. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/fblightconvnet.py +0 -0
  58. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/fbmsnet.py +0 -0
  59. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/hybrid.py +0 -0
  60. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/ifnet.py +0 -0
  61. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/msvtnet.py +0 -0
  62. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/patchedtransformer.py +0 -0
  63. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/sccnet.py +0 -0
  64. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/shallow_fbcsp.py +0 -0
  65. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/signal_jepa.py +0 -0
  66. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/sinc_shallow.py +0 -0
  67. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  68. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  69. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/sparcnet.py +0 -0
  70. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/sstdpn.py +0 -0
  71. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/summary.csv +0 -0
  72. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/syncnet.py +0 -0
  73. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/tcn.py +0 -0
  74. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/tidnet.py +0 -0
  75. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/tsinception.py +0 -0
  76. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/usleep.py +0 -0
  77. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/models/util.py +0 -0
  78. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/__init__.py +0 -0
  79. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/activation.py +0 -0
  80. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/attention.py +0 -0
  81. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/blocks.py +0 -0
  82. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/convolution.py +0 -0
  83. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/filter.py +0 -0
  84. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/layers.py +0 -0
  85. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/linear.py +0 -0
  86. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/parametrization.py +0 -0
  87. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/stats.py +0 -0
  88. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/util.py +0 -0
  89. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/modules/wrapper.py +0 -0
  90. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/preprocessing/__init__.py +0 -0
  91. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/preprocessing/mne_preprocess.py +0 -0
  92. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/preprocessing/preprocess.py +0 -0
  93. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/preprocessing/windowers.py +0 -0
  94. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/regressor.py +0 -0
  95. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/samplers/__init__.py +0 -0
  96. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/samplers/base.py +0 -0
  97. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/samplers/ssl.py +0 -0
  98. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/training/__init__.py +0 -0
  99. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/training/callbacks.py +0 -0
  100. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/training/losses.py +0 -0
  101. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/training/scoring.py +0 -0
  102. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/util.py +0 -0
  103. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/visualization/__init__.py +0 -0
  104. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/visualization/confusion_matrices.py +0 -0
  105. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode/visualization/gradients.py +0 -0
  106. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode.egg-info/SOURCES.txt +0 -0
  107. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode.egg-info/dependency_links.txt +0 -0
  108. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode.egg-info/requires.txt +0 -0
  109. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/braindecode.egg-info/top_level.txt +0 -0
  110. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/Makefile +0 -0
  111. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/_templates/autosummary/class.rst +0 -0
  112. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/_templates/autosummary/function.rst +0 -0
  113. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/api.rst +0 -0
  114. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/cite.rst +0 -0
  115. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/conf.py +0 -0
  116. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/help.rst +0 -0
  117. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/index.rst +0 -0
  118. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/install/install.rst +0 -0
  119. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/install/install_pip.rst +0 -0
  120. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/install/install_source.rst +0 -0
  121. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/categorization/attention.rst +0 -0
  122. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/categorization/channel.rst +0 -0
  123. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/categorization/convolution.rst +0 -0
  124. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/categorization/filterbank.rst +0 -0
  125. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/categorization/gnn.rst +0 -0
  126. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/categorization/interpretable.rst +0 -0
  127. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/categorization/lbm.rst +0 -0
  128. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/categorization/recurrent.rst +0 -0
  129. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/categorization/spd.rst +0 -0
  130. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/models.rst +0 -0
  131. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/models_categorization.rst +0 -0
  132. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/models_table.rst +0 -0
  133. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/models/models_visualization.rst +0 -0
  134. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/docs/sg_execution_times.rst +0 -0
  135. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/pyproject.toml +0 -0
  136. {braindecode-1.3.0.dev180329405 → braindecode-1.3.0.dev180851780}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.3.0.dev180329405
3
+ Version: 1.3.0.dev180851780
4
4
  Summary: Deep learning software to decode EEG, ECG or MEG signals
5
5
  Author-email: Robin Tibor Schirrmeister <robintibor@gmail.com>
6
6
  Maintainer-email: Alexandre Gramfort <agramfort@meta.com>, Bruno Aristimunha Pinto <b.aristimunha@gmail.com>, Robin Tibor Schirrmeister <robintibor@gmail.com>
@@ -189,8 +189,6 @@ class _EEGNeuralNet(NeuralNet, abc.ABC):
189
189
  "Skipping setting signal-related parameters from data."
190
190
  )
191
191
  return
192
- if classes is None:
193
- classes = getattr(self, "classes", None)
194
192
  # get kwargs from signal:
195
193
  signal_kwargs = dict()
196
194
  # Using shape to work both with torch.tensor and numpy.array:
@@ -381,8 +381,6 @@ class AttentionBaseNet(EEGModuleMixin, nn.Module):
381
381
  for k, pl, ps in zip(kernel_lengths, pool_lengths, pool_strides):
382
382
  out = math.floor(out + 2 * (k // 2) - k + 1)
383
383
  out = math.floor((out - pl) / ps + 1)
384
- # Ensure output is at least 1 to avoid zero-sized tensors
385
- out = max(1, out)
386
384
  seq_lengths.append(int(out))
387
385
  return seq_lengths
388
386
 
@@ -61,24 +61,13 @@ class Labram(EEGModuleMixin, nn.Module):
61
61
 
62
62
  .. versionadded:: 0.9
63
63
 
64
-
65
- Examples on how to load pre-trained weights:
66
- --------------------------------------------
67
- >>> import torch
68
- >>> from braindecode.models import Labram
69
- >>> model = Labram(n_times=1600, n_chans=64, n_outputs=4)
70
- >>> url = 'https://huggingface.co/braindecode/Labram-Braindecode/blob/main/braindecode_labram_base.pt'
71
- >>> state = torch.hub.load_state_dict_from_url(url, progress=True)
72
- >>> model.load_state_dict(state)
73
-
74
-
75
64
  Parameters
76
65
  ----------
77
66
  patch_size : int
78
67
  The size of the patch to be used in the patch embedding.
79
68
  emb_size : int
80
69
  The dimension of the embedding.
81
- in_conv_channels : int
70
+ in_channels : int
82
71
  The number of convolutional input channels.
83
72
  out_channels : int
84
73
  The number of convolutional output channels.
@@ -90,10 +79,8 @@ class Labram(EEGModuleMixin, nn.Module):
90
79
  The expansion ratio of the mlp layer
91
80
  qkv_bias : bool (default=False)
92
81
  If True, add a learnable bias to the query, key, and value tensors.
93
- qk_norm : Pytorch Normalize layer (default=nn.LayerNorm)
94
- If not None, apply LayerNorm to the query and key tensors.
95
- Default is nn.LayerNorm for better weight transfer from original LaBraM.
96
- Set to None to disable Q,K normalization.
82
+ qk_norm : Pytorch Normalize layer (default=None)
83
+ If not None, apply LayerNorm to the query and key tensors
97
84
  qk_scale : float (default=None)
98
85
  If not None, use this value as the scale factor. If None,
99
86
  use head_dim**-0.5, where head_dim = dim // num_heads.
@@ -105,10 +92,9 @@ class Labram(EEGModuleMixin, nn.Module):
105
92
  Dropout rate for the attention weights used on DropPath.
106
93
  norm_layer : Pytorch Normalize layer (default=nn.LayerNorm)
107
94
  The normalization layer to be used.
108
- init_values : float (default=0.1)
95
+ init_values : float (default=None)
109
96
  If not None, use this value to initialize the gamma_1 and gamma_2
110
- parameters for residual scaling. Default is 0.1 for better weight
111
- transfer from original LaBraM. Set to None to disable.
97
+ parameters.
112
98
  use_abs_pos_emb : bool (default=True)
113
99
  If True, use absolute position embedding.
114
100
  use_mean_pooling : bool (default=True)
@@ -149,19 +135,19 @@ class Labram(EEGModuleMixin, nn.Module):
149
135
  input_window_seconds=None,
150
136
  patch_size=200,
151
137
  emb_size=200,
152
- in_conv_channels=1,
138
+ in_channels=1,
153
139
  out_channels=8,
154
140
  n_layers=12,
155
141
  att_num_heads=10,
156
142
  mlp_ratio=4.0,
157
143
  qkv_bias=False,
158
- qk_norm=nn.LayerNorm,
144
+ qk_norm=None,
159
145
  qk_scale=None,
160
146
  drop_prob=0.0,
161
147
  attn_drop_prob=0.0,
162
148
  drop_path_prob=0.0,
163
149
  norm_layer=nn.LayerNorm,
164
- init_values=0.1,
150
+ init_values=None,
165
151
  use_abs_pos_emb=True,
166
152
  use_mean_pooling=True,
167
153
  init_scale=0.001,
@@ -197,15 +183,15 @@ class Labram(EEGModuleMixin, nn.Module):
197
183
  self.patch_size = patch_size
198
184
  self.n_path = self.n_times // self.patch_size
199
185
 
200
- if neural_tokenizer and in_conv_channels != 1:
186
+ if neural_tokenizer and in_channels != 1:
201
187
  warn(
202
188
  "The model is in Neural Tokenizer mode, but the variable "
203
- + "`in_conv_channels` is different from the default values."
204
- + "`in_conv_channels` is only needed for the Neural Decoder mode."
205
- + "in_conv_channels is not used in the Neural Tokenizer mode.",
189
+ + "`in_channels` is different from the default values."
190
+ + "`in_channels` is only needed for the Neural Decoder mode."
191
+ + "in_channels is not used in the Neural Tokenizer mode.",
206
192
  UserWarning,
207
193
  )
208
- in_conv_channels = 1
194
+ in_channels = 1
209
195
  # If you can use the model in Neural Tokenizer mode,
210
196
  # temporal conv layer will be use over the patched dataset
211
197
  if neural_tokenizer:
@@ -242,7 +228,7 @@ class Labram(EEGModuleMixin, nn.Module):
242
228
  _PatchEmbed(
243
229
  n_times=self.n_times,
244
230
  patch_size=patch_size,
245
- in_channels=in_conv_channels,
231
+ in_channels=in_channels,
246
232
  emb_dim=self.emb_size,
247
233
  ),
248
234
  )
@@ -387,7 +373,8 @@ class Labram(EEGModuleMixin, nn.Module):
387
373
  Parameters
388
374
  ----------
389
375
  x : torch.Tensor
390
- The input data with shape (batch, n_chans, n_times).
376
+ The input data with shape (batch, n_chans, n_patches, patch size),
377
+ if neural decoder or (batch, n_chans, n_times), if neural tokenizer.
391
378
  input_chans : int
392
379
  The number of input channels.
393
380
  return_patch_tokens : bool
@@ -400,72 +387,37 @@ class Labram(EEGModuleMixin, nn.Module):
400
387
  x : torch.Tensor
401
388
  The output of the model.
402
389
  """
403
- batch_size = x.shape[0]
404
-
405
390
  if self.neural_tokenizer:
406
- # For neural tokenizer: input is (batch, n_chans, n_times)
407
- # patch_embed returns (batch, n_chans, emb_dim)
408
- x = self.patch_embed(x)
409
- # x shape: (batch, n_chans, emb_dim)
410
- n_patch = self.n_chans
411
- temporal = self.emb_size
391
+ batch_size, nch, n_patch, temporal = self.patch_embed.segment_patch(x).shape
412
392
  else:
413
- # For neural decoder: input is (batch, n_chans, n_times)
414
- # patch_embed returns (batch, n_patchs, emb_dim)
415
- x = self.patch_embed(x)
416
- # x shape: (batch, n_patchs, emb_dim)
417
- batch_size, n_patch, temporal = x.shape
418
-
393
+ batch_size, nch, n_patch = self.patch_embed(x).shape
394
+ x = self.patch_embed(x)
419
395
  # add the [CLS] token to the embedded patch tokens
420
396
  cls_tokens = self.cls_token.expand(batch_size, -1, -1)
421
397
 
422
- # Concatenate cls token with patch/channel embeddings
423
398
  x = torch.cat((cls_tokens, x), dim=1)
424
399
 
425
400
  # Positional Embedding
426
- if self.position_embedding is not None:
427
- if self.neural_tokenizer:
428
- # In tokenizer mode, use channel-based position embedding
429
- if input_chans is not None:
430
- pos_embed_used = self.position_embedding[:, input_chans]
431
- else:
432
- pos_embed_used = self.position_embedding
433
-
434
- pos_embed = self._adj_position_embedding(
435
- pos_embed_used=pos_embed_used, batch_size=batch_size
436
- )
437
- else:
438
- # In decoder mode, we have different number of patches
439
- # Adapt position embedding for n_patch patches
440
- # Use the first n_patch+1 positions from position_embedding
441
- n_pos = min(self.position_embedding.shape[1], n_patch + 1)
442
- pos_embed_used = self.position_embedding[:, :n_pos, :]
443
- pos_embed = pos_embed_used.expand(batch_size, -1, -1)
401
+ if input_chans is not None:
402
+ pos_embed_used = self.position_embedding[:, input_chans]
403
+ else:
404
+ pos_embed_used = self.position_embedding
444
405
 
406
+ if self.position_embedding is not None:
407
+ pos_embed = self._adj_position_embedding(
408
+ pos_embed_used=pos_embed_used, batch_size=batch_size
409
+ )
445
410
  x += pos_embed
446
411
 
447
412
  # The time embedding is added across the channels after the [CLS] token
448
413
  if self.neural_tokenizer:
449
414
  num_ch = self.n_chans
450
- time_embed = self._adj_temporal_embedding(
451
- num_ch=num_ch, batch_size=batch_size, dim_embed=temporal
452
- )
453
- x[:, 1:, :] += time_embed
454
415
  else:
455
- # In decoder mode, we have n_patch patches and don't need to expand
456
- # Just broadcast the temporal embedding
457
- if temporal is None:
458
- temporal = self.emb_size
459
-
460
- # Get temporal embeddings for n_patch patches
461
- n_time_tokens = min(n_patch, self.temporal_embedding.shape[1] - 1)
462
- time_embed = self.temporal_embedding[
463
- :, 1 : n_time_tokens + 1, :
464
- ] # (1, n_patch, emb_dim)
465
- time_embed = time_embed.expand(
466
- batch_size, -1, -1
467
- ) # (batch, n_patch, emb_dim)
468
- x[:, 1:, :] += time_embed
416
+ num_ch = n_patch
417
+ time_embed = self._adj_temporal_embedding(
418
+ num_ch=num_ch, batch_size=batch_size, dim_embed=temporal
419
+ )
420
+ x[:, 1:, :] += time_embed
469
421
 
470
422
  x = self.pos_drop(x)
471
423
 
@@ -476,10 +428,10 @@ class Labram(EEGModuleMixin, nn.Module):
476
428
  if self.fc_norm is not None:
477
429
  if return_all_tokens:
478
430
  return self.fc_norm(x)
479
- tokens = x[:, 1:, :]
431
+ temporal = x[:, 1:, :]
480
432
  if return_patch_tokens:
481
- return self.fc_norm(tokens)
482
- return self.fc_norm(tokens.mean(1))
433
+ return self.fc_norm(temporal)
434
+ return self.fc_norm(temporal.mean(1))
483
435
  else:
484
436
  if return_all_tokens:
485
437
  return x
@@ -553,16 +505,14 @@ class Labram(EEGModuleMixin, nn.Module):
553
505
  def _adj_temporal_embedding(self, num_ch, batch_size, dim_embed=None):
554
506
  """
555
507
  Adjust the dimensions of the time embedding to match the
556
- number of channels or patches.
508
+ number of channels.
557
509
 
558
510
  Parameters
559
511
  ----------
560
512
  num_ch : int
561
- The number of channels or number of patches.
513
+ The number of channels or number of code books vectors.
562
514
  batch_size : int
563
515
  Batch size of the input data.
564
- dim_embed : int
565
- The embedding dimension (temporal feature dimension).
566
516
 
567
517
  Returns
568
518
  -------
@@ -573,24 +523,17 @@ class Labram(EEGModuleMixin, nn.Module):
573
523
  if dim_embed is None:
574
524
  cut_dimension = self.patch_size
575
525
  else:
576
- cut_dimension = min(dim_embed, self.temporal_embedding.shape[1] - 1)
577
-
578
- # Get the temporal embedding: (1, temporal_embedding_dim, emb_size)
579
- # Slice to cut_dimension: (1, cut_dimension, emb_size)
580
- temporal_embedding = self.temporal_embedding[:, 1 : cut_dimension + 1, :]
581
-
526
+ cut_dimension = dim_embed
527
+ # first step will be match the time_embed to the number of channels
528
+ temporal_embedding = self.temporal_embedding[:, 1:cut_dimension, :]
582
529
  # Add a new dimension to the time embedding
583
- # e.g. (1, 5, 200) -> (1, 1, 5, 200)
530
+ # e.g. (batch, 62, 200) -> (batch, 1, 62, 200)
584
531
  temporal_embedding = temporal_embedding.unsqueeze(1)
585
-
586
- # Expand the time embedding to match the number of channels or patches
587
- # (1, 1, cut_dimension, 200) -> (batch_size, num_ch, cut_dimension, 200)
532
+ # Expand the time embedding to match the number of channels
533
+ # or number of patches from
588
534
  temporal_embedding = temporal_embedding.expand(batch_size, num_ch, -1, -1)
589
-
590
535
  # Flatten the intermediate dimensions
591
- # (batch_size, num_ch, cut_dimension, 200) -> (batch_size, num_ch * cut_dimension, 200)
592
536
  temporal_embedding = temporal_embedding.flatten(1, 2)
593
-
594
537
  return temporal_embedding
595
538
 
596
539
  def _adj_position_embedding(self, pos_embed_used, batch_size):
@@ -736,27 +679,25 @@ class _SegmentPatch(nn.Module):
736
679
 
737
680
 
738
681
  class _PatchEmbed(nn.Module):
739
- """EEG to Patch Embedding for Neural Decoder mode.
682
+ """EEG to Patch Embedding.
740
683
 
741
684
  This code is used when we want to apply the patch embedding
742
- after the codebook layer (Neural Decoder mode).
743
-
744
- The input is expected to be in the format (Batch, n_channels, n_times),
745
- but the original LaBraM expects pre-patched data (Batch, n_channels, n_patches, patch_size).
746
- This class reshapes the input to the pre-patched format, then applies a 2D
747
- convolution to project this pre-patched data to the embedding dimension,
748
- and finally flattens across channels to produce a unified embedding.
685
+ after the codebook layer.
749
686
 
750
687
  Parameters:
751
688
  -----------
752
689
  n_times: int (default=2000)
753
- Number of temporal components of the input tensor (used for dimension calculation).
690
+ Number of temporal components of the input tensor.
754
691
  patch_size: int (default=200)
755
692
  Size of the patch, default is 1-seconds with 200Hz.
756
693
  in_channels: int (default=1)
757
- Number of input channels (from VQVAE codebook).
694
+ Number of input channels for to be used in the convolution.
758
695
  emb_dim: int (default=200)
759
- Number of output embedding dimension.
696
+ Number of out_channes to be used in the convolution, here,
697
+ we used the same as patch_size.
698
+ n_codebooks: int (default=62)
699
+ Number of patches to be used in the convolution, here,
700
+ we used the same as n_times // patch_size.
760
701
  """
761
702
 
762
703
  def __init__(
@@ -766,13 +707,10 @@ class _PatchEmbed(nn.Module):
766
707
  self.n_times = n_times
767
708
  self.patch_size = patch_size
768
709
  self.patch_shape = (1, self.n_times // self.patch_size)
769
- self.n_patchs = self.n_times // self.patch_size
770
- self.emb_dim = emb_dim
771
- self.in_channels = in_channels
710
+ n_patchs = n_codebooks * (self.n_times // self.patch_size)
711
+
712
+ self.n_patchs = n_patchs
772
713
 
773
- # 2D Conv to project the pre-patched data
774
- # Input: (Batch, in_channels, n_patches, patch_size)
775
- # After proj: (Batch, emb_dim, n_patches, 1)
776
714
  self.proj = nn.Conv2d(
777
715
  in_channels=in_channels,
778
716
  out_channels=emb_dim,
@@ -780,64 +718,27 @@ class _PatchEmbed(nn.Module):
780
718
  stride=(1, self.patch_size),
781
719
  )
782
720
 
721
+ self.merge_transpose = Rearrange(
722
+ "Batch ch patch spatch -> Batch patch spatch ch",
723
+ )
724
+
783
725
  def forward(self, x):
784
726
  """
785
- Apply the temporal projection to the input tensor after grouping channels.
727
+ Apply the convolution to the input tensor.
728
+ then merge the output tensor to the desired shape.
786
729
 
787
- Parameters
788
- ----------
789
- x : torch.Tensor
790
- Input tensor of shape (Batch, n_channels, n_times) or
791
- (Batch, n_channels, n_patches, patch_size).
730
+ Parameters:
731
+ -----------
732
+ x: torch.Tensor
733
+ Input tensor of shape (Batch, Channels, n_patchs, patch_size).
792
734
 
793
- Returns
735
+ Return:
794
736
  -------
795
- torch.Tensor
796
- Output tensor of shape (Batch, n_patchs, emb_dim).
737
+ x: torch.Tensor
738
+ Output tensor of shape (Batch, n_patchs, patch_size, channels).
797
739
  """
798
- if x.ndim == 4:
799
- batch_size, n_channels, n_patchs, patch_len = x.shape
800
- if patch_len != self.patch_size:
801
- raise ValueError(
802
- "When providing a 4D tensor, the last dimension "
803
- f"({patch_len}) must match patch_size ({self.patch_size})."
804
- )
805
- n_times = n_patchs * patch_len
806
- x = x.reshape(batch_size, n_channels, n_times)
807
- elif x.ndim == 3:
808
- batch_size, n_channels, n_times = x.shape
809
- else:
810
- raise ValueError(
811
- "Input must be either 3D (batch, channels, times) or "
812
- "4D (batch, channels, n_patches, patch_size)."
813
- )
814
-
815
- if n_times % self.patch_size != 0:
816
- raise ValueError(
817
- f"n_times ({n_times}) must be divisible by patch_size ({self.patch_size})."
818
- )
819
- if n_channels % self.in_channels != 0:
820
- raise ValueError(
821
- "The input channel dimension "
822
- f"({n_channels}) must be divisible by in_channels ({self.in_channels})."
823
- )
824
-
825
- group_size = n_channels // self.in_channels
826
-
827
- # Reshape so Conv2d sees `in_channels` feature maps and uses the grouped
828
- # EEG channels as the spatial height dimension.
829
- # Shape after view: (Batch, in_channels, group_size, n_times)
830
- x = x.view(batch_size, self.in_channels, group_size, n_times)
831
-
832
- # Apply the temporal projection per group.
833
- # Output shape: (Batch, emb_dim, group_size, n_patchs)
834
740
  x = self.proj(x)
835
-
836
- # THIS IS braindecode's MODIFICATION:
837
- # Average over the grouped channel dimension and permute to (Batch, n_patchs, emb_dim)
838
- x = x.mean(dim=2)
839
- x = x.transpose(1, 2).contiguous()
840
-
741
+ x = self.merge_transpose(x)
841
742
  return x
842
743
 
843
744
 
@@ -0,0 +1 @@
1
+ __version__ = "1.3.0.dev180851780"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.3.0.dev180329405
3
+ Version: 1.3.0.dev180851780
4
4
  Summary: Deep learning software to decode EEG, ECG or MEG signals
5
5
  Author-email: Robin Tibor Schirrmeister <robintibor@gmail.com>
6
6
  Maintainer-email: Alexandre Gramfort <agramfort@meta.com>, Bruno Aristimunha Pinto <b.aristimunha@gmail.com>, Robin Tibor Schirrmeister <robintibor@gmail.com>
@@ -35,7 +35,7 @@ Bugs
35
35
  - Fixing the issues with :class:`braindecode.models.ATCNet` (:gh:`782` by `Hamdi Altaheri`_)
36
36
  - Fixing expired path when loading a preprocessed dataset that was moved (:gh:`786` by `Pierre Guetschel`_)
37
37
  - Fix OverflowError sometimes when saving description to a json file (:gh:`789` by `Pierre Guetschel`_)
38
- - Small adjustment in :class:`braindecode.models.Labram` model to allow pre-loading of weights (:gh:`792` by `Bruno Aristimunha`_)
38
+
39
39
 
40
40
  Current 1.2 (stable)
41
41
  ----------------------
@@ -1 +0,0 @@
1
- __version__ = "1.3.0.dev180329405"