ForeverBlue commited on
Commit
2309f6d
·
verified ·
1 Parent(s): a3c71e8

Upload folder using huggingface_hub

Browse files
README.md CHANGED
@@ -16,9 +16,9 @@ transformer serves four electrode layouts through route-specific wavelet
16
  frontends, and channel identity enters as a learned embedding of the channel
17
  NAME rather than of its index.
18
 
19
- Trained for 2 epochs
20
- (8 optimizer updates) on a mixture of public EEG
21
- corpora, 3.4 M parameters.
22
 
23
  ## Objective
24
 
@@ -36,14 +36,14 @@ applied BEFORE the wavelet frontend (True), at ratio
36
 
37
  | metric | value | what 1.0 would mean |
38
  |---|---|---|
39
- | total loss | 0.7962 | — |
40
- | spec MSE | 1.0093 | — |
41
- | spec NMSE | 1.009 | predicting zero |
42
- | spec Pearson r | -0.000 | perfect |
43
- | raw SmoothL1 | 0.5832 | — |
44
- | raw NMSE | 1.009 | predicting zero |
45
- | raw Pearson r | -0.000 | perfect |
46
- | route-macro total | 0.7962 | — |
47
 
48
  NMSE is dimensionless: MSE(prediction, target) / MSE(0, target), so 1.0 is
49
  what predicting zero scores on that head's own target. The two losses are NOT
@@ -77,25 +77,40 @@ pretraining-only. It exists because it cannot be loaded wrong.
77
  | file | what it is |
78
  |---|---|
79
  | `eeg_c1_encoder.pth` | encoder alone: channel embedding, gate, transformer |
80
- | `pretrain_eeg_c1_moe_best.pth` | complete model, lowest validation total loss (epoch 1) |
81
- | `pretrain_eeg_c1_moe_final.pth` | complete model, last epoch, cosine fully annealed |
 
 
82
  | `metrics_epoch.jsonl` | the full training curve |
83
  | `config_resolved.yaml` | every resolved hyperparameter |
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  ### What is in the complete model
86
 
87
  | component | parameters | share | |
88
  |---|---|---|---|
89
- | shared transformer | 0.01 M | 0.4% | encoder, always transfers |
90
- | channel-name embedding | 0.00 M | 0.1% | always transfers |
91
- | channel projection | 0.00 M | 0.0% | always transfers |
92
- | wavelet frontends (all 4 routes) | 3.37 M | 98.3% | route-bound; downstream usually builds its own |
93
- | patchers (both rates) | 0.01 M | 0.4% | route-bound |
94
- | spec decoder | 0.01 M | 0.4% | pretraining only |
95
- | raw decoder | 0.01 M | 0.4% | pretraining only |
96
- | **total** | **3.43 M** | 100% | |
97
 
98
- At this width the four frontends (98%) outweigh the shared transformer (0%). There is still one encoder file rather than four, because what a per-route file adds is a frontend that only loads onto that exact montage; cut the one you want out of the complete checkpoint.
99
 
100
  ### What transfers, and what does not
101
 
@@ -144,7 +159,7 @@ which is why the hash is checked rather than assumed.
144
  ## Architecture
145
 
