braindecode 0.4.3__tar.gz → 0.4.5__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 (79) hide show
  1. {Braindecode-0.4.3 → Braindecode-0.4.5}/Braindecode.egg-info/PKG-INFO +1 -1
  2. {Braindecode-0.4.3 → Braindecode-0.4.5}/Braindecode.egg-info/SOURCES.txt +0 -1
  3. {Braindecode-0.4.3 → Braindecode-0.4.5}/PKG-INFO +1 -1
  4. Braindecode-0.4.5/braindecode/datautil/splitters.py +190 -0
  5. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/experiments/experiment.py +2 -7
  6. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/models/base.py +16 -4
  7. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/models/deep4.py +3 -3
  8. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/models/eegnet.py +2 -2
  9. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/models/hybrid.py +31 -14
  10. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/models/shallow_fbcsp.py +3 -3
  11. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/torch_ext/constraints.py +2 -2
  12. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/torch_ext/init.py +1 -1
  13. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/torch_ext/optimizers.py +1 -1
  14. Braindecode-0.4.5/braindecode/version.py +1 -0
  15. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/visualization/perturbation.py +12 -6
  16. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/visualization/plot.py +2 -4
  17. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/notebooks/BBCI_Data.ipynb +1 -1
  18. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/notebooks/BBCI_Data_Start_Stop.ipynb +1 -1
  19. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/notebooks/BBCI_Data_Trialwise.ipynb +1 -1
  20. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/notebooks/Cropped_Manual_Training_Loop.ipynb +81 -73
  21. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/notebooks/Trialwise_Manual_Training_Loop.ipynb +6 -2
  22. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/notebooks/visualization/Perturbation.ipynb +260 -247
  23. Braindecode-0.4.3/braindecode/datautil/splitters.py +0 -106
  24. Braindecode-0.4.3/braindecode/models/deep4new.py +0 -228
  25. Braindecode-0.4.3/braindecode/version.py +0 -1
  26. {Braindecode-0.4.3 → Braindecode-0.4.5}/Braindecode.egg-info/dependency_links.txt +0 -0
  27. {Braindecode-0.4.3 → Braindecode-0.4.5}/Braindecode.egg-info/not-zip-safe +0 -0
  28. {Braindecode-0.4.3 → Braindecode-0.4.5}/Braindecode.egg-info/requires.txt +0 -0
  29. {Braindecode-0.4.3 → Braindecode-0.4.5}/Braindecode.egg-info/top_level.txt +0 -0
  30. {Braindecode-0.4.3 → Braindecode-0.4.5}/LICENSE.txt +0 -0
  31. {Braindecode-0.4.3 → Braindecode-0.4.5}/MANIFEST.in +0 -0
  32. {Braindecode-0.4.3 → Braindecode-0.4.5}/README.rst +0 -0
  33. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/__init__.py +0 -0
  34. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datasets/__init__.py +0 -0
  35. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datasets/bbci.py +0 -0
  36. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datasets/bcic_iv_2a.py +0 -0
  37. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datasets/multiple.py +0 -0
  38. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datasets/sensor_positions.py +0 -0
  39. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datautil/__init__.py +0 -0
  40. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datautil/iterators.py +0 -0
  41. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datautil/signal_target.py +0 -0
  42. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datautil/signalproc.py +0 -0
  43. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datautil/trial_segment.py +0 -0
  44. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/datautil/util.py +0 -0
  45. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/experiments/__init__.py +0 -0
  46. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/experiments/loggers.py +0 -0
  47. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/experiments/monitors.py +0 -0
  48. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/experiments/stopcriteria.py +0 -0
  49. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/mne_ext/__init__.py +0 -0
  50. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/mne_ext/signalproc.py +0 -0
  51. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/models/__init__.py +0 -0
  52. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/models/util.py +0 -0
  53. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/torch_ext/__init__.py +0 -0
  54. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/torch_ext/functions.py +0 -0
  55. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/torch_ext/losses.py +0 -0
  56. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/torch_ext/modules.py +0 -0
  57. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/torch_ext/schedulers.py +0 -0
  58. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/torch_ext/util.py +0 -0
  59. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/util.py +0 -0
  60. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/visualization/__init__.py +0 -0
  61. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/visualization/input_windows.py +0 -0
  62. {Braindecode-0.4.3 → Braindecode-0.4.5}/braindecode/visualization/sinfit.py +0 -0
  63. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/Makefile +0 -0
  64. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/conf.py +0 -0
  65. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/index.rst +0 -0
  66. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/notebooks/Cropped_Decoding.ipynb +0 -0
  67. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/notebooks/Cropped_Trialwise_Explanation_Figures.ipynb +0 -0
  68. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/notebooks/Trialwise_Decoding.ipynb +0 -0
  69. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/source/braindecode.datasets.rst +0 -0
  70. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/source/braindecode.datautil.rst +0 -0
  71. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/source/braindecode.experiments.rst +0 -0
  72. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/source/braindecode.mne_ext.rst +0 -0
  73. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/source/braindecode.models.rst +0 -0
  74. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/source/braindecode.rst +0 -0
  75. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/source/braindecode.torch_ext.rst +0 -0
  76. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/source/braindecode.visualization.rst +0 -0
  77. {Braindecode-0.4.3 → Braindecode-0.4.5}/docs/source/modules.rst +0 -0
  78. {Braindecode-0.4.3 → Braindecode-0.4.5}/setup.cfg +0 -0
  79. {Braindecode-0.4.3 → Braindecode-0.4.5}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: Braindecode
