braindecode 0.4.0__tar.gz → 0.4.3__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.0 → Braindecode-0.4.3}/Braindecode.egg-info/PKG-INFO +1 -1
  2. {Braindecode-0.4.0 → Braindecode-0.4.3}/Braindecode.egg-info/SOURCES.txt +1 -1
  3. {Braindecode-0.4.0 → Braindecode-0.4.3}/PKG-INFO +1 -1
  4. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/models/base.py +15 -7
  5. Braindecode-0.4.3/braindecode/models/deep4new.py +228 -0
  6. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/models/eegnet.py +1 -1
  7. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/models/hybrid.py +15 -1
  8. Braindecode-0.4.3/braindecode/version.py +1 -0
  9. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/notebooks/Cropped_Decoding.ipynb +3 -1
  10. Braindecode-0.4.0/braindecode/version.py +0 -1
  11. Braindecode-0.4.0/docs/notebooks/visualization/Perturbation_Old.ipynb +0 -780
  12. {Braindecode-0.4.0 → Braindecode-0.4.3}/Braindecode.egg-info/dependency_links.txt +0 -0
  13. {Braindecode-0.4.0 → Braindecode-0.4.3}/Braindecode.egg-info/not-zip-safe +0 -0
  14. {Braindecode-0.4.0 → Braindecode-0.4.3}/Braindecode.egg-info/requires.txt +0 -0
  15. {Braindecode-0.4.0 → Braindecode-0.4.3}/Braindecode.egg-info/top_level.txt +0 -0
  16. {Braindecode-0.4.0 → Braindecode-0.4.3}/LICENSE.txt +0 -0
  17. {Braindecode-0.4.0 → Braindecode-0.4.3}/MANIFEST.in +0 -0
  18. {Braindecode-0.4.0 → Braindecode-0.4.3}/README.rst +0 -0
  19. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/__init__.py +0 -0
  20. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datasets/__init__.py +0 -0
  21. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datasets/bbci.py +0 -0
  22. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datasets/bcic_iv_2a.py +0 -0
  23. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datasets/multiple.py +0 -0
  24. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datasets/sensor_positions.py +0 -0
  25. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datautil/__init__.py +0 -0
  26. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datautil/iterators.py +0 -0
  27. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datautil/signal_target.py +0 -0
  28. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datautil/signalproc.py +0 -0
  29. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datautil/splitters.py +0 -0
  30. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datautil/trial_segment.py +0 -0
  31. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/datautil/util.py +0 -0
  32. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/experiments/__init__.py +0 -0
  33. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/experiments/experiment.py +0 -0
  34. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/experiments/loggers.py +0 -0
  35. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/experiments/monitors.py +0 -0
  36. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/experiments/stopcriteria.py +0 -0
  37. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/mne_ext/__init__.py +0 -0
  38. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/mne_ext/signalproc.py +0 -0
  39. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/models/__init__.py +0 -0
  40. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/models/deep4.py +0 -0
  41. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/models/shallow_fbcsp.py +0 -0
  42. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/models/util.py +0 -0
  43. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/torch_ext/__init__.py +0 -0
  44. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/torch_ext/constraints.py +0 -0
  45. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/torch_ext/functions.py +0 -0
  46. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/torch_ext/init.py +0 -0
  47. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/torch_ext/losses.py +0 -0
  48. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/torch_ext/modules.py +0 -0
  49. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/torch_ext/optimizers.py +0 -0
  50. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/torch_ext/schedulers.py +0 -0
  51. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/torch_ext/util.py +0 -0
  52. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/util.py +0 -0
  53. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/visualization/__init__.py +0 -0
  54. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/visualization/input_windows.py +0 -0
  55. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/visualization/perturbation.py +0 -0
  56. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/visualization/plot.py +0 -0
  57. {Braindecode-0.4.0 → Braindecode-0.4.3}/braindecode/visualization/sinfit.py +0 -0
  58. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/Makefile +0 -0
  59. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/conf.py +0 -0
  60. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/index.rst +0 -0
  61. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/notebooks/BBCI_Data.ipynb +0 -0
  62. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/notebooks/BBCI_Data_Start_Stop.ipynb +0 -0
  63. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/notebooks/BBCI_Data_Trialwise.ipynb +0 -0
  64. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/notebooks/Cropped_Manual_Training_Loop.ipynb +0 -0
  65. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/notebooks/Cropped_Trialwise_Explanation_Figures.ipynb +0 -0
  66. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/notebooks/Trialwise_Decoding.ipynb +0 -0
  67. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/notebooks/Trialwise_Manual_Training_Loop.ipynb +0 -0
  68. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/notebooks/visualization/Perturbation.ipynb +0 -0
  69. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/source/braindecode.datasets.rst +0 -0
  70. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/source/braindecode.datautil.rst +0 -0
  71. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/source/braindecode.experiments.rst +0 -0
  72. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/source/braindecode.mne_ext.rst +0 -0
  73. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/source/braindecode.models.rst +0 -0
  74. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/source/braindecode.rst +0 -0
  75. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/source/braindecode.torch_ext.rst +0 -0
  76. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/source/braindecode.visualization.rst +0 -0
  77. {Braindecode-0.4.0 → Braindecode-0.4.3}/docs/source/modules.rst +0 -0
  78. {Braindecode-0.4.0 → Braindecode-0.4.3}/setup.cfg +0 -0
  79. {Braindecode-0.4.0 → Braindecode-0.4.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: Braindecode
3
- Version: 0.4.0
3
+ Version: 0.4.3
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,6 +33,7 @@ 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
36
37
  braindecode/models/eegnet.py
37
38
  braindecode/models/hybrid.py
38
39
  braindecode/models/shallow_fbcsp.py
@@ -63,7 +64,6 @@ docs/notebooks/Cropped_Trialwise_Explanation_Figures.ipynb
63
64
  docs/notebooks/Trialwise_Decoding.ipynb
64
65
  docs/notebooks/Trialwise_Manual_Training_Loop.ipynb
65
66
  docs/notebooks/visualization/Perturbation.ipynb
66
- docs/notebooks/visualization/Perturbation_Old.ipynb
67
67
  docs/source/braindecode.datasets.rst
68
68
  docs/source/braindecode.datautil.rst
69
69
  docs/source/braindecode.experiments.rst
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: Braindecode
3
- Version: 0.4.0
3
+ Version: 0.4.3
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
@@ -57,7 +57,7 @@ class BaseModel(object):
57
57
  self.cuda = False
58
58
  self.compiled = False
59
59
 
60
- def compile(self, loss, optimizer, monitors=None, cropped=False, iterator_seed=0):
60
+ def compile(self, loss, optimizer, extra_monitors=None, cropped=False, iterator_seed=0):
61
61
  """
62
62
  Setup training for this model.
63
63
 
@@ -66,7 +66,7 @@ class BaseModel(object):
66
66
  loss: function (predictions, targets) -> torch scalar
67
67
  optimizer: `torch.optim.Optimizer` or string
68
68
  Either supply an optimizer or the name of the class (e.g. 'adam')
69
- monitors: List of Braindecode monitors, optional
69
+ extra_monitors: List of Braindecode monitors, optional
70
70
  In case you want to monitor additional values except for loss, misclass and runtime.
71
71
  cropped: bool
72
72
  Whether to perform cropped decoding, see cropped decoding tutorial.
@@ -84,7 +84,7 @@ class BaseModel(object):
84
84
  optimizer_class = find_optimizer(optimizer)
85
85
  optimizer = optimizer_class(self.network.parameters())
86
86
  self.optimizer = optimizer
87
- self.extra_monitors = monitors
87
+ self.extra_monitors = extra_monitors
88
88
  # Already setting it here, so multiple calls to fit
89
89
  # will lead to different batches being drawn
90
90
  self.seed_rng = RandomState(iterator_seed)
@@ -93,7 +93,8 @@ class BaseModel(object):
93
93
 
94
94
  def fit(self, train_X, train_y, epochs, batch_size, input_time_length=None,
95
95
  validation_data=None, model_constraint=None,
96
- remember_best_column=None, scheduler=None):
96
+ remember_best_column=None, scheduler=None,
97
+ log_0_epoch=True):
97
98
  """
98
99
  Fit the model using the given training data.
99
100
 
@@ -122,6 +123,8 @@ class BaseModel(object):
122
123
  determines the best epoch.
123
124
  scheduler: 'cosine' or None, optional
124
125
  Whether to use cosine annealing (:class:`.CosineAnnealing`).
126
+ log_0_epoch: bool
127
+ Whether to compute the metrics once before training as well.
125
128
 
126
129
  Returns
127
130
  -------
@@ -137,6 +140,7 @@ class BaseModel(object):
137
140
  "which is the number of timesteps that will be pushed through"
138
141
  "the network in a single pass.")