146
  ```
147
- embed_dim 32 depth 1 heads 4
148
  norm rmsnorm ffn swiglu qk_norm True
149
  wavelet max_level 3, kernel 16
150
  channel id embedding, injected at the token site
@@ -200,5 +215,5 @@ mismatch rather than silently training on relabelled electrodes.
200
  Code: <https://github.com/ForeverBlue816/PhysioWave-T>
201
 
202
  ---
203
- Prepared by `scripts/prepare_hf_release.py` from `run`
204
  on 2026-09-09.
 
16
  frontends, and channel identity enters as a learned embedding of the channel
17
  NAME rather than of its index.
18
 
19
+ Trained for 60 epochs
20
+ (46080 optimizer updates) on a mixture of public EEG
21
+ corpora, 30.3 M parameters.
22
 
23
  ## Objective
24
 
 
36
 
37
  | metric | value | what 1.0 would mean |
38
  |---|---|---|
39
+ | total loss | 0.2488 | — |
40
+ | spec MSE | 0.3046 | — |
41
+ | spec NMSE | 0.305 | predicting zero |
42
+ | spec Pearson r | 0.831 | perfect |
43
+ | raw SmoothL1 | 0.1930 | — |
44
+ | raw NMSE | 0.278 | predicting zero |
45
+ | raw Pearson r | 0.847 | perfect |
46
+ | route-macro total | 0.2403 | — |
47
 
48
  NMSE is dimensionless: MSE(prediction, target) / MSE(0, target), so 1.0 is
49
  what predicting zero scores on that head's own target. The two losses are NOT
 
77
  | file | what it is |
78
  |---|---|
79
  | `eeg_c1_encoder.pth` | encoder alone: channel embedding, gate, transformer |
80
+ | `pretrain_eeg_c1_moe_best.pth` | complete model, lowest validation **total** loss (epoch 57) |
81
+ | `pretrain_eeg_c1_moe_final.pth` | complete model, last epoch (epoch 60) |
82
+ | `pretrain_eeg_c1_moe_best_spec.pth` | complete model, lowest spec MSE (epoch 59) |
83
+ | `pretrain_eeg_c1_moe_best_raw.pth` | complete model, lowest raw SmoothL1 (epoch 57) |
84
  | `metrics_epoch.jsonl` | the full training curve |
85
  | `config_resolved.yaml` | every resolved hyperparameter |
86
 
87
+ ### Why several checkpoints
88
+
89
+ Each is the minimum of a different validation metric, and they are published
90
+ together so a downstream comparison can ask which criterion transfers instead
91
+ of assuming the one that names `best.pth`. The four bars are within validation
92
+ noise of each other here, which is exactly why the question is worth asking and
93
+ why reconstruction loss cannot answer it.
94
+
95
+ `best.pth` is selected on the TOTAL loss -- the loss that was trained. It is
96
+ not the best spec loss, and not the best raw loss.
97
+
98
+ `pretrain_eeg_c1_moe_best_macro.pth` would have been byte-identical to `pretrain_eeg_c1_moe_best.pth` -- the same epoch won both bars -- so it is not published separately.
99
+
100
  ### What is in the complete model
101
 
102
  | component | parameters | share | |
103
  |---|---|---|---|
104
+ | shared transformer | 25.22 M | 83.2% | encoder, always transfers |
105
+ | channel-name embedding | 0.02 M | 0.1% | always transfers |
106
+ | channel projection | 0.03 M | 0.1% | always transfers |
107
+ | wavelet frontends (all 4 routes) | 3.37 M | 11.1% | route-bound; downstream usually builds its own |
108
+ | patchers (both rates) | 0.20 M | 0.7% | route-bound |
109
+ | spec decoder | 0.72 M | 2.4% | pretraining only |
110
+ | raw decoder | 0.72 M | 2.4% | pretraining only |
111
+ | **total** | **30.30 M** | 100% | |
112
 
113
+ The shared transformer is 83% of the model and the four frontends together are 11%, which is why there is no per-route encoder file here: four of them would duplicate that transformer four times to deliver frontends that are a small fraction of it. Cut the one you want out of the complete checkpoint instead.
114
 
115
  ### What transfers, and what does not
116
 
 
159
  ## Architecture
160
 
161
  ```
162
+ embed_dim 512 depth 8 heads 8
163
  norm rmsnorm ffn swiglu qk_norm True
164
  wavelet max_level 3, kernel 16
165
  channel id embedding, injected at the token site
 
215
  Code: <https://github.com/ForeverBlue816/PhysioWave-T>
216
 
217
  ---
218
+ Prepared by `scripts/prepare_hf_release.py` from `pretrain_eeg_c1_moe`
219
  on 2026-09-09.
config_resolved.yaml CHANGED
@@ -4,13 +4,13 @@ data:
4
  modality: eeg
5
  weights: temperature:0.5
6
  model:
7
- channel_embed_dim: 8
8
  channel_encoding: id
9
  channel_injection: token
10
  channel_token_gate_init: 0.0
11
- depth: 1
12
  dropout: 0.0
13
- embed_dim: 32
14
  ffn: swiglu
15
  fold_gamma: 0.1
16
  fold_synthesis: 3
@@ -20,7 +20,7 @@ model:
20
  max_level: 3
21
  mlp_ratio: 4.0
22
  norm: rmsnorm
23
- num_heads: 4
24
  qk_norm: true
25
  scale_fold: dynamic
26
  use_separate_channel: true
@@ -44,19 +44,19 @@ run_name: pretrain_eeg_c1_moe
44
  seed: 42
45
  train:
46
  batch_size_by_route:
47
- E128_512: 1
48
- E19_256: 1
49
- E32_512: 1
50
- E64_256: 1
51
  clip_grad_norm: 1.0
52
- epochs: 2
53
  grad_accumulation_steps: 1
54
  lr: 0.0003
55
  min_lr_ratio: 0.01
56
- precision: fp32
57
- steps_per_epoch: 4
58
  val_mask_seed: 1234
59
  val_max_batches_per_dataset: 100
60
- warmup_epochs: 0
61
  weight_decay: 0.05
62
  trainer: eeg_c1_moe
 
4
  modality: eeg
5
  weights: temperature:0.5
6
  model:
7
+ channel_embed_dim: 64
8
  channel_encoding: id
9
  channel_injection: token
10
  channel_token_gate_init: 0.0
11
+ depth: 8
12
  dropout: 0.0
13
+ embed_dim: 512
14
  ffn: swiglu
15
  fold_gamma: 0.1
16
  fold_synthesis: 3
 
20
  max_level: 3
21
  mlp_ratio: 4.0
22
  norm: rmsnorm
23
+ num_heads: 8
24
  qk_norm: true
25
  scale_fold: dynamic
26
  use_separate_channel: true
 
44
  seed: 42
45
  train:
46
  batch_size_by_route:
47
+ E128_512: 24
48
+ E19_256: 128
49
+ E32_512: 96
50
+ E64_256: 48
51
  clip_grad_norm: 1.0
52
+ epochs: 60
53
  grad_accumulation_steps: 1
54
  lr: 0.0003
55
  min_lr_ratio: 0.01
56
+ precision: bf16
57
+ steps_per_epoch: 768
58
  val_mask_seed: 1234
59
  val_max_batches_per_dataset: 100
60
+ warmup_epochs: 2
61
  weight_decay: 0.05
62
  trainer: eeg_c1_moe
eeg_c1_encoder.pth CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:e4f6cbbf6195640ad7989a1c62a69b0ecb898840e6ef559402959906128bac8b
3
- size 75665
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:220e4652345e7ad6b9c9fc293970e82818d3d04512f3389ad7b29c45484024c9
3
+ size 101155630
metrics_epoch.jsonl CHANGED
The diff for this file is too large to render. See raw diff
 
pretrain_eeg_c1_moe_best.pth CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:8feea87150d668aa70fbf6c3e755cf669feb5396649ed03d8c4baedd1aa7ae48
3
- size 13874923
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:82fc7fa7874aa7125cb300a6a015b0679897a68602638b9362698282e083a204
3
+ size 121389646
pretrain_eeg_c1_moe_best_raw.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:30e7fb3e5ae4be0663168069a229d40ed7d3297c6e0e19d6cfd23a09bf55cab8
3
+ size 121391422
pretrain_eeg_c1_moe_best_spec.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:36c1bc7fcf2f781b333a45153958c0ab75eee829189922c4cd473191385d6df1
3
+ size 121391850
pretrain_eeg_c1_moe_final.pth CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:0ff4af884954ebc781ebc1b806808f76ae7a3111b16b082fa621b7d0cd3d47a7
3
- size 13875275
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2dcd0c18db845ce2b6d6f10a9eddc85c9fdfadac19e8b7f3f2f7a1b529e8c285
3
+ size 121390138