3
- Version: 0.4.3
3
+ Version: 0.4.5
4
4
  Summary: A deep learning toolbox to decode raw time-domain EEG.
5
5
  Home-page: https://github.com/robintibor/braindecode
6
6
  Author: Robin Tibor Schirrmeister
@@ -33,7 +33,6 @@ braindecode/mne_ext/signalproc.py
33
33
  braindecode/models/__init__.py
34
34
  braindecode/models/base.py
35
35
  braindecode/models/deep4.py
36
- braindecode/models/deep4new.py
37
36
  braindecode/models/eegnet.py
38
37
  braindecode/models/hybrid.py
39
38
  braindecode/models/shallow_fbcsp.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: Braindecode
3
- Version: 0.4.3
3
+ Version: 0.4.5
4
4
  Summary: A deep learning toolbox to decode raw time-domain EEG.
5
5
  Home-page: https://github.com/robintibor/braindecode
6
6
  Author: Robin Tibor Schirrmeister
@@ -0,0 +1,190 @@
1
+ import numpy as np
2
+
3
+ from braindecode.datautil.iterators import get_balanced_batches
4
+ from braindecode.datautil.signal_target import apply_to_X_y, SignalAndTarget
5
+
6
+
7
+ def concatenate_sets(sets):
8
+ """
9
+ Concatenate all sets together.
10
+
11
+ Parameters
12
+ ----------
13
+ sets: list of :class:`.SignalAndTarget`
14
+
15
+ Returns
16
+ -------
17
+ concatenated_set: :class:`.SignalAndTarget`
18
+ """
19
+ concatenated_set = sets[0]
20
+ for s in sets[1:]:
21
+ concatenated_set = concatenate_two_sets(concatenated_set, s)
22
+ return concatenated_set
23
+
24
+
25
+ def concatenate_two_sets(set_a, set_b):
26
+ """
27
+ Concatenate two sets together.
28
+
29
+ Parameters
30
+ ----------
31
+ set_a, set_b: :class:`.SignalAndTarget`
32
+
33
+ Returns
34
+ -------
35
+ concatenated_set: :class:`.SignalAndTarget`
36
+ """
37
+ new_X = concatenate_np_array_or_add_lists(set_a.X, set_b.X)
38
+ new_y = concatenate_np_array_or_add_lists(set_a.y, set_b.y)
39
+ return SignalAndTarget(new_X, new_y)
40
+
41
+ def concatenate_np_array_or_add_lists(a, b):
42
+ if hasattr(a, 'ndim') and hasattr(b, 'ndim'):
43
+ new = np.concatenate((a, b), axis=0)
44
+ else:
45
+ if hasattr(a, 'ndim'):
46
+ a = a.tolist()
47
+ if hasattr(b, 'ndim'):
48
+ b = b.tolist()
49
+ new = a + b
50
+ return new
51
+
52
+
53
+
54
+ def split_into_two_sets(dataset, first_set_fraction=None, n_first_set=None):
55
+ """
56
+ Split set into two sets either by fraction of first set or by number
57
+ of trials in first set.
58
+
59
+ Parameters
60
+ ----------
61
+ dataset: :class:`.SignalAndTarget`
62
+ first_set_fraction: float, optional
63
+ Fraction of trials in first set.
64
+ n_first_set: int, optional
65
+ Number of trials in first set
66
+
67
+ Returns
68
+ -------
69
+ first_set, second_set: :class:`.SignalAndTarget`
70
+ The two splitted sets.
71
+ """
72
+ assert (first_set_fraction is None) != (n_first_set is None), (
73
+ "Pass either first_set_fraction or n_first_set")
74
+ if n_first_set is None:
75
+ n_first_set = int(round(len(dataset.X) * first_set_fraction))
76
+ assert n_first_set < len(dataset.X)
77
+ first_set = apply_to_X_y(lambda a: a[:n_first_set], dataset)
78
+ second_set = apply_to_X_y(lambda a: a[n_first_set:], dataset)
79
+ return first_set, second_set
80
+
81
+
82
+ def select_examples(dataset, indices):
83
+ """
84
+ Select examples from dataset.
85
+
86
+ Parameters
87
+ ----------
88
+ dataset: :class:`.SignalAndTarget`
89
+ indices: list of int, 1d-array of int
90
+ Indices to select
91
+
92
+ Returns
93
+ -------
94
+ reduced_set: :class:`.SignalAndTarget`
95
+ Dataset with only examples selected.
96
+ """
97
+ # probably not necessary
98
+ indices = np.array(indices)
99
+ if hasattr(dataset.X, 'ndim'):
100
+ # numpy array
101
+ new_X = np.array(dataset.X)[indices]
102
+ else:
103
+ # list
104
+ new_X = [dataset.X[i] for i in indices]
105
+ new_y = np.asarray(dataset.y)[indices]
106
+ return SignalAndTarget(new_X, new_y)
107
+
108
+
109
+ def split_into_train_valid_test(dataset, n_folds, i_test_fold, rng=None):
110
+ """
111
+ Split datasets into folds, select one valid fold, one test fold and merge rest as train fold.
112
+
113
+ Parameters
114
+ ----------
115
+ dataset: :class:`.SignalAndTarget`
116
+ n_folds: int
117
+ Number of folds to split dataset into.
118
+ i_test_fold: int
119
+ Index of the test fold (0-based). Validation fold will be immediately preceding fold.
120
+ rng: `numpy.random.RandomState`, optional
121
+ Random Generator for shuffling, None means no shuffling
122
+
123
+ Returns
124
+ -------
125
+ reduced_set: :class:`.SignalAndTarget`
126
+ Dataset with only examples selected.
127
+ """
128
+ n_trials = len(dataset.X)
129
+ if n_trials < n_folds:
130
+ raise ValueError("Less Trials: {:d} than folds: {:d}".format(
131
+ n_trials, n_folds
132
+ ))
133
+ shuffle = rng is not None
134
+ folds = get_balanced_batches(
135
+ n_trials, rng, shuffle, n_batches=n_folds)
136
+ test_inds = folds[i_test_fold]
137
+ valid_inds = folds[i_test_fold - 1]
138
+ all_inds = list(range(n_trials))
139
+ train_inds = np.setdiff1d(all_inds, np.union1d(test_inds, valid_inds))
140
+ assert np.intersect1d(train_inds, valid_inds).size == 0
141
+ assert np.intersect1d(train_inds, test_inds).size == 0
142
+ assert np.intersect1d(valid_inds, test_inds).size == 0
143
+ assert np.array_equal(np.sort(
144
+ np.union1d(train_inds, np.union1d(valid_inds, test_inds))),
145
+ all_inds)
146
+
147
+ train_set = select_examples(dataset, train_inds)
148
+ valid_set = select_examples(dataset, valid_inds)
149
+ test_set = select_examples(dataset, test_inds)
150
+
151
+ return train_set, valid_set, test_set
152
+
153
+
154
+ def split_into_train_test(dataset, n_folds, i_test_fold, rng=None):
155
+ """
156
+ Split datasets into folds, select one test fold and merge rest as train fold.
157
+
158
+ Parameters
159
+ ----------
160
+ dataset: :class:`.SignalAndTarget`
161
+ n_folds: int
162
+ Number of folds to split dataset into.
163
+ i_test_fold: int
164
+ Index of the test fold (0-based)
165
+ rng: `numpy.random.RandomState`, optional
166
+ Random Generator for shuffling, None means no shuffling
167
+
168
+ Returns
169
+ -------
170
+ reduced_set: :class:`.SignalAndTarget`
171
+ Dataset with only examples selected.
172
+ """
173
+ n_trials = len(dataset.X)
174
+ if n_trials < n_folds:
175
+ raise ValueError("Less Trials: {:d} than folds: {:d}".format(
176
+ n_trials, n_folds
177
+ ))
178
+ shuffle = rng is not None
179
+ folds = get_balanced_batches(n_trials, rng, shuffle,
180
+ n_batches=n_folds)
181
+ test_inds = folds[i_test_fold]
182
+ all_inds = list(range(len(n_trials)))
183
+ train_inds = np.setdiff1d(all_inds, test_inds)
184
+ assert np.intersect1d(train_inds, test_inds).size == 0
185
+ assert np.array_equal(np.sort(np.union1d(train_inds, test_inds)),
186
+ all_inds)
187
+
188
+ train_set = select_examples(dataset, train_inds)
189
+ test_set = select_examples(dataset, test_inds)
190
+ return train_set, test_set
@@ -146,8 +146,6 @@ class Experiment(object):
146
146
  start of training.
