Production MI engine: wide-window fine-tuned CBraMod (grouped-CV 0.784 zero-calibration; parity 7e-6 abs, 210/210 decisions)
Browse files
CBraModMI.mlpackage/Data/com.apple.CoreML/model.mlmodel
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c9f4825df8d95a8317ac753096d41a0449875b8b9969e9955b9db5c036038ade
|
| 3 |
+
size 327364
|
CBraModMI.mlpackage/Data/com.apple.CoreML/weights/weight.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:6b4b694d9b1120c81e4a5701f133507ccf3fc3f7e4e44dc6ad3a2725b4f3a4e8
|
| 3 |
+
size 20146048
|
CBraModMI.mlpackage/Manifest.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fileFormatVersion": "1.0.0",
|
| 3 |
+
"itemInfoEntries": {
|
| 4 |
+
"8585A9D1-98D5-49F6-9A33-D43E87441E0E": {
|
| 5 |
+
"author": "com.apple.CoreML",
|
| 6 |
+
"description": "CoreML Model Specification",
|
| 7 |
+
"name": "model.mlmodel",
|
| 8 |
+
"path": "com.apple.CoreML/model.mlmodel"
|
| 9 |
+
},
|
| 10 |
+
"D96CFFCE-E706-4EF9-AFD3-DCC48C2CC4A7": {
|
| 11 |
+
"author": "com.apple.CoreML",
|
| 12 |
+
"description": "CoreML Model Weights",
|
| 13 |
+
"name": "weights",
|
| 14 |
+
"path": "com.apple.CoreML/weights"
|
| 15 |
+
}
|
| 16 |
+
},
|
| 17 |
+
"rootModelIdentifier": "8585A9D1-98D5-49F6-9A33-D43E87441E0E"
|
| 18 |
+
}
|
README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: bsd-3-clause
|
| 3 |
+
base_model: braindecode/cbramod-pretrained
|
| 4 |
+
tags:
|
| 5 |
+
- coreml
|
| 6 |
+
- eeg
|
| 7 |
+
- bci
|
| 8 |
+
- motor-imagery
|
| 9 |
+
- ios
|
| 10 |
+
- macos
|
| 11 |
+
- visionos
|
| 12 |
+
language:
|
| 13 |
+
- en
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
# CBraMod-MI-CoreML
|
| 17 |
+
|
| 18 |
+
**Zero-calibration motor-imagery decoder for 14-channel consumer EEG (EMOTIV EPOC X montage), running natively on Apple silicon. Subject-grouped estimate on unseen users: 78.4% left/right accuracy with no calibration trials.**
|
| 19 |
+
|
| 20 |
+
This is CBraMod fine-tuned end-to-end for left/right-hand motor imagery on all 109 PhysioNet EEGBCI subjects, exported to Core ML as a single classifier. Unlike embedding-based deployments, it needs **no per-subject head**: preprocessed EEG in, left/right probabilities out.
|
| 21 |
+
|
| 22 |
+
## The two-zone window (read this β it is the model's contract)
|
| 23 |
+
|
| 24 |
+
The input window is **[1.0, 4.5] s after imagery onset** β deliberately covering both the sustained-imagery zone *and* the post-imagery beta rebound. Our profiling showed the rebound period is anti-correlated under sweet-spot-trained decoders (it reverses the linear decision) but is the single most informative zone when trained on directly; the two-zone window is what lifts unseen-user accuracy from 0.717 to 0.784. Feeding a different window degrades the model to that extent.
|
| 25 |
+
|
| 26 |
+
| Item | Value |
|
| 27 |
+
|---|---|
|
| 28 |
+
| Model | `CBraModMI.mlpackage` (fp32 `mlprogram`) |
|
| 29 |
+
| Input | `eeg` β `float32 [1, 14, 1000]` |
|
| 30 |
+
| Output | `logits` β `float32 [1, 2]` = [left, right] (apply softmax) |
|
| 31 |
+
| Window | 3.5 s starting 1.0 s after imagery onset, source 256 Hz (896 samples) |
|
| 32 |
+
| Preprocessing | average reference over the 14 channels β global z-score of the window β resample to 200 Hz (polyphase) β zero-pad to 1000 samples |
|
| 33 |
+
| Channels (order matters) | AF3, F7, F3, FC5, T7, P7, O1, O2, P8, T8, FC6, F4, F8, AF4 |
|
| 34 |
+
| Also included | `cbramod_mi_wide.safetensors` (the fine-tuned PyTorch weights), `training_meta.json`, `parity.json` |
|
| 35 |
+
|
| 36 |
+
## Honest evaluation
|
| 37 |
+
|
| 38 |
+
All numbers are **subject-grouped** (GroupKFold 5 on 109 subjects: the evaluated model never saw any window from the tested user) with pre-registered hyperparameters; the published checkpoint is the same recipe trained on all 109.
|
| 39 |
+
|
| 40 |
+
- **0.784 Β± 0.132** mean unseen-user accuracy; 56/109 users β₯ 80%, 25/109 β₯ 90%.
|
| 41 |
+
- +14.7 points over the best frozen-feature decoder *with* per-user calibration (paired p = 7Γ10β»Β²β°).
|
| 42 |
+
- **Bounds, stated plainly:** the identical recipe does not lift fists-vs-feet decoding (0.567 β the montage lacks midline-central coverage), and transfer across *recording setups* degrades: frozen-feature priors lost ~3 points crossing to a different amplifier/protocol (Cho2017), and the same should be expected here. This model is trained on research-grade recordings channel-subset to the EPOC X montage; true dry-electrode performance is unvalidated until live-headset data exists.
|
| 43 |
+
- The model is **cue-paced by design**: it decodes a window anchored to a known imagery onset (an app prompt). It is not an asynchronous/self-paced decoder β our pseudo-online study showed free-running decoding fails on this paradigm regardless of decoder.
|
| 44 |
+
|
| 45 |
+
## Core ML parity
|
| 46 |
+
|
| 47 |
+
Converted with `torch.export` + `run_decompositions({})` (fp32; `torch.jit.trace` fails on CBraMod's criss-cross reshapes β see the conversion notes in [CBraMod-CoreML-Apple](https://huggingface.co/oraculumai/CBraMod-CoreML-Apple)). Gates on real EEG windows vs PyTorch: logits rel-L2, 100% decision agreement, softmax max-abs-diff β results in `parity.json`.
|
| 48 |
+
|
| 49 |
+
## Usage
|
| 50 |
+
|
| 51 |
+
```python
|
| 52 |
+
import numpy as np
|
| 53 |
+
import coremltools as ct
|
| 54 |
+
from huggingface_hub import snapshot_download
|
| 55 |
+
|
| 56 |
+
# local_dir is required: Core ML cannot resolve the default HF cache's symlinks
|
| 57 |
+
repo = snapshot_download("oraculumai/CBraMod-MI-CoreML", local_dir="CBraMod-MI-CoreML")
|
| 58 |
+
model = ct.models.MLModel(f"{repo}/CBraModMI.mlpackage")
|
| 59 |
+
|
| 60 |
+
# window: [1.0, 4.5]s post-onset, 14ch x 896 @ 256 Hz, avg-ref + z-scored,
|
| 61 |
+
# then resampled to 200 Hz and zero-padded to 1000 samples:
|
| 62 |
+
logits = model.predict({"eeg": window_1x14x1000})["logits"] # [1, 2] = [left, right]
|
| 63 |
+
```
|
| 64 |
+
|
| 65 |
+
Python helper with the exact preprocessing: `oraculum.cbramod.CBraModMIClassifier` in <https://github.com/nschlaepfer/oraculum-gpt-mk1>.
|
| 66 |
+
|
| 67 |
+
## Provenance & credit
|
| 68 |
+
|
| 69 |
+
- **Base model:** CBraMod (Wang et al., ICLR 2025, BSD-3-Clause) via [`braindecode/cbramod-pretrained`](https://huggingface.co/braindecode/cbramod-pretrained).
|
| 70 |
+
- **Fine-tuning data:** PhysioNet EEGBCI (Schalk et al. 2004; Goldberger et al. 2000) β 109 subjects, motor-imagery runs, 14-channel subset. Please cite both when using this model.
|
| 71 |
+
- **Method & evaluation:** the accompanying study (repository above) documents the two-zone window discovery, the fine-tuning recipe, and every control.
|
| 72 |
+
|
| 73 |
+
Research artifact β not a medical device; not validated for clinical use.
|
cbramod_mi_wide.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e8cf5f04c8e42c6782d7c27d67f285a55be08233b985c91e17ede4e6c02db954
|
| 3 |
+
size 19830136
|
parity.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"export_fidelity_rel_l2": 0.0,
|
| 3 |
+
"worst_logits_absdiff": 6.973743438720703e-06,
|
| 4 |
+
"decision_agreement": "210/210",
|
| 5 |
+
"worst_prob_absdiff": 2.384185791015625e-06,
|
| 6 |
+
"gate_abs": 0.0001,
|
| 7 |
+
"pass": true
|
| 8 |
+
}
|
training_meta.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"windows": 4606,
|
| 3 |
+
"subjects": 109,
|
| 4 |
+
"window_s": [
|
| 5 |
+
1.0,
|
| 6 |
+
4.5
|
| 7 |
+
],
|
| 8 |
+
"recipe": "AdamW back 3e-5/head 1e-3, wd 0.05, bs 64, 12 ep, cosine, ls 0.1, seed 0",
|
| 9 |
+
"grouped_cv_estimate": 0.784,
|
| 10 |
+
"train_sanity_acc": 0.8323925314806774,
|
| 11 |
+
"base": "braindecode/cbramod-pretrained (BSD-3-Clause)",
|
| 12 |
+
"data": "PhysioNet EEGBCI runs 4/8/12, 109 subjects, 14 EPOC X channels"
|
| 13 |
+
}
|