← Pierre Guetschel

Preprint · 2026

What Masking Geometry Works Best for EEG Foundation Models?

For MAE or JEPA pre-training, how do the temporal length (L), the spatial radius (r) and the ratio (ρ) of the mask influence model performance?

We answer this question with a controlled sweep of 58 models and linear probes of their learned representations.

The formalism: Three parameters cover the masking strategies of the EEG literature

Blocks of radius r on the scalp and length L in time are sampled such that a fraction ≈ ρ of the signal is hidden.

0.55
2 tokens
6 cm
30 s
K
– blocks
Masked
–

Cursor

Loading 3-D view…

3-D view unavailable (WebGL is disabled in this browser).

Drag to rotate · scroll to zoom · hover an electrode or a signal for its name · click an electrode to find its signal · click the signals to move the cursor electrode (colour = position on the scalp) masked at the cursor time extent of a block active at the cursor time its footprint on the cap masked token (0.9 s) time cursor = the moment shown in the frame

L = 1, r = one gives random patch masking, r = all hides whole time segments and L = 33 (the whole 30 s window) hides whole channels. Everything in between is a spatio-temporal block mask.

The study: 58 models that differ only in their mask and pretext

MAE reconstructs the hidden EEG, JEPA predicts how a teacher network encodes it. Each frozen encoder is then scored by a linear probe on the 12 datasets of OpenEEGBench.

The model reconstructs the raw EEG of the hidden patches.

Everything outside the coloured box is shared by MAE and JEPA.

The model predicts how a teacher network encodes the hidden patches, not the raw EEG.

Everything outside the coloured box is shared by MAE and JEPA.

The mask, decoder and teacher are gone. The frozen encoder turns a new EEG recording into features, and a linear model predicts the label from them. The same protocol is used for all 58 models on the 12 OpenEEGBench datasets.

Kept from pre-training, and frozen: the tokeniser and the encoder.

MAE-only Show the MAE branch JEPA-only Show the JEPA branch EEG Mask Decoder outputs JEPA predictions Linear Transformer Encoder Transformer Decoder remove masked tokens Maskingstrategy(L, r) MAE targets MAE predictions Linear remove unmasked signal patches L2 MAE JEPA targets Transformer Encoder (Teacher) remove unmasked tokens EMA gradient stop L2 JEPA Linear Transformer Encoder Random proj. Ridge regression flattened 5,000-d ŷ prediction linear probe
Hover or tap a block for details · the grids are toy examples token (a real pre-training window: 32 channels × 33 patches) hidden by the mask mask pattern (not data)

29 mask geometries (ρ fixed at 0.55) × 2 pretexts = 58 models

The results: MAE and JEPA agree on the best mask, L = 2 s and r = 9 cm

Each cell is one pre-trained model, evaluated on the 12 datasets of OpenEEGBench.

Both pretexts pick L = 2 s, r = 9 cm. Both fail when blocks are too local (r = one), too global (r = all) or, in most cases, too long (L = 8, 16).

JEPA

JEPA: downstream performance per mask (radius r in rows, length L in columns)
12481633
one −0.03 +0.02 −0.01 −0.02 −0.02 −0.07
6 cm +0.07 +0.03 +0.07 +0.02 −0.05 −0.04
9 cm +0.07 +0.10 +0.06 −0.01 −0.03 −0.04
12 cm −0.07 +0.04 +0.06 −0.18 −0.27 +0.02
all −0.41 −0.67 −0.37 −0.36 −0.31 not trained

MAE

MAE: downstream performance per mask (radius r in rows, length L in columns)
12481633
one −0.02 −0.01 +0.02 +0.04 +0.02 −0.00
6 cm −0.02 +0.06 +0.07 +0.02 −0.13 +0.04
9 cm +0.01 +0.07 +0.05 +0.03 −0.16 +0.07
12 cm +0.01 +0.03 +0.02 +0.03 −0.10 +0.05
all −0.05 −0.08 −0.10 −0.14 −0.25 not trained
10 · final · 5 probe seeds

