Reproducible motor-imagery EEG classification on the MI3 dataset with notebook and script-based training pipelines.
This repository contains multiple model families (CNN, LSTM-CNN, graph neural network, transformer, and CSP+SVM) evaluated under a shared comparison contract for per-subject runs.
- Quick Setup
- Models and Entry Points
- Data Download
- How to Run Experiments
- Results (Best Full Runs)
- Cross-subject comparison charts
Before running any experiment command, sync the environment from the repository root:
pip install uv
uv sync| Goal | Entry point | Command |
|---|---|---|
| Run SVM baseline | Notebooks/MI3_SVM.ipynb |
uv run jupyter nbconvert --to notebook --execute --inplace Notebooks/MI3_SVM.ipynb |
| Run LENet CNN | Notebooks/MI3_CNN.ipynb |
uv run jupyter nbconvert --to notebook --execute --inplace Notebooks/MI3_CNN.ipynb |
| Run LSTM-CNN | Notebooks/MI3_LSTM_CNN.ipynb |
uv run jupyter nbconvert --to notebook --execute --inplace Notebooks/MI3_LSTM_CNN.ipynb |
| Run DDGCNN | Notebooks/MI3_Graph.ipynb |
uv run jupyter nbconvert --to notebook --execute --inplace Notebooks/MI3_Graph.ipynb |
| Run EEG Transformer | Notebooks/FinalTransformer/main.py |
uv run python Notebooks/FinalTransformer/main.py --mode all |
Notes:
- Edit each notebook config cell before executing long runs.
- For Transformer runs, edit
Notebooks/FinalTransformer/.envbefore execution.
- Dataset: MI3 motor-imagery EEG (3 classes: Rest, Elbow, Hand)
- Problem type: 3-class EEG classification
- Primary benchmark style: per-subject training/evaluation in batch mode (no pooled-subject training)
- Split policy lock: stratified train/val/test with val=0.1, test=0.1, seed=42
- Tuned-run policy: one-time Optuna tuning on a reference subject, then reuse tuned params for all subjects in that run
- Research goal: reduce the cognitive disconnect in prosthetic BCI control by decoding joint-specific imagery within the same limb
- Performance goal: exceed the reported 87.03% benchmark from the Deep Channel-Correlation Network on this same-limb task
- Engineering goal: improve accuracy while maintaining practical computational efficiency
Many BCI prosthetic systems map unrelated imagined movements to prosthetic actions (for example, imagining a foot movement to command a hand action). This creates a cognitive disconnect and increases mental load.
This project targets a more intuitive alternative: decoding fine-grained motor imagery from different joints of the same limb (Elbow vs Hand, plus Rest). If successful, this improves control naturalness for users and advances scientific understanding of how overlapping motor-cortex patterns encode subtle movement intent.
This repository solves a supervised 3-class EEG time-series classification problem.
- Input per trial: multivariate EEG matrix
X in R^(C x T)C = 62channelsT = 800samples for 4 seconds at 200 Hz
- Output per trial: one label in
{0,1,2}0 = Rest1 = Elbow2 = Hand
Formal objective:
- Learn
f: R^(62 x 800) -> {0,1,2}from labeled trials.
Practical challenge:
- EEG has low signal-to-noise ratio and high inter-subject variability.
- Elbow-vs-Hand imagery activates partially overlapping cortical regions, making class boundaries subtle.
.
├── Datasets/
│ └── MI3/
│ ├── code/ # MATLAB preprocessing scripts and channel dictionaries
│ ├── derivatives/ # Preprocessed .mat files (sub-001 ... sub-025)
│ └── README.md # Dataset and preprocessing notes
├── Notebooks/
│ ├── MI3_CNN.ipynb
│ ├── MI3_LSTM_CNN.ipynb
│ ├── MI3_Graph.ipynb
│ ├── MI3_SVM.ipynb
│ ├── FinalTransformer/ # Scripted EEG Transformer pipeline
│ └── reports/
│ └── comparison_ready/ # Standardized run artifacts for model comparison
├── pyproject.toml
└── uv.lock
This repository benchmarks several model families, from interpretable classical methods to modern deep learning architectures.
- Traditional baseline (CSP/FBCSP + SVM)
- Purpose: establish a strong classical baseline and quantify gains from learned deep features.
- Notebook:
Notebooks/MI3_SVM.ipynb
- Multi-scale CNNs (LENet-style / EEG-focused CNN)
- Purpose: capture local temporal and spatial EEG patterns with efficient convolutions.
- Notebook:
Notebooks/MI3_CNN.ipynb
- Hybrid recurrent models (CNN-LSTM)
- Purpose: combine spatial feature extraction with temporal dynamics modeling over the full trial.
- Notebook:
Notebooks/MI3_LSTM_CNN.ipynb
- Transformer/attention models
- Purpose: model long-range dependencies and prioritize informative channels/time segments.
- Entry point:
Notebooks/FinalTransformer/main.py
- Graph models (dynamic channel-connectivity learning)
- Purpose: represent EEG electrodes as a graph and learn connectivity signatures for same-limb discrimination.
- Notebook:
Notebooks/MI3_Graph.ipynb
| Model family | Entry point | Typical output directory |
|---|---|---|
| LENet CNN | Notebooks/MI3_CNN.ipynb |
Notebooks/reports/comparison_ready/LENet/{run_tag}/ |
| LSTM-CNN | Notebooks/MI3_LSTM_CNN.ipynb |
Notebooks/reports/comparison_ready/lstm_cnn/{run_tag}/ |
| DDGCNN (graph) | Notebooks/MI3_Graph.ipynb |
Notebooks/reports/comparison_ready/ddgcnn/{run_tag}/ |
| EEG Transformer | Notebooks/FinalTransformer/main.py |
Notebooks/reports/comparison_ready/eeg_transformer/{run_tag}/ |
| CSP + SVM | Notebooks/MI3_SVM.ipynb |
Notebooks/reports/comparison_ready/svm/{run_tag}/ |
Notes:
- Comparison artifacts are organized under
Notebooks/reports/comparison_ready/. - Transformer runs use
NotebookConfigdefaults fromNotebooks/FinalTransformer/eeg_transformer_config.pyplus overrides from.envand CLI args.
- Preprocessed MI3 derivatives in
Datasets/MI3/derivatives/:sub-001_eeg200hz.mat...sub-025_eeg200hz.mat
- BIDS-style metadata files under
Datasets/MI3/
- Subjects: 25 healthy participants
- Approximate labeled trials: 22,500 total
- Task labels: Rest / Elbow / Hand motor imagery
- Label quality: original data collection used EMG monitoring to reject physical movement contamination; derivatives include artifact-removal and filtering workflow
- Privacy and access: public, anonymized, EEG-BIDS structured dataset
If your local Datasets/MI3/derivatives/ folder is missing files, download the preprocessed 200Hz derivatives (already formatted for the notebook data loaders) from:
Place all downloaded .mat files under:
Datasets/MI3/derivatives/
Raw CNT files are available from the public MI3 release:
- Scientific Data article: https://www.nature.com/articles/s41597-020-0535-2
- Dataverse DOI: https://doi.org/10.7910/DVN/RBN3XG
For MATLAB preprocessing requirements and plugin setup, see:
Datasets/MI3/README.mdDatasets/MI3/code/MI3_process.m
Key related references for this same-limb MI setting:
- FBCSP baseline for MI BCI: https://doi.org/10.1109/IJCNN.2008.4634130
- Same-limb MI classification (hand/elbow/rest): https://doi.org/10.1371/journal.pone.0121896
- Time-domain same-limb MI features: https://doi.org/10.1371/journal.pone.0174161
- The LENet CNN original architecture: Xiaojian Liao, Guang Li, You Wang, Lining Sun, Hongmiao Zhang, "Constructing lightweight and efficient spiking neural networks for EEG-based motor imagery classification," Biomedical Signal Processing and Control, vol. 100, part B, 2025, Art. no. 107000, ISSN 1746-8094. https://doi.org/10.1016/j.bspc.2024.107000
- EEGNet: https://doi.org/10.1088/1741-2552/aace8c
- DeepConvNet EEG decoding: https://doi.org/10.1002/hbm.23730
- CNN-LSTM MI decoding: https://doi.org/10.1016/j.bspc.2021.103342
- Deep channel-correlation network (87.03 benchmark): https://doi.org/10.1109/TNSRE.2019.2953121
- Channel-attention MLP-Mixer for MI: https://doi.org/10.1109/ICASSP43922.2022.9747488
- Dynamic graph CNN for EEG modeling: https://arxiv.org/abs/1809.02660
- Python 3.11
- CUDA-compatible PyTorch build (configured to use cu124 index in
pyproject.toml) - uv package manager (recommended)
git clone https://github.com/AlonResearch/MI-EEG-Pattern-Recog.git
cd MI-EEG-Pattern-Recog
pip install uv
uv syncuv run python -c "import torch; print(torch.__version__); print('cuda:', torch.cuda.is_available())"- Choose a pipeline:
- Notebook pipelines: open one notebook in
Notebooks/. - EEG Transformer pipeline: configure
Notebooks/FinalTransformer/.envand runNotebooks/FinalTransformer/main.py.
- Notebook pipelines: open one notebook in
- Set at minimum:
- subject range (
subject_start,subject_end) - run length (
epochsor model-specific equivalent) - tuning flags (
enable_tuning,n_trials,tuning_subject_id)
- subject range (
- Keep split-lock defaults unchanged:
split_strategy = stratified_train_val_testval_size = 0.1,test_size = 0.1,split_seed = 42
- Run either:
- all notebook cells top-to-bottom in a fresh kernel, or
uv run python Notebooks/FinalTransformer/main.py --mode all
- Collect outputs from the run directory printed by the notebook/script.
- Compare runs in the relevant comparison directory.
The pipelines used here are designed around these rules:
- Per-subject execution in batch mode
- Deterministic split settings across models (0.8/0.1/0.1 train/validation/test split)
- One-time tuning on
tuning_subject_idand reuse of tuned params for the rest of subjects - Standardized run artifacts for cross-model comparison
Most comparison-ready runs export a subset of:
run_manifest.jsonmetrics_subject_level.csvmetrics_subject_level.jsonlmetrics_summary.jsonconfusion_matrix_subject_level.npztraining_history_subject_level.jsonlfig_training_curves.pngfig_confusion_matrix.pngrun.logbest_params_sub-XXX.json(when tuning is enabled)- model checkpoint (
*_best.pth) for PyTorch models
Selection rule used for this summary:
- Only full runs were considered (
n_subjects_total = 25andn_subjects_success = 25). - Per model family, the run with highest
overall_accuracywas selected. - For SVM, both kernels are reported from full run
20260317_202816usingacc_rbf_testandacc_linear_test.
| Rank | Model | Run tag | Overall accuracy | Macro F1 |
|---|---|---|---|---|
| 1 | EEG Transformer | 20260318_164456 |
85.07% | 84.99% |
| 2 | DDGCNN | 20260319_224819 |
65.56% | 65.55% |
| 3 | SVM (Linear kernel) | 20260317_202816 |
58.93% | 55.96% |
| 4 | CNN-LSTM | 20260318_164251 |
57.91% | 57.09% |
| 5 | LENet CNN | 20260319_215417 |
54.76% | 54.24% |
| 6 | SVM (RBF kernel) | 20260317_202816 |
50.36% | 50.15% |
Average statistics by model
| Average learning curve | Average confusion matrix |
![]() |
![]() |
| Average learning curve | Average confusion matrix |
![]() |
![]() |
| Confusion matrix (Linear) | Confusion matrix (RBF) |
![]() |
![]() |
| Learning curves (all subjects overlaid) | Average confusion matrix |
![]() |
![]() |
| Average learning curve | Average confusion matrix |
![]() |
![]() |
| EEG Transformer (best full run) | DDGCNN (best full run) |
![]() |
![]() |
| CNN-LSTM (best full run) | SVM kernel accuracy comparison |
![]() |
![]() |
Relevant notes:
- All rows above are from full 25-subject runs under the same split lock (
val_size=0.1,test_size=0.1,split_seed=42).













