braindecode 0.1.6.4__tar.gz → 0.1.7__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.1.6.4 → Braindecode-0.1.7}/Braindecode.egg-info/PKG-INFO +23 -1
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/PKG-INFO +23 -1
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/README.rst +22 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datautil/signalproc.py +1 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/experiments/experiment.py +13 -6
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/models/deep4.py +11 -11
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/models/eegnet.py +5 -4
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/models/util.py +14 -8
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/torch_ext/util.py +17 -2
- Braindecode-0.1.7/braindecode/visualization/__init__.py +3 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/visualization/perturbation.py +28 -4
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/visualization/plot.py +3 -2
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/index.rst +24 -0
- Braindecode-0.1.7/docs/notebooks/BBCI_Data.ipynb +845 -0
- Braindecode-0.1.7/docs/notebooks/BBCI_Data_Start_Stop.ipynb +802 -0
- Braindecode-0.1.7/docs/notebooks/BBCI_Data_Trialwise.ipynb +780 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/notebooks/Cropped_Decoding.ipynb +27 -89
- Braindecode-0.1.7/docs/notebooks/Experiment_Class.ipynb +804 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/notebooks/TrialWise_Decoding.ipynb +50 -116
- Braindecode-0.1.7/docs/notebooks/visualization/Perturbation.ipynb +743 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/setup.py +1 -1
- Braindecode-0.1.6.4/braindecode/visualization/__init__.py +0 -0
- Braindecode-0.1.6.4/docs/notebooks/BBCI_Data.ipynb +0 -933
- Braindecode-0.1.6.4/docs/notebooks/BBCI_Data_Start_Stop.ipynb +0 -842
- Braindecode-0.1.6.4/docs/notebooks/BBCI_Data_Trialwise.ipynb +0 -820
- Braindecode-0.1.6.4/docs/notebooks/Experiment_Class.ipynb +0 -807
- Braindecode-0.1.6.4/docs/notebooks/visualization/Perturbation.ipynb +0 -840
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/Braindecode.egg-info/SOURCES.txt +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/Braindecode.egg-info/dependency_links.txt +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/Braindecode.egg-info/not-zip-safe +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/Braindecode.egg-info/requires.txt +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/Braindecode.egg-info/top_level.txt +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/LICENSE.txt +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/MANIFEST.in +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/__init__.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datasets/__init__.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datasets/bbci.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datasets/bcic_iv_2a.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datasets/multiple.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datasets/sensor_positions.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datautil/__init__.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datautil/iterators.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datautil/signal_target.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datautil/splitters.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datautil/trial_segment.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/datautil/util.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/experiments/__init__.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/experiments/monitors.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/experiments/stopcriteria.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/mne_ext/__init__.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/mne_ext/signalproc.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/models/__init__.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/models/shallow_fbcsp.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/torch_ext/__init__.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/torch_ext/constraints.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/torch_ext/functions.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/torch_ext/init.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/torch_ext/losses.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/torch_ext/modules.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/braindecode/util.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/Makefile +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/conf.py +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/source/braindecode.datasets.rst +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/source/braindecode.datautil.rst +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/source/braindecode.experiments.rst +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/source/braindecode.mne_ext.rst +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/source/braindecode.models.rst +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/source/braindecode.rst +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/source/braindecode.torch_ext.rst +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/source/braindecode.visualization.rst +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/docs/source/modules.rst +0 -0
- {Braindecode-0.1.6.4 → Braindecode-0.1.7}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 1.1
|
|
2
2
|
Name: Braindecode
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
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
|
|
@@ -52,6 +52,28 @@ Description: Note: The old braindecode repository has been moved to
|
|
|
52
52
|
|
|
53
53
|
Documentation is online under https://robintibor.github.io/braindecode/
|
|
54
54
|
|
|
55
|
+
|
|
56
|
+
Citing
|
|
57
|
+
======
|
|
58
|
+
If you use this code in a scientific publication, please cite us as:
|
|
59
|
+
|
|
60
|
+
.. code-block:: bibtex
|
|
61
|
+
|
|
62
|
+
@article {HBM:HBM23730,
|
|
63
|
+
author = {Schirrmeister, Robin Tibor and Springenberg, Jost Tobias and Fiederer,
|
|
64
|
+
Lukas Dominique Josef and Glasstetter, Martin and Eggensperger, Katharina and Tangermann, Michael and
|
|
65
|
+
Hutter, Frank and Burgard, Wolfram and Ball, Tonio},
|
|
66
|
+
title = {Deep learning with convolutional neural networks for EEG decoding and visualization},
|
|
67
|
+
journal = {Human Brain Mapping},
|
|
68
|
+
issn = {1097-0193},
|
|
69
|
+
url = {http://dx.doi.org/10.1002/hbm.23730},
|
|
70
|
+
doi = {10.1002/hbm.23730},
|
|
71
|
+
month = {aug},
|
|
72
|
+
year = {2017},
|
|
73
|
+
keywords = {electroencephalography, EEG analysis, machine learning, end-to-end learning, brain–machine interface,
|
|
74
|
+
brain–computer interface, model interpretability, brain mapping},
|
|
75
|
+
}
|
|
76
|
+
|
|
55
77
|
Keywords: eeg deep-learning brain-state-decoding
|
|
56
78
|
Platform: UNKNOWN
|
|
57
79
|
Classifier: Development Status :: 3 - Alpha
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 1.1
|
|
2
2
|
Name: Braindecode
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
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
|
|
@@ -52,6 +52,28 @@ Description: Note: The old braindecode repository has been moved to
|
|
|
52
52
|
|
|
53
53
|
Documentation is online under https://robintibor.github.io/braindecode/
|
|
54
54
|
|
|
55
|
+
|
|
56
|
+
Citing
|
|
57
|
+
======
|
|
58
|
+
If you use this code in a scientific publication, please cite us as:
|
|
59
|
+
|
|
60
|
+
.. code-block:: bibtex
|
|
61
|
+
|
|
62
|
+
@article {HBM:HBM23730,
|
|
63
|
+
author = {Schirrmeister, Robin Tibor and Springenberg, Jost Tobias and Fiederer,
|
|
64
|
+
Lukas Dominique Josef and Glasstetter, Martin and Eggensperger, Katharina and Tangermann, Michael and
|
|
65
|
+
Hutter, Frank and Burgard, Wolfram and Ball, Tonio},
|
|
66
|
+
title = {Deep learning with convolutional neural networks for EEG decoding and visualization},
|
|
67
|
+
journal = {Human Brain Mapping},
|
|
68
|
+
issn = {1097-0193},
|
|
69
|
+
url = {http://dx.doi.org/10.1002/hbm.23730},
|
|
70
|
+
doi = {10.1002/hbm.23730},
|
|
71
|
+
month = {aug},
|
|
72
|
+
year = {2017},
|
|
73
|
+
keywords = {electroencephalography, EEG analysis, machine learning, end-to-end learning, brain–machine interface,
|
|
74
|
+
brain–computer interface, model interpretability, brain mapping},
|
|
75
|
+
}
|
|
76
|
+
|
|
55
77
|
Keywords: eeg deep-learning brain-state-decoding
|
|
56
78
|
Platform: UNKNOWN
|
|
57
79
|
Classifier: Development Status :: 3 - Alpha
|
|
@@ -43,3 +43,25 @@ Documentation
|
|
|
43
43
|
=============
|
|
44
44
|
|
|
45
45
|
Documentation is online under https://robintibor.github.io/braindecode/
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
Citing
|
|
49
|
+
======
|
|
50
|
+
If you use this code in a scientific publication, please cite us as:
|
|
51
|
+
|
|
52
|
+
.. code-block:: bibtex
|
|
53
|
+
|
|
54
|
+
@article {HBM:HBM23730,
|
|
55
|
+
author = {Schirrmeister, Robin Tibor and Springenberg, Jost Tobias and Fiederer,
|
|
56
|
+
Lukas Dominique Josef and Glasstetter, Martin and Eggensperger, Katharina and Tangermann, Michael and
|
|
57
|
+
Hutter, Frank and Burgard, Wolfram and Ball, Tonio},
|
|
58
|
+
title = {Deep learning with convolutional neural networks for EEG decoding and visualization},
|
|
59
|
+
journal = {Human Brain Mapping},
|
|
60
|
+
issn = {1097-0193},
|
|
61
|
+
url = {http://dx.doi.org/10.1002/hbm.23730},
|
|
62
|
+
doi = {10.1002/hbm.23730},
|
|
63
|
+
month = {aug},
|
|
64
|
+
year = {2017},
|
|
65
|
+
keywords = {electroencephalography, EEG analysis, machine learning, end-to-end learning, brain–machine interface,
|
|
66
|
+
brain–computer interface, model interpretability, brain mapping},
|
|
67
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from collections import OrderedDict
|
|
3
3
|
from copy import deepcopy
|
|
4
|
+
import time
|
|
4
5
|
|
|
5
6
|
import pandas as pd
|
|
6
7
|
import torch as th
|
|
@@ -131,6 +132,8 @@ class Experiment(object):
|
|
|
131
132
|
augmentation
|
|
132
133
|
cuda: bool, optional
|
|
133
134
|
Whether to use cuda.
|
|
135
|
+
pin_memory: bool, optional
|
|
136
|
+
Whether to pin memory of inputs and targets of batch.
|
|
134
137
|
|
|
135
138
|
Attributes
|
|
136
139
|
----------
|
|
@@ -142,7 +145,7 @@ class Experiment(object):
|
|
|
142
145
|
monitors, stop_criterion, remember_best_column,
|
|
143
146
|
run_after_early_stop,
|
|
144
147
|
model_loss_function=None,
|
|
145
|
-
batch_modifier=None, cuda=True):
|
|
148
|
+
batch_modifier=None, cuda=True, pin_memory=False):
|
|
146
149
|
self.model = model
|
|
147
150
|
self.datasets = OrderedDict(
|
|
148
151
|
(('train', train_set), ('valid', valid_set), ('test', test_set)))
|
|
@@ -160,6 +163,7 @@ class Experiment(object):
|
|
|
160
163
|
self.epochs_df = pd.DataFrame()
|
|
161
164
|
self.before_stop_df = None
|
|
162
165
|
self.rememberer = None
|
|
166
|
+
self.pin_memory = pin_memory
|
|
163
167
|
|
|
164
168
|
def run(self):
|
|
165
169
|
"""
|
|
@@ -250,7 +254,7 @@ class Experiment(object):
|
|
|
250
254
|
"""
|
|
251
255
|
batch_generator = self.iterator.get_batches(datasets['train'],
|
|
252
256
|
shuffle=True)
|
|
253
|
-
|
|
257
|
+
start_train_epoch_time = time.time()
|
|
254
258
|
for inputs, targets in batch_generator:
|
|
255
259
|
if self.batch_modifier is not None:
|
|
256
260
|
inputs, targets = self.batch_modifier.process(inputs,
|
|
@@ -258,6 +262,9 @@ class Experiment(object):
|
|
|
258
262
|
# could happen that batch modifier has removed all inputs...
|
|
259
263
|
if len(inputs) > 0:
|
|
260
264
|
self.train_batch(inputs, targets)
|
|
265
|
+
end_train_epoch_time = time.time()
|
|
266
|
+
log.info("Time only for training updates: {:.2f}s".format(
|
|
267
|
+
end_train_epoch_time - start_train_epoch_time))
|
|
261
268
|
|
|
262
269
|
self.monitor_epoch(datasets)
|
|
263
270
|
self.print_epoch()
|
|
@@ -275,8 +282,8 @@ class Experiment(object):
|
|
|
275
282
|
targets: `torch.autograd.Variable`
|
|
276
283
|
"""
|
|
277
284
|
self.model.train()
|
|
278
|
-
input_vars = np_to_var(inputs)
|
|
279
|
-
target_vars = np_to_var(targets)
|
|
285
|
+
input_vars = np_to_var(inputs, pin_memory=self.pin_memory)
|
|
286
|
+
target_vars = np_to_var(targets, pin_memory=self.pin_memory)
|
|
280
287
|
if self.cuda:
|
|
281
288
|
input_vars = input_vars.cuda()
|
|
282
289
|
target_vars = target_vars.cuda()
|
|
@@ -306,8 +313,8 @@ class Experiment(object):
|
|
|
306
313
|
|
|
307
314
|
"""
|
|
308
315
|
self.model.eval()
|
|
309
|
-
input_vars = np_to_var(inputs)
|
|
310
|
-
target_vars = np_to_var(targets)
|
|
316
|
+
input_vars = np_to_var(inputs, pin_memory=self.pin_memory)
|
|
317
|
+
target_vars = np_to_var(targets, pin_memory=self.pin_memory)
|
|
311
318
|
if self.cuda:
|
|
312
319
|
input_vars = input_vars.cuda()
|
|
313
320
|
target_vars = target_vars.cuda()
|
|
@@ -29,11 +29,11 @@ class Deep4Net(object):
|
|
|
29
29
|
filter_time_length=10,
|
|
30
30
|
pool_time_length=3,
|
|
31
31
|
pool_time_stride=3,
|
|
32
|
-
|
|
32
|
+
n_filters_2=50,
|
|
33
33
|
filter_length_2=10,
|
|
34
|
-
|
|
34
|
+
n_filters_3=100,
|
|
35
35
|
filter_length_3=10,
|
|
36
|
-
|
|
36
|
+
n_filters_4=200,
|
|
37
37
|
filter_length_4=10,
|
|
38
38
|
first_nonlin=elu,
|
|
39
39
|
first_pool_mode='max',
|
|
@@ -89,18 +89,18 @@ class Deep4Net(object):
|
|
|
89
89
|
stride=(self.pool_time_stride, 1)))
|
|
90
90
|
model.add_module('pool_nonlin', Expression(self.first_pool_nonlin))
|
|
91
91
|
|
|
92
|
-
def add_conv_pool_block(model,
|
|
93
|
-
|
|
92
|
+
def add_conv_pool_block(model, n_filters_before,
|
|
93
|
+
n_filters, filter_length, block_nr):
|
|
94
94
|
suffix = '_{:d}'.format(block_nr)
|
|
95
95
|
model.add_module('drop' + suffix,
|
|
96
96
|
nn.Dropout(p=self.drop_prob))
|
|
97
97
|
model.add_module('conv' + suffix.format(block_nr),
|
|
98
|
-
nn.Conv2d(
|
|
98
|
+
nn.Conv2d(n_filters_before, n_filters,
|
|
99
99
|
(filter_length, 1),
|
|
100
100
|
stride=1, bias=not self.batch_norm))
|
|
101
101
|
if self.batch_norm:
|
|
102
102
|
model.add_module('bnorm' + suffix,
|
|
103
|
-
nn.BatchNorm2d(
|
|
103
|
+
nn.BatchNorm2d(n_filters,
|
|
104
104
|
momentum=self.batch_norm_alpha,
|
|
105
105
|
affine=True,
|
|
106
106
|
eps=1e-5))
|
|
@@ -114,11 +114,11 @@ class Deep4Net(object):
|
|
|
114
114
|
model.add_module('pool_nonlin' + suffix,
|
|
115
115
|
Expression(self.later_pool_nonlin))
|
|
116
116
|
|
|
117
|
-
add_conv_pool_block(model, n_filters_conv, self.
|
|
117
|
+
add_conv_pool_block(model, n_filters_conv, self.n_filters_2,
|
|
118
118
|
self.filter_length_2, 2)
|
|
119
|
-
add_conv_pool_block(model, self.
|
|
119
|
+
add_conv_pool_block(model, self.n_filters_2, self.n_filters_3,
|
|
120
120
|
self.filter_length_3, 3)
|
|
121
|
-
add_conv_pool_block(model, self.
|
|
121
|
+
add_conv_pool_block(model, self.n_filters_3, self.n_filters_4,
|
|
122
122
|
self.filter_length_4, 4)
|
|
123
123
|
|
|
124
124
|
|
|
@@ -129,7 +129,7 @@ class Deep4Net(object):
|
|
|
129
129
|
n_out_time = out.cpu().data.numpy().shape[2]
|
|
130
130
|
self.final_conv_length = n_out_time
|
|
131
131
|
model.add_module('conv_classifier',
|
|
132
|
-
nn.Conv2d(self.
|
|
132
|
+
nn.Conv2d(self.n_filters_4, self.n_classes,
|
|
133
133
|
(self.final_conv_length, 1), bias=True))
|
|
134
134
|
model.add_module('softmax', nn.LogSoftmax())
|
|
135
135
|
# remove empty dim at end and potentially remove empty time dim
|
|
@@ -56,13 +56,14 @@ class EEGNet(object):
|
|
|
56
56
|
model.add_module('drop_1', nn.Dropout(p=self.drop_prob))
|
|
57
57
|
|
|
58
58
|
n_filters_2 = 4
|
|
59
|
-
#
|
|
60
|
-
#
|
|
59
|
+
# keras padds unequal padding more in front, so padding
|
|
60
|
+
# too large should be ok.
|
|
61
|
+
# Not padding in time so that croped training makes sense
|
|
61
62
|
# https://stackoverflow.com/questions/43994604/padding-with-even-kernel-size-in-a-convolutional-layer-in-keras-theano
|
|
62
63
|
|
|
63
64
|
model.add_module('conv_2', nn.Conv2d(
|
|
64
65
|
1, n_filters_2, self.second_kernel_size, stride=1,
|
|
65
|
-
padding=(self.second_kernel_size[0] // 2,
|
|
66
|
+
padding=(self.second_kernel_size[0] // 2, 0),
|
|
66
67
|
bias=True))
|
|
67
68
|
model.add_module('bnorm_2',nn.BatchNorm2d(
|
|
68
69
|
n_filters_2, momentum=0.01, affine=True, eps=1e-3),)
|
|
@@ -74,7 +75,7 @@ class EEGNet(object):
|
|
|
74
75
|
n_filters_3 = 4
|
|
75
76
|
model.add_module('conv_3', nn.Conv2d(
|
|
76
77
|
n_filters_2, n_filters_3, self.third_kernel_size, stride=1,
|
|
77
|
-
padding=(self.third_kernel_size[0] // 2,
|
|
78
|
+
padding=(self.third_kernel_size[0] // 2, 0),
|
|
78
79
|
bias=True))
|
|
79
80
|
model.add_module('bnorm_3',nn.BatchNorm2d(
|
|
80
81
|
n_filters_3, momentum=0.01, affine=True, eps=1e-3),)
|
|
@@ -13,6 +13,12 @@ def to_dense_prediction_model(model, axis=(2, 3)):
|
|
|
13
13
|
axis: int or (int,int)
|
|
14
14
|
Axis to transform (in terms of intermediate output axes)
|
|
15
15
|
can either be 2, 3, or (2,3).
|
|
16
|
+
|
|
17
|
+
Notes
|
|
18
|
+
-----
|
|
19
|
+
Does not yet work correctly for average pooling.
|
|
20
|
+
Prior to version 0.1.7, there had been a bug that could move strides
|
|
21
|
+
backwards one layer.
|
|
16
22
|
|
|
17
23
|
"""
|
|
18
24
|
if not hasattr(axis, '__len__'):
|
|
@@ -21,14 +27,6 @@ def to_dense_prediction_model(model, axis=(2, 3)):
|
|
|
21
27
|
axis = np.array(axis) - 2
|
|
22
28
|
stride_so_far = np.array([1, 1])
|
|
23
29
|
for module in model.modules():
|
|
24
|
-
if hasattr(module, 'stride'):
|
|
25
|
-
if not hasattr(module.stride, '__len__'):
|
|
26
|
-
module.stride = (module.stride, module.stride)
|
|
27
|
-
stride_so_far *= np.array(module.stride)
|
|
28
|
-
new_stride = list(module.stride)
|
|
29
|
-
for ax in axis:
|
|
30
|
-
new_stride[ax] = 1
|
|
31
|
-
module.stride = tuple(new_stride)
|
|
32
30
|
if hasattr(module, 'dilation'):
|
|
33
31
|
assert module.dilation == 1 or (module.dilation == (1, 1)), (
|
|
34
32
|
"Dilation should equal 1 before conversion, maybe the model is "
|
|
@@ -37,3 +35,11 @@ def to_dense_prediction_model(model, axis=(2, 3)):
|
|
|
37
35
|
for ax in axis:
|
|
38
36
|
new_dilation[ax] = int(stride_so_far[ax])
|
|
39
37
|
module.dilation = tuple(new_dilation)
|
|
38
|
+
if hasattr(module, 'stride'):
|
|
39
|
+
if not hasattr(module.stride, '__len__'):
|
|
40
|
+
module.stride = (module.stride, module.stride)
|
|
41
|
+
stride_so_far *= np.array(module.stride)
|
|
42
|
+
new_stride = list(module.stride)
|
|
43
|
+
for ax in axis:
|
|
44
|
+
new_stride[ax] = 1
|
|
45
|
+
module.stride = tuple(new_stride)
|
|
@@ -4,18 +4,33 @@ import numpy as np
|
|
|
4
4
|
import random
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def np_to_var(X, requires_grad=False, **var_kwargs):
|
|
7
|
+
def np_to_var(X, requires_grad=False, dtype=None, pin_memory=False, **var_kwargs):
|
|
8
8
|
"""
|
|
9
9
|
Convenience function to transform numpy array to `torch.autograd.Variable`.
|
|
10
10
|
|
|
11
11
|
Converts `X` to ndarray using asarray if necessary.
|
|
12
12
|
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
X: ndarray or list
|
|
16
|
+
Input arrays
|
|
17
|
+
requires_grad: bool
|
|
18
|
+
passed on to Variable constructor
|
|
19
|
+
dtype: numpy dtype, optional
|
|
20
|
+
var_kwargs:
|
|
21
|
+
passed on to Variable constructor
|
|
22
|
+
|
|
13
23
|
Returns
|
|
14
24
|
-------
|
|
15
25
|
var: `torch.autograd.Variable`
|
|
16
26
|
"""
|
|
17
27
|
X = np.asarray(X)
|
|
18
|
-
|
|
28
|
+
if dtype is not None:
|
|
29
|
+
X = X.astype(dtype)
|
|
30
|
+
X_tensor = th.from_numpy(X)
|
|
31
|
+
if pin_memory:
|
|
32
|
+
X_tensor = X_tensor.pin_memory()
|
|
33
|
+
return Variable(X_tensor, requires_grad=requires_grad, **var_kwargs)
|
|
19
34
|
|
|
20
35
|
|
|
21
36
|
def var_to_np(var):
|
|
@@ -10,7 +10,22 @@ log = logging.getLogger(__name__)
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def gaussian_perturbation(amps, rng):
|
|
13
|
-
|
|
13
|
+
"""
|
|
14
|
+
Create gaussian noise tensor with same shape as amplitudes.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
amps: ndarray
|
|
19
|
+
Amplitudes.
|
|
20
|
+
rng: RandomState
|
|
21
|
+
Random generator.
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
perturbation: ndarray
|
|
26
|
+
Perturbations to add to the amplitudes.
|
|
27
|
+
"""
|
|
28
|
+
perturbation = rng.randn(*amps.shape).astype(np.float32)
|
|
14
29
|
return perturbation
|
|
15
30
|
|
|
16
31
|
|
|
@@ -46,6 +61,15 @@ def compute_amplitude_prediction_correlations(pred_fn, examples, n_iterations,
|
|
|
46
61
|
amplitude_pred_corrs: ndarray
|
|
47
62
|
Correlations between amplitude perturbations and prediction changes
|
|
48
63
|
for all sensors and frequency bins.
|
|
64
|
+
|
|
65
|
+
References
|
|
66
|
+
----------
|
|
67
|
+
|
|
68
|
+
.. [EEGDeepLearning] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
|
|
69
|
+
Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
|
|
70
|
+
Deep learning with convolutional neural networks for EEG decoding and
|
|
71
|
+
visualization.
|
|
72
|
+
arXiv preprint arXiv:1703.05051.
|
|
49
73
|
"""
|
|
50
74
|
inds_per_batch = get_balanced_batches(
|
|
51
75
|
n_trials=len(examples), rng=None, shuffle=False, batch_size=batch_size)
|
|
@@ -68,8 +92,8 @@ def compute_amplitude_prediction_correlations(pred_fn, examples, n_iterations,
|
|
|
68
92
|
# zero
|
|
69
93
|
perturbation = np.maximum(-amps, perturbation)
|
|
70
94
|
new_amps = amps + perturbation
|
|
71
|
-
log.info("Compute new
|
|
72
|
-
new_complex =
|
|
95
|
+
log.info("Compute new complex inputs...")
|
|
96
|
+
new_complex = _amplitude_phase_to_complex(new_amps, phases)
|
|
73
97
|
log.info("Compute new real inputs...")
|
|
74
98
|
new_in = np.fft.irfft(new_complex, axis=2).astype(np.float32)
|
|
75
99
|
log.info("Compute new predictions...")
|
|
@@ -88,5 +112,5 @@ def compute_amplitude_prediction_correlations(pred_fn, examples, n_iterations,
|
|
|
88
112
|
return amp_pred_corrs
|
|
89
113
|
|
|
90
114
|
|
|
91
|
-
def
|
|
115
|
+
def _amplitude_phase_to_complex(amplitude, phase):
|
|
92
116
|
return amplitude * np.cos(phase) + amplitude * np.sin(phase) * 1j
|
|
@@ -18,7 +18,8 @@ def ax_scalp(v, channels,
|
|
|
18
18
|
scalp_line_width=1,
|
|
19
19
|
scalp_line_style='solid',
|
|
20
20
|
chan_pos_list=CHANNEL_10_20_APPROX,
|
|
21
|
-
interpolation='bilinear'
|
|
21
|
+
interpolation='bilinear',
|
|
22
|
+
fontsize=8):
|
|
22
23
|
"""Draw a scalp plot.
|
|
23
24
|
|
|
24
25
|
Draws a scalp plot on an existing axes. The method takes an array of
|
|
@@ -138,7 +139,7 @@ def ax_scalp(v, channels,
|
|
|
138
139
|
if annotate:
|
|
139
140
|
for i in zip(channels, list(zip(x, y))):
|
|
140
141
|
ax.annotate(" " + i[0], i[1], horizontalalignment="center",
|
|
141
|
-
verticalalignment='center')
|
|
142
|
+
verticalalignment='center', fontsize=fontsize)
|
|
142
143
|
ax.set_aspect(1)
|
|
143
144
|
return image
|
|
144
145
|
|
|
@@ -63,6 +63,30 @@ API
|
|
|
63
63
|
braindecode.mne_ext
|
|
64
64
|
braindecode.models
|
|
65
65
|
braindecode.torch_ext
|
|
66
|
+
braindecode.visualization
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
Citing
|
|
70
|
+
======
|
|
71
|
+
If you use this code in a scientific publication, please cite us as:
|
|
72
|
+
|
|
73
|
+
.. code-block:: bibtex
|
|
74
|
+
|
|
75
|
+
@article {HBM:HBM23730,
|
|
76
|
+
author = {Schirrmeister, Robin Tibor and Springenberg, Jost Tobias and Fiederer,
|
|
77
|
+
Lukas Dominique Josef and Glasstetter, Martin and Eggensperger, Katharina and Tangermann, Michael and
|
|
78
|
+
Hutter, Frank and Burgard, Wolfram and Ball, Tonio},
|
|
79
|
+
title = {Deep learning with convolutional neural networks for EEG decoding and visualization},
|
|
80
|
+
journal = {Human Brain Mapping},
|
|
81
|
+
issn = {1097-0193},
|
|
82
|
+
url = {http://dx.doi.org/10.1002/hbm.23730},
|
|
83
|
+
doi = {10.1002/hbm.23730},
|
|
84
|
+
month = {aug},
|
|
85
|
+
year = {2017},
|
|
86
|
+
keywords = {electroencephalography, EEG analysis, machine learning, end-to-end learning, brain–machine interface,
|
|
87
|
+
brain–computer interface, model interpretability, brain mapping},
|
|
88
|
+
}
|
|
89
|
+
|
|
66
90
|
|
|
67
91
|
Indices and tables
|
|
68
92
|
==================
|