Skip to content

Commit a090af5

Browse files
committed
ENH fit banded ridge only on good voxels for speed and memory
1 parent b7bee53 commit a090af5

1 file changed

Lines changed: 54 additions & 25 deletions

File tree

tutorials/movies_3T/05_plot_banded_ridge_model.py

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@
4848
print("(n_samples_train, n_voxels) =", Y_train.shape)
4949
print("(n_repeats, n_samples_test, n_voxels) =", Y_test.shape)
5050

51+
###############################################################################
52+
# We also compute the explainable variance, to exclude voxels with low
53+
# explainable variance from the fit, and speed up the model fitting.
54+
55+
from voxelwise_tutorials.utils import explainable_variance
56+
ev = explainable_variance(Y_test)
57+
print("(n_voxels,) =", ev.shape)
58+
59+
mask = ev > 0.1
60+
print("(n_voxels_mask,) =", ev[mask].shape)
61+
5162
###############################################################################
5263
# We average the test repeats, to remove the non-repeatable part of fMRI
5364
# responses.
@@ -247,15 +258,23 @@
247258
#
248259
# We fit on the train set, and score on the test set.
249260
#
261+
# To speed up the fit and to limit the memory peak in Colab, we only fit on
262+
# voxels with explainable variance above 0.1.
263+
#
250264
# With a GPU backend, the fitting of this model takes around 6 minutes. With a
251265
# CPU backend, it can last 10 times more.
252266

253-
pipeline.fit(X_train, Y_train)
267+
pipeline.fit(X_train, Y_train[:, mask])
254268

255-
scores = pipeline.score(X_test, Y_test)
256-
scores = backend.to_numpy(scores)
269+
scores_mask = pipeline.score(X_test, Y_test[:, mask])
270+
scores_mask = backend.to_numpy(scores_mask)
271+
print("(n_voxels_mask,) =", scores_mask.shape)
257272

258-
print("(n_voxels,) =", scores.shape)
273+
# Then we extend the scores to all voxels, giving a score of zero to unfitted
274+
# voxels.
275+
n_voxels = Y_train.shape[1]
276+
scores = np.zeros(n_voxels)
277+
scores[mask] = scores_mask
259278

260279
###############################################################################
261280
# Compare with a ridge model
@@ -279,16 +298,21 @@
279298
pipeline_baseline
280299

281300
###############################################################################
282-
pipeline_baseline.fit(X_train, Y_train)
283-
scores_baseline = pipeline_baseline.score(X_test, Y_test)
284-
scores_baseline = backend.to_numpy(scores_baseline)
301+
pipeline_baseline.fit(X_train, Y_train[:, mask])
302+
scores_baseline_mask = pipeline_baseline.score(X_test, Y_test[:, mask])
303+
scores_baseline_mask = backend.to_numpy(scores_baseline_mask)
304+
305+
# extend to unfitted voxels
306+
n_voxels = Y_train.shape[1]
307+
scores_baseline = np.zeros(n_voxels)
308+
scores_baseline[mask] = scores_baseline_mask
285309

286310
###############################################################################
287-
# Here we plot the comparison of model prediction accuracies with a 2D histogram.
288-
# All 70k voxels are represented in this histogram, where the diagonal
289-
# corresponds to identical model prediction accuracy for both models. A distibution deviating
290-
# from the diagonal means that one model has better predictive performance
291-
# than the other.
311+
# Here we plot the comparison of model prediction accuracies with a 2D
312+
# histogram. All 70k voxels are represented in this histogram, where the
313+
# diagonal corresponds to identical model prediction accuracy for both models.
314+
# A distibution deviating from the diagonal means that one model has better
315+
# predictive performance than the other.
292316
import matplotlib.pyplot as plt
293317
from voxelwise_tutorials.viz import plot_hist2d
294318

@@ -326,10 +350,16 @@
326350
from himalaya.scoring import r2_score_split
327351

328352
Y_test_pred_split = pipeline.predict(X_test, split=True)
329-
split_scores = r2_score_split(Y_test, Y_test_pred_split)
330-
split_scores.shape
353+
split_scores_mask = r2_score_split(Y_test[:, mask], Y_test_pred_split)
354+
355+
print("(n_kernels, n_samples_test, n_voxels_mask) =", Y_test_pred_split.shape)
356+
print("(n_kernels, n_voxels_mask) =", split_scores_mask.shape)
331357

332-
print("(n_kernels, n_samples_test, n_voxels) =", Y_test_pred_split.shape)
358+
# extend to unfitted voxels
359+
n_kernels = split_scores_mask.shape[0]
360+
n_voxels = Y_train.shape[1]
361+
split_scores = np.zeros((n_kernels, n_voxels))
362+
split_scores[:, mask] = split_scores_mask
333363
print("(n_kernels, n_voxels) =", split_scores.shape)
334364

335365
###############################################################################
@@ -345,18 +375,17 @@
345375
plt.show()
346376

347377
###############################################################################
348-
# The blue regions are better predicted by the motion-energy features, the orange
349-
# regions are better predicted by the wordnet features, and the white regions are
350-
# well predicted by both feature spaces.
378+
# The blue regions are better predicted by the motion-energy features, the
379+
# orange regions are better predicted by the wordnet features, and the white
380+
# regions are well predicted by both feature spaces.
351381
#
352382
# Compared to the last figure of the previous example, we see that most white
353-
# regions have been replaced by either blue or orange regions. The
354-
# banded ridge regression disentangled the two feature spaces in voxels where
355-
# both feature spaces had good prediction accuracy (see previous example). For
356-
# example, motion-energy features predict brain activity in early visual
357-
# cortex, while wordnet features predict in semantic visual areas. For more
358-
# discussions about these results, we refer the reader to the original
359-
# publication [1]_.
383+
# regions have been replaced by either blue or orange regions. The banded ridge
384+
# regression disentangled the two feature spaces in voxels where both feature
385+
# spaces had good prediction accuracy (see previous example). For example,
386+
# motion-energy features predict brain activity in early visual cortex, while
387+
# wordnet features predict in semantic visual areas. For more discussions about
388+
# these results, we refer the reader to the original publication [1]_.
360389

361390
###############################################################################
362391
# References

0 commit comments

Comments
 (0)