665. CMI - Detect Behavior with Sensor Data | cmi-detect-behavior-with-sensor-data
恭喜获奖者,并感谢组织者准备了如此精彩的比赛。我非常感激能参加这次竞赛,在这里人们可以互相学习,分享想法和资源。有些 Notebook 非常有指导意义。其他的比如许多巨大的洗牌集成模型就没那么有用了,哈哈。
这是我的第二次 Kaggle 竞赛——我还是个初学者。我很高兴获得了第 35 名,虽然我对许多错过的地方感到有点沮丧。我也很高兴能在这个暑假期间学到这么多,尽管我本希望能投入更多的时间,以及更多的计算资源到这次比赛中。
我训练了两个模型,一个仅使用 IMU 数据,另一个使用所有数据(IMU+TOF+THM)。手势被用作标签,我没有做手势 + 方向标签,我不知道为什么,我就是没去看方向标签 :(
原始四元数数据首先通过球面线性插值 (Slerp) 插值缺失值进行清洗,然后修复符号翻转以确保时间连续性。TOF 中的 -1 被填充为 300,因为 -1 意味着太远,信号没有返回。
我从这个模型 https://www.kaggle.com/code/jiazhuang/cmi-imu-only-lstm 获取了 IMU 特征,我只在那组特征中添加了四元数差分特征。
左右手归一化: acc_x, rot_y, 和 rot_z 必须乘以 -1 进行翻转。对于 TOF 和 THM,传感器 3 和 5 被交换,并垂直翻转。传感器 1,2,4 只是水平翻转。我认为这是对传感器数据应用的正确物理变换,我通过查看数据进行了检查,看起来也是正确的变换。
特定受试者校正: 'SUBJ_045235', 'SUBJ_019262' 这两个受试者将设备戴反了,所以我曾考虑移除他们,但最终决定进行正确的变换,并将 TOF 1 传感器设置为 Nan,因为向上看无法变换为向下看,但对于其他传感器——acc x, acc y, rot x 和 rot y 都乘以 -1 翻转,就像左右手传感器一样 (THM/TOF) 3 和 5 被交换,并且所有 (2,3,4,5) 传感器旋转了 180 度,这等同于垂直和水平翻转。这也似乎是正确的物理变换,数据也吻合,所以我没有移除这些受试者。
具有 'bad' 相位列值的序列被手动修正。
对于 TOF/THM:我使用了一个 2D CNN 从 8x8 TOF 图像中提取模式,然后与每个对应传感器的 TOF 和 THM 的均值、标准差、最大值和最小值连接,例如 TOF i 与 THM i。
注意:全数据模型是建立在已经不错的 IMU 模型之上的,不是从头开始,所以很多东西是相似的。
两个模型都首先通过多分支 1D CNN 处理 IMU 数据:
self.feature_groups = {
'raw_acc': ['acc_x', 'acc_y', 'acc_z'],
'raw_rot': ['rot_w', 'rot_x', 'rot_y', 'rot_z'],
'linear_acc': ['linear_acc_x', 'linear_acc_y', 'linear_acc_z', 'linear_acc_mag'],
'angular_vel': ['angular_vel_x', 'angular_vel_y', 'angular_vel_z'],
'derivatives': ['acc_mag', 'rot_angle', 'acc_mag_jerk', 'rot_angle_vel',
'linear_acc_mag_jerk', 'angular_distance'],
'rot_diff': ['q_diff_w', 'q_diff_x', 'q_diff_y', 'q_diff_z']
}
对于全数据模型,使用 Performer 在每个时间步融合来自 5 个 TOF 和 THM 传感器的数据。这个分支试图模拟不同传感器之间的空间关系。
来自 IMU 仅模型的 CNN,以及来自全数据模型 Performer 的输出,被输入到两个并行的 GRU 中,一个是过渡 GRU,一个是手势 GRU,基于训练数据的 'phase' 列,使用辅助损失进行相位预测并在推理期间使用。
来自两个 GRU 的最终隐藏状态使用基于 MLP 的注意力、最大池化和平均池化进行聚合,以获得用于分类头的最终向量。
数据增强: 对于仅 IMU 模型,使用了 Mixup, 时间缩放,时间扭曲,时间平移(我忘了尝试缩放!)。参考代码:https://www.kaggle.com/code/alejopaullier/cmi-sequence-data-augmentation。对于全数据模型,只有抖动/高斯噪声有效,尽管我没有为 TOF 和 THM 尝试太多增强。
标准交叉熵损失,基于受试者分层的组 K 折交叉验证,我做了 10 个分割而不是 5 个,种子之间的方差更小,所以测试可能更准确一些,不过话说回来,我应该让模型更轻量级直到比赛后期,以便能运行更多测试。EMA 也有帮助。
我看到很多人做了超过 200 个 epoch,我不确定我是否做错了,但我只是使用了默认未调优的训练和在这个 Notebook https://www.kaggle.com/code/jiazhuang/cmi-imu-only-lstm 中看到的所有参数,所以我只有 20 的耐心值,训练了 50 个 epoch,学习率 0.001,我不是很清楚如何直观地改进超参数而不只是某种暴力调优。
我只是做了折叠模型的 Logits 平均。抖动 TTA 将 LB 提高了 0.001,但太少了,所以我没有包含它。
仅 IMU CV 0.842。全数据 10 折 CV 0.898。平均 CV 为 0.870,这与公共 LB 0.870 相当吻合。可惜私有 LB 较低,为 0.845,尽管我看到每个人的 LB 都至少下降了一点,我可能在验证集上过拟合了。
感谢阅读 :)