adammnrr commited on
Commit
d5abbde
·
verified ·
1 Parent(s): 670f9de

Ship the encoder alone, under the production STFT recipe

Browse files

config.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.

Files changed (4) hide show
  1. README.md +19 -5
  2. config.json +5 -3
  3. model.safetensors +2 -2
  4. pytorch_model.bin +2 -2
README.md CHANGED
@@ -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 (the masked
29
- spectrogram-reconstruction head, used only for the self-supervised pretraining
30
- objective, is kept for weight parity; the classification head is a
31
- braindecode-native addition, randomly initialized).
 
 
 
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
- | `freq_cutoff` (input_dim) | 40 |
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
config.json CHANGED
@@ -5,8 +5,10 @@
5
  "n_heads": 12,
6
  "nperseg": 400,
7
  "noverlap": 350,
8
- "freq_cutoff": 40,
9
- "stft_clip": 5,
 
 
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.7.0dev0"
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
  }
model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:a20e81cfb90192b58dd3002c5dac960a0193c727f026e6fd27bb872363edb23c
3
- size 172753928
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dbdab4696be1315bc559c620de510aebd5f83890aedc2fbaa1d08b1b8e040a33
3
+ size 172741344
pytorch_model.bin CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d953e90c8ab27afb3f44a9bce1ecd52705012dc948702227cdfeca6ac4c4da60
3
- size 172776905
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5e1e93aaec221fa3316a565cb4e54ccde35f11376a30e6b275e750f25cd18a3b
3
+ size 172759165