139
142
  if self.cropped:
143
+ self.network.eval()
140
144
  test_input = np_to_var(train_X[0:1], dtype=np.float32)
141
145
  while len(test_input.size()) < 4:
142
146
  test_input = test_input.unsqueeze(-1)
@@ -152,7 +156,10 @@ class BaseModel(object):
152
156
  self.iterator = BalancedBatchSizeIterator(
153
157
  batch_size=batch_size,
154
158
  seed=self.seed_rng.randint(0, 4294967295))
155
- stop_criterion = MaxEpochs(epochs - 1)# -1 since we dont print 0 epoch, which matters for this stop criterion
159
+ if log_0_epoch:
160
+ stop_criterion = MaxEpochs(epochs)
161
+ else:
162
+ stop_criterion = MaxEpochs(epochs - 1)
156
163
  train_set = SignalAndTarget(train_X, train_y)
157
164
  optimizer = self.optimizer
158
165
  if scheduler is not None:
@@ -192,7 +199,8 @@ class BaseModel(object):
192
199
  monitors=self.monitors,
193
200
  stop_criterion=stop_criterion,
194
201
  remember_best_column=remember_best_column,
195
- run_after_early_stop=False, cuda=self.cuda, log_0_epoch=False,
202
+ run_after_early_stop=False, cuda=self.cuda,
203
+ log_0_epoch=log_0_epoch,
196
204
  do_early_stop=(remember_best_column is not None))
