braindecode.models.MSCFormer#
- class braindecode.models.MSCFormer(n_outputs=None, n_chans=None, sfreq=None, chs_info=None, n_times=None, input_window_seconds=None, kernel_sizes=(85, 65, 45), n_filters_time=16, pooling_size=44, cnn_drop_prob=0.5, activation_cnn=<class 'torch.nn.modules.activation.ELU'>, activation_ffn=<class 'torch.nn.modules.activation.GELU'>, num_heads=8, num_layers=5, forward_expansion=4, att_drop_prob=0.5, att_positional_drop_prob=0.1, final_drop_prob=0.25, attention_scale=None)[source]#
MSCFormer from Zhao, W et al (2025) [mscformer].
Convolution Attention/Transformer
Multi-scale convolutional transformer network for motor imagery brain-computer interface.
MSCFormer is an end-to-end network for classifying motor imagery (MI) tasks from EEG signals. To handle the individual variability of EEG signals and the limited receptive field of CNNs, the model combines a multi-branch multi-scale convolutional module with a Transformer encoder for global feature integration.
The architecture consists of three main components:
Multi-scale convolutional module:
Three parallel branches with temporal convolution kernels of different widths
(85, 65, 45)followed by a depth-wise spatial convolution across channels, batch normalization, activation, average pooling and dropout.The branch outputs are concatenated along the feature dimension, giving an embedding size of
3 * n_filters_time.
Transformer encoder module:
A learnable class token (BERT-style) is prepended to the embedded patches, followed by a learnable positional encoding.
A stack of Transformer encoder blocks with post-norm residual connections captures global dependencies across temporal patches.
Classifier module:
The Transformer output at the class-token position is passed through dropout and a fully connected layer producing the classification logits.
- Parameters:
n_outputs (int) – Number of outputs of the model. This is the number of classes in the case of classification.
n_chans (int) – Number of EEG channels.
sfreq (float) – Sampling frequency of the EEG recordings.
chs_info (list of dict) – Information about each individual EEG channel. This should be filled with
info["chs"]. Refer tomne.Infofor more details.n_times (int) – Number of time samples of the input window.
input_window_seconds (float) – Length of the input window in seconds.
kernel_sizes (
tuple[int,int,int]) – Kernel widths of the temporal convolutions in the three multi-scale branches.n_filters_time (
int) – Number of temporal filters in each convolutional branch; the total embedding size isn_filters_time * len(kernel_sizes).pooling_size (
int) – Average pooling size in the convolutional module. The original implementation uses 44 for BCI IV-2a and 52 for BCI IV-2b.cnn_drop_prob (
float) – Dropout probability in the convolutional module. The original implementation uses 0.5 for subject-specific training and 0.25 for cross-subject training.activation_cnn (
type[Module]) – Activation function in the convolutional branches.activation_ffn (
type[Module]) – Activation function in the Transformer feed-forward blocks.num_heads (
int) – Number of attention heads in the Transformer encoder.num_layers (
int) – Number of encoder blocks in the Transformer.forward_expansion (
int) – Expansion factor of the feed-forward block hidden layer.att_drop_prob (
float) – Dropout probability in the attention and feed-forward residual blocks.att_positional_drop_prob (
float) – Dropout probability applied after the positional encoding.final_drop_prob (
float) – Dropout probability before the final classification layer.attention_scale (
float|None) – Multiplier applied to the attention logits before the softmax inbraindecode.modules.MultiHeadAttention. WhenNone(default), it reproduces the released source scaleembed_dim ** -0.5(i.e.1 / sqrt(3 * n_filters_time)), not the more commonhead_dim ** -0.5: the two only coincide whennum_heads == 1. Numerically verified against the original implementation (max abs logit diff < 1e-6 with matched weights); passinghead_dim ** -0.5explicitly instead gives a max abs logit diff of about 0.035 on a random smoke input.
- Raises:
ValueError – If some input signal-related parameters are not specified: and can not be inferred.
Notes
This implementation is adapted from the original MSCFormer source code [mscformercode] to comply with Braindecode’s model standards. The multi-head attention is the shared
braindecode.modules.MultiHeadAttention, configured throughattention_scaleto match the originalembed_dim ** -0.5logit scaling by default (see the parameter description above).References
[mscformer]Zhao, W., Zhang, B., Zhou, H. et al. Multi-scale convolutional transformer network for motor imagery brain-computer interface. Scientific Reports, 15, 12935 (2025). https://doi.org/10.1038/s41598-025-96611-5
[mscformercode]Zhao, W. et al. MSCFormer source code: snailpt/MSCFormer
Hugging Face Hub integration
When the optional
huggingface_hubpackage is installed, all models automatically gain the ability to be pushed to and loaded from the Hugging Face Hub. Install with:pip install braindecode[hub]
Pushing a model to the Hub:
from braindecode.models import MSCFormer # Train your model model = MSCFormer(n_chans=22, n_outputs=4, n_times=1000) # ... training code ... # Push to the Hub model.push_to_hub( repo_id="username/my-mscformer-model", commit_message="Initial model upload", )
Loading a model from the Hub:
from braindecode.models import MSCFormer # Load pretrained model model = MSCFormer.from_pretrained("username/my-mscformer-model") # Load with a different number of outputs (head is rebuilt automatically) model = MSCFormer.from_pretrained("username/my-mscformer-model", n_outputs=4)
Extracting features and replacing the head:
import torch x = torch.randn(1, model.n_chans, model.n_times) # Extract encoder features (consistent dict across all models) out = model(x, return_features=True) features = out["features"] # Replace the classification head model.reset_head(n_outputs=10)
Saving and restoring full configuration:
import json config = model.get_config() # all __init__ params with open("config.json", "w") as f: json.dump(config, f) model2 = MSCFormer.from_config(config) # reconstruct (no weights)
All model parameters (both EEG-specific and model-specific such as dropout rates, activation functions, number of filters) are automatically saved to the Hub and restored when loading.
See Loading and Adapting Pretrained Foundation Models for a complete tutorial.
Methods