braindecode 0.1.8__tar.gz → 0.2.0__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.8 → Braindecode-0.2.0}/Braindecode.egg-info/PKG-INFO +1 -1
- {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/SOURCES.txt +1 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/PKG-INFO +1 -1
- Braindecode-0.2.0/braindecode/__init__.py +1 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/iterators.py +9 -4
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/signalproc.py +1 -2
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/splitters.py +14 -9
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/models/deep4.py +15 -6
- Braindecode-0.2.0/braindecode/torch_ext/losses.py +76 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/util.py +1 -0
- Braindecode-0.2.0/braindecode/version.py +1 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/Makefile +10 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/conf.py +8 -21
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/index.rst +1 -1
- Braindecode-0.2.0/docs/notebooks/BBCI_Data_Trialwise.ipynb +839 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/Cropped_Decoding.ipynb +3 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.rst +8 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/setup.cfg +1 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/setup.py +7 -4
- Braindecode-0.1.8/braindecode/__init__.py +0 -0
- Braindecode-0.1.8/braindecode/torch_ext/losses.py +0 -41
- Braindecode-0.1.8/docs/notebooks/BBCI_Data_Trialwise.ipynb +0 -780
- {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/dependency_links.txt +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/not-zip-safe +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/requires.txt +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/top_level.txt +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/LICENSE.txt +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/MANIFEST.in +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/README.rst +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datasets/__init__.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datasets/bbci.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datasets/bcic_iv_2a.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datasets/multiple.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datasets/sensor_positions.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/__init__.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/signal_target.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/trial_segment.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/util.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/experiments/__init__.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/experiments/experiment.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/experiments/monitors.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/experiments/stopcriteria.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/mne_ext/__init__.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/mne_ext/signalproc.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/models/__init__.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/models/eegnet.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/models/shallow_fbcsp.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/models/util.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/__init__.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/constraints.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/functions.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/init.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/modules.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/util.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/visualization/__init__.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/visualization/perturbation.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/visualization/plot.py +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/BBCI_Data.ipynb +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/BBCI_Data_Start_Stop.ipynb +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/Experiment_Class.ipynb +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/TrialWise_Decoding.ipynb +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/visualization/Perturbation.ipynb +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.datasets.rst +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.datautil.rst +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.experiments.rst +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.mne_ext.rst +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.models.rst +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.torch_ext.rst +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.visualization.rst +0 -0
- {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/modules.rst +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from braindecode.version import __version__
|
|
@@ -218,7 +218,7 @@ class CropsFromTrialsIterator(object):
|
|
|
218
218
|
for i_blocks in blocks_per_batch:
|
|
219
219
|
start_stop_blocks = i_trial_start_stop_block[i_blocks]
|
|
220
220
|
batch = _create_batch_from_i_trial_start_stop_blocks(
|
|
221
|
-
X, y, start_stop_blocks)
|
|
221
|
+
X, y, start_stop_blocks, self.n_preds_per_input)
|
|
222
222
|
yield batch
|
|
223
223
|
|
|
224
224
|
|
|
@@ -231,7 +231,7 @@ def _compute_start_stop_block_inds(i_trial_starts, i_trial_stops,
|
|
|
231
231
|
----------
|
|
232
232
|
i_trial_starts: 1darray/list of int
|
|
233
233
|
Indices of first samples to predict(!).
|
|
234
|
-
i_trial_stops:
|
|
234
|
+
i_trial_stops: 1darray/list of int
|
|
235
235
|
Indices one past last sample to predict.
|
|
236
236
|
input_time_length: int
|
|
237
237
|
n_preds_per_input: int
|
|
@@ -299,12 +299,17 @@ def _get_start_stop_blocks_for_trial(i_trial_start, i_trial_stop,
|
|
|
299
299
|
return start_stop_blocks
|
|
300
300
|
|
|
301
301
|
|
|
302
|
-
def _create_batch_from_i_trial_start_stop_blocks(X, y, i_trial_start_stop_block
|
|
302
|
+
def _create_batch_from_i_trial_start_stop_blocks(X, y, i_trial_start_stop_block,
|
|
303
|
+
n_preds_per_input=None):
|
|
303
304
|
Xs = []
|
|
304
305
|
ys = []
|
|
305
306
|
for i_trial, start, stop in i_trial_start_stop_block:
|
|
306
307
|
Xs.append(X[i_trial][:,start:stop])
|
|
307
|
-
|
|
308
|
+
if not hasattr(y[i_trial], '__len__'):
|
|
309
|
+
ys.append(y[i_trial])
|
|
310
|
+
else:
|
|
311
|
+
assert n_preds_per_input is not None
|
|
312
|
+
ys.append(y[i_trial][stop-n_preds_per_input:stop])
|
|
308
313
|
batch_X = np.array(Xs)
|
|
309
314
|
batch_y = np.array(ys)
|
|
310
315
|
# add empty fourth dimension if necessary
|
|
@@ -17,7 +17,7 @@ def exponential_running_standardize(data, factor_new=0.001,
|
|
|
17
17
|
:math:`m_t=\mathrm{factornew} \cdot mean(x_t) + (1 - \mathrm{factornew}) \cdot m_{t-1}`.
|
|
18
18
|
|
|
19
19
|
Then, compute exponential running variance :math:`v_t` at time `t` as
|
|
20
|
-
:math:`
|
|
20
|
+
:math:`v_t=\mathrm{factornew} \cdot (m_t - x_t)^2 + (1 - \mathrm{factornew}) \cdot v_{t-1}`.
|
|
21
21
|
|
|
22
22
|
Finally, standardize the data point :math:`x_t` at time `t` as:
|
|
23
23
|
:math:`x'_t=(x_t - m_t) / max(\sqrt{v_t}, eps)`.
|
|
@@ -214,4 +214,3 @@ def filter_is_stable(a):
|
|
|
214
214
|
"a: {:s}".format(str(a)))
|
|
215
215
|
# from http://stackoverflow.com/a/8812737/1469195
|
|
216
216
|
return np.all(np.abs(np.roots(a))<1)
|
|
217
|
-
|
|
@@ -33,17 +33,22 @@ def concatenate_two_sets(set_a, set_b):
|
|
|
33
33
|
-------
|
|
34
34
|
concatenated_set: :class:`.SignalAndTarget`
|
|
35
35
|
"""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
else:
|
|
39
|
-
if hasattr(set_a.X, 'ndim'):
|
|
40
|
-
set_a.X = set_a.X.tolist()
|
|
41
|
-
if hasattr(set_b.X, 'ndim'):
|
|
42
|
-
set_b.X = set_b.X.tolist()
|
|
43
|
-
new_X = set_a.X + set_b.X
|
|
44
|
-
new_y = np.concatenate((set_a.y, set_b.y), axis=0)
|
|
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)
|
|
45
38
|
return SignalAndTarget(new_X, new_y)
|
|
46
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
|
+
|
|
47
52
|
|
|
48
53
|
def split_into_two_sets(dataset, first_set_fraction=None, n_first_set=None):
|
|
49
54
|
"""
|
|
@@ -45,7 +45,8 @@ class Deep4Net(object):
|
|
|
45
45
|
double_time_convs=False,
|
|
46
46
|
split_first_layer=True,
|
|
47
47
|
batch_norm=True,
|
|
48
|
-
batch_norm_alpha=0.1
|
|
48
|
+
batch_norm_alpha=0.1,
|
|
49
|
+
stride_before_pool=False):
|
|
49
50
|
if final_conv_length == 'auto':
|
|
50
51
|
assert input_time_length is not None
|
|
51
52
|
|
|
@@ -53,6 +54,12 @@ class Deep4Net(object):
|
|
|
53
54
|
del self.self
|
|
54
55
|
|
|
55
56
|
def create_network(self):
|
|
57
|
+
if self.stride_before_pool:
|
|
58
|
+
conv_stride = self.pool_time_stride
|
|
59
|
+
pool_stride = 1
|
|
60
|
+
else:
|
|
61
|
+
conv_stride = 1
|
|
62
|
+
pool_stride = self.pool_time_stride
|
|
56
63
|
pool_class_dict = dict(max=nn.MaxPool2d, mean=AvgPool2dWithConv)
|
|
57
64
|
first_pool_class = pool_class_dict[self.first_pool_mode]
|
|
58
65
|
later_pool_class = pool_class_dict[self.later_pool_mode]
|
|
@@ -66,14 +73,15 @@ class Deep4Net(object):
|
|
|
66
73
|
stride=1, ))
|
|
67
74
|
model.add_module('conv_spat',
|
|
68
75
|
nn.Conv2d(self.n_filters_time, self.n_filters_spat,
|
|
69
|
-
(1, self.in_chans),
|
|
76
|
+
(1, self.in_chans),
|
|
77
|
+
stride=(conv_stride, 1),
|
|
70
78
|
bias=not self.batch_norm))
|
|
71
79
|
n_filters_conv = self.n_filters_spat
|
|
72
80
|
else:
|
|
73
81
|
model.add_module('conv_time',
|
|
74
82
|
nn.Conv2d(self.in_chans, self.n_filters_time,
|
|
75
83
|
(self.filter_time_length, 1),
|
|
76
|
-
stride=1,
|
|
84
|
+
stride=(conv_stride, 1),
|
|
77
85
|
bias=not self.batch_norm))
|
|
78
86
|
n_filters_conv = self.n_filters_time
|
|
79
87
|
if self.batch_norm:
|
|
@@ -86,7 +94,7 @@ class Deep4Net(object):
|
|
|
86
94
|
model.add_module('pool',
|
|
87
95
|
first_pool_class(
|
|
88
96
|
kernel_size=(self.pool_time_length, 1),
|
|
89
|
-
stride=(
|
|
97
|
+
stride=(pool_stride, 1)))
|
|
90
98
|
model.add_module('pool_nonlin', Expression(self.first_pool_nonlin))
|
|
91
99
|
|
|
92
100
|
def add_conv_pool_block(model, n_filters_before,
|
|
@@ -97,7 +105,8 @@ class Deep4Net(object):
|
|
|
97
105
|
model.add_module('conv' + suffix.format(block_nr),
|
|
98
106
|
nn.Conv2d(n_filters_before, n_filters,
|
|
99
107
|
(filter_length, 1),
|
|
100
|
-
stride=
|
|
108
|
+
stride=(conv_stride, 1),
|
|
109
|
+
bias=not self.batch_norm))
|
|
101
110
|
if self.batch_norm:
|
|
102
111
|
model.add_module('bnorm' + suffix,
|
|
103
112
|
nn.BatchNorm2d(n_filters,
|
|
@@ -110,7 +119,7 @@ class Deep4Net(object):
|
|
|
110
119
|
model.add_module('pool' + suffix,
|
|
111
120
|
later_pool_class(
|
|
112
121
|
kernel_size=(self.pool_time_length, 1),
|
|
113
|
-
stride=(
|
|
122
|
+
stride=(pool_stride, 1)))
|
|
114
123
|
model.add_module('pool_nonlin' + suffix,
|
|
115
124
|
Expression(self.later_pool_nonlin))
|
|
116
125
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import torch as th
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def log_categorical_crossentropy_1_hot(logpreds, targets, dims=None):
|
|
5
|
+
"""
|
|
6
|
+
Returns log categorical crossentropy for given log-predictions and targets,
|
|
7
|
+
targets should be one-hot-encoded.
|
|
8
|
+
|
|
9
|
+
Computes :math:`-\mathrm{logpreds} \cdot \mathrm{targets}`
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
logpreds: `torch.autograd.Variable`
|
|
14
|
+
Logarithm of softmax output.
|
|
15
|
+
targets: `torch.autograd.Variable`
|
|
16
|
+
One-hot encoded targets
|
|
17
|
+
dims: int or iterable of int, optional.
|
|
18
|
+
Compute sum across these dims
|
|
19
|
+
|
|
20
|
+
Returns
|
|
21
|
+
-------
|
|
22
|
+
loss: `torch.autograd.Variable`
|
|
23
|
+
:math:`-\mathrm{logpreds} \cdot \mathrm{targets}`
|
|
24
|
+
"""
|
|
25
|
+
assert logpreds.size() == targets.size()
|
|
26
|
+
result = -logpreds * targets
|
|
27
|
+
# Sum across dims if axis given or more than 1 dim
|
|
28
|
+
if dims is not None:
|
|
29
|
+
if not hasattr(dims, '__len__'):
|
|
30
|
+
dims = [dims]
|
|
31
|
+
for dim in dims:
|
|
32
|
+
result = th.sum(result, dim=int(dim))
|
|
33
|
+
return result
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def log_categorical_crossentropy(log_preds, targets):
|
|
37
|
+
"""
|
|
38
|
+
Returns log categorical crossentropy for given log-predictions and targets.
|
|
39
|
+
|
|
40
|
+
Computes :math:`-\mathrm{logpreds} \cdot \mathrm{targets}` if you assume
|
|
41
|
+
targets to be one-hot-encoded. Also works for targets that are not
|
|
42
|
+
one-hot-encoded, in this case only uses targets that are in the range
|
|
43
|
+
of the expected class labels, i.e., [0,log_preds.size()[1]-1].
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
log_preds: torch.autograd.Variable`
|
|
48
|
+
Logarithm of softmax output.
|
|
49
|
+
targets: `torch.autograd.Variable`
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
|
|
54
|
+
loss: `torch.autograd.Variable`
|
|
55
|
+
"""
|
|
56
|
+
if log_preds.size() == targets.size():
|
|
57
|
+
return log_categorical_crossentropy_1_hot(log_preds, targets)
|
|
58
|
+
n_classes = log_preds.size()[1]
|
|
59
|
+
n_elements = 0
|
|
60
|
+
losses = []
|
|
61
|
+
for i_class in range(n_classes):
|
|
62
|
+
mask = targets == i_class
|
|
63
|
+
mask = mask.type_as(log_preds)
|
|
64
|
+
n_elements -= th.sum(mask)
|
|
65
|
+
losses.append(th.sum(mask * log_preds[:,i_class]))
|
|
66
|
+
return th.sum(th.stack(losses)) / n_elements
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def l2_loss(model):
|
|
70
|
+
losses = [th.sum(p * p) for p in model.parameters()]
|
|
71
|
+
return sum(losses)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def l1_loss(model):
|
|
75
|
+
losses = [th.sum(th.abs(p)) for p in model.parameters()]
|
|
76
|
+
return sum(losses)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.0"
|
|
@@ -21,3 +21,13 @@ apidoc:
|
|
|
21
21
|
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
|
22
22
|
%: Makefile
|
|
23
23
|
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
removeipynbcheckpoints: Makefile
|
|
27
|
+
rm -rf notebooks/.ipynb_checkpoints/ notebooks/visualization/.ipynb_checkpoints/
|
|
28
|
+
|
|
29
|
+
removesource: Makefile
|
|
30
|
+
rm -rf source/
|
|
31
|
+
|
|
32
|
+
rmanddoc: removesource removeipynbcheckpoints apidoc html
|
|
33
|
+
echo "Done"
|
|
@@ -21,6 +21,8 @@ import os
|
|
|
21
21
|
import sys
|
|
22
22
|
sys.path.insert(0, os.path.abspath('.'))
|
|
23
23
|
sys.path.insert(0, os.path.abspath('..'))
|
|
24
|
+
import matplotlib
|
|
25
|
+
matplotlib.use('agg')
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
|
|
@@ -80,8 +82,9 @@ autodoc_member_order = 'bysource'
|
|
|
80
82
|
## Default flags used by autodoc directives
|
|
81
83
|
autodoc_default_flags = ['members', 'show-inheritance']
|
|
82
84
|
|
|
83
|
-
exclude_patterns = ['_build', '_templates'
|
|
84
|
-
|
|
85
|
+
exclude_patterns = ['_build', '_templates']
|
|
86
|
+
|
|
87
|
+
|
|
85
88
|
napoleon_google_docstring = False
|
|
86
89
|
napoleon_use_param = False
|
|
87
90
|
napoleon_use_ivar = True
|
|
@@ -108,9 +111,10 @@ author = 'Robin Tibor Schirrmeister'
|
|
|
108
111
|
# built documents.
|
|
109
112
|
#
|
|
110
113
|
# The short X.Y version.
|
|
111
|
-
|
|
114
|
+
import braindecode
|
|
115
|
+
version = braindecode.__version__
|
|
112
116
|
# The full version, including alpha/beta/rc tags.
|
|
113
|
-
release =
|
|
117
|
+
release = version
|
|
114
118
|
|
|
115
119
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
|
116
120
|
# for a list of supported languages.
|
|
@@ -209,20 +213,3 @@ texinfo_documents = [
|
|
|
209
213
|
author, 'Braindecode', 'One line description of project.',
|
|
210
214
|
'Miscellaneous'),
|
|
211
215
|
]
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
## mock stuff
|
|
215
|
-
"""
|
|
216
|
-
import sys
|
|
217
|
-
from mock import Mock as MagicMock
|
|
218
|
-
#from unittest.mock import MagicMock
|
|
219
|
-
|
|
220
|
-
class Mock(MagicMock):
|
|
221
|
-
@classmethod
|
|
222
|
-
def __getattr__(cls, name):
|
|
223
|
-
return MagicMock()
|
|
224
|
-
|
|
225
|
-
MOCK_MODULES = ['torch', 'h5py',]
|
|
226
|
-
sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
|
|
227
|
-
|
|
228
|
-
"""
|
|
@@ -3,7 +3,7 @@ Welcome to Braindecode
|
|
|
3
3
|
|
|
4
4
|
A deep learning toolbox to decode raw time-domain EEG.
|
|
5
5
|
|
|
6
|
-
For EEG researchers that want to
|
|
6
|
+
For EEG researchers that want to work with deep learning and
|
|
7
7
|
deep learning researchers that want to work with EEG data.
|
|
8
8
|
For now focussed on convolutional networks.
|
|
9
9
|
|