147
147
  loggers: list of :class:`.Logger`
148
148
  How to show computed metrics.
149
- seed: int
150
- Random seed for python random module numpy.random and torch.
151
149
 
152
150
  Attributes
153
151
  ----------
@@ -163,8 +161,7 @@ class Experiment(object):
163
161
  do_early_stop=True,
164
162
  reset_after_second_run=False,
165
163
  log_0_epoch=True,
166
- loggers=('print',),
167
- seed=2382938):
164
+ loggers=('print',)):
168
165
  if run_after_early_stop or reset_after_second_run:
169
166
  assert do_early_stop == True, ("Can only run after early stop or "
170
167
  "reset after second run if doing an early stop")
@@ -199,7 +196,6 @@ class Experiment(object):
199
196
  self.do_early_stop = do_early_stop
200
197
  self.reset_after_second_run = reset_after_second_run
201
198
  self.log_0_epoch = log_0_epoch
202
- self.seed = seed
203
199
  self.loggers = loggers
204
200
 
205
201
  def run(self):
@@ -230,7 +226,7 @@ class Experiment(object):
230
226
 
231
227
  def setup_training(self):
232
228
  """
233
- Setup training, i.e. set random seeds, transform model to cuda,
229
+ Setup training, i.e. transform model to cuda,
234
230
  initialize monitoring.
235
231
  """
