第一名解决方案
第一名解决方案
作者: Ogurtsov (及团队成员 yuanzhe zhou, Devin Anzelmo)
发布时间: 2025-09-03
竞赛排名: 第 1 名
解决方案撰写
祝贺所有获奖者,并非常感谢组织者举办了如此具有挑战性和 rewarding 的比赛。
特别感谢我的队友 yuanzhe zhou 和 Devin Anzelmo 的出色合作和团队精神。
解决方案概述
- 针对仅 IMU 样本和全特征样本的大型集成模型,组装为 logits 的加权和
- 后处理以考虑每个类别和每个受试者每个方向的样本数量有限(已在 此处 描述)
- 用于方向预测的额外模型
Devin 的部分
1. 预处理/特征工程:
- 从训练和验证集中移除佩戴设备不正确的受试者
- 对于 TOF,通过取九个 2x2 方块并计算每个方块的平均值进行子采样(首先将 -1 转为 null)
- 某些模型使用上述 TOF 特征和热成像的时间差分进行训练
- IMU:原始 7 个特征 +
acc 的时间差分, notebooks 中发布的旋转差分,以及 acc/rot 的幅值;共 16 个
- 预处理左手习惯数据以匹配右手习惯数据(针对 IMU 和 THM/TOF)。翻转
acc_x,将 rot 转换为 xyz 欧拉角并翻转 y 和 z 的符号
- 鲁棒缩放器 (robust scaler)
2. 数据增强:
3. 模型:
- CNN GRU,针对不同特征使用不同的主干。特征提取器是四个没有池化的 CNN 分支
- 纯 CNN。与上述相同的特征提取器,但在末尾有三个残差块,使用扩展核 (5, 9, 13)
- dense GRU,得分较低但在集成中有一点帮助
- 一些自激励模型,有些不结合使用有帮助
- 用于 TOF 数据的 3D CNN 得分约为 0.83,但融合效果好
4. 训练:
- 批量大小 64
- 训练 60-80 次迭代(取决于模型),使用 AdamW
lr = 0.0005
5. 集成:
- 混合 IMU 模型与全特征模型
- 混合仅 TOF 模型可提高全数据得分
Ogurtsov 的部分
1. 数据过滤:
- [所有模型] 移除没有手势的序列 SEQ_011975
- [所有模型] 移除手势/总比例 < 0.2 的序列(此子集包含几乎所有最短序列)
- [带有 THM 和 TOF 数据的模型] 移除 TOF 完全缺失的序列(TOF 中的缺失值模式 - 0%, 20% 或 100%;20% 缺失是可以的)
- 少数模型训练时没有包含“有问题”的受试者 SUBJ_045235 和 SUBJ_019262
2. 预处理:
- 填充四元数缺失值(如果可能)
- 镜像左手习惯受试者的数据
- 将 -1 的 TOF 值替换为 500,因为 -1 编码大距离
- 最终使用
seq.ffill().bfill().fillna(0) 填充 NaN
- 在每个折中按 94 百分位数填充/裁剪(~120 最大序列长度)
- 无缩放器 - 这在早期阶段带来了最大的改进
3. 特征工程:
- THM 和 TOF 无额外特征
- 35 个 IMU 特征:
['acc_x', 'acc_y', 'acc_z', 'acc_mag', 'acc_mag_jerk', 'jerk_x', 'jerk_y', 'jerk_z', 'jerk_magnitude', 'acc_xy_corr', 'acc_xz_corr', 'acc_yz_corr',
'rot_w', 'rot_x', 'rot_y', 'rot_z', 'rot_angle', 'rot_angle_vel', 'angular_vel_x', 'angular_vel_y', 'angular_vel_z', 'angular_vel_magnitude', 'angular_distance',
'acc_x2', 'acc_y2', 'acc_z2', 'acc_mag2', 'acc_mag_jerk2', 'jerk_x2', 'jerk_y2', 'jerk_z2', 'jerk_magnitude2', 'acc_xy_corr2', 'acc_xz_corr2', 'acc_yz_corr2']
acc_x2 和其他 ***2 特征是解决方案的重要组成部分。
这些特征是在通过 remove_gravity_from_acc() 转换后的值上计算的。
4. 模型:
- 一堆用于仅 IMU 数据训练的不同架构模型,以及用于全特征训练的类似模型
- 时间维度处理的主要区别:基于 LSTM、注意力机制或 CNN
- 关键部分 - 在第一层独立处理特征组
5. 数据增强:
transforms = Compose([
TimeShift(p = 0.35, padding_mode = "zero", max_shift_pct = 0.25),
TimeStretch(p = 0.35, max_rate = 1.5, min_rate = 0.5),
])
带有一些变体。
很难选择合适的增强方式及其概率和强度,并按正确的顺序应用。
6. 训练:
- CV5,按受试者分组的 K 折,推理时使用 5 个模型
- 200 或 220 个 epoch,耐心值 30 或 35
torch.optim.Adam,lr = 4e-4 或 lr = 5e-4,weight_decay = 3e-4
CosineAnnealingWarmRestarts;基于注意力的模型使用 LinearLR + CosineAnnealingWarmRestarts
- 一个模型使用 focal loss 和类别权重训练(类别权重对 mixup 样本显然没有意义,也许可以作为正则化)
- 一个模型在交叉注意力中包含 bug(3 个不同的注意力共享权重),但效果相当好
7. 一些技巧:
- 在 3 次运行中为每个折选择最佳结果
- 推理时将序列长度增加 5(这不会提高 CV 分数,但有效地使模型去相关)
zyz 的部分
- 1.1. 使用来自 CMI3 Pyroch Baseline+model_add, Aug, folds 的流水线结构
- 1.2. 修复许多 bug 后将我的分数提高到了 0.85。
- 模型:RNN 和 CNN1D 的简单组合。
- 使用 pytorch 进行特征工程,这避免了一致性问题但使训练变慢。
- 大多数团队提到的基本预处理:填充 NaN、 handedness 等。
- 基于数据结构的后处理。
- 来自队友的增强想法:
- 6.1. 训练期间掩码数据有帮助。