665. CMI - Detect Behavior with Sensor Data | cmi-detect-behavior-with-sensor-data
副标题:以下是我如何使用视觉 Transformer 在仅 IMU 模型和全模型上均实现高精度的方法。
我的解决方案的关键区别在于利用计算机视觉来训练序列模型。
我发现有四个关键因素会显著影响最终结果:
我使用计算机视觉模型是因为其训练速度快且收敛快(22 个轮次,每个轮次约 40 秒)。使用 1DCNN + GRU 的 pipeline 仅用于仅 IMU 模型(需要 120 个轮次收敛,每个轮次约 110 秒)。我选择的计算机视觉模型是 Dino patch 8。为什么选 Dino?因为在视觉 Transformer 模型中,Dino 提供更快的收敛速度和更好的最终结果(可能得益于良好的预训练)。为什么选 patch 8?因为 TOF 特征组织在 8x8 矩阵中。我试过 Dinov2 patch 14,但结果不如 Dino patch 8(分数差异约 1%)。在 Dino 家族(Dino, Dinov2, Dinov3)中,只有两个模型满足 patch 8 条件:ViT-S/8 和 xcit_small_12_p8。其中,xcit small 的表现显著优于 ViT small,但 ViT small 的训练速度快 1.5 倍。
CV: 0.825
| 模型 | CV |
|---|---|
| xcit_small without softlabel | 0.875 |
| xcit_small with softlabel | 0.895 |
我使用 CutMix, MixUp 和 RandomErasing。MixUp 和 CutMix 对提高 CV 贡献显著。
填充方法:
我发现手势表现段仅落在最后 5 秒(约 50 帧)。然而,当我将其裁剪到最后 64 帧以使模型专注于手势段时,准确率下降了。这表明过渡段似乎也在为模型提供额外的有用信息。
此外,在填充时,我本打算通过在序列开头插入零来保持帧之间的时间间隔。然而,该方法似乎无效。最终,我通过复制元素来填充该元素周围的 gaps。
纠正错误的受试者:
感谢这两个 notebook 的作者,我使用了他们的特征。
特征集:
['acc_mag', 'acc_mag_jerk', 'rot_angle', 'rot_angle_vel', 'linear_acc_mag', 'linear_acc_mag_jerk', 'angular_vel_x', 'angular_vel_y', 'angular_vel_z', 'angular_vel_mag', 'angular_vel_mag_jerk', 'angular_distance', 'roll', 'pitch', 'yaw']
为了避免序列中两个元素之间出现 NaN 元素,我实现了 safe_diff_fillna_zero 函数并修正了公共 notebook 中的特征计算方法。
我使用卡尔曼滤波来平滑序列并消除异常值,但分数提升不显著。
输出形状:(1, 24, 192)
归一化:未使用
输出形状:(192, 17)
归一化:未使用
输出形状:(192, 17)
归一化:未使用
输出形状:(1, 352, 192)
归一化:IMU 未使用。THM + TOF 使用
这里的特殊之处在于我将特征维度视为模型的高度 (h),将序列长度 (seq len) 视为模型的宽度 (w)。当模型移动 patch 窗口时,它沿时间维度滑动。如果反过来,模型的准确率会显著下降。
我使用 StratifiedGroupKFold 拆分数据(按受试者分组,按 gesture_handedness_height_cm_bin 分层)。
我使用最后一个轮次,正如 @theoviel 建议的那样:讨论链接
训练 k-fold 模型后,我使用 k 个模型预测 OOF(折外)结果。然后,我将预测概率与真实标签以 3:7 的比例组合以获得软标签。使用这些软标签进行训练使 CV 分数提高了 2.x%。
我一次使用一个模型进行集成技术。由于我做了改进但没有时间重新训练旧模型,旧模型的 CV 分数低于新模型。
结果:Public=0.874. Private=0.849