A comprehensive toolkit for EEG-based Motor Imagery classification, implementing deep learning, classical ML, and ensemble approaches with real-time BrainFlow streaming support.
This project provides complete implementations of:
- EEGNet v2 - Compact CNN for EEG classification (Lawhern et al. 2018)
- Conformer - Transformer-based EEG classifier
- TCN - Temporal Convolutional Network for time-series EEG
- CSP - Common Spatial Pattern (classical BCI approach)
- Riemannian MDM - Covariance-based classification using Riemannian geometry
- Ensemble - Voting & Stacking with tangent space features
- BrainFlow Real-Time Pipeline - Hardware-agnostic streaming (Synthetic/Ganglion/Cyton)
| Model | Evaluation | Accuracy | Notes |
|---|---|---|---|
| EEGNet v2 (baseline) | 5-fold CV | 45.83% | 4-class (25% random) |
| EEGNet v2 (tuned) | 5-fold CV | 54.32% | Hyperparameter search |
| Conformer | 5-fold CV | 38.43% | |
| TCN | 5-fold CV | 40.35% | |
| Ensemble Voting(soft) | train/test split | 79.29% | EEGNet+Conformer+TCN |
| Ensemble Stacking(tangent) | train/test split | 82.14% | Cohen's Kappa 0.537 |
| Riemannian MDM | single subject | 73.63% |
NeuroDecode/
├── src/ # Core package
│ ├── data/ # Data loading and preprocessing
│ │ ├── loader.py # PhysioNet dataset loader
│ │ └── preprocessing.py # EEG preprocessing pipeline
│ ├── models/ # ML models
│ │ ├── eegnet.py # EEGNet v2 implementation
│ │ ├── conformer.py # Conformer model
│ │ ├── tcn.py # TCN model
│ │ ├── ensemble.py # Voting & Stacking ensemble
│ │ ├── csp.py # CSP classifier
│ │ └── riemann_mdm.py # Riemannian MDM classifier
│ ├── training/ # Training utilities
│ │ ├── trainer.py # Unified training loop
│ │ └── augment.py # Data augmentation (6 methods)
│ ├── inference/ # Real-time inference
│ │ └── pipeline.py # StreamingBuffer + RealTimePipeline
│ ├── evaluation/ # Metrics
│ │ └── metrics.py # Comprehensive evaluation
│ ├── intent/ # Phase 1: Intent encoding
│ │ ├── intent_encoder.py # MI to cognitive mode mapping
│ │ └── context_manager.py # State machine + dialogue context
│ ├── llm_bridge/ # Phase 1: LLM integration
│ │ └── llm_client.py # Ollama/API/Mock pluggable backend
│ ├── feedback/ # Phase 1: Visual feedback
│ │ └── visual_feedback.py # Flask+SSE real-time web UI
│ └── utils/ # Utilities
│ └── config.py # Configuration management
├── tests/ # Unit tests (Phase 1)
│ ├── test_intent_encoder.py # Intent encoder tests
│ ├── test_context_manager.py # Context manager tests
│ └── test_llm_client.py # LLM client tests
├── scripts/ # Executable scripts
│ ├── brainflow_realtime.py # BrainFlow real-time streaming
│ ├── collaborative_reasoning_demo.py # Phase 1: BCI×LLM collaborative demo
│ ├── realtime_demo.py # Real-time pipeline demo
│ ├── train_eegnet.py # EEGNet training
│ ├── train_ensemble.py # Ensemble training
│ ├── train_csp.py # CSP training
│ ├── train_riemann.py # Riemannian training
│ ├── compare_models.py # Model comparison
│ └── tune_eegnet.py # Hyperparameter tuning
├── visualizations/ # Charts (CN + EN)
├── configs/ # Configuration files
│ └── default.yaml # Default configuration
├── outputs/ # Results and checkpoints
├── README.md # This file
└── requirements.txt # Python dependencies
# Create conda environment (if not already done)
conda create -n bci_dev python=3.10
conda activate bci_dev
# Install PyTorch
pip install torch>=2.0.0
# Install MNE and dependencies
pip install mne>=1.0.0 scipy>=1.7.0 numpy>=1.21.0
# Install scikit-learn
pip install scikit-learn>=1.0.0
# Install pyRiemann (for Riemannian classifiers)
pip install pyriemann>=0.3.0
# Install Braindecode (optional, for additional models)
pip install braindecode>=0.8.0
# Install other utilities
pip install pyyaml matplotlib tqdmcd NeuroDecode
pip install -r requirements.txtThe first time you run a script, MNE will attempt to download the PhysioNet Motor Movement/Imagery dataset. This requires internet access.
python scripts/train_eegnet.py --subjects 1 2 3# Basic training
python scripts/train_eegnet.py --subjects 1 2 3 --epochs 100
# With data augmentation
python scripts/train_eegnet.py --subjects 1 2 --augment --epochs 100
# With cross-validation
python scripts/train_eegnet.py --subjects 1 --cv_folds 5python scripts/train_csp.py --subjects 1 2 3 --n_components 4python scripts/train_riemann.py --subjects 1 2 --metric riemannpython scripts/compare_models.py --subjects 1 2 3 --quick# Run all strategies
python scripts/tune_eegnet.py --all --subjects 1 2
# Run specific strategy
python scripts/tune_eegnet.py --strategy A --augmentations gaussian_noise mixup
python scripts/tune_eegnet.py --strategy B --full_search
python scripts/tune_eegnet.py --strategy C --improvements batchnorm# Synthetic board (no hardware needed)
python scripts/brainflow_realtime.py --duration 30
# Real hardware (requires device)
python scripts/brainflow_realtime.py --board ganglion # OpenBCI Ganglion
python scripts/brainflow_realtime.py --board cyton # OpenBCI Cyton
python scripts/brainflow_realtime.py --board cerelog # Cerelog ESP-EEGSupports 8 channels at 250Hz, sliding window inference (4s window, 0.5s step). Switch hardware by changing --board parameter only.
Systematically test augmentation methods:
- Gaussian Noise
- Temporal Masking
- Channel Masking
- Time Shifting
- Band Perturbation
- Mixup
Search over key parameters:
- F1 (temporal filters): [4, 8, 16]
- D (depth multiplier): [1, 2, 4]
- Dropout: [0.3, 0.5, 0.7]
- Kernel length: [32, 64, 128]
Test architectural modifications:
- Batch Normalization
- Label Smoothing
- SE Attention
- Combined approaches
NeuroDecode Phase 1 bridges BCI motor imagery decoding with LLM-powered collaborative reasoning. Instead of treating BCI as a keyboard (one label = one character), we map MI classes to high-level cognitive modes, leveraging the human brain's strength in rapid intuitive selection.
EEG Signal -> BrainFlow -> EEGNet Decoder -> IntentEncoder -> ContextManager
|
LLM Bridge (Ollama/API/Mock)
|
3 Candidate Responses
|
User BCI Selection (2nd round)
|
Expand -> Visual Feedback (Flask+SSE)
| Motor Imagery Class | Cognitive Mode | Description |
|---|---|---|
| Left Hand | QUERY | Search for knowledge / factual lookup |
| Right Hand | REASON | Logical deduction / calculation / analysis |
| Feet | CREATE | Generate solutions / creative ideas |
| Tongue | REVIEW | Summarize / synthesize current context |
# Install Phase 1 dependencies
pip install flask brainflow scipy
# Run collaborative reasoning demo with mock LLM
python scripts/collaborative_reasoning_demo.py --backend mock
# Open browser to http://127.0.0.1:8080# Install Ollama from https://ollama.ai
ollama pull qwen2.5:7b
ollama serve
# Run with real LLM
python scripts/collaborative_reasoning_demo.py --backend ollama --model qwen2.5:7bpython scripts/collaborative_reasoning_demo.py \
--backend api \
--api-url https://api.deepseek.com/v1 \
--api-key YOUR_KEY \
--api-model deepseek-chatpytest tests/ -vCurrent coverage: 86% across intent encoder, context manager, and LLM client modules.
| Module | File | Description |
|---|---|---|
| IntentEncoder | src/intent/intent_encoder.py |
MI classification to cognitive mode mapping with debounce + confidence threshold |
| ContextManager | src/intent/context_manager.py |
Thread-safe state machine + dialogue context window |
| LLMClient | src/llm_bridge/llm_client.py |
Pluggable LLM backend: Ollama / OpenAI-compatible API / Mock |
| VisualFeedback | src/feedback/visual_feedback.py |
Flask + SSE real-time web UI with EEG waveform + candidate cards |
| Demo | scripts/collaborative_reasoning_demo.py |
Main entry point, orchestrates full collaborative reasoning pipeline |
from src.training.augment import EEGAugmentor, AugmentationConfig
config = AugmentationConfig(
enabled=True,
temporal_mask={'enabled': True, 'prob': 0.3},
channel_mask={'enabled': True, 'prob': 0.2},
gaussian_noise={'enabled': True, 'prob': 0.3, 'snr_db': 10},
time_shift={'enabled': True, 'prob': 0.2},
band_perturbation={'enabled': True, 'prob': 0.2},
mixup={'enabled': True, 'prob': 0.3, 'alpha': 0.2},
)
augmentor = EEGAugmentor(config, sfreq=128)
X_aug = augmentor.augment(X)from src.data.preprocessing import PreprocessingPipeline, PreprocessingConfig
config = PreprocessingConfig(
bandpass_low=4,
bandpass_high=38,
tmin=-1.0,
tmax=4.0,
baseline=(-1.0, 0.0),
normalize=True,
resample_freq=128,
)
pipeline = PreprocessingPipeline(config)
epochs = pipeline.process_raw(raw)| Model | Evaluation | Accuracy | Notes |
|---|---|---|---|
| EEGNet v2 (baseline) | 5-fold CV | 45.83% | 4-class (25% random) |
| EEGNet v2 (tuned) | 5-fold CV | 54.32% | Hyperparameter search |
| Conformer | 5-fold CV | 38.43% | |
| TCN | 5-fold CV | 40.35% | |
| Ensemble Voting(soft) | train/test split | 79.29% | EEGNet+Conformer+TCN |
| Ensemble Stacking(tangent) | train/test split | 82.14% | Cohen's Kappa 0.537 |
| Riemannian MDM | single subject | 73.63% |
# configs/default.yaml
data:
dataset_path: "./NeuroDecode/data/"
subjects: [1, 2, 3, 4, 5, 6, 7, 8]
runs: [4, 5, 6]
preprocessing:
bandpass_low: 4
bandpass_high: 38
normalize: true
eegnet:
F1: 8
D: 2
kernel_length: 64
dropout_rate: 0.5
epochs: 100
batch_size: 64
learning_rate: 0.001
augmentation:
enabled: true
probability: 0.5
temporal_mask:
enabled: true
prob: 0.3If the PhysioNet dataset fails to download:
# Try setting a proxy if behind firewall
# Use synthetic data for testing: scripts will auto-generate if download fails# Reduce batch size
python scripts/train_eegnet.py --subjects 1 --batch_size 32
# Use CPU if GPU memory is limited
python scripts/train_eegnet.py --subjects 1 --device cpu# Make sure you're in the project root
cd NeuroDecode
export PYTHONPATH="${PYTHONPATH}:$(pwd)"
# Or run scripts directly
python scripts/train_eegnet.py-
Lawhern, V. J., et al. (2018). EEGNet: A compact convolutional neural network for EEG-based brain-computer interfaces. Journal of Neural Engineering.
-
Blankertz, B., et al. (2008). The BCI competition III: Validating alternative approaches to actual EEG problems. IEEE TNSRE.
-
Barachant, A., et al. (2012). Classification of covariance matrices using a Riemannian-based kernel for BCI applications. NeuroImage.
MIT.This project is for educational and research purposes.
Contributions welcome! Please submit issues and pull requests.