Ship the encoder alone, under the production STFT recipe
Browse filesconfig.json was written before the review renamed freq_cutoff to
idx_freq_cutoff, so the loader silently dropped it, and it carried
stft_clip=5 -- the notebook recipe, not the production one behind this
checkpoint. Measured on iEEG-scale input, the two recipes differ by
max|d|=0.36 on logits of amplitude 0.50, enough to flip the argmax.
The config is now regenerated by the model itself, so it cannot drift
from the constructor again, and states stft_clip=10,
stft_zscore_before_clip=True and pool_n_frames=10 explicitly.
The four final_layer.* tensors are dropped. Two were a LayerNorm the
review removed, and the other two were an untrained nn.Linear(768, 2)
init (weight std 0.0207, against 0.0209 for a fresh one) shipped as if
it were pretrained. BrainBERT pretrains by masked spectrogram
reconstruction and has no classification head to inherit. The 82
encoder tensors are bit-identical to what was published.
- README.md +19 -5
- config.json +5 -3
- model.safetensors +2 -2
- pytorch_model.bin +2 -2
|
@@ -25,10 +25,13 @@ self-supervised foundation model for intracranial (sEEG/iEEG) recordings.
|
|
| 25 |
|
| 26 |
These weights are the **official pretrained "large" checkpoint** (`stft`
|
| 27 |
variant) released by the original authors. The Transformer encoder and input
|
| 28 |
-
encoding are mapped **1:1** into the braindecode `BrainBERT` module
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
The upstream repository ships **no explicit license file**, so this repository is
|
| 34 |
labelled `unknown`: the original authors retain all rights, and these weights are
|
|
@@ -46,12 +49,23 @@ This checkpoint uses the released "large" configuration (~43M parameters):
|
|
| 46 |
| `ffn_dim` | 3072 |
|
| 47 |
| `n_layers` | 6 |
|
| 48 |
| `n_heads` | 12 |
|
| 49 |
-
| `
|
| 50 |
| `nperseg` | 400 |
|
| 51 |
| `noverlap` | 350 |
|
|
|
|
|
|
|
| 52 |
| `activation` | GELU |
|
| 53 |
| `sfreq` | 2048 Hz |
|
| 54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
The signal is expected at **2048 Hz** (Laplacian-re-referenced, as in the paper).
|
| 56 |
The short-time Fourier transform front-end is computed **inside** the model, so it
|
| 57 |
consumes raw `(batch, n_chans, n_times)` signal directly (upstream fed a
|
|
|
|
| 25 |
|
| 26 |
These weights are the **official pretrained "large" checkpoint** (`stft`
|
| 27 |
variant) released by the original authors. The Transformer encoder and input
|
| 28 |
+
encoding are mapped **1:1** into the braindecode `BrainBERT` module.
|
| 29 |
+
|
| 30 |
+
This repository ships the **encoder only** — 82 tensors, bit-identical to the
|
| 31 |
+
authors' release. No downstream head is included: BrainBERT is pretrained by
|
| 32 |
+
masked spectrogram reconstruction and has no classification head to inherit, so
|
| 33 |
+
`final_layer` is freshly initialized by `from_pretrained` for whatever
|
| 34 |
+
`n_outputs` you ask for.
|
| 35 |
|
| 36 |
The upstream repository ships **no explicit license file**, so this repository is
|
| 37 |
labelled `unknown`: the original authors retain all rights, and these weights are
|
|
|
|
| 49 |
| `ffn_dim` | 3072 |
|
| 50 |
| `n_layers` | 6 |
|
| 51 |
| `n_heads` | 12 |
|
| 52 |
+
| `idx_freq_cutoff` (input_dim) | 40 |
|
| 53 |
| `nperseg` | 400 |
|
| 54 |
| `noverlap` | 350 |
|
| 55 |
+
| `stft_clip` | 10 |
|
| 56 |
+
| `stft_zscore_before_clip` | `True` |
|
| 57 |
| `activation` | GELU |
|
| 58 |
| `sfreq` | 2048 Hz |
|
| 59 |
|
| 60 |
+
Upstream ships **two contradictory STFT recipes**. `preprocessors/stft.py` —
|
| 61 |
+
reached from `conf/preprocessor/stft_pretrained.yaml` and therefore the one
|
| 62 |
+
behind the released checkpoint — z-scores the spectrogram and *then* trims 10
|
| 63 |
+
frequency bins. `notebooks/demo.ipynb` trims 5 bins first and z-scores after.
|
| 64 |
+
The order matters, because it decides whether the boundary artifacts enter the
|
| 65 |
+
z-score statistics. This repository is configured for the **production** recipe
|
| 66 |
+
(`stft_clip=10`, `stft_zscore_before_clip=True`); pass
|
| 67 |
+
`stft_clip=5, stft_zscore_before_clip=False` to reproduce the notebook instead.
|
| 68 |
+
|
| 69 |
The signal is expected at **2048 Hz** (Laplacian-re-referenced, as in the paper).
|
| 70 |
The short-time Fourier transform front-end is computed **inside** the model, so it
|
| 71 |
consumes raw `(batch, n_chans, n_times)` signal directly (upstream fed a
|
|
@@ -5,8 +5,10 @@
|
|
| 5 |
"n_heads": 12,
|
| 6 |
"nperseg": 400,
|
| 7 |
"noverlap": 350,
|
| 8 |
-
"
|
| 9 |
-
"stft_clip":
|
|
|
|
|
|
|
| 10 |
"activation": "torch.nn.modules.activation.GELU",
|
| 11 |
"drop_prob": 0.1,
|
| 12 |
"n_outputs": 2,
|
|
@@ -15,5 +17,5 @@
|
|
| 15 |
"n_times": 2048,
|
| 16 |
"input_window_seconds": null,
|
| 17 |
"sfreq": 2048.0,
|
| 18 |
-
"braindecode_version": "1.
|
| 19 |
}
|
|
|
|
| 5 |
"n_heads": 12,
|
| 6 |
"nperseg": 400,
|
| 7 |
"noverlap": 350,
|
| 8 |
+
"idx_freq_cutoff": 40,
|
| 9 |
+
"stft_clip": 10,
|
| 10 |
+
"stft_zscore_before_clip": true,
|
| 11 |
+
"pool_n_frames": 10,
|
| 12 |
"activation": "torch.nn.modules.activation.GELU",
|
| 13 |
"drop_prob": 0.1,
|
| 14 |
"n_outputs": 2,
|
|
|
|
| 17 |
"n_times": 2048,
|
| 18 |
"input_window_seconds": null,
|
| 19 |
"sfreq": 2048.0,
|
| 20 |
+
"braindecode_version": "1.8.1"
|
| 21 |
}
|
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:dbdab4696be1315bc559c620de510aebd5f83890aedc2fbaa1d08b1b8e040a33
|
| 3 |
+
size 172741344
|
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5e1e93aaec221fa3316a565cb4e54ccde35f11376a30e6b275e750f25cd18a3b
|
| 3 |
+
size 172759165
|