236
232
  # reset remember best extension in case you rerun some experiment
@@ -239,7 +235,6 @@ class Experiment(object):
239
235
  if self.loggers == ('print',):
240
236
  self.loggers = [Printer()]
241
237
  self.epochs_df = pd.DataFrame()
242
- set_random_seeds(seed=self.seed, cuda=self.cuda)
243
238
  if self.cuda:
244
239
  assert th.cuda.is_available(), "Cuda not available"
245
240
  self.model.cuda()
@@ -15,6 +15,9 @@ from braindecode.datautil.signal_target import SignalAndTarget
15
15
  from braindecode.models.util import to_dense_prediction_model
16
16
  from braindecode.torch_ext.schedulers import CosineAnnealing, ScheduledOptimizer
17
17
  from braindecode.torch_ext.util import np_to_var, var_to_np
18
+ import logging
19
+
20
+ log = logging.getLogger(__name__)
18
21
 
19
22
 
20
23
  def find_optimizer(optimizer_name):
@@ -79,7 +82,14 @@ class BaseModel(object):
79
82
  self.loss = loss
80
83
  self._ensure_network_exists()
81
84
  if cropped:
82
- to_dense_prediction_model(self.network)
85
+ model_already_dense = np.any([
86
+ hasattr(m, 'dilation') and (m.dilation != 1) and
87
+ (m.dilation) != (1, 1) for m in self.network.modules()
88
+ ])
89
+ if not model_already_dense:
90
+ to_dense_prediction_model(self.network)
91
+ else:
92
+ log.info("Seems model was already converted to dense model...")
83
93
  if not hasattr(optimizer, 'step'):
