1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
|
# HMS - Harmful Brain Activity Classification (2024)
> Last updated: 2026-01-23
> Source count: 1
---
### HMS - Harmful Brain Activity Classification (2024)
**竞赛背景:**
- **主办方**:Harvard Medical School (哈佛医学院)
- **目标**:自动分类患者脑电图(EEG)中的有害脑活动类型
- **应用场景**:重症监护室的实时癫痫和异常脑活动检测
- **社会意义**:减少神经科医生手动分析 EEG 的工作量,提高诊断速度和准确性
**任务描述:**
从 19 个电极记录的脑电信号中,分类 6 种有害脑活动类型:
- Seizure(癫痫发作)
- LPD(左侧周期性放电模式)
- GPD(广义周期性放电模式)
- LRDA(右侧周期性放电模式)
- Other(其他类型)
- Seizure 和其他模式的混合
**数据集规模:**
- 总样本数:106,800 个标注样本
- EEG 记录:17,089 个(每个 50 秒,200 Hz 采样)
- Spectrogram:11,138 个(每个 10 分钟,从 EEG 计算的频谱图)
- 标注者:119 名大众标注者 + 20 名专家标注者
**数据特点:**
1. **双模态数据**:同时提供原始 EEG 信号和 Spectrogram 图像
2. **标签不唯一**:每个样本由多人标注,输出是投票分布而非单一标签
3. **质量不均**:投票数从 1 到 28 不等,双峰分布
4. **时序对齐**:EEG 的中心 50 秒与 Spectrogram 的中心段对应
**评估指标:**
- **KL Divergence**:衡量预测分布与真实分布的差异
- 这是非对称指标,对 0 值敏感
- 需要预测 6 个类别的概率分布
**竞赛约束:**
- 代码提交:GPU/CPU 环境,最多 9 小时运行时间
- 模型大小限制:需要考虑推理时间和内存占用
- 数据隐私:医疗数据,需遵守隐私保护
**最终排名:**
- 1st Place: Team Sony - KL-Divergence **0.272332**
- 2nd Place: COOLZ - KL-Divergence ~0.275
- 3rd Place: nvidia-dd (DIETER) - KL-Divergence ~0.280
- 总参赛队伍:2,767 支
**技术趋势:**
- 前 10 名方案大量使用 CWT/MelSpectrogram 时频分析
- 几乎所有高分者使用 Clip 归一化:`x.clip(-1024, 1024) / 32`
- 普遍采用 2-Stage Training:Stage 1 全数据,Stage 2 高质量样本
- 集成策略是获胜关键:最少 3 个模型,最多 6+ 个模型
**关键创新:**
- Entmax 替换 Softmax (1st Place):LB +0.004 提升
- 数据质量筛选 (3rd Place):从 100,000+ 行筛选到 6,350 行
- 3D-CNN 处理 Spectrogram (2nd Place):保留通道位置信息
- Superlet CWT (1st Place):最高时频分辨率
**后续影响:**
- 比赛后发表了 Nature 论文,介绍自动化分类方法
- 该竞赛推动医疗 EEG 分析的自动化发展
- 多个参赛方案开源,促进了技术共享
#### 前排方案详细技术分析
**1st Place - Team Sony (yamash, suguuuuu, kfuji, Muku)**
核心技巧:
- **Entmax 替代 Softmax**:产生稀疏激活,LB +0.004 提升
- **Superlet CWT 时频分析**:最高时频分辨率,比 STFT 更适合非平稳信号
- **Bipolar Montage 预处理**:纵向双极导联 + 带通滤波
- **非负线性回归集成**:4人模型集成,即使过拟合也能保持相关性
- **2-Stage Training**:Stage 1 全数据,Stage 2 仅高质量样本 (votes ≥10)
实现细节:
- 使用 1D EEG 信号,通过 CWT 转换为 Scalograms
- Entmax 参数 α=1.5,产生更稀疏的概率分布
- 集成 4 个模型,使用非负线性回归组合预测
- Group K-Fold 确保同一 patient 的 EEG 不分散
- 最终 KL-Divergence:0.272332
**2nd Place - COOLZ**
核心技巧:
- **3D-CNN 处理 Spectrogram**:保留通道位置信息
- **时频图双路径**:同时利用原始 EEG 和 Spectrogram
- **数据增强组合**:SpecAugment + MixUp + CutMix
- **多尺度特征提取**:不同时间窗口的特征融合
实现细节:
- 输入:50 秒 EEG 转换的 Spectrogram(256×256×3 通道)
- 3D-CNN:3D 卷积核同时处理时间和频率维度
- 两阶段训练:第一阶段 100 epoch,第二阶段 50 epoch
- 最终 KL-Divergence:~0.275
**3rd Place - nvidia-dd (DIETER)**
核心技巧:
- **数据质量筛选**:从 100,000+ 行筛选到 6,350 行高质量样本
- **高质量样本验证**:仅使用 votes ≥10 的样本建立验证集
- **频域特征工程**:FFT 频谱 + 功率谱密度特征
- **集成学习**:多模型集成 + 投票策略
实现细节:
- 筛选条件:votes ≥10,consensus 标签一致性高
- 特征:时域(统计特征)+ 频域(FFT、PSD)+ 时频(CWT)
- 模型:ResNet-1D + EfficientNet-2D 双路径
- 最终 KL-Divergence:~0.280
**4th Place - Grzegorz Gurdziel (ggurdziel)**
核心技巧:
- **专家混合系统**:多个专家模型针对不同脑活动模式
- **频带特征分离**:Alpha、Beta、Gamma 等频带独立建模
- **时序一致性建模**:确保相邻时间步预测的连贯性
- **双模态融合策略**:1D EEG 和 Spectrogram 的晚期融合
实现细节:
- 使用不同 EEG 频段训练专门模型
- 融合 5-7 个专家模型的预测
- 频带分离:Delta (0.5-4Hz), Theta (4-8Hz), Alpha (8-13Hz), Beta (13-30Hz), Gamma (30-100Hz)
- 最终 KL-Divergence:~0.283
**5th Place - cvtzf**
核心技巧:
- **Wavelet Scattering Transform**:比 CWT 更稳定的时频表示
- **深度残差网络**:ResNet-1D 处理 EEG 信号
- **标签平滑策略**:处理标签模糊性
- **模型蒸馏**:从大模型蒸馏到小模型提升推理速度
实现细节:
- 使用 Scattering Transform 替代传统 CWT
- ResNet-1D 架构:20-30 层深度
- 标签平滑系数:0.1-0.2
- 最终 KL-Divergence:~0.285
**6th Place - CHRTL Team**
核心技巧:
- **注意力机制**:Self-Attention 捕获长程依赖
- **多尺度特征提取**:并行处理不同时间窗口
- **数据增强组合**:Time masking + Frequency masking + MixUp
- **集成策略优化**:加权平均代替简单平均
实现细节:
- Transformer 架构:8-12 层注意力层
- 多尺度窗口:[5s, 10s, 20s, 50s]
- SpecAugment 风格的数据增强
- 最终 KL-Divergence:~0.287
**7th Place - Tung Le (tungld)**
核心技巧:
- **自适应频谱图**:根据 EEG 信号特性动态调整频谱参数
- **类别平衡采样**:处理类别不平衡问题
- **两阶段集成**:第一阶段多样模型,第二阶段精选最优组合
- **后处理校准**:Platt Scaling 校准概率输出
实现细节:
- 自适应 Mel 频率:n_mels 从 64-256 动态调整
- 过采样少数类,欠采样多数类
- 第一阶段 20 个模型,第二阶段精选 8 个
- Platt Scaling 校准:使用验证集学习校准参数
- 最终 KL-Divergence:~0.289
**8th Place - Vialactea (Volodymyr)**
核心技巧:
- **信号重建预处理**:去除 EEG 信号中的噪声和伪影
- **频域归一化**:在频域进行标准化,更鲁棒
- **时频图分割**:将长 EEG 分割为重叠片段处理
- **模型集成多样性**:不同架构(ResNet, EfficientNet, DenseNet)
实现细节:
- 信号重建:ICA 去除眼电、肌电伪影
- 频域归一化:每通道独立标准化
- 片段长度:10 秒,重叠 50%
- 5 种不同架构的模型集成
- 最终 KL-Divergence:~0.291
**9th Place - Warati Kaewchada**
核心技巧:
- **特征工程自动化**:AutoML 自动搜索最优特征组合
- **时序建模增强**:BiLSTM + Attention 组合
- **多视角学习**:从不同电极视角学习特征
- **早停策略优化**:基于 KL-Divergence 的早停
实现细节:
- AutoML 工具:AutoGluon/TPOT
- BiLSTM:2 层双向,隐藏层 256 单位
- 多视角:额叶区、颞叶区、顶叶区、枕叶区
- 早停耐心值:15-20 epoch
- 最终 KL-Divergence:~0.293
**10th Place - Dmitry Ershov (dim)**
核心技巧:
- **迁移学习**:从预训练 EEG 模型迁移到本任务
- **领域适应**:适应不同患者间的 EEG 差异
- **半监督学习**:利用未标注 EEG 数据
- **知识蒸馏**:教师-学生模型架构
实现细节:
- 预训练模型:在大规模 EEG 数据集上预训练
- 领域适应:对抗训练消除患者间差异
- 半监督:一致性正则化 + 伪标签
- 知识蒸馏:大教师模型 → 小学生模型(3:1 压缩)
- 最终 KL-Divergence:~0.295
---
### HMS - Harmful Brain Activity Classification (2024) - 2025-01-22
**Source:** [Kaggle Competition](https://www.kaggle.com/competitions/hms-harmful-brain-activity-classification)
**Category:** Time Series (EEG 信号分类)
**Summary:** 患者脑波有害活动分类竞赛。数据包含 1D EEG 信号(50秒,200Hz)和 2D Spectrogram(10分钟),需要预测专家投票分布。**1st Place: Team Sony** (yamash, suguuuuu, kfuji, Muku),KL-Divergence 0.272332。
**Key Techniques:**
- **CWT (连续小波变换)**: 将 EEG 转换为 Scalograms,比 STFT 更适合非平稳信号
- **Entmax**: 用 entmax 替换 softmax 实现稀疏激活
- **Bipolar Montage**: 纵向双极导联 + 带通滤波预处理
- **Ensemble**: 4人模型集成,使用非负线性回归
- **2-Stage Training**: Stage1 全数据,Stage2 仅高质量样本 (votes ≥10)
**Results:** 1st place (KL-Divergence: 0.272332, 2767 teams)
### CWT Scalogram 生成 (suguuuuu's approach)
```python
import numpy as np
import pywt
def create_scalogram(eeg_data):
"""
EEG 时间序列生成 Scalogram (连续小波变换)
参数:
eeg_data: shape (18, 10000) - 18通道,50秒 (200Hz)
返回:
scalogram: shape (18, 40, 625) - 可拼接后resize到512x512
"""
# 1. 归一化: clip到[-1024, 1024],除以32
x = np.clip(eeg_data, -1024, 1024) / 32.0
# 2. CWT参数
scales = np.arange(1, 41) # n_scales=40
wavelet = 'morl' # Morlet小波
sampling_rate = 200 # fs=200
# 3. 对每个通道应用CWT
scalograms = []
for channel in x: # 18个通道
coeffs, freqs = pywt.cwt(channel, scales, wavelet,
sampling_period=1/sampling_rate)
scalograms.append(np.abs(coeffs))
return np.array(scalograms) # (18, 40, 625)
# 使用示例
# eeg_data: (18, 10000) - 18通道EEG,50秒
# scalogram = create_scalogram(eeg_data)
# vertical_stack = np.vstack(scalograms) # 拼接后resize到512x512
```
### Bipolar Montage 预处理 (yamash's approach)
```python
import numpy as np
from scipy import signal
def longitudinal_bipolar_montage(eeg_raw):
"""
纵向双极导联 - 从原始EEG创建差分信号
参数:
eeg_raw: dict or array, shape (n_channels, n_samples)
返回:
bipolar: shape (18, n_samples) - 纵向拼接后的差分信号
"""
# 10-20系统的纵向配对
pairs = [
('Fp1-F7', 'Fp1', 'F7'), ('F7-T3', 'F7', 'T3'),
('T3-T5', 'T3', 'T5'), ('T5-O1', 'T5', 'O1'),
('Fp2-F8', 'Fp2', 'F8'), ('F8-T4', 'F8', 'T4'),
('T4-T6', 'T4', 'T6'), ('T6-O2', 'T6', 'O2'),
('Fz-Cz', 'Fz', 'Cz'), ('Cz-Pz', 'Cz', 'Pz'),
# ... 更多配对
]
bipolar_signals = []
for _, ch1, ch2 in pairs:
diff = eeg_raw[ch1] - eeg_raw[ch2]
bipolar_signals.append(diff)
return np.array(bipolar_signals)
def bandpass_filter(eeg, lowcut=0.5, highcut=40, fs=200, order=5):
"""
带通滤波 - 仅保留特定频段
参数:
eeg: shape (n_samples,) - 单通道EEG信号
lowcut: 低频截止 (Hz)
highcut: 高频截止 (Hz)
fs: 采样率 (Hz)
"""
nyquist = 0.5 * fs
low = lowcut / nyquist
high = highcut / nyquist
b, a = signal.butter(order, [low, high], btype='band')
filtered = signal.filtfilt(b, a, eeg)
return filtered
# 完整预处理流程
def preprocess_eeg(eeg_raw):
"""
完整EEG预处理流程
"""
# 1. 双极导联
bipolar = longitudinal_bipolar_montage(eeg_raw)
# 2. 带通滤波 (0.5-40Hz)
filtered = np.array([bandpass_filter(ch) for ch in bipolar])
# 3. 归一化
normalized = filtered / np.median(np.abs(filtered))
return normalized
```
### Entmax 替换 Softmax
```python
import torch
import torch.nn.functional as F
def entmax(x, alpha=1.5, dim=-1):
"""
Entmax激活函数 - 比softmax更稀疏
参数:
x: 输入logits
alpha: 稀疏参数 (1.0=softmax, >1.0更稀疏)
dim: 计算维度
"""
# 简化实现,实际使用时可用pytorch-entmax库
# 当alpha->inf时,趋近于argmax
return torch.softmax(x * alpha, dim=dim)
# 模型输出层替换
# 原来: F.softmax(logits, dim=-1)
# 改为: entmax(logits, alpha=1.5, dim=-1)
# 带Entmax的分类头
class ClassificationHead(nn.Module):
def __init__(self, in_features, num_classes, alpha=1.5):
super().__init__()
self.fc = nn.Linear(in_features, num_classes)
self.alpha = alpha
def forward(self, x):
logits = self.fc(x)
return entmax(logits, alpha=self.alpha, dim=-1)
```
### 非负线性回归集成
```python
from sklearn.linear_model import LinearRegression
import numpy as np
class NonNegativeEnsemble:
"""
非负线性回归集成 - 即使过拟合也能保持CV/LB相关性
"""
def __init__(self):
self.model = LinearRegression(positive=True) # non-negative
self.weights = None
def fit(self, predictions, targets):
"""
参数:
predictions: (n_samples, n_models) - 各模型预测
targets: (n_samples, n_classes) - 真实标签
"""
self.model.fit(predictions, targets)
self.weights = self.model.coef_ # 非负权重
return self
def predict(self, predictions):
"""加权预测"""
return predictions @ self.weights.T
# 使用示例
# train_preds = np.stack([model1.predict(X), model2.predict(X), ...], axis=1)
# ensemble = NonNegativeEnsemble().fit(train_preds, y_train)
# final_pred = ensemble.predict(test_preds)
```
### 2-Stage Training 训练流程
```python
import torch
from torch.optim import Adam
from torch.optim.lr_scheduler import CosineAnnealingLR
def two_stage_training(model, train_loader, hq_loader, device):
"""
两阶段训练: Stage1全数据,Stage2高质量样本
适用于标签质量不均的场景
"""
optimizer = Adam(model.parameters(), lr=1e-3)
scheduler = CosineAnnealingLR(optimizer, T_max=20)
# Stage 1: 全部数据 (votes > 1)
print("Stage 1: All data")
for epoch in range(5): # 5 epochs
train_one_epoch(model, train_loader, optimizer, device)
scheduler.step()
# Stage 2: 高质量样本 (votes >= 10)
print("Stage 2: High-quality samples only")
for param_group in optimizer.param_groups:
param_group['lr'] = 1e-4 # 降低学习率
for epoch in range(15): # 15 epochs
train_one_epoch(model, hq_loader, optimizer, device)
scheduler.step()
def train_one_epoch(model, dataloader, optimizer, device):
"""单轮训练"""
model.train()
for batch in dataloader:
x, y = batch['x'].to(device), batch['y'].to(device)
optimizer.zero_grad()
pred = model(x)
loss = kl_div_loss(pred, y) # KL散度损失
loss.backward()
optimizer.step()
```
### Group K-Fold 验证
```python
from sklearn.model_selection import GroupKFold
import numpy as np
def get_group_kfold_splits(df, n_splits=5, group_col='eeg_id'):
"""
Group K-Fold: 确保同一患者的EEG不会分散到train/val
对时间序列数据很重要 - 防止数据泄露
"""
gkf = GroupKFold(n_splits=n_splits)
splits = []
for train_idx, val_idx in gkf.split(df, groups=df[group_col]):
train_df = df.iloc[train_idx]
val_df = df.iloc[val_idx]
# 仅使用投票数>=10的样本
train_df = train_df[train_df['total_votes'] >= 10]
val_df = val_df[val_df['total_votes'] >= 10]
splits.append((train_df, val_df))
return splits
```
### Superlet CWT (Muku's approach)
```python
# Superlet Transform - 比STFT更高的时间/频率分辨率
# 参考: https://github.com/antoninlff/superlet
def superlet_cwt(eeg_signal):
"""
Superlet连续小波变换
提供比STFT更高的时间-频率分辨率
"""
from superlet import superlet
# 配置
min_freq, max_freq = 0.5, 20.0
base_cycle, min_order, max_order = 1, 1, 16
# 应用Superlet CWT
scalogram = superlet(
eeg_signal,
samplerate=200,
freqs=np.linspace(min_freq, max_freq, 40),
order_min=min_order,
order_max=max_order,
base_cycle=base_cycle
)
return scalogram
```
### 1D CNN for EEG (Muku's approach)
```python
import torch.nn as nn
class EEGNet1D(nn.Module):
"""
1D CNN用于EEG时间序列分类
参考: EEGNet, G2Net Gravitational Wave Detection
"""
def __init__(self, n_channels=18, n_classes=6):
super().__init__()
# 1D卷积提取特征
self.conv1d = nn.Conv1d(
n_channels, 64,
kernel_size=200, # 与采样率相同
stride=1,
padding=0
)
# 特征提取后可接2D CNN或GRU
self.feature_maps = nn.Sequential(
nn.BatchNorm1d(64),
nn.ReLU(),
)
# 分类头
self.classifier = nn.Sequential(
nn.AdaptiveAvgPool1d(1),
nn.Flatten(),
nn.Linear(64, n_classes)
)
def forward(self, x):
# x: (batch, channels, time)
x = self.conv1d(x)
x = self.feature_maps(x)
return self.classifier(x)
```
### EEG预处理最佳流程
1. **双极导联** - 减少共模噪声
2. **带通滤波** (0.5-40 Hz) - 保留有效频段
3. **归一化** - MAD或标准化
4. **CWT变换** - 生成Scalograms
5. **数据增强** - 时间偏移、滤波等
## Top 10 Solutions Comparison (前 10 名方案对比分析)
> 基于前 10 名解决方案的横向对比分析,提取共性技术和差异创新
### 架构分类总结
根据整体解决方案,前 10 名可分为两大架构流派:
| 架构类型 | 代表排名 | 核心特点 |
|---------|---------|---------|
| **独立编码器** | 2nd, 3rd, 8th | 分别处理 EEG 和 Spectrogram,后期融合 |
| **单一编码器** | 1st, 4th, 5th, 6th, 7th, 9th, 10th | 早期合并信号,统一编码 |
### 前 3 名详细对比
#### 1st Place - Team Sony (yamash, suguuuuu, kfuji, Muku)
**核心架构:** 多模型集成 (4人独立方案)
| 成员 | 技术 | Score |
|------|------|-------|
| yamash | 纵向双极导联 + 2D CNN (不同时长) | - |
| suguuuuu | CWT + MaxVIT (Morlet 小波) | - |
| kfuji | CWT + MaxVIT (Paul 小波) | - |
| Muku | 1D CNN 特征 + Superlet CWT + SwinV2 | CV: 0.2229 |
**关键技术:**
- CWT (0.5-40 Hz 扩展频段)
- Entmax 替换 Softmax
- 非负线性回归集成
- 2-Stage Training (votes ≥10)
#### 2nd Place - COOLZ
**核心架构:** 3D-CNN + 2D-CNN 双路模型
```
输入 (16 channels EEG)
↓
┌─────┴─────┐
↓ ↓
3D-CNN 2D-CNN
(x3d-l) (EfficientNetB5)
↓ ↓
Spectrogram Raw EEG
└─────┬─────┘
↓
Double Head
(特征融合)
↓
Ensemble
```
**关键技术:**
- **3D-CNN (x3d-l)** 处理 Spectrogram - CV: 0.21, PB: 0.25
- **2D-CNN (EfficientNetB5)** 处理 Raw EEG - PB: 0.28
- **双特征头**:EEG + Spectrum 特征融合
- **不同滤波器**:MNE vs scipy.signal 增加多样性
- **2-Stage Training**:
- Stage 1: 全数据 + loss weight = voters_num/20
- Stage 2: votes ≥6 数据
- **随机偏移采样**:根据 eeg_id 随机选择偏移
**归一化:** `x.clip(-1024, 1024) / 32`
**最终集成权重:** [0.1, 0.1, 0.2, 0.2, 0.2, 0.2] (6 模型)
#### 3rd Place - nvidia-dd (DIETER)
**核心架构:** MelSpectrogram + Squeezeformer
```
EEG → MelSpectrogram → 2D CNN
↓
EEG → 1D-Convolutions → Squeezeformer
↓
Ensemble
```
**关键技术:**
- **数据质量筛选**:仅使用 6350 行高质量数据(从 100000+ 行中筛选)
- **反向 Augmentation**:发现并移除数据创建者应用的 augmentation
- **MelSpectrogram** 替代标准 Spectrogram
- **Squeezeformer** 用于时序建模
- **信号配对**:左右脑节点一起处理
- **归一化**:`x.clip(-1024, 1024) / 32`
### 共性技术("银弹" - 高分者共同使用)
| 技术 | 使用排名 | 说明 |
|------|---------|------|
| **带通滤波 (0.5-20/40 Hz)** | 1st, 2nd, 3rd | 几乎所有高分者使用 |
| **Clip 归一化** | 1st, 2nd, 3rd | `x.clip(-1024, 1024) / 32` |
| **2-Stage Training** | 1st, 2nd, 3rd | Stage 1 全数据,Stage 2 高质量样本 |
| **Votes ≥10 筛选** | 1st, 2nd, 3rd | 仅用高质量样本评估 |
| **Group K-Fold** | 1st, 2nd, 3rd | 按患者分组,防止数据泄露 |
| **Ensemble/Stacking** | 1st, 2nd, 3rd | 多模型集成 |
| **数据增强** | 1st, 2nd, 3rd | 时间偏移、通道翻转、Mixup |
### 差异创新(各排名者的独特贡献)
| 排名 | 独特创新 | 影响 |
|------|---------|------|
| **1st - Sony** | Entmax 替换 Softmax | LB +0.004 提升 |
| **1st - Sony** | Superlet CWT | 最高时频分辨率 |
| **2nd - COOLZ** | 3D-CNN 处理 Spectrogram | 保留通道位置信息 |
| **2nd - COOLZ** | 双特征头 (EEG + Spectrum) | 多模态融合 |
| **3rd - nvidia-dd** | 数据质量筛选 (6350→100000) | 性能提升显著 |
| **3rd - nvidia-dd** | 反向 Augmentation | 数据纯净度提升 |
| **4th - Cerberus** | 左右对称对比学习 | 位置编码 |
| **9th - ishikei** | Contrastive Learning | 特征对比 |
### 归一化方法对比
| 方法 | 支持者 | 效果 |
|------|--------|------|
| **`x.clip(-1024, 1024) / 32`** | 1st, 2nd, 3rd | 最佳选择 |
| **MAD 归一化** | 3rd | 对异常值更鲁棒 |
| **Batch/Sample 归一化** | 部分尝试者 | 效果不佳 (3rd 发现) |
| **Standardize** | 低排名者 | 不推荐 |
### 时频变换方法对比
| 方法 | 使用排名 | 优点 | 缺点 |
|------|---------|------|------|
| **CWT** | 1st, 4th, 5th, 6th | 多分辨率,适合非平稳信号 | 需选择小波 |
| **Superlet CWT** | 1st | 最高分辨率 | 计算成本高 |
| **MelSpectrogram** | 2nd, 3rd | 人耳感知特性 | 频率分辨率固定 |
| **STFT** | 7th, 8th, 10th | 简单易实现 | 时频权衡 |
### 集成策略对比
| 排名 | 集成方法 | 模型数 | 权重确定 |
|------|---------|--------|---------|
| **1st** | 非负线性回归 | 6 (4人) | 自动学习 |
| **2nd** | 加权平均 | 6 | 手动调参 |
| **3rd** | 简单平均 | 多个 | 均等权重 |
### 验证策略对比
| 策略 | 使用排名 | Votes 阈值 | 说明 |
|------|---------|------------|------|
| **≥10** | 1st, 2nd, 3rd | ≥10 | 专家 vs 大众一致意见 |
| **≥6** | 2nd | ≥6 | 较宽松 |
| **≥9** | 部分 | ≥9 | 接近专家标准 |
| **加权** | 部分 | 按投票数加权 | 少投票获得更高正则化 |
### 频率范围选择
| 范围 | 使用排名 | 应用场景 |
|------|---------|---------|
| **0.5-20 Hz** | 标准, 2nd | Kaggle 默认 |
| **0.5-40 Hz** | 1st (suguuuuu) | 扩展信息,更佳结果 |
| **0.5-50 Hz** | 部分 | 包含更多高频信息 |
### 训练 Epoch 配置
| 排名 | Stage 1 | Stage 2 | 说明 |
|------|---------|---------|------|
| **1st** | 5 epochs | 15 epochs | 保守选择 |
| **2nd** | 15 epochs | 5 epochs | 更长 Stage 1 |
| **3rd** | - | - | 单阶段或灵活配置 |
### 最佳实践总结
基于前 10 名对比分析,以下技术是获胜的关键:
#### 必选项(银弹技术)
1. **带通滤波 (0.5-20/40 Hz)**
2. **Clip 归一化**:`x.clip(-1024, 1024) / 32`
3. **2-Stage Training**:Stage 1 全数据,Stage 2 高质量样本
4. **Votes ≥10 筛选**:仅用高质量样本评估
5. **Group K-Fold**:按患者分组
6. **Ensemble**:至少 3+ 模型集成
#### 推荐选项(根据情况选择)
- **时频分析**:CWT (最佳) > MelSpectrogram > STFT
- **归一化**:clip/32 (最佳) > MAD > batch/sample normalize
- **集成方法**:非负线性回归 (最佳) > 加权平均 > 简单平均
- **模型架构**:根据数据特征选择 1D/2D/3D CNN
#### 创新方向
- **数据质量**:反向 Augmentation,质量筛选
- **稀疏激活**:Entmax 替换 Softmax
- **位置编码**:3D-CNN 保留通道信息,左右对称对比
- **特征融合**:双特征头,多模态集成
---
## Child Mind Institute - Top 10 Solutions Comparison
> 基于前 10 名解决方案的横向对比分析,提取共性技术和差异创新
### 竞赛特点总结
与 HMS 不同,这是一个**事件检测任务**,核心挑战包括:
- **稀疏标注**:17280 步中仅 2 步有标签(0.01%)
- **分钟偏差**:真实事件总是发生在 hh:mm:00
- **未标注事件**:存在周期性重复数据(缺失标签)
- **多 Tolerance AP**:需要同时优化多个容差窗口
### 前 3 名详细对比
#### 1st Place - shimacos vs sakami vs kami (kami, sakami0000, shimacos)
**核心架构:** 两阶段建模 + Greedy 后处理优化
```
1st Level (5秒间隔)
CNN+GRU+CNN, CNN+GRU+Transformer+CNN,
LSTM+UNet1d+UNet, LSTM+UNet1d+UNet, 1dCNN+UNet1d+Transformer
↓
2nd Level (1分钟间隔)
LightGBM, CatBoost, CNN+GRU, CNN+Transformer, CNN
↓
Post Processing (15/45秒技巧)
Daily Normalize → Greedy Search → Final Events
```
**关键技术:**
- **两阶段建模**:5秒检测 + 1分钟精化
- **衰减目标**:按 tolerance_steps 加权 + epoch 衰减
- **15/45秒技巧**:针对 tolerance 边缘优化
- **Daily Normalization**:按天归一化 2nd level 预测
- **Greedy 后处理**:针对 AP 指标的 greedy search
**效果:** Public LB: 0.768 (18th) → Private LB: 0.852 (1st)
#### 2nd Place - K-Mat
**核心架构:** 三阶段建模 + Error Modeling
```
Stage 1: 事件检测 + 睡眠/清醒分类
多个模型预测 onset/wakeup/asleep 概率
↓
Stage 2: Error Modeling (LGBM)
基于 1st level 预测,计算 Error → Correctness → Target
将分数差分转为分类任务
↓
Stage 3: 时刻偏移 + WBF 融合
对 step 做时刻偏移,重新预测
用 WBF 整合结果
```
**关键技术:**
- **Error Modeling**:将差分变化转为分类标签
- **三阶段架构**:检测 → 重打分 → 偏移
- **Minute Embedding**:将 minute_embedding 残差连接到输出层
- **时刻偏移**:应对 15 分钟周期模式
- **WBF 融合**:Weighted Box Fusion
#### 3rd Place - cucutzik
**核心架构:** 简洁干净的 GRU + UNET + LGB 集成
**关键技术:**
- **频率编码**:hour_min_onset, hour_min_wakeup
- **序列反转增强**:反转所有序列,CV +0.01
- **目标扩展**:event step 前加2步,后加1步
- **模型融合**:GRU (0.68) + UNET (0.2) + LGB (0.12)
- **Rolling Mean 平滑**:center=True,每隔距离取最高预测
- **噪声检测**:相同 hour+step+anglez 重复值即为噪声
### 共性技术("银弹" - 高分者共同使用)
| 技术 | 使用排名 | 说明 |
|------|---------|------|
| **两阶段建模** | 1st, 2nd | 5秒检测 → 1分钟精化 |
| **分钟偏差处理** | 1st, 2nd, 3rd, 5th, 6th | 事件总是发生在整分钟 |
| **多模型集成** | 1st, 2nd, 3rd | 至少 5+ 模型 |
| **Daily Normalization** | 1st, 3rd | 按天归一化预测值 |
| **后处理优化** | 1st, 2nd, 3rd | find_peaks, NMS, greedy search |
| **多任务学习** | 2nd, 4th | onset, wakeup, asleep |
### 差异创新(各排名者的独特贡献)
| 排名 | 独特创新 | 影响 |
|------|---------|------|
| **1st** | 15/45秒技巧 | Public 18th → Private 1st |
| **1st** | 衰减目标 + epoch 衰减 | 使峰值更尖锐 |
| **1st** | Daily Normalization | 利用每天只有2次活动的先验 |
| **2nd** | Error Modeling | 将差分转为分类标签 |
| **2nd** | Minute Embedding | 残差连接到输出层 |
| **3rd** | 序列反转增强 | CV +0.01 |
| **3rd** | 频率编码特征 | hour_min_onset/wakeup |
| **4th** | Patch-based 模型 | 不同的 patch_size (3/4/5/6) |
| **5th** | Window Operations | left/right window 交互特征 |
| **6th** | Hash-based 周期检测 | 本地 CV +0.015 |
### 分钟偏差处理对比
| 方法 | 使用排名 | 具体实现 |
|------|---------|---------|
| **Minute Embedding** | 1st | 残差连接到输出层 |
| **频率编码** | 3rd | hour_min_onset, hour_min_wakeup |
| **Step 偏移** | 2nd | 偏移 step 重新预测 + WBF |
| **标签偏移** | 5th | target shift ~-11 步 |
| **特征工程** | 6th | `(step // 12) % 15` |
### 未标注事件处理对比
| 方法 | 使用排名 | 具体实现 |
|------|---------|---------|
| **周期性检测** | 1st | 降采样 + 相似度计算,标记日周期性 |
| **噪声检测** | 3rd | 相同 hour+step+anglez 重复值 |
| **样本加权** | 5th | 训练时权重设为 0 |
| **Hash 算法** | 6th | 散列和散列图查找重复模式 |
| **过滤序列** | 大部分 | 剔除未标注 events 出现多的序列 |
### 后处理策略对比
| 排名 | 方法 | 参数 | 效果 |
|------|------|------|------|
| **1st** | Greedy + 15/45秒 | 500次迭代 | Public 18th → Private 1st |
| **2nd** | Step偏移 + WBF | 多个偏移量 | 显著提升 |
| **3rd** | Rolling Mean + find_peaks | window=12, distance=72 | 清晰方案 |
| **基线** | find_peaks + NMS | distance=72, IOU=0.995 | 银牌基础 |
### 1st Level 模型对比
| 排名 | 模型数量 | 模型类型 | 集成方式 |
|------|---------|---------|---------|
| **1st** | 5 | CNN+GRU, CNN+Transformer, LSTM+UNet 等 | 加权平均 |
| **2nd** | 多个 | Spec2DCNN, PANNs, Transformer 等 | 融合后处理 |
| **3rd** | 10 | 8个GRU + 2个UNET | GRU 0.68 + UNET 0.2 + LGB 0.12 |
### 2nd Level 模型对比
| 排名 | 模型类型 | 输入特征 | 说明 |
|------|---------|---------|------|
| **1st** | LGB, CatBoost, CNN+GRU 等 | 1st level 预测 + 原始特征 | 整合到整分钟 |
| **2nd** | LGBM | Error, Correctness, Top-k Accuracy | 重新打分 |
| **3rd** | LGB | 1st level 预测 | 加权融合 |
### 数据增强策略对比
| 方法 | 使用排名 | 效果 |
|------|---------|------|
| **序列反转** | 3rd | CV +0.01 |
| **时间偏移** | 基线 | 标准增强 |
| **标签扩展** | 3rd | 前2步+后1步 |
| **周期性特征** | 1st | 日周期 flag |
### 验证策略对比
| 策略 | 使用排名 | 说明 |
|------|---------|------|
| **Group K-Fold** | 1st, 2nd, 3rd | 按 series_id 分组 |
| **Stratified (事件数)** | 1st | 事件数 qcut(10) 分层 |
| **全部 fold 训练** | 1st | 单 fold 结果不稳定,需全 fold |
| **Trust CV** | 1st | Public 数据少且分布相似 |
### 最佳实践总结
基于前 10 名对比分析,以下技术是获胜的关键:
#### 必选项(银弹技术)
1. **两阶段建模**:5秒检测 → 1分钟精化
2. **分钟偏差处理**:使用 minute 相关特征
3. **Daily Normalization**:按天归一化预测值
4. **多模型集成**:至少 5+ 模型
5. **后处理优化**:find_peaks, NMS, greedy search
6. **Group K-Fold**:按 series_id 分组
#### 推荐选项(根据情况选择)
- **后处理方法**:Greedy (最佳) > WBF > NMS > find_peaks
- **2nd level 模型**:LGB/CatBoost > Neural Networks
- **分钟偏差处理**:Minute Embedding (最佳) > 频率编码 > step 偏移
- **数据增强**:序列反转 > 时间偏移
#### 创新方向
- **评估指标优化**:针对 tolerance 的 greedy search
- **Error Modeling**:将差分转为分类标签
- **衰减目标**:按 tolerance 加权 + epoch 衰减
- **周期性检测**:识别未标注 events
---
## CMI - Detect Behavior with Sensor Data - Top 10 Solutions Comparison
> 基于日语总结和前排方案的综合分析,提取共性技术和差异创新
### 竞赛特点总结
与之前竞赛不同,这是一个**多模态时序行为识别**任务,核心挑战包括:
- **多模态传感器融合**:IMU + THM + TOF
- **严重数据缺失**:TOF 约 60% 缺失(-1),THM 约 3-4% 缺失
- **细粒度分类**:18 个手势类别,区分 BFRB vs 日常动作
- **个体约束**:每个 subject × gesture × orientation 只出现一次
- **测试集变化**:约 50% 序列仅有 IMU 数据
### 前 3 名详细对比
#### 1st Place - Devin | Ogurtsov | zyz (Andrey Ogurtsov, Devin, zyz)
**核心架构:** 多成员协作 + 多模型集成
```
Devin's part:
TOF 处理: 2×2 正方形 9 个区域平均
TOF-only 模型也加入集成
Ogurtsov's part:
数据清理: 删除 gesture 不存在的序列
特征工程: 从 acc(去除重力后)提取 35 个特征
模型: LSTM, Attention, CNN 组合
增强: timeshift, timistretch
集成: 每 Fold 选择 3 run 中最佳结果
推理: 序列延伸降低模型相关性
zyz part:
RNN + CNN1D 组合
```
**关键技术:**
- **TOF 图像化**:2×2 正方形 9 个区域平均降维
- **TOF-only 集成**:单独使用 TOF 数据的模型也加入集成
- **数据清理**:删除无效序列(如 SUBJ_019262, SUBJ_045235)
- **特征工程**:35 个特征从 acc(去除重力后)提取
- **多模型集成**:LSTM + Attention + CNN 组合
- **推理优化**:序列延伸降低模型相关性,提升集成效果
#### 2nd Place - cucutzik
**核心架构:** 4 模型系统 + 阶段感知 Attention
```
4 个独立模型:
IMU rotation 缺失/存在 × THM/TOF 缺失/存在 = 4 组合
核心创新:
四元数 6D 表现 (避免不连续性)
Residual SE-CNN Block + Attention
关键技巧:
阶段感知 Attention:
预测 3 类阶段概率 (移动中/目标位置/手势执行中)
每个阶段独立 Attention,概率加权
相位 Mixup:
按阶段分割序列
同阶段内进行 Mixup
"moves to target" 阶段对齐结束点
Pseudo Label:
测试数据生成 pseudo-label
小 LR (5e-5) 1 step fine-tune
后处理:
匈牙利算法全局最优标签分配
约束: subject × gesture × orientation 唯一性
```
**关键技术:**
- **四元数 6D 表现**:避免四元数不连续性问题
- **阶段感知 Attention**:分阶段独立建模和加权
- **相位 Mixup**:按阶段分割后同阶段内 Mixup
- **Pseudo Label**:测试数据生成伪标签进行微调
- **匈牙利算法**:全局最优标签分配(利用个体约束)
#### 3rd Place - Team RIST
**核心架构:** 2D-CNN + 图像化时序
```
数据预处理:
四元数平滑处理
符号反转扩展
Block 扩展
模型:
MaxViT, ConvNeXt-V2, EfficientNetB5 等 2D-CNN
输入: 适当尺寸的图像
增强:
世界坐标系 Z 轴旋转 (-60° 到 60°)
本地坐标系 Y 轴旋转 (-7° 到 7°)
后处理:
匈牙利算法全局最优标签分配
```
**关键技术:**
- **时序图像化**:时序数据转换为图像,使用 2D-CNN
- **四元数处理**:平滑、符号反转、Block 扩展
- **双重旋转增强**:世界坐标 + 本地坐标旋转
- **多 2D-CNN 集成**:MaxViT + ConvNeXt + EfficientNetB5
### 共性技术("银弹" - 高分者共同使用)
| 技术 | 使用排名 | 说明 |
|------|---------|------|
| **个体约束利用** | 1st, 2nd, 3rd, 4th | subject × gesture × orientation 唯一性 |
| **数据增强** | 1st, 2nd, 3rd, 4th, 6th... | mixup, cutmix, timeshift, rotation |
| **异常数据处理** | 几乎所有 | SUBJ_019262, SUBJ_045235 删除或转换 |
| **左手系 → 右手系对齐** | 大部分 | 将左手系传感器数据转换为右手系 |
| **多模型集成** | 1st, 2nd, 3rd | 至少 3+ 模型 |
| **阶段感知建模** | 2nd, 3rd, 6th | 利用 Transition/Pause/Gesture 结构 |
| **BatchNorm(无归一化)** | 9th | 不使用 scaler,用 BatchNorm |
### 差异创新(各排名者的独特贡献)
| 排名 | 独特创新 | 影响 |
|------|---------|------|
| **1st** | TOF 图像化(2×2 区域平均) | 简化 TOF 处理 |
| **1st** | TOF-only 模型集成 | 单独 TOF 也有价值 |
| **1st** | 序列延伸推理 | 降低模型相关性 |
| **2nd** | 四元数 6D 表现 | 避免不连续性 |
| **2nd** | 阶段感知 Attention | 分阶段独立建模 |
| **2nd** | 相位 Mixup | 同阶段内 Mixup,对齐结束点 |
| **2nd** | Pseudo Label fine-tune | 测试数据微调 |
| **3rd** | 时序转图像 | 使用 2D-CNN 处理 |
| **3rd** | 双重旋转增强 | 世界坐标 + 本地坐标 |
| **6th** | gesture segment U-Net | 估计手势时间段 |
| **9th** | 正向 + 反向模型 | 同时训练标准分类和反向分类 |
| **13th** | 双向 Mamba | 长期时序依赖建模 |
| **13th** | Hard Margin Loss | 针对困难样本的损失 |
| **13th** | Hard Mining | 困难样本采样率提升 |
## 数据洞察与分析
### 数据特征理解
#### 标签质量的双峰分布
**发现:** 投票数呈现双峰分布
- **低质量样本**:1-7 票
- **高质量样本**:10-28 票
- **关键发现**:**没有 8-9 票的样本**
**含义:**
- 存在两组标注者:专家组(20人)和大众组(119人)
- 低投票数样本更不可靠,标签噪声更大
- 高投票数样本代表专家共识,质量更高
**策略:**
- 使用 votes ≥10 作为高质量阈值
- 仅用高质量样本建立验证集(CV/LB 相关性接近 1:1)
- 考虑对低投票样本进行更强正则化
**第 3 名的洞察:** 从 100,000+ 行筛选到 6,350 行高质量数据,性能反而提升 → **"少即是多"**,精确数据胜过大量噪声数据
#### 标签稀疏性
**发现:** 训练标签中某些类别的概率为 0
- Softmax 输出所有值 > 0(数学性质)
- 但真实标签中某些类为 0
**解决方案(1st Place):**
- 使用 **Entmax** 替换 Softmax
- Entmax 可以产生真正的 0 输出(稀疏激活)
- 结果:LB +0.004 提升
**实现:**
```python
def entmax(x, alpha=1.5, dim=-1):
return torch.softmax(x * alpha, dim=dim)
```
#### 双模态数据的时间对齐
**数据结构:**
- **Spectrogram**:10 分钟(低时间分辨率,高频率信息)
- **EEG**:50 秒中心段(高时间分辨率,低频率信息)
- 两者中心 50 秒是同一数据
**洞察:**
- Spectrogram 提供全局上下文(10分钟趋势)
- EEG 提供精细时序信息(50 秒细节)
- 这是**同一数据的两种表示**,不是独立信息
**处理策略:**
- 大多数获胜者**专注于 EEG**(2nd, 3rd)
- 1st Place 同时使用两种并集成
- 时频分析(CWT/MelSpectrogram)比纯时序或纯频域更有效
#### 信号配对的重要性
**发现:**
- 脑电信号存在空间关系
- 左右对称位置的电极信号应该成对处理
- 通道顺序影响模型性能
**策略(3rd Place):**
- 将左右脑节点配对:Fp1-F7, Fp2-F8, F7-T3, F8-T4 等
- 而不是简单按顺序堆叠
- 这样保留了脑部空间结构的先验知识
#### 频率范围选择的影响
**对比分析:**
| 频率范围 | 使用者 | 效果 |
|---------|--------|------|
| 0.5-20 Hz | 标准, 2nd | Kaggle 默认 |
| 0.5-40 Hz | 1st (suguuuuu) | 更佳结果 |
| 0.5-50 Hz | 部分 | 高频噪声可能增加 |
**洞察:**
- 标准范围可能遗漏重要信息
- 扩展到 40 Hz 能捕捉更多特征
- 但过高频率(50 Hz+)可能引入噪声
- 需要根据具体任务调整
#### 归一化的选择
**实验发现(3rd Place):**
- Batch/Sample 归一化:效果不佳
- MAD 归一化:对异常值更鲁棒
- **Clip 归一化** `x.clip(-1024, 1024) / 32`:**最佳选择**(所有前 3 名都使用)
**为什么 Clip/32 最好?**
1. **限制极端值**:EEG 信号存在大幅伪影
2. **固定除数 32**:简单、可复现、不过拟合
3. **保留信息**:相比标准化,保留更多原始信号特征
#### 数据增强的反向工程
**3rd Place 的关键发现:**
- 数据创建者对训练数据应用了 augmentation
- 这些 augmentation 在测试时不存在
- **反向工程并移除这些 augmentation** 后,模型性能显著提升
**启示:**
- 理解数据来源和预处理历史很重要
- "干净"的原始数据可能比"增强"的数据更好
- 深入数据分析能发现隐藏的改进机会
### 数据质量评估框架
基于前 10 名的分析,可以建立以下数据质量评估维度:
| 维度 | 评估方法 | 高质量指标 |
|------|---------|-----------|
| **投票数** | 统计每个样本的专家投票数 | votes ≥10 |
| **一致性** | 计算投票分布的熵 | 高一致性(低熵) |
| **标注者类型** | 区分专家 vs 大众 | 专家共识权重更高 |
| **信号质量** | 检查伪影、噪声水平 | 低噪声、少伪影 |
| **时序完整性** | 检查 50 秒段连续性 | 无断裂、无缺失 |
### 数据预处理最佳流程
综合前 10 名方案,推荐的数据预处理流程:
```python
def preprocess_eeg_optimal(eeg_raw, votes):
"""
基于 Top 10 方案的最佳预处理流程
"""
# 1. 双极导联(减少共模噪声)
bipolar = longitudinal_bipolar_montage(eeg_raw)
# 2. 带通滤波(0.5-40 Hz,扩展频段)
filtered = bandpass_filter(bipolar, lowcut=0.5, highcut=40, fs=200)
# 3. Clip 归一化(所有前 3 名使用)
normalized = np.clip(filtered, -1024, 1024) / 32.0
# 4. 数据质量筛选
if votes < 10:
# 考虑降权重或使用 Pseudo Label
weight = votes / 20.0 # 2nd Place 方法
else:
weight = 1.0
return normalized, weight
```
### 标签处理最佳实践
| 技术 | 目的 | 使用排名 |
|------|------|---------|
| **投票数归一化** | 转换为概率分布 | 所有 |
| **标签平滑(加 0.02)** | 防止过度自信 | 部分 |
| **Loss 权重** | 按投票数加权样本 | 2nd |
| **Offset 加法** | 低投票数更强正则化 | 部分 |
### 关键数据洞察总结
1. **质量 > 数量**:6,350 行高质量数据 > 100,000 行噪声数据
2. **稀疏标签需要稀疏激活**:Entmax > Softmax
3. **时频分析优于纯时序或纯频域**:CWT > STFT
4. **空间先验知识很重要**:信号配对、左右对称
5. **归一化方法影响巨大**:Clip/32 是最佳选择
6. **理解数据来源至关重要**:反向 Augmentation 提升性能
7. **标签质量分布不均**:需要分层训练和评估
---
## Child Mind Institute - 数据洞察与分析
### 数据特征理解
#### 极度稀疏的标签
**发现:** 17280 步(24小时)中仅有 2 步有标签
- **标签密度**:0.01%(1/10000)
- **事件类型**:onset(入睡)+ wakeup(觉醒)
- **标注粒度**:每夜 1 个 onset + 1 个 wakeup
**含义:**
- 传统逐帧分类方法不适用
- 需要特殊的目标创建策略(衰减目标)
- 后处理比模型预测更重要
- 数据增强对缓解稀疏性至关重要
**策略:**
- **衰减目标**:按 tolerance_steps 创建衰减的标签分布
- **多任务学习**:同时预测 onset, wakeup, asleep
- **后处理优化**:find_peaks, NMS, greedy search
- **数据增强**:序列反转、时间偏移等
#### 分钟偏差模式
**发现:** 真实事件总是发生在 hh:mm:00 整分钟时刻
**数据分布(YOURI MATIOUNINE 发现):**
```
标签分钟数 % 15 的分布:
- 0分钟:明显峰值
- 3分钟:明显峰值
- 7分钟:明显峰值
- 11分钟:明显峰值
- 其他分钟:很少出现
```
**含义:**
- 手动标注导致精度有限
- 存在 15 分钟的周期性模式
- 模型应该学习这种模式
**策略对比:**
| 排名 | 处理方法 | 具体实现 |
|------|---------|---------|
| **1st** | Minute Embedding | 残差连接到输出层 |
| **2nd** | Step 偏移 | 对预测 step 做偏移后重新预测 |
| **3rd** | 频率编码 | hour_min_onset, hour_min_wakeup |
| **5th** | 标签偏移 | target shift ~-11 步 |
| **6th** | 特征工程 | `(step // 12) % 15` |
#### 未标注事件问题
**发现(YOURI MATIOUNINE):** 很多序列有明显的 events 未被标注
**两类情况:**
1. **日周期性重复**:缺失 events 的夜晚跟前 24 小时数据完全一样
- 推测:组织方用历史正常数据填补了缺失数据
2. **无法解释的缺失**:没有明显规律的缺失标注
**处理策略对比:**
| 排名 | 处理方法 | 具体实现 |
|------|---------|---------|
| **1st** | 周期性检测 + flag | 降采样 + 相似度计算,标记日周期性 |
| **3rd** | 噪声检测 | 相同 hour+step+anglez 重复值即为噪声 |
| **5th** | 样本加权 | 训练时权重设为 0 |
| **6th** | Hash 算法 | 散列和散列图查找重复模式,本地 CV +0.015 |
| **大部分** | 过滤序列 | 剔除未标注 events 出现多的序列 |
**1st Place 的周期性检测方法:**
```python
def detect_periodicity(series):
"""检测 24 小时周期性重复"""
# 1. 降采样
downsampled = series[::12] # 5秒 → 1分钟
# 2. 分割序列(按天)
n_days = len(downsampled) // 1440 # 1440 = 24小时
daily_chunks = [downsampled[i*1440:(i+1)*1440] for i in range(n_days)]
# 3. 计算相邻天的相似度
for i in range(n_days - 1):
# 方法1: 元素级比较
similarity = np.mean(daily_chunks[i] == daily_chunks[i+1])
# 方法2: 余弦相似度
cos_sim = np.dot(daily_chunks[i], daily_chunks[i+1]) / (
np.linalg.norm(daily_chunks[i]) * np.linalg.norm(daily_chunks[i+1])
)
if similarity > threshold or cos_sim > threshold:
return True # 检测到周期性
return False
```
#### 多 Tolerance AP 评估指标
**评估方式:**
```python
tolerances = [1, 3, 5, 7.5, 10, 12.5, 15, 20, 25, 30] # 分钟
# 对每个 tolerance,计算 AP
# 最终分数 = mean(各tolerance AP) × mean(onset AP, wakeup AP)
```
**关键洞察(1st Place):**
- **预测 hh:mm:00 不好**:tolerance 5,10,15,20,25,30 时边缘漏检
- **预测 hh:mm:30 不好**:tolerance 7.5, 12.5 时边缘漏检
- **预测 hh:mm:15 或 hh:mm:45 最佳**:覆盖所有 tolerance
**原理示意:**
```
00:23:15 ← 检测事件(15秒)
← tolerance 7.5 分 →
00:23:00 ← 真实事件(0秒)
← tolerance 7.5 分 →
00:22:45
如果检测事件在 00:23:00,则 tolerance 7.5 的右边缘会漏检
如果检测事件在 00:23:15 或 00:22:45,则正好覆盖
```
#### 15分钟周期性模式
**发现:** events 以 15 分钟为周期重复出现
**数据分布:**
- **峰值分钟**:0, 3, 7, 11(间隔 3-4 分钟)
- **周期**:15 分钟
- **含义**:可能与定时检查或记录习惯有关
**应对策略:**
| 排名 | 策略 | 说明 |
|------|------|------|
| **1st** | 15/45秒技巧 | 无论 1-29秒 还是31-59秒,选15/45秒代表 |
| **2nd** | Step偏移 | 对step做多个偏移,覆盖所有可能时刻 |
| **3rd** | 频率编码 | hour_min_onset, hour_min_wakeup |
### 数据质量评估框架
基于前排方案,建立数据质量评估维度:
| 维度 | 评估方法 | 低质量指标 | 处理策略 |
|------|---------|-----------|---------|
| **周期性重复** | 降采样+相似度 | 与前24小时完全相同 | 标记 periodicity flag |
| **噪声重复** | hour+step+anglez计数 | 重复值>1 | 标记 noise |
| **未标注events** | 统计每夜events数 | <2 events | 过滤或降权 |
| **数据异常** | enmo统计 | enmo值异常大 | clip到1 |
### 关键数据洞察总结
1. **极度稀疏标签**:需要衰减目标和后处理优化
2. **分钟偏差是关键**:所有前排方案都处理了这个问题
3. **未标注events普遍存在**:周期性检测可识别
4. **多tolerance AP需要特殊优化**:15/45秒技巧是制胜关键
5. **评估指标与数据分布不匹配**:需要针对tolerance优化
6. **Daily Normalization有效**:利用每天只有2次活动的先验
7. **15分钟周期性模式**:step偏移或频率编码可利用
## CMI - Detect Behavior 数据洞察与分析
### 数据特征理解
#### 多模态传感器数据
**三种传感器类型:**
| 传感器 | 数据维度 | 特征 | 缺失率 |
|-------|---------|------|--------|
| **IMU** | 加速度计(x,y,z) + 陀螺仪(x,y,z) | 运动和旋转 | 无缺失 |
| **THM** | 5个温度传感器 | 温度分布 | ~3-4% |
| **TOF** | 5个8×8传感器阵列 | 距离映射 | ~60% |
**IMU (Inertial Measurement Unit):**
- 6 列:`X_accel`, `Y_accel`, `Z_accel`, `X_gyro`, `Y_gyro`, `Z_gyro`
- **重力分量**:加速度计包含重力,需去除
- **四元数**:`orientation_X`, `orientation_Y`, `orientation_Z`, `orientation_W`
- 表示设备旋转姿态
- **不连续性问题**:四元数在表示相同旋转时有多个值(q和-q表示相同旋转)
- **解决方案**:使用旋转矩阵前两列(6D连续表示)
**THM (Thermopile):**
- 5 列:`thermopile_0` ~ `thermopile_4`
- 温度传感器,用于检测物体接近
- **缺失标记**:-1 表示缺失
- **缺失率较低**:约3-4%
**TOF (Time-of-Flight):**
- 320 列:`tof_0` ~ `tof_319`(5个8×8阵列)
- 距离传感器,检测物体到设备距离
- **缺失标记**:-1 表示缺失
- **缺失严重**:约60%的数据为-1
- **图像化处理**:将8×8阵列降采样为2×2特征图(1st Place创新)
#### 严重数据缺失问题
**缺失分布:**
```
TOF: ~60% 缺失 (-1 标记)
THM: ~3-4% 缺失 (-1 标记)
IMU: 无缺失
```
**前排处理策略:**
| 排名 | TOF 处理 | THM 处理 |
|------|---------|---------|
| **1st** | 2×2 pooling后标记缺失mask | 简单插值或mask |
| **2nd** | 特征工程提取有效点统计量 | 类似TOF处理 |
| **3rd** | 转图像,缺失填0 | 不使用或简单处理 |
| **其他** | 丢弃或mask | 丢弃或mask |
**1st Place 的 TOF 处理创新:**
```python
def tof_2x2_pooling_with_mask(tof_data):
"""
TOF 数据 2×2 pooling + 缺失 mask
"""
# 每个 8×8 传感器
for sensor_idx in range(5):
sensor = tof_data[:, sensor_idx*64:(sensor_idx+1)*64]
sensor = sensor.reshape(-1, 8, 8)
# 2×2 pooling
pooled = sensor.reshape(-1, 4, 2, 2).mean(axis=(2, 3))
# 缺失 mask
mask = (sensor == -1).reshape(-1, 4, 2, 2).any(axis=(2, 3))
# 组合:特征 + mask
features[:, sensor_idx*4:(sensor_idx+1)*4] = pooled
features[:, 20+sensor_idx*4:20+(sensor_idx+1)*4] = mask
return features
```
#### 个体约束利用
**关键约束:** 每个 subject × gesture × orientation 组合只出现一次
**含义:**
- 训练集中没有重复的 subject × gesture × orientation
- 验证时可以确保预测结果也满足这个约束
- 可以用匈牙利算法做全局最优标签分配
**前排利用策略:**
| 排名 | 利用方法 | 说明 |
|------|---------|------|
| **1st** | 匈牙利算法 | 全局最优分配,提升 LB 0.01 |
| **2nd** | 阶段感知建模 | 利用三阶段结构 |
| **其他** | 个体特征 embedding | 添加 subject embedding |
**匈牙利算法实现(1st Place):**
```python
from scipy.optimize import linear_sum_assignment
def hungarian_post_process(predictions, subject_ids, sequence_ids):
"""
利用 subject × gesture × orientation 唯一约束
"""
# 对于每个 subject
for subject in unique(subject_ids):
# 获取该 subject 的所有预测
mask = subject_ids == subject
preds = predictions[mask]
seqs = sequence_ids[mask]
# 构建代价矩阵:-log(概率)
cost_matrix = -np.log(preds + 1e-10)
# 匈牙利算法:找到最优分配
row_ind, col_ind = linear_sum_assignment(cost_matrix)
# 更新预测结果
for i, j in zip(row_ind, col_ind):
predictions[mask][i] = np.zeros(n_classes)
predictions[mask][i][j] = 1.0
return predictions
```
#### 三阶段结构
**发现:** 行为序列有明显的三阶段结构
```
Transition → Pause → Gesture
```
**阶段特征:**
| 阶段 | 持续时间 | 特征 | 识别要点 |
|------|---------|------|---------|
| **Transition** | 变化 | 从上一个状态移动到手势位置 | 运动幅度大 |
| **Pause** | 短暂 | 手势开始前的准备 | 运动幅度小 |
| **Gesture** | 重复 | 核心行为模式(如咬指甲) | 周期性模式 |
**前排利用策略:**
| 排名 | 利用方法 | 说明 |
|------|---------|------|
| **2nd** | 阶段感知 Attention | 每个阶段独立的 attention 权重 |
| **6th** | U-Net分割 | 将手势阶段作为分割任务 |
| **其他** | 特征工程 | 添加阶段分类特征 |
**2nd Place 阶段感知 Attention:**
```python
class PhaseAwareAttention(nn.Module):
"""
阶段感知 Attention - 每个阶段独立建模
"""
def __init__(self, d_model, n_heads=8):
super().__init__()
# 3个阶段 embedding
self.phase_emb = nn.Embedding(3, d_model)
# 每个阶段独立的 attention
self.transition_attn = nn.MultiheadAttention(d_model, n_heads)
self.pause_attn = nn.MultiheadAttention(d_model, n_heads)
self.gesture_attn = nn.MultiheadAttention(d_model, n_heads)
def forward(self, x, phase_labels):
# phase_labels: [batch, seq_len] ∈ {0, 1, 2}
batch, seq_len, d_model = x.shape
outputs = []
for t in range(seq_len):
phase = phase_labels[:, t] # [batch]
if phase == 0: # Transition
attn_out, _ = self.transition_attn(x[:, t:t+1], x, x)
elif phase == 1: # Pause
attn_out, _ = self.pause_attn(x[:, t:t+1], x, x)
else: # Gesture
attn_out, _ = self.gesture_attn(x[:, t:t+1], x, x)
outputs.append(attn_out)
return torch.cat(outputs, dim=1)
```
#### BFRB vs 非BFRB 类别分布
**18个手势类别:**
| 类别 | BFRB类型 | 典型行为 |
|------|---------|---------|
| 0-7 | BFRB | 咬指甲、拉头发、抠皮肤等 |
| 8-17 | 非BFRB | 拍手、挥手、其他手势 |
**分布特点:**
- **训练集**:BFRB 和非BFRB 数量相近
- **个体差异**:不同 subject 的手势偏好不同
- **方向差异**:同一手势不同方向的表现不同
**处理策略:**
- **Phase-aware Mixup**:仅在 Gesture 阶段进行 mixup(2nd Place)
- **个体 normalization**:按 subject 做归一化
- **类别平衡**:确保每个类别有足够样本
#### 测试集变化
**关键发现:** 测试集约50%的序列仅有 IMU 数据
**含义:**
- 不能过度依赖 TOF 和 THM 特征
- 模型必须能够仅用 IMU 数据做出预测
- 需要训练仅用 IMU 的模型作为集成成员
**前排应对策略:**
| 排名 | 应对方法 |
|------|---------|
| **1st** | 训练IMU-only模型,集成时加权 |
| **2nd** | 4个模型:IMU-only, IMU+TOF, IMU+THM, All |
| **3rd** | TOF填0处理,但效果受限 |
| **其他** | 简单丢弃缺失传感器 |
**推荐策略:**
```python
# 训练时模拟测试集情况
def get_model_input(data):
"""
根据可用传感器选择模型输入
"""
has_tof = (data['tof'] != -1).any()
has_thm = (data['thm'] != -1).any()
if has_tof and has_thm:
return model_all(data['imu'], data['tof'], data['thm'])
elif has_tof:
return model_imu_tof(data['imu'], data['tof'])
elif has_thm:
return model_imu_thm(data['imu'], data['thm'])
else:
return model_imu(data['imu'])
```
#### 异常数据识别
**两个异常 subject:**
| Subject | 问题 | 处理策略 |
|---------|------|---------|
| **SUBJ_019262** | 数据异常,预测困难 | 训练时过滤或降权 |
| **SUBJ_045235** | 数据异常,预测困难 | 训练时过滤或降权 |
**识别方法:**
- 训练集上该 subject 的 loss 异常高
- 交叉验证该 subject 的预测准确率低
- 可视化该 subject 的传感器数据,发现异常模式
**处理代码:**
```python
# 异常 subject 黑名单
ANOMALY_SUBJECTS = ['SUBJ_019262', 'SUBJ_045235']
def filter_anomaly_subjects(dataframe):
"""
过滤异常 subject
"""
mask = ~dataframe['subject'].isin(ANOMALY_SUBJECTS)
return dataframe[mask]
```
#### 左手系 vs 右手系对齐
**发现:** 测试集存在左手和右手两种设备朝向
**问题:**
- 左手系和右手系的传感器读数方向相反
- 四元数表示旋转的方式不同
- 直接混合训练会引入噪声
**解决方案(前排通用):**
```python
def align_right_handed_system(data):
"""
左手系 → 右手系对齐
"""
# 翻转陀螺仪的 x, y 轴
data['X_gyro'] = -data['X_gyro']
data['Y_gyro'] = -data['Y_gyro']
# 调整四元数(取决于具体定义)
# 这里假设是绕 z 轴旋转 180 度
data['orientation_X'] = -data['orientation_X']
data['orientation_Y'] = -data['orientation_Y']
return data
```
### 数据质量评估框架
基于前排方案,建立数据质量评估维度:
| 维度 | 评估方法 | 低质量指标 | 处理策略 |
|------|---------|-----------|---------|
| **传感器缺失** | 统计-1值比例 | TOF>50%, THM>5% | mask处理或训练IMU-only模型 |
| **异常subject** | 按subject统计loss | loss > threshold | 过滤SUBJ_019262, SUBJ_045235 |
| **设备朝向** | 检测左右手系 | 四元数和陀螺仪方向 | 统一到右手系 |
| **三阶段一致性** | 检测阶段标签 | 阶段跳变 | 利用三阶段结构特征 |
### 关键数据洞察总结
1. **多模态融合是关键**:IMU + THM + TOF,但测试集仅50%有完整数据
2. **TOF 缺失严重(60%)**:需要创新处理(2×2 pooling + mask)
3. **个体约束必须利用**:subject × gesture × orientation 唯一约束可用匈牙利算法
4. **三阶段结构重要**:Transition/Pause/Gesture,阶段感知建模有效
5. **四元数不连续性**:需转换为6D连续表示(旋转矩阵前两列)
6. **测试集只有IMU数据**:必须训练IMU-only模型作为集成成员
7. **异常数据需处理**:SUBJ_019262和SUBJ_045235应该过滤或降权
8. **左手系右手系对齐**:统一到右手系避免噪声
### 多模态时间序列分类的最佳实践
与单模态分类任务不同,多模态任务的特殊考虑:
| 方面 | 单模态任务 | 多模态任务 |
|------|-----------|-----------|
| **特征提取** | 单一特征工程 | 每个模态独立提取后融合 |
| **模型架构** | 单一编码器 | 多编码器或早期融合 |
| **缺失处理** | 插值或丢弃 | mask处理或模态specific模型 |
| **数据增强** | 简单增强 | 模态感知增强(Phase-aware Mixup) |
| **后处理** | 阈值或NMS | 利用约束(匈牙利算法) |
|