197
205
  exp.run()
198
206
  self.epochs_df = exp.epochs_df
@@ -237,7 +245,7 @@ class BaseModel(object):
237
245
  stop_criterion=stop_criterion,
238
246
  remember_best_column=None,
239
247
  run_after_early_stop=False, cuda=self.cuda,
240
- log_0_epoch=False,
248
+ log_0_epoch=True,
241
249
  do_early_stop=False)
242
250
 
243
251
  exp.monitor_epoch({'train': train_set})
@@ -0,0 +1,228 @@
1
+ import numpy as np
2
+ from torch import nn
3
+ from torch.nn import init
4
+ from torch.nn.functional import elu
5
+
6
+ from braindecode.models.base import BaseModel
7
+ from braindecode.torch_ext.modules import Expression, AvgPool2dWithConv
8
+ from braindecode.torch_ext.functions import identity
9
+ from braindecode.torch_ext.util import np_to_var
10
+
11
+
12
+ class Deep4NetNew(BaseModel):
13
+ """
14
+ Deep ConvNet model from [1]_.
15
+
16
+ References
17
+ ----------
18
+
19
+ .. [1] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
20
+ Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
21
+ Deep learning with convolutional neural networks for EEG decoding and
22
+ visualization.
23
+ arXiv preprint arXiv:1703.05051.
24
+ """
25
+ def __init__(self, in_chans,
26
+ n_classes,
27
+ input_time_length,
28
+ final_conv_length,
29
+ n_filters_time=25,
30
+ n_filters_spat=25,
31
+ filter_time_length=10,
32
+ pool_time_length=3,
33
+ pool_time_stride=3,
34
+ n_filters_2=50,
35
+ filter_length_2=10,
36
+ n_filters_3=100,
37
+ filter_length_3=10,
38
+ n_filters_4=200,
39
+ filter_length_4=10,
40
+ first_nonlin=elu,
41
+ first_pool_mode='max',
42
+ first_pool_nonlin=identity,
43
+ later_nonlin=elu,
44
+ later_pool_mode='max',
45
+ later_pool_nonlin=identity,
46
+ drop_prob=0.5,
47
+ double_time_convs=False,
48
+ split_first_layer=True,
49
+ batch_norm=True,
50
+ batch_norm_alpha=0.1,
51
+ stride_before_pool=False,
52
+ separable=False):
53
+ if final_conv_length == 'auto':
54
+ assert input_time_length is not None
55
+
56
+ self.__dict__.update(locals())
57
+ del self.self
58
+
59
+ def create_network(self):
60
+ def add_conv_2d(separable, model, name,
61
+ in_filters, out_filters, kernel_size, **kwargs):
62
+ if separable:
63
+ model.add_module(
64
+ name + '_depth',
65
+ nn.Conv2d(
66
+ in_filters, in_filters, kernel_size, groups=in_filters,
67
+ **kwargs))
68
+ model.add_module(
69
+ name + '_point',
70
+ nn.Conv2d(
71
+ in_filters, out_filters, (1, 1), **kwargs))
72
+ else:
73
+ model.add_module(
74
+ name,
75
+ nn.Conv2d(in_filters, out_filters,
76
+ kernel_size, **kwargs))
77
+
78
+ if self.stride_before_pool:
79
+ conv_stride = self.pool_time_stride
80
+ pool_stride = 1
81
+ else:
82
+ conv_stride = 1
83
+ pool_stride = self.pool_time_stride
84
+ pool_class_dict = dict(max=nn.MaxPool2d, mean=AvgPool2dWithConv)
85
+ first_pool_class = pool_class_dict[self.first_pool_mode]
86
+ later_pool_class = pool_class_dict[self.later_pool_mode]
87
+ model = nn.Sequential()
88
+ if self.split_first_layer:
89
+ model.add_module('dimshuffle', Expression(_transpose_time_to_spat))
90
+ model.add_module('conv_time', nn.Conv2d(1, self.n_filters_time,
91
+ (
92
+ self.filter_time_length, 1),
93
+ stride=1, ))
94
+ add_conv_2d(
95
+ self.separable, model, 'conv_spat',
96
+ self.n_filters_time, self.n_filters_spat,
97
+ (1, self.in_chans),
98
+ stride=(conv_stride, 1),
99
+ bias=not self.batch_norm)
100
+ n_filters_conv = self.n_filters_spat
101
+ else:
102
+ add_conv_2d(
103
+ self.separable, model, 'conv_time',
104
+ self.in_chans, self.n_filters_time,
105
+ (self.filter_time_length, 1),
106
+ stride=(conv_stride, 1),
107
+ bias=not self.batch_norm)
108
+ n_filters_conv = self.n_filters_time
109
+ if self.batch_norm:
110
+ model.add_module('bnorm',
111
+ nn.BatchNorm2d(n_filters_conv,
112
+ momentum=self.batch_norm_alpha,
113
+ affine=True,
114
+ eps=1e-5),)
115
+ model.add_module('conv_nonlin', Expression(self.first_nonlin))
116
+ model.add_module('pool',
117
+ first_pool_class(
118
+ kernel_size=(self.pool_time_length, 1),
119
+ stride=(pool_stride, 1)))
120
+ model.add_module('pool_nonlin', Expression(self.first_pool_nonlin))
121
+
122
+ def add_conv_pool_block(model, n_filters_before,
123
+ n_filters, filter_length, block_nr):
124
+ suffix = '_{:d}'.format(block_nr)
125
+ model.add_module('drop' + suffix,
126
+ nn.Dropout(p=self.drop_prob))
127
+ add_conv_2d(
128
+ self.separable, model, 'conv' + suffix.format(block_nr),
129
+ n_filters_before, n_filters,
130
+ (filter_length, 1),
131
+ stride=(conv_stride, 1),
132
+ bias=not self.batch_norm)
133
+ if self.batch_norm:
134
+ model.add_module('bnorm' + suffix,
135
+ nn.BatchNorm2d(n_filters,
136
+ momentum=self.batch_norm_alpha,
137
+ affine=True,
138
+ eps=1e-5))
139
+ model.add_module('nonlin' + suffix,
140
+ Expression(self.later_nonlin))
141
+
142
+ model.add_module('pool' + suffix,
143
+ later_pool_class(
144
+ kernel_size=(self.pool_time_length, 1),
145
+ stride=(pool_stride, 1)))
146
+ model.add_module('pool_nonlin' + suffix,
147
+ Expression(self.later_pool_nonlin))
148
+
149
+ add_conv_pool_block(model, n_filters_conv, self.n_filters_2,
150
+ self.filter_length_2, 2)
151
+ add_conv_pool_block(model, self.n_filters_2, self.n_filters_3,
152
+ self.filter_length_3, 3)
153
+ add_conv_pool_block(model, self.n_filters_3, self.n_filters_4,
154
+ self.filter_length_4, 4)
155
+
156
+
157
+ model.eval()
158
+ if self.final_conv_length == 'auto':
159
+ out = model(np_to_var(np.ones(
160
+ (1, self.in_chans, self.input_time_length,1),
161
+ dtype=np.float32)))
162
+ n_out_time = out.cpu().data.numpy().shape[2]
163
+ self.final_conv_length = n_out_time
164
+ model.add_module('conv_classifier',
165
+ nn.Conv2d(self.n_filters_4, self.n_classes,
166
+ (self.final_conv_length, 1), bias=True))
167
+ model.add_module('softmax', nn.LogSoftmax(dim=1))
168
+ model.add_module('squeeze', Expression(_squeeze_final_output))
169
+
170
+ # Initialization, xavier is same as in our paper...
171
+ # was default from lasagne
172
+ init.xavier_uniform_(model.conv_time.weight, gain=1)
173
+ # maybe no bias in case of no split layer and batch norm
174
+ if self.split_first_layer or (not self.batch_norm):
175
+ init.constant_(model.conv_time.bias, 0)
176
+ if self.split_first_layer:
177
+ if self.separable:
178
+ init.xavier_uniform_(model.conv_spat_depth.weight, gain=1)
179
+ init.xavier_uniform_(model.conv_spat_point.weight, gain=1)
180
+ else:
181
+ init.xavier_uniform_(model.conv_spat.weight, gain=1)
182
+ if not self.batch_norm:
183
+ if self.separable:
184
+ init.constant_(model.conv_spat_depth.bias, 0)
185
+ init.constant_(model.conv_spat_point.bias, 0)
186
+ else:
187
+ init.constant_(model.conv_spat.bias, 0)
188
+ if self.batch_norm:
189
+ init.constant_(model.bnorm.weight, 1)
190
+ init.constant_(model.bnorm.bias, 0)
191
+ param_dict = dict(list(model.named_parameters()))
192
+ for block_nr in range(2,5):
193
+ suffixes = {True: ['_depth', '_point'], False:['']}[self.separable]
194
+ for suffix in suffixes:
195
+ conv_weight = param_dict['conv_{:d}{:s}.weight'.format(
196
+ block_nr, suffix)]
197
+ init.xavier_uniform_(conv_weight, gain=1)
198
+ if not self.batch_norm:
199
+ for suffix in suffixes:
200
+ conv_bias = param_dict['conv_{:d}{:s}.bias'.format(
201
+ block_nr, suffix)]
202
+ init.constant_(conv_bias, 0)
203
+ else:
204
+ bnorm_weight = param_dict['bnorm_{:d}.weight'.format(block_nr)]
205
+ bnorm_bias = param_dict['bnorm_{:d}.bias'.format(block_nr)]
206
+ init.constant_(bnorm_weight, 1)
207
+ init.constant_(bnorm_bias, 0)
208
+
209
+ init.xavier_uniform_(model.conv_classifier.weight, gain=1)
210
+ init.constant_(model.conv_classifier.bias, 0)
211
+
212
+ # Start in eval mode
213
+ model.eval()
214
+ return model
215
+
216
+
217
+ # remove empty dim at end and potentially remove empty time dim
218
+ # do not just use squeeze as we never want to remove first dim
219
+ def _squeeze_final_output(x):
220
+ assert x.size()[3] == 1
221
+ x = x[:,:,:,0]
222
+ if x.size()[2] == 1:
223
+ x = x[:,:,0]
224
+ return x
225
+
226
+
227
+ def _transpose_time_to_spat(x):
228
+ return x.permute(0, 3, 2, 1)
@@ -45,7 +45,7 @@ class EEGNetv4(BaseModel):
45
45
  pool_mode='mean',
46
46
  F1=8,
47
47
  D=2,
48
- F2=16,
48
+ F2=16, # usually set to F1*D (?)
49
49
  kernel_length=64,
50
50
  third_kernel_size=(8, 4),
51
51
  drop_prob=0.25
@@ -9,6 +9,20 @@ from braindecode.models.util import to_dense_prediction_model
9
9
 
10
10
 
11
11
  class HybridNet(nn.Module, BaseModel):
12
+ """
13
+ Hybrid ConvNet model from [3]_.
14
+
15
+ Very hardcoded at the moment.
16
+
17
+ References
18
+ ----------
19
+
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.
25
+ """
12
26
  def __init__(self, n_chans, n_classes, input_time_length):
13
27
  super(HybridNet, self).__init__()
14
28
  deep_model = Deep4Net(n_chans, n_classes, n_filters_time=20,
@@ -74,4 +88,4 @@ class HybridNet(nn.Module, BaseModel):
74
88
  linear_out = self.final_conv(merged_out)
75
89
  softmaxed = nn.LogSoftmax(dim=1)(linear_out)
76
90
  squeezed = softmaxed.squeeze(3)
77
- return squeezed
91
+ return squeezed
@@ -0,0 +1 @@
1
+ __version__ = "0.4.3"
@@ -256,7 +256,9 @@
256
256
  {
257
257
  "cell_type": "code",
258
258
  "execution_count": 7,
259
- "metadata": {},
259
+ "metadata": {
260
+ "collapsed": true
261
+ },
260
262
  "outputs": [],
261
263
  "source": [
262
264
  "from braindecode.torch_ext.optimizers import AdamW\n",
@@ -1 +0,0 @@
1
- __version__ = "0.4.0"