84
94
  optimizer_class = find_optimizer(optimizer)
85
95
  optimizer = optimizer_class(self.network.parameters())
@@ -141,7 +151,9 @@ class BaseModel(object):
141
151
  "the network in a single pass.")
142
152
  if self.cropped:
143
153
  self.network.eval()
144
- test_input = np_to_var(train_X[0:1], dtype=np.float32)
154
+ test_input = np_to_var(np.ones(
155
+ (1, train_X.shape[1], input_time_length,) + train_X.shape[3:],
156
+ dtype=np.float32))
145
157
  while len(test_input.size()) < 4:
146
158
  test_input = test_input.unsqueeze(-1)
147
159
  if self.cuda:
@@ -151,11 +163,11 @@ class BaseModel(object):
151
163
  self.iterator = CropsFromTrialsIterator(
152
164
  batch_size=batch_size, input_time_length=input_time_length,
153
165
  n_preds_per_input=n_preds_per_input,
154
- seed=self.seed_rng.randint(0, 4294967295))
166
+ seed=self.seed_rng.randint(0, np.iinfo(np.int32).max-1))
155
167
  else:
156
168
  self.iterator = BalancedBatchSizeIterator(
157
169
  batch_size=batch_size,
158
- seed=self.seed_rng.randint(0, 4294967295))
170
+ seed=self.seed_rng.randint(0, np.iinfo(np.int32).max-1))
159
171
  if log_0_epoch:
160
172
  stop_criterion = MaxEpochs(epochs)
161
173
  else:
@@ -17,10 +17,10 @@ class Deep4Net(BaseModel):
17
17
  ----------
18
18
 
19
19
  .. [1] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
20
- Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
20
+ Glasstetter, M., Eggensperger, K., Tangermann, M., Hutter, F. & Ball, T. (2017).
21
21
  Deep learning with convolutional neural networks for EEG decoding and
22
22
  visualization.
23
- arXiv preprint arXiv:1703.05051.
23
+ Human Brain Mapping , Aug. 2017. Online: http://dx.doi.org/10.1002/hbm.23730
24
24
  """
25
25
  def __init__(self, in_chans,
26
26
  n_classes,
@@ -103,7 +103,7 @@ class Deep4Net(BaseModel):
103
103
  suffix = '_{:d}'.format(block_nr)
104
104
  model.add_module('drop' + suffix,
105
105
  nn.Dropout(p=self.drop_prob))
106
- model.add_module('conv' + suffix.format(block_nr),
106
+ model.add_module('conv' + suffix,
107
107
  nn.Conv2d(n_filters_before, n_filters,
108
108
  (filter_length, 1),
109
109
  stride=(conv_stride, 1),
@@ -21,7 +21,7 @@ class Conv2dWithConstraint(nn.Conv2d):
21
21
 
22
22
  class EEGNetv4(BaseModel):
23
23
  """
