braindecode 0.5.1__py3-none-any.whl

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 (69) hide show
  1. Braindecode-0.5.1.dist-info/LICENSE.txt +31 -0
  2. Braindecode-0.5.1.dist-info/METADATA +133 -0
  3. Braindecode-0.5.1.dist-info/RECORD +69 -0
  4. Braindecode-0.5.1.dist-info/WHEEL +5 -0
  5. Braindecode-0.5.1.dist-info/top_level.txt +2 -0
  6. braindecode/__init__.py +4 -0
  7. braindecode/classifier.py +258 -0
  8. braindecode/datasets/__init__.py +7 -0
  9. braindecode/datasets/base.py +293 -0
  10. braindecode/datasets/bbci.py +679 -0
  11. braindecode/datasets/moabb.py +110 -0
  12. braindecode/datasets/sleep_physionet.py +103 -0
  13. braindecode/datasets/tuh.py +230 -0
  14. braindecode/datautil/__init__.py +11 -0
  15. braindecode/datautil/mne.py +136 -0
  16. braindecode/datautil/preprocess.py +364 -0
  17. braindecode/datautil/serialization.py +111 -0
  18. braindecode/datautil/util.py +36 -0
  19. braindecode/datautil/windowers.py +435 -0
  20. braindecode/datautil/xy.py +77 -0
  21. braindecode/models/__init__.py +12 -0
  22. braindecode/models/deep4.py +252 -0
  23. braindecode/models/eegnet.py +339 -0
  24. braindecode/models/eegresnet.py +232 -0
  25. braindecode/models/functions.py +43 -0
  26. braindecode/models/hybrid.py +103 -0
  27. braindecode/models/modules.py +150 -0
  28. braindecode/models/shallow_fbcsp.py +158 -0
  29. braindecode/models/sleep_stager_chambon_2018.py +113 -0
  30. braindecode/models/tcn.py +143 -0
  31. braindecode/models/util.py +66 -0
  32. braindecode/regressor.py +240 -0
  33. braindecode/samplers/__init__.py +5 -0
  34. braindecode/samplers/base.py +78 -0
  35. braindecode/samplers/ssl.py +118 -0
  36. braindecode/training/__init__.py +8 -0
  37. braindecode/training/callbacks.py +21 -0
  38. braindecode/training/losses.py +17 -0
  39. braindecode/training/scoring.py +296 -0
  40. braindecode/util.py +362 -0
  41. braindecode/version.py +1 -0
  42. braindecode/visualization/__init__.py +5 -0
  43. braindecode/visualization/gradients.py +53 -0
  44. test/__init__.py +0 -0
  45. test/acceptance_tests/__init__.py +0 -0
  46. test/acceptance_tests/test_cropped_decoding.py +171 -0
  47. test/acceptance_tests/test_eeg_classifier.py +255 -0
  48. test/acceptance_tests/test_model_architectures.py +54 -0
  49. test/acceptance_tests/test_trialwise_decoding.py +168 -0
  50. test/unit_tests/__init__.py +0 -0
  51. test/unit_tests/datasets/__init__.py +0 -0
  52. test/unit_tests/datasets/test_dataset.py +227 -0
  53. test/unit_tests/datasets/test_mne.py +145 -0
  54. test/unit_tests/datasets/test_sleep_physionet.py +23 -0
  55. test/unit_tests/datasets/test_tuh.py +97 -0
  56. test/unit_tests/datasets/test_xy.py +31 -0
  57. test/unit_tests/datautil/__init__.py +0 -0
  58. test/unit_tests/datautil/test_preprocess.py +270 -0
  59. test/unit_tests/datautil/test_serialization.py +127 -0
  60. test/unit_tests/datautil/test_windowers.py +519 -0
  61. test/unit_tests/models/__init__.py +0 -0
  62. test/unit_tests/models/test_models.py +136 -0
  63. test/unit_tests/models/test_util.py +22 -0
  64. test/unit_tests/test_eeg_classifier.py +73 -0
  65. test/unit_tests/test_eeg_regressor.py +72 -0
  66. test/unit_tests/test_scoring.py +282 -0
  67. test/unit_tests/test_util.py +30 -0
  68. test/unit_tests/visualization/__init__.py +0 -0
  69. test/unit_tests/visualization/test_gradients.py +38 -0