Mean normalised score over the 12 OpenEEGBench datasets and the probe seeds, minus that of the public REVE-Base checkpoint (0 = REVE; linear probe on frozen features). Framed: the best mask of each pretext.

Mean rank (1 = best) of each mask among the 29 of its pretext, under a hierarchical bootstrap over datasets and probe seeds (10,000 replicates). Framed: the best mean rank. Circles: masks statistically tied with it (epoch 10 only, as in the paper).

Hover a cell for its training curve · empty cell: r = all with L = 33 would hide the whole window (not trained) · epochs 1–9: 3 probe seeds, epoch 10: 5

Why the mask matters: EEG is redundant across electrodes, much less across time

A good mask hides enough neighbours to make the task non-trivial, but leaves enough context to solve it: hence a moderate radius and a short length.

Same channel, time-shifted

0 0.2 0.4 0.6 0.8 1 0 5 10 15 time lag (s) R² L = 2 s R² ≈ 0.13

Same time, different channels

0 0.2 0.4 0.6 0.8 1 0 5 10 15 20 distance between the electrodes (cm) R² r = 9 cm R² ≈ 0.33
Squared correlation R² of the EEG signal (0.5–99.5 Hz) on 908 random 30 s windows of the pre-training corpus. Lines: mean; shading: spread over windows (left) and over electrode pairs (right). Dashed: the block size of the best mask.

Use the models: All 58 checkpoints are public

For most uses, take the best mask; the other 56 are there to study how masking shapes representations.

Pick a checkpoint

At the best mask, MAE and JEPA both score above REVE: either is a good starting point. The code below follows your pick.

Pretext

Length L

Radius r

PierreGtch/eeg-fm-masking_mae_r9cm_L2

+0.07 vs REVE · rank 8.6 of 29 · best mask

Load a pre-trained model

Install the code (pip install git+https://github.com/PierreGtch/eeg-fm-masking), then load any checkpoint by its id:

import json
from huggingface_hub import hf_hub_download
from safetensors.torch import load_file
from eeg_fm_masking.oeb.wrapper import ContextualEncoderBenchmarkWrapper

repo = "PierreGtch/eeg-fm-masking_mae_r9cm_L2"
config = json.load(open(hf_hub_download(repo, "config.json")))
model = ContextualEncoderBenchmarkWrapper(
    n_chans=n_chans, n_times=n_times, n_outputs=n_outputs, sfreq=200.0,
    chs_info=chs_info,  # MNE channel info (info["chs"]), positions in metres
    **config,
)
model.load_state_dict(load_file(hf_hub_download(repo, "model.safetensors")), strict=False)

Evaluate on OpenEEGBench

OpenEEGBench freezes the encoder and fits a ridge probe on its features for each of the 12 datasets, the protocol of the paper. One call runs it on any checkpoint, or on your own model:

import json
from huggingface_hub import hf_hub_download
from open_eeg_bench import benchmark

repo = "PierreGtch/eeg-fm-masking_mae_r9cm_L2"
results = benchmark(
    model_cls="eeg_fm_masking.oeb.wrapper.ContextualEncoderBenchmarkWrapper",
    hub_repo=repo,
    model_kwargs=json.load(open(hf_hub_download(repo, "config.json"))),
    finetuning_strategies=["ridge_probe"],  # frozen encoder + ridge probe, as in the paper
    n_seeds=5,
)  # a pandas DataFrame with the test metrics

The video: The paper in two minutes

Citation

@article{guetschel2026masking,
  title   = {What Masking Geometry Works Best for {EEG} Foundation Models?},
  author  = {Guetschel, Pierre and Aristimunha, Bruno and El Ouahidi, Yassine and
             Delorme, Arnaud and Moreau, Thomas and Tangermann, Michael},
  journal = {arXiv preprint arXiv:2609.33487},
  year    = {2026},
  month   = sep
}