24
- EEGNet v4 model from [EEGNet]_.
24
+ EEGNet v4 model from [EEGNet4]_.
25
25
 
26
26
  Notes
27
27
  -----
@@ -31,7 +31,7 @@ class EEGNetv4(BaseModel):
31
31
  References
32
32
  ----------
33
33
 
34
- .. [EEGNet] Lawhern, V. J., Solon, A. J., Waytowich, N. R., Gordon,
34
+ .. [EEGNet4] Lawhern, V. J., Solon, A. J., Waytowich, N. R., Gordon,
35
35
  S. M., Hung, C. P., & Lance, B. J. (2018).
36
36
  EEGNet: A Compact Convolutional Network for EEG-based
37
37
  Brain-Computer Interfaces.
@@ -8,31 +8,48 @@ from braindecode.models.shallow_fbcsp import ShallowFBCSPNet
8
8
  from braindecode.models.util import to_dense_prediction_model
9
9
 
10
10
 
11
- class HybridNet(nn.Module, BaseModel):
11
+ class HybridNet(BaseModel):
12
12
  """
13
- Hybrid ConvNet model from [3]_.
13
+ Wrapper for HybridNetModule
14
+ """
15
+ def __init__(self, in_chans, n_classes, input_time_length):
16
+ self.in_chans = in_chans
17
+ self.n_classes = n_classes
18
+ self.input_time_length = input_time_length
19
+
20
+ def create_network(self):
21
+ return HybridNetModule(
22
+ in_chans=self.in_chans,
23
+ n_classes=self.n_classes,
24
+ input_time_length=self.input_time_length
25
+ )
26
+
27
+
28
+ class HybridNetModule(nn.Module):
29
+ """
30
+ Hybrid ConvNet model from [3]_.
14
31
 
15
- Very hardcoded at the moment.
32
+ Very hardcoded at the moment.
16
33
 
17
- References
18
- ----------
34
+ References
35
+ ----------
19
36
 
20
- .. [3] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
21
- Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
22
- Deep learning with convolutional neural networks for EEG decoding and
23
- visualization.
24
- arXiv preprint arXiv:1703.05051.
37
+ .. [3] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
38
+ Glasstetter, M., Eggensperger, K., Tangermann, M., Hutter, F. & Ball, T. (2017).
39
+ Deep learning with convolutional neural networks for EEG decoding and
40
+ visualization.
41
+ Human Brain Mapping , Aug. 2017. Online: http://dx.doi.org/10.1002/hbm.23730
25
42
  """