@@ -0,0 +1,73 @@
1
+ # Authors: Maciej Sliwowski <maciek.sliwowski@gmail.com>
2
+ #
3
+ # License: BSD-3
4
+
5
+ import numpy as np
6
+ import torch
7
+ from skorch.utils import to_tensor
8
+ from torch import optim
9
+ from torch.nn.functional import nll_loss
10
+
11
+ from braindecode import EEGClassifier
12
+ from braindecode.training import CroppedLoss
13
+
14
+
15
+ class MockDataset(torch.utils.data.Dataset):
16
+ def __len__(self):
17
+ return 4
18
+
19
+ def __getitem__(self, item):
20
+ return torch.rand(4, 1), torch.ones(4)
21
+
22
+
23
+ class MockModule(torch.nn.Module):
24
+ def __init__(self, preds):
25
+ super().__init__()
26
+ self.preds = to_tensor(preds, device='cpu')
27
+ self.linear = torch.nn.Linear(5, 5)
28
+
29
+ def forward(self, x):
30
+ return self.preds
31
+
32
+
33
+ def test_trialwise_predict_and_predict_proba():
34
+ preds = np.array(
35
+ [
36
+ [0.125, 0.875],
37
+ [1., 0.],
38
+ [0.8, 0.2],
39
+ [0.9, 0.1],
40
+ ]
41
+ )
42
+ clf = EEGClassifier(
43
+ MockModule(preds),
44
+ optimizer=optim.Adam,
45
+ batch_size=32
46
+ )
47
+ clf.initialize()
48
+ np.testing.assert_array_equal(preds.argmax(1), clf.predict(MockDataset()))
49
+ np.testing.assert_array_equal(preds, clf.predict_proba(MockDataset()))
50
+
51
+
52
+ def test_cropped_predict_and_predict_proba():
53
+ preds = np.array(
54
+ [
55
+ [[0.2, 0.1, 0.1, 0.1], [0.8, 0.9, 0.9, 0.9]],
56
+ [[1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]],
57
+ [[1.0, 1.0, 1.0, 0.2], [0.0, 0.0, 0.0, 0.8]],
58
+ [[0.9, 0.8, 0.9, 1.0], [0.1, 0.2, 0.1, 0.0]],
59
+ ]
60
+ )
61
+ clf = EEGClassifier(
62
+ MockModule(preds),
63
+ cropped=True,
64
+ criterion=CroppedLoss,
65
+ criterion__loss_function=nll_loss,
66
+ optimizer=optim.Adam,
67
+ batch_size=32
68
+ )
69
+ clf.initialize()
70
+ # for cropped decoding classifier returns one label for each trial (averaged over all crops)
71
+ np.testing.assert_array_equal(preds.mean(-1).argmax(1), clf.predict(MockDataset()))
72
+ # for cropped decoding classifier returns values for each trial (average over all crops)
73
+ np.testing.assert_array_equal(preds.mean(-1), clf.predict_proba(MockDataset()))
@@ -0,0 +1,72 @@
1
+ # Authors: Maciej Sliwowski <maciek.sliwowski@gmail.com>
2
+ #
3
+ # License: BSD-3
4
+
5
+ import numpy as np
6
+ import torch
7
+ from skorch.utils import to_tensor
8
+ from torch import optim
9
+ from torch.nn.functional import nll_loss
10
+
11
+ from braindecode import EEGRegressor
12
+ from braindecode.training import CroppedLoss
13
+
14
+
15
+ class MockDataset(torch.utils.data.Dataset):
16
+ def __len__(self):
17
+ return 4
18
+
19
+ def __getitem__(self, item):
20
+ return torch.rand(4, 1), torch.ones(4)
21
+
22
+
23
+ class MockModule(torch.nn.Module):
24
+ def __init__(self, preds):
25
+ super().__init__()
26
+ self.preds = to_tensor(preds, device='cpu')
27
+ self.linear = torch.nn.Linear(5, 5)
28
+
29
+ def forward(self, x):
30
+ return self.preds
31
+
32
+
33
+ def test_trialwise_predict_and_predict_proba():
34
+ preds = np.array(
35
+ [
36
+ [0.125, 0.875],
37
+ [1., 0.],
38
+ [0.8, 0.2],
39
+ [0.9, 0.1],
40
+ ]
41
+ )
42
+ clf = EEGRegressor(
43
+ MockModule(preds),
44
+ optimizer=optim.Adam,
45
+ batch_size=32
46
+ )
47
+ clf.initialize()
48
+ np.testing.assert_array_equal(preds, clf.predict(MockDataset()))
49
+ np.testing.assert_array_equal(preds, clf.predict_proba(MockDataset()))
50
+
51
+
52
+ def test_cropped_predict_and_predict_proba():
53
+ preds = np.array(
54
+ [
55
+ [[0.2, 0.1, 0.1, 0.1], [0.8, 0.9, 0.9, 0.9]],
56
+ [[1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]],
57
+ [[1.0, 1.0, 1.0, 0.2], [0.0, 0.0, 0.0, 0.8]],
58
+ [[0.9, 0.8, 0.9, 1.0], [0.1, 0.2, 0.1, 0.0]],
59
+ ]
60
+ )
61
+ clf = EEGRegressor(
62
+ MockModule(preds),
63
+ cropped=True,
64
+ criterion=CroppedLoss,
65
+ criterion__loss_function=nll_loss,
66
+ optimizer=optim.Adam,
67
+ batch_size=32
68
+ )
69
+ clf.initialize()
70
+ # for cropped decoding regressor returns value for each trial (average over all crops)
71
+ np.testing.assert_array_equal(preds.mean(-1), clf.predict(MockDataset()))
72
+ np.testing.assert_array_equal(preds.mean(-1), clf.predict_proba(MockDataset()))
@@ -0,0 +1,282 @@
1
+ # Authors: Maciej Sliwowski
2
+ # Lukas Gemein
3
+ # Robin Tibor Schirrmeister
4
+ #
5
+ # License: BSD-3
6
+
7
+
8
+ import numpy as np
9
+ import sklearn.datasets
10
+ import torch
11
+ from sklearn.metrics import f1_score, accuracy_score
12
+ from skorch import History
13
+ from skorch.callbacks import Callback
14
+ from skorch.utils import to_numpy, to_tensor
15
+ from torch import optim
16
+ from torch.utils.data import Dataset, DataLoader
17
+ from braindecode.classifier import EEGClassifier
18
+ from braindecode.datautil.xy import create_from_X_y
19
+ from braindecode.training.scoring import CroppedTrialEpochScoring
20
+ from braindecode.training.scoring import PostEpochTrainScoring
21
+ from braindecode.models import ShallowFBCSPNet
22
+ from braindecode.util import set_random_seeds
23
+ from braindecode.training.scoring import trial_preds_from_window_preds
24
+
25
+
26
+ class MockSkorchNet:
27
+ def __init__(self):
28
+ self.device = "cpu"
29
+ self.forward_iter = None
30
+ self.history = History()
31
+ self.history.new_epoch()
32
+ self._default_callbacks = []
33
+
34
+ def fit(self, X, y=None):
35
+ return self
36
+
37
+ def predict(self, X):
38
+ return np.concatenate(
39
+ [to_numpy(x.argmax(1)) for x in self.forward_iter(X)], 0
40
+ )
41
+
42
+ def get_iterator(self, X_test, training):
43
+ return DataLoader(X_test, batch_size=2)
44
+
45
+
46
+ def test_cropped_trial_epoch_scoring():
47
+
48
+ dataset_train = None
49
+ # Definition of test cases
50
+ predictions_cases = [
51
+ # Expected predictions classification results: [1, 0, 0, 0]
52
+ np.array(
53
+ [
54
+ [[0.2, 0.1, 0.1, 0.1], [0.8, 0.9, 0.9, 0.9]], # trial 0 preds
55
+ [[1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]], # trial 1 preds
56
+ [[1.0, 1.0, 1.0, 0.2], [0.0, 0.0, 0.0, 0.8]], # trial 2 preds
57
+ [[0.9, 0.8, 0.9, 1.0], [0.1, 0.2, 0.1, 0.0]], # trial 3 preds
58
+ ]
59
+ ),
60
+ # Expected predictions classification results: [1, 1, 1, 0]
61
+ np.array(
62
+ [
63
+ [[0.2, 0.1, 0.1, 0.1], [0.8, 0.9, 0.9, 0.9]],
64
+ [[0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]],
65
+ [[0.0, 0.0, 0.0, 0.2], [1.0, 1.0, 1.0, 0.8]],
66
+ [[0.9, 0.8, 0.9, 1.0], [0.1, 0.2, 0.1, 0.0]],
67
+ ]
68
+ ),
69
+ ]
70
+ y_true_cases = [
71
+ [torch.tensor([0, 0]), torch.tensor([1, 1])],
72
+ [torch.tensor([1, 1]), torch.tensor([1, 1])],
73
+ ]
74
+ expected_accuracies_cases = [0.25, 0.75]
75
+
76
+ window_inds = [(
77
+ torch.tensor([0, 0]), # i_window_in_trials
78
+ [None], # won't be used
79
+ torch.tensor([4, 4]), # i_window_stops
80
+ ),(
81
+ torch.tensor([0, 0]), # i_window_in_trials
82
+ [None], # won't be used
83
+ torch.tensor([4, 4]), # i_window_stops
84
+ ),]
85
+
86
+ for predictions, y_true, accuracy in zip(
87
+ predictions_cases, y_true_cases, expected_accuracies_cases
88
+ ):
89
+ dataset_valid = create_from_X_y(
90
+ np.zeros((4, 1, 10)), np.concatenate(y_true),
91
+ window_size_samples=10, window_stride_samples=4, drop_last_window=False)
92
+
93
+ mock_skorch_net = MockSkorchNet()
94
+ cropped_trial_epoch_scoring = CroppedTrialEpochScoring(
95
+ "accuracy", on_train=False)
96
+ mock_skorch_net.callbacks = [(
97
+ "", cropped_trial_epoch_scoring)]
98
+ cropped_trial_epoch_scoring.initialize()
99
+ cropped_trial_epoch_scoring.y_preds_ = [
100
+ to_tensor(predictions[:2], device="cpu"),
101
+ to_tensor(predictions[2:], device="cpu"),
102
+ ]
103
+ cropped_trial_epoch_scoring.y_trues_ = y_true
104
+ cropped_trial_epoch_scoring.window_inds_ = window_inds
105
+
106
+ cropped_trial_epoch_scoring.on_epoch_end(
107
+ mock_skorch_net, dataset_train, dataset_valid
108
+ )
109
+
110
+ np.testing.assert_almost_equal(
111
+ mock_skorch_net.history[0]["accuracy"], accuracy
112
+ )
113
+
114
+
115
+ def test_cropped_trial_epoch_scoring_none_x_test():
116
+ dataset_train = None
117
+ dataset_valid = None
118
+ predictions = np.array(
119
+ [
120
+ [[0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]],
121
+ [[1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]],
122
+ [[1.0, 1.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]],
123
+ [[1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]],
124
+ ]
125
+ )
126
+ y_true = [torch.tensor([0, 0]), torch.tensor([1, 1])]
127
+ window_inds = [(
128
+ torch.tensor([0, 0]), # i_window_in_trials
129
+ [None], # won't be used
130
+ torch.tensor([4, 4]), # i_window_stops
131
+ ),
132
+ (
133
+ torch.tensor([0, 0]), # i_window_in_trials
134
+ [None], # won't be used
135
+ torch.tensor([4, 4]), # i_window_stops
136
+ )]
137
+ cropped_trial_epoch_scoring = CroppedTrialEpochScoring("accuracy")
138
+ cropped_trial_epoch_scoring.initialize()
139
+ cropped_trial_epoch_scoring.y_preds_ = [
140
+ to_tensor(predictions[:2], device="cpu"),
141
+ to_tensor(predictions[2:], device="cpu"),
142
+ ]
143
+ cropped_trial_epoch_scoring.y_trues_ = y_true
144
+ cropped_trial_epoch_scoring.window_inds_ = window_inds
145
+
146
+ mock_skorch_net = MockSkorchNet()
147
+ mock_skorch_net.callbacks = [(
148
+ "", cropped_trial_epoch_scoring)]
149
+ output = cropped_trial_epoch_scoring.on_epoch_end(
150
+ mock_skorch_net, dataset_train, dataset_valid
151
+ )
152
+ assert output is None
153
+
154
+
155
+ def test_post_epoch_train_scoring():
156
+ cuda = False
157
+ set_random_seeds(seed=20170629, cuda=cuda)
158
+
159
+ n_classes = 2
160
+
161
+ class EEGDataSet(Dataset):
162
+ def __init__(self, X, y):
163
+ self.X = X
164
+ if self.X.ndim == 3:
165
+ self.X = self.X[:, :, :, None]
166
+ self.y = y
167
+
168
+ def __len__(self):
169
+ return len(self.X)
170
+
171
+ def __getitem__(self, idx):
172
+ return self.X[idx], self.y[idx]
173
+
174
+ X, y = sklearn.datasets.make_classification(
175
+ 40, (3 * 100), n_informative=3 * 50, n_classes=2
176
+ )
177
+ X = X.reshape(40, 3, 100).astype(np.float32)
178
+
179
+ in_chans = X.shape[1]
180
+
181
+ train_set = EEGDataSet(X, y)
182
+
183
+ class TestCallback(Callback):
184
+ def on_epoch_end(self, net, *args, **kwargs):
185
+ preds = net.predict(train_set.X)
186
+ y_true = train_set.y
187
+ np.testing.assert_allclose(
188
+ clf.history[-1]["train_f1"],
189
+ f1_score(y_true, preds),
190
+ rtol=1e-4,
191
+ atol=1e-4,
192
+ )
193
+ np.testing.assert_allclose(
194
+ clf.history[-1]["train_acc"],
195
+ accuracy_score(y_true, preds),
196
+ rtol=1e-4,
197
+ atol=1e-4,
198
+ )
199
+
200
+ set_random_seeds(20200114, cuda)
201
+
202
+ # final_conv_length = auto ensures
203
+ # we only get a single output in the time dimension
204
+ model = ShallowFBCSPNet(
205
+ in_chans=in_chans,
206
+ n_classes=n_classes,
207
+ input_window_samples=train_set.X.shape[2],
208
+ pool_time_stride=1,
209
+ pool_time_length=2,
210
+ final_conv_length="auto",
211
+ )
212
+ if cuda:
213
+ model.cuda()
214
+
215
+ clf = EEGClassifier(
216
+ model,
217
+ criterion=torch.nn.NLLLoss,
218
+ optimizer=optim.AdamW,
219
+ train_split=None,
220
+ optimizer__lr=0.0625 * 0.01,
221
+ optimizer__weight_decay=0,
222
+ batch_size=64,
223
+ callbacks=[
224
+ (
225
+ "train_accuracy",
226
+ PostEpochTrainScoring(
227
+ "accuracy", lower_is_better=False, name="train_acc"
228
+ ),
229
+ ),
230
+ (
231
+ "train_f1_score",
232
+ PostEpochTrainScoring(
233
+ "f1", lower_is_better=False, name="train_f1"
234
+ ),
235
+ ),
236
+ ("test_callback", TestCallback()),
237
+ ],
238
+ )
239
+
240
+ clf.fit(train_set, y=None, epochs=4)
241
+
242
+
243
+ def _check_preds_windows_trials(preds, window_inds, expected_trial_preds):
244
+ # transform to 2 lists from tuples
245
+ i_window_in_trials = []
246
+ i_stop_in_trials = []
247
+ for i_window_in_trial, _, i_stop_in_trial in window_inds:
248
+ i_window_in_trials.append(i_window_in_trial)
249
+ i_stop_in_trials.append(i_stop_in_trial)
250
+ trial_preds = trial_preds_from_window_preds(
251
+ preds, i_window_in_trials, i_stop_in_trials)
252
+ np.testing.assert_equal(len(trial_preds), len(expected_trial_preds),)
253
+ for expected_pred, actual_pred in zip(expected_trial_preds, trial_preds):
254
+ np.testing.assert_array_equal(actual_pred, expected_pred, )
255
+
256
+
257
+ def test_two_windows_same_trial_with_overlap():
258
+ preds = [[[4, 5, 6, 7]], [[6, 7, 8, 9]], ]
259
+ window_inds = ((0, 0, 8), (1, 2, 10))
260
+ expected_trial_preds = [[[4, 5, 6, 7, 8, 9]]]
261
+ _check_preds_windows_trials(preds, window_inds, expected_trial_preds)
262
+
263
+
264
+ def test_three_windows_two_trials_with_overlap():
265
+ preds = [[[4, 5, 6, 7]], [[6, 7, 8, 9]], [[0, 1, 2, 3]]]
266
+ window_inds = ((0, 0, 8), (1, 2, 10), (0, 0, 6,))
267
+ expected_trial_preds = [[[4, 5, 6, 7, 8, 9]], [[0, 1, 2, 3]]]
268
+ _check_preds_windows_trials(preds, window_inds, expected_trial_preds)
269
+
270
+
271
+ def test_one_window_one_trial():
272
+ preds = [[[4, 5, 6, 7]]]
273
+ window_inds = ((0, 0, 8),)
274
+ expected_trial_preds = [[[4, 5, 6, 7]]]
275
+ _check_preds_windows_trials(preds, window_inds, expected_trial_preds)
276
+
277
+
278
+ def test_three_windows_two_trials_no_overlap():
279
+ preds = [[[4, 5, 6, 7]], [[6, 7, 8, 9]], [[0, 1, 2, 3]]]
280
+ window_inds = ((0, 0, 8), (1, 4, 12), (0, 0, 6,))
281
+ expected_trial_preds = [[[4, 5, 6, 7, 6, 7, 8, 9]], [[0, 1, 2, 3]]]
282
+ _check_preds_windows_trials(preds, window_inds, expected_trial_preds)
@@ -0,0 +1,30 @@
1
+ # Authors: Hubert Banville <hubert.jbanville@gmail.com>
2
+ #
3
+ # License: BSD-3
4
+
5
+ import os
6
+
7
+ import mne
8
+ import numpy as np
9
+ import h5py
10
+
11
+ from braindecode.util import create_mne_dummy_raw
12
+
13
+
14
+ def test_create_mne_dummy_raw(tmp_path):
15
+ n_channels, n_times, sfreq = 2, 10000, 100
16
+ raw, fnames = create_mne_dummy_raw(
17
+ n_channels, n_times, sfreq, savedir=tmp_path,
18
+ save_format=['fif', 'hdf5'])
19
+
20
+ assert isinstance(raw, mne.io.RawArray)
21
+ assert len(raw.ch_names) == n_channels
22
+ assert raw.n_times == n_times
23
+ assert raw.info['sfreq'] == sfreq
24
+ assert isinstance(fnames, dict)
25
+ assert os.path.isfile(fnames['fif'])
26
+ assert os.path.isfile(fnames['hdf5'])
27
+
28
+ raw = mne.io.read_raw_fif(fnames['fif'], preload=False, verbose=None)
29
+ with h5py.File(fnames['hdf5'], 'r') as hf:
30
+ _ = np.array(hf['fake_raw'])
File without changes
@@ -0,0 +1,38 @@
1
+ # Authors: Robin Schirrmeister <robintibor@gmail.com>
2
+ #
3
+ # License: BSD (3-clause)
4
+
5
+ import numpy as np
6
+ import torch
7
+ from torch import nn
8
+ from braindecode.util import set_random_seeds
9
+ from braindecode.visualization.gradients import compute_amplitude_gradients_for_X
10
+
11
+
12
+
13
+ def test_compute_amplitude_gradients_for_X():
14
+ # If the weights are initalized with a sine function
15
+ # gradient of amplitude should be only in one frequency bin
16
+ set_random_seeds(948, False)
17
+ model = nn.Conv1d(1,1, 16)
18
+ # torch.linspace(,,n)[:n-1] is same as np.linspace(,,n,endpoint=False)
19
+ model.weight.data[:,:,:] = torch.sin(torch.linspace(0,2*np.pi,17)[:16])
20
+ model.bias.data[:] = 0
21
+ grads = compute_amplitude_gradients_for_X(model, torch.randn(1,1,16))
22
+ grads = grads.squeeze()
23
+ assert np.abs(grads[1]) / np.sum(np.abs(grads)) > 0.99
24
+
25
+
26
+ def test_compute_amplitude_gradients_for_X_two_filters():
27
+ # If the weights are initalized with a sine function
28
+ # gradient of amplitude should be only in one frequency bin
29
+ set_random_seeds(948, False)
30
+ model = nn.Conv1d(1,2, 16)
31
+ # torch.linspace(,,n)[:n-1] is same as np.linspace(,,n,endpoint=False)
32
+ model.weight.data[0,:,:] = torch.sin(torch.linspace(0,2*np.pi,17)[:16])
33
+ model.weight.data[1,:,:] = torch.sin(torch.linspace(0,4*np.pi,17)[:16])
34
+ model.bias.data[:] = 0
35
+ grads = compute_amplitude_gradients_for_X(model, torch.randn(1,1,16))
36
+ grads = grads.squeeze()
37
+ assert np.abs(grads[0][1]) / np.sum(np.abs(grads[0])) > 0.99
38
+ assert np.abs(grads[1][2]) / np.sum(np.abs(grads[1])) > 0.99