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.
Files changed (70) hide show
  1. {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/PKG-INFO +1 -1
  2. {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/SOURCES.txt +1 -0
  3. {Braindecode-0.1.8 → Braindecode-0.2.0}/PKG-INFO +1 -1
  4. Braindecode-0.2.0/braindecode/__init__.py +1 -0
  5. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/iterators.py +9 -4
  6. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/signalproc.py +1 -2
  7. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/splitters.py +14 -9
  8. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/models/deep4.py +15 -6
  9. Braindecode-0.2.0/braindecode/torch_ext/losses.py +76 -0
  10. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/util.py +1 -0
  11. Braindecode-0.2.0/braindecode/version.py +1 -0
  12. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/Makefile +10 -0
  13. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/conf.py +8 -21
  14. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/index.rst +1 -1
  15. Braindecode-0.2.0/docs/notebooks/BBCI_Data_Trialwise.ipynb +839 -0
  16. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/Cropped_Decoding.ipynb +3 -0
  17. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.rst +8 -0
  18. {Braindecode-0.1.8 → Braindecode-0.2.0}/setup.cfg +1 -0
  19. {Braindecode-0.1.8 → Braindecode-0.2.0}/setup.py +7 -4
  20. Braindecode-0.1.8/braindecode/__init__.py +0 -0
  21. Braindecode-0.1.8/braindecode/torch_ext/losses.py +0 -41
  22. Braindecode-0.1.8/docs/notebooks/BBCI_Data_Trialwise.ipynb +0 -780
  23. {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/dependency_links.txt +0 -0
  24. {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/not-zip-safe +0 -0
  25. {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/requires.txt +0 -0
  26. {Braindecode-0.1.8 → Braindecode-0.2.0}/Braindecode.egg-info/top_level.txt +0 -0
  27. {Braindecode-0.1.8 → Braindecode-0.2.0}/LICENSE.txt +0 -0
  28. {Braindecode-0.1.8 → Braindecode-0.2.0}/MANIFEST.in +0 -0
  29. {Braindecode-0.1.8 → Braindecode-0.2.0}/README.rst +0 -0
  30. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datasets/__init__.py +0 -0
  31. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datasets/bbci.py +0 -0
  32. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datasets/bcic_iv_2a.py +0 -0
  33. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datasets/multiple.py +0 -0
  34. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datasets/sensor_positions.py +0 -0
  35. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/__init__.py +0 -0
  36. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/signal_target.py +0 -0
  37. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/trial_segment.py +0 -0
  38. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/datautil/util.py +0 -0
  39. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/experiments/__init__.py +0 -0
  40. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/experiments/experiment.py +0 -0
  41. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/experiments/monitors.py +0 -0
  42. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/experiments/stopcriteria.py +0 -0
  43. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/mne_ext/__init__.py +0 -0
  44. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/mne_ext/signalproc.py +0 -0
  45. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/models/__init__.py +0 -0
  46. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/models/eegnet.py +0 -0
  47. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/models/shallow_fbcsp.py +0 -0
  48. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/models/util.py +0 -0
  49. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/__init__.py +0 -0
  50. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/constraints.py +0 -0
  51. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/functions.py +0 -0
  52. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/init.py +0 -0
  53. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/modules.py +0 -0
  54. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/torch_ext/util.py +0 -0
  55. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/visualization/__init__.py +0 -0
  56. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/visualization/perturbation.py +0 -0
  57. {Braindecode-0.1.8 → Braindecode-0.2.0}/braindecode/visualization/plot.py +0 -0
  58. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/BBCI_Data.ipynb +0 -0
  59. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/BBCI_Data_Start_Stop.ipynb +0 -0
  60. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/Experiment_Class.ipynb +0 -0
  61. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/TrialWise_Decoding.ipynb +0 -0
  62. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/notebooks/visualization/Perturbation.ipynb +0 -0
  63. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.datasets.rst +0 -0
  64. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.datautil.rst +0 -0
  65. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.experiments.rst +0 -0
  66. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.mne_ext.rst +0 -0
  67. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.models.rst +0 -0
  68. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.torch_ext.rst +0 -0
  69. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/braindecode.visualization.rst +0 -0
  70. {Braindecode-0.1.8 → Braindecode-0.2.0}/docs/source/modules.rst +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: Braindecode
3
- Version: 0.1.8
3
+ Version: 0.2.0
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
@@ -10,6 +10,7 @@ Braindecode.egg-info/requires.txt
10
10
  Braindecode.egg-info/top_level.txt
11
11
  braindecode/__init__.py
12
12
  braindecode/util.py
13
+ braindecode/version.py
13
14
  braindecode/datasets/__init__.py
14
15
  braindecode/datasets/bbci.py
15
16
  braindecode/datasets/bcic_iv_2a.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: Braindecode
3
- Version: 0.1.8
3
+ Version: 0.2.0
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 @@
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: 1daray/list of int
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
- ys.append(y[i_trial])
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:`m_t=\mathrm{factornew} \cdot (m_t - x_t)^2 + (1 - \mathrm{factornew}) \cdot v_{t-1}`.
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
- if hasattr(set_a.X, 'ndim') and hasattr(set_b.X, 'ndim'):
37
- new_X = np.concatenate((set_a.X, set_b.X), axis=0)
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), stride=1,
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=(self.pool_time_stride, 1)))
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=1, bias=not self.batch_norm))
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=(self.pool_time_stride, 1)))
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)
@@ -59,6 +59,7 @@ def wrap_reshape_apply_fn(stat_fn, a, b, axis_a, axis_b):
59
59
  """
60
60
  Reshape two nd-arrays into 2d-arrays, apply function and reshape
61
61
  result back.
62
+
62
63
  Parameters
63
64
  ----------
64
65
  stat_fn: function
@@ -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
- version = '0.1.6'
114
+ import braindecode
115
+ version = braindecode.__version__
112
116
  # The full version, including alpha/beta/rc tags.
113
- release = '0.1.6'
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 want to work with deep learning and
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