26
- def __init__(self, n_chans, n_classes, input_time_length):
27
- super(HybridNet, self).__init__()
28
- deep_model = Deep4Net(n_chans, n_classes, n_filters_time=20,
43
+ def __init__(self, in_chans, n_classes, input_time_length):
44
+ super(HybridNetModule, self).__init__()
45
+ deep_model = Deep4Net(in_chans, n_classes, n_filters_time=20,
29
46
  n_filters_spat=30,
30
47
  n_filters_2=40,
31
48
  n_filters_3=50,
32
49
  n_filters_4=60,
33
50
  input_time_length=input_time_length,
34
51
  final_conv_length=2).create_network()
35
- shallow_model = ShallowFBCSPNet(n_chans, n_classes,
52
+ shallow_model = ShallowFBCSPNet(in_chans, n_classes,
36
53
  input_time_length=input_time_length,
37
54
  n_filters_time=30,
38
55
  n_filters_spat=40,
@@ -15,11 +15,11 @@ class ShallowFBCSPNet(BaseModel):
15
15
  References
16
16
  ----------
17
17
 
18
- .. [2] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
19
- Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
18
+ .. [2] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
19
+ Glasstetter, M., Eggensperger, K., Tangermann, M., Hutter, F. & Ball, T. (2017).
20
20
  Deep learning with convolutional neural networks for EEG decoding and
21
21
  visualization.
22
- arXiv preprint arXiv:1703.05051.
22
+ Human Brain Mapping , Aug. 2017. Online: http://dx.doi.org/10.1002/hbm.23730
23
23
  """
24
24
  def __init__(self, in_chans,
25
25
  n_classes,
@@ -10,10 +10,10 @@ class MaxNormDefaultConstraint(object):
10
10
  ----------
11
11
 
12
12
  .. [1] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
13
- Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
13
+ Glasstetter, M., Eggensperger, K., Tangermann, M., Hutter, F. & Ball, T. (2017).
14
14
  Deep learning with convolutional neural networks for EEG decoding and
15
15
  visualization.
16
- arXiv preprint arXiv:1703.05051.
16
+ Human Brain Mapping , Aug. 2017. Online: http://dx.doi.org/10.1002/hbm.23730
17
17
 
18
18
  """
19
19
  def apply(self, model):
@@ -17,7 +17,7 @@ def glorot_weight_zero_bias(model):
17
17
  if not ('BatchNorm' in module.__class__.__name__):
18
18
  init.xavier_uniform_(module.weight, gain=1)
19
19
  else:
20
- init.constant(module.weight, 1)
20
+ init.constant_(module.weight, 1)
21
21
  if hasattr(module, 'bias'):
22
22
  if module.bias is not None:
23
23
  init.constant_(module.bias, 0)
@@ -4,7 +4,7 @@ from torch.optim.optimizer import Optimizer
4
4
 
5
5
 
6
6
  class AdamW(Optimizer):
7
- """Implements Adam algorithm with fixed as TODO
7
+ """Implements Adam algorithm with fixed as in `AdamW`
8
8
 
9
9
  It has been proposed in `Adam: A Method for Stochastic Optimization`_.
10
10
 
@@ -0,0 +1 @@
1
+ __version__ = "0.4.5"
@@ -8,7 +8,7 @@ from braindecode.util import wrap_reshape_apply_fn, corr
8
8
  log = logging.getLogger(__name__)
9
9
 
10
10
 
11
- def phase_perturbation(amps,phases,rng=np.random.RandomState()):
11
+ def phase_perturbation(amps,phases,rng=None):
12
12
  """Takes amps and phases of BxCxF with B input, C channels, F frequencies
13
13
  Shifts spectral phases randomly U(-pi,pi) for input and frequencies, but same for all channels
14
14
 
@@ -19,7 +19,7 @@ def phase_perturbation(amps,phases,rng=np.random.RandomState()):
19
19
  phases : numpy array
20
20
  Spectral phases
21
21
  rng : object
22
- Random Seed
22
+ Random Generator
23
23
 
24
24
  Returns
25
25
  -------
@@ -30,6 +30,8 @@ def phase_perturbation(amps,phases,rng=np.random.RandomState()):
30
30
  pert_vals : numpy array
31
31
  Absolute phase shifts
32
32
  """
33
+ if rng is None:
34
+ rng = np.random.RandomState()
33
35
  noise_shape = list(phases.shape)
34
36
  noise_shape[1] = 1 # Do not sample noise for channels individually
35
37
 
@@ -44,7 +46,7 @@ def phase_perturbation(amps,phases,rng=np.random.RandomState()):
44
46
  pert_vals = np.abs(phase_noise)
45
47
  return amps,phases_pert,pert_vals
46
48
 
47
- def amp_perturbation_additive(amps,phases,rng=np.random.RandomState()):
49
+ def amp_perturbation_additive(amps,phases,rng=None):
48
50
  """Takes amplitudes and phases of BxCxF with B input, C channels, F frequencies
49
51
  Adds additive noise N(0,0.02) to amplitudes
50
52
 
@@ -66,13 +68,15 @@ def amp_perturbation_additive(amps,phases,rng=np.random.RandomState()):
66
68
  pert_vals : numpy array
67
69
  Amplitude noise
68
70
  """
71
+ if rng is None:
72
+ rng = np.random.RandomState()
69
73
  amp_noise = rng.normal(0,1,amps.shape).astype(np.float32)
70
74
  amps_pert = amps+amp_noise
71
75
  amps_pert[amps_pert<0] = 0
72
76
  amp_noise = amps_pert-amps
73
77
  return amps_pert,phases,amp_noise
74
78
 
75
- def amp_perturbation_multiplicative(amps,phases,rng=np.random.RandomState()):
79
+ def amp_perturbation_multiplicative(amps,phases,rng=None):
76
80
  """Takes amplitude and phases of BxCxF with B input, C channels, F frequencies
77
81
  Adds multiplicative noise N(1,0.02) to amplitudes
78
82
 
@@ -94,6 +98,8 @@ def amp_perturbation_multiplicative(amps,phases,rng=np.random.RandomState()):
94
98
  pert_vals : numpy array
95
99
  Amplitude scaling factor
96
100
  """
101
+ if rng is None:
102
+ rng = np.random.RandomState()
97
103
  amp_noise = rng.normal(1,0.02,amps.shape).astype(np.float32)
98
104
  amps_pert = amps*amp_noise
99
105
  amps_pert[amps_pert<0] = 0
@@ -278,10 +284,10 @@ def compute_amplitude_prediction_correlations(pred_fn, examples, n_iterations,
278
284
  ----------
279
285
 
280
286
  .. [EEGDeepLearning] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
281
- Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
287
+ Glasstetter, M., Eggensperger, K., Tangermann, M., Hutter, F. & Ball, T. (2017).
282
288
  Deep learning with convolutional neural networks for EEG decoding and
283
289
  visualization.
284
- arXiv preprint arXiv:1703.05051.
290
+ Human Brain Mapping , Aug. 2017. Online: http://dx.doi.org/10.1002/hbm.23730
285
291
  """
286
292
  pred_fn_new = lambda x: [pred_fn(x)]
287
293
  pred_corrs = spectral_perturbation_correlation(perturb_fn, mean_diff_feature_maps,
@@ -67,13 +67,11 @@ def ax_scalp(v, channels,
67
67
  References
68
68
  ----------
69
69
 
70
-
71
70
  .. [1] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
72
- Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
71
+ Glasstetter, M., Eggensperger, K., Tangermann, M., Hutter, F. & Ball, T. (2017).
73
72
  Deep learning with convolutional neural networks for EEG decoding and
74
73
  visualization.
75
- arXiv preprint arXiv:1703.05051.
76
-
74
+ Human Brain Mapping , Aug. 2017. Online: http://dx.doi.org/10.1002/hbm.23730
77
75
  """
78
76
  if ax is None:
79
77
  ax = plt.gca()
@@ -833,7 +833,7 @@
833
833
  "name": "python",
834
834
  "nbconvert_exporter": "python",
835
835
  "pygments_lexer": "ipython3",
836
- "version": "3.6.2"
836
+ "version": "3.6.6"
837
837
  }
838
838
  },
839
839
  "nbformat": 4,
@@ -891,7 +891,7 @@
891
891
  "name": "python",
892
892
  "nbconvert_exporter": "python",
893
893
  "pygments_lexer": "ipython3",
894
- "version": "3.6.2"
894
+ "version": "3.6.6"
895
895
  }
896
896
  },
897
897
  "nbformat": 4,
@@ -707,7 +707,7 @@
707
707
  "name": "python",
708
708
  "nbconvert_exporter": "python",
709
709
  "pygments_lexer": "ipython3",
710
- "version": "3.6.2"
710
+ "version": "3.6.6"
711
711
  }
712
712
  },
713
713
  "nbformat": 4,