braindecode 0.4.4__tar.gz → 0.4.6__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.
- {Braindecode-0.4.4 → Braindecode-0.4.6}/Braindecode.egg-info/PKG-INFO +1 -1
- {Braindecode-0.4.4 → Braindecode-0.4.6}/PKG-INFO +1 -1
- Braindecode-0.4.6/braindecode/datautil/splitters.py +190 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/models/base.py +20 -4
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/models/eegnet.py +2 -2
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/models/hybrid.py +22 -5
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/torch_ext/init.py +1 -1
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/torch_ext/optimizers.py +1 -1
- Braindecode-0.4.6/braindecode/version.py +1 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/visualization/perturbation.py +10 -4
- Braindecode-0.4.4/braindecode/datautil/splitters.py +0 -106
- Braindecode-0.4.4/braindecode/version.py +0 -1
- {Braindecode-0.4.4 → Braindecode-0.4.6}/Braindecode.egg-info/SOURCES.txt +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/Braindecode.egg-info/dependency_links.txt +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/Braindecode.egg-info/not-zip-safe +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/Braindecode.egg-info/requires.txt +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/Braindecode.egg-info/top_level.txt +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/LICENSE.txt +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/MANIFEST.in +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/README.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/__init__.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datasets/__init__.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datasets/bbci.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datasets/bcic_iv_2a.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datasets/multiple.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datasets/sensor_positions.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datautil/__init__.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datautil/iterators.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datautil/signal_target.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datautil/signalproc.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datautil/trial_segment.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/datautil/util.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/experiments/__init__.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/experiments/experiment.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/experiments/loggers.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/experiments/monitors.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/experiments/stopcriteria.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/mne_ext/__init__.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/mne_ext/signalproc.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/models/__init__.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/models/deep4.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/models/shallow_fbcsp.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/models/util.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/torch_ext/__init__.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/torch_ext/constraints.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/torch_ext/functions.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/torch_ext/losses.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/torch_ext/modules.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/torch_ext/schedulers.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/torch_ext/util.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/util.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/visualization/__init__.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/visualization/input_windows.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/visualization/plot.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/braindecode/visualization/sinfit.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/Makefile +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/conf.py +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/index.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/notebooks/BBCI_Data.ipynb +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/notebooks/BBCI_Data_Start_Stop.ipynb +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/notebooks/BBCI_Data_Trialwise.ipynb +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/notebooks/Cropped_Decoding.ipynb +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/notebooks/Cropped_Manual_Training_Loop.ipynb +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/notebooks/Cropped_Trialwise_Explanation_Figures.ipynb +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/notebooks/Trialwise_Decoding.ipynb +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/notebooks/Trialwise_Manual_Training_Loop.ipynb +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/notebooks/visualization/Perturbation.ipynb +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/source/braindecode.datasets.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/source/braindecode.datautil.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/source/braindecode.experiments.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/source/braindecode.mne_ext.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/source/braindecode.models.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/source/braindecode.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/source/braindecode.torch_ext.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/source/braindecode.visualization.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/docs/source/modules.rst +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/setup.cfg +0 -0
- {Braindecode-0.4.4 → Braindecode-0.4.6}/setup.py +0 -0
|
@@ -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
|
|
@@ -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
|
-
|
|
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(
|
|
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:
|
|
@@ -273,8 +285,12 @@ class BaseModel(object):
|
|
|
273
285
|
Predicted labels per trial.
|
|
274
286
|
"""
|
|
275
287
|
all_preds = []
|
|
276
|
-
|
|
277
|
-
|
|
288
|
+
with th.no_grad():
|
|
289
|
+
for b_X, _ in self.iterator.get_batches(SignalAndTarget(X, X), False):
|
|
290
|
+
b_X_var = np_to_var(b_X)
|
|
291
|
+
if self.cuda:
|
|
292
|
+
b_X_var = b_X_var.cuda()
|
|
293
|
+
all_preds.append(var_to_np(self.network(b_X_var)))
|
|
278
294
|
if self.cropped:
|
|
279
295
|
pred_labels = compute_trial_labels_from_crop_preds(
|
|
280
296
|
all_preds, self.iterator.input_time_length, X)
|
|
@@ -21,7 +21,7 @@ class Conv2dWithConstraint(nn.Conv2d):
|
|
|
21
21
|
|
|
22
22
|
class EEGNetv4(BaseModel):
|
|
23
23
|
"""
|
|
24
|
-
EEGNet v4 model from [
|
|
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
|
-
.. [
|
|
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,7 +8,24 @@ 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(
|
|
11
|
+
class HybridNet(BaseModel):
|
|
12
|
+
"""
|
|
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):
|
|
12
29
|
"""
|
|
13
30
|
Hybrid ConvNet model from [3]_.
|
|
14
31
|
|
|
@@ -23,16 +40,16 @@ class HybridNet(nn.Module, BaseModel):
|
|
|
23
40
|
visualization.
|
|
24
41
|
Human Brain Mapping , Aug. 2017. Online: http://dx.doi.org/10.1002/hbm.23730
|
|
25
42
|
"""
|
|
26
|
-
def __init__(self,
|
|
27
|
-
super(
|
|
28
|
-
deep_model = Deep4Net(
|
|
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(
|
|
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,
|
|
@@ -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.
|
|
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)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.6"
|
|
@@ -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=
|
|
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
|
|
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=
|
|
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=
|
|
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
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
|
|
3
|
-
from braindecode.datautil.signal_target import apply_to_X_y, SignalAndTarget
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def concatenate_sets(sets):
|
|
7
|
-
"""
|
|
8
|
-
Concatenate all sets together.
|
|
9
|
-
|
|
10
|
-
Parameters
|
|
11
|
-
----------
|
|
12
|
-
sets: list of :class:`.SignalAndTarget`
|
|
13
|
-
|
|
14
|
-
Returns
|
|
15
|
-
-------
|
|
16
|
-
concatenated_set: :class:`.SignalAndTarget`
|
|
17
|
-
"""
|
|
18
|
-
concatenated_set = sets[0]
|
|
19
|
-
for s in sets[1:]:
|
|
20
|
-
concatenated_set = concatenate_two_sets(concatenated_set, s)
|
|
21
|
-
return concatenated_set
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def concatenate_two_sets(set_a, set_b):
|
|
25
|
-
"""
|
|
26
|
-
Concatenate two sets together.
|
|
27
|
-
|
|
28
|
-
Parameters
|
|
29
|
-
----------
|
|
30
|
-
set_a, set_b: :class:`.SignalAndTarget`
|
|
31
|
-
|
|
32
|
-
Returns
|
|
33
|
-
-------
|
|
34
|
-
concatenated_set: :class:`.SignalAndTarget`
|
|
35
|
-
"""
|
|
36
|
-
new_X = concatenate_np_array_or_add_lists(set_a.X, set_b.X)
|
|
37
|
-
new_y = concatenate_np_array_or_add_lists(set_a.y, set_b.y)
|
|
38
|
-
return SignalAndTarget(new_X, new_y)
|
|
39
|
-
|
|
40
|
-
def concatenate_np_array_or_add_lists(a, b):
|
|
41
|
-
if hasattr(a, 'ndim') and hasattr(b, 'ndim'):
|
|
42
|
-
new = np.concatenate((a, b), axis=0)
|
|
43
|
-
else:
|
|
44
|
-
if hasattr(a, 'ndim'):
|
|
45
|
-
a = a.tolist()
|
|
46
|
-
if hasattr(b, 'ndim'):
|
|
47
|
-
b = b.tolist()
|
|
48
|
-
new = a + b
|
|
49
|
-
return new
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def split_into_two_sets(dataset, first_set_fraction=None, n_first_set=None):
|
|
54
|
-
"""
|
|
55
|
-
Split set into two sets either by fraction of first set or by number
|
|
56
|
-
of trials in first set.
|
|
57
|
-
|
|
58
|
-
Parameters
|
|
59
|
-
----------
|
|
60
|
-
dataset: :class:`.SignalAndTarget`
|
|
61
|
-
first_set_fraction: float, optional
|
|
62
|
-
Fraction of trials in first set.
|
|
63
|
-
n_first_set: int, optional
|
|
64
|
-
Number of trials in first set
|
|
65
|
-
|
|
66
|
-
Returns
|
|
67
|
-
-------
|
|
68
|
-
first_set, second_set: :class:`.SignalAndTarget`
|
|
69
|
-
The two splitted sets.
|
|
70
|
-
"""
|
|
71
|
-
assert (first_set_fraction is None) != (n_first_set is None), (
|
|
72
|
-
"Pass either first_set_fraction or n_first_set")
|
|
73
|
-
if n_first_set is None:
|
|
74
|
-
n_first_set = int(round(len(dataset.X) * first_set_fraction))
|
|
75
|
-
assert n_first_set < len(dataset.X)
|
|
76
|
-
first_set = apply_to_X_y(lambda a: a[:n_first_set], dataset)
|
|
77
|
-
second_set = apply_to_X_y(lambda a: a[n_first_set:], dataset)
|
|
78
|
-
return first_set, second_set
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def select_examples(dataset, indices):
|
|
82
|
-
"""
|
|
83
|
-
Select examples from dataset.
|
|
84
|
-
|
|
85
|
-
Parameters
|
|
86
|
-
----------
|
|
87
|
-
dataset: :class:`.SignalAndTarget`
|
|
88
|
-
indices: list of int, 1d-array of int
|
|
89
|
-
Indices to select
|
|
90
|
-
|
|
91
|
-
Returns
|
|
92
|
-
-------
|
|
93
|
-
reduced_set: :class:`.SignalAndTarget`
|
|
94
|
-
Dataset with only examples selected.
|
|
95
|
-
"""
|
|
96
|
-
# probably not necessary
|
|
97
|
-
indices = np.array(indices)
|
|
98
|
-
if hasattr(dataset.X, 'ndim'):
|
|
99
|
-
# numpy array
|
|
100
|
-
new_X = np.array(dataset.X)[indices]
|
|
101
|
-
else:
|
|
102
|
-
# list
|
|
103
|
-
new_X = [dataset.X[i] for i in indices]
|
|
104
|
-
new_y = np.asarray(dataset.y)[indices]
|
|
105
|
-
return SignalAndTarget(new_X, new_y)
|
|
106
|
-
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.4.4"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{Braindecode-0.4.4 → Braindecode-0.4.6}/docs/notebooks/Cropped_Trialwise_Explanation_Figures.ipynb
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|