返回列表

4th Place Solution - XGB + NN Ensemble

680. MABe Challenge - Social Action Recognition in Mice | MABe-mouse-behavior-detection

开始: 2025-09-18 结束: 2025-12-15 智慧养殖 数据算法赛
第四名解决方案 - XGB + 神经网络集成

第四名解决方案 - XGB + 神经网络集成

作者:Eduardo Rocha de Andrade (arc144), matheus (tomirol), Ahmet Erdem (aerdem4)

排名:第 4 名

发布时间:2025 年 12 月 16 日

首先感谢主办方和 Kaggle 举办这次比赛!此外,还要特别感谢 @tomirol@aerdem4 在本次挑战中的合作与努力!

简要总结 (TLDR)

我们的解决方案基于针对每个实验室训练的不同设置和参数的神经网络 (NN) 和 XGB 模型。对于大多数实验室,我们 simply 选择该实验室交叉验证 (CV) 分数最高的模型,除了 "LyricalHare"、"InvincibleJellyfish" 和 "ElegantMink",我们在这些实验室上执行逐帧多数投票。

我们模型的每个实验室 CV 分数如下:

模型每个实验室 CV 分数

XGB 流程

我们的代码最初 fork 自 @ravaghi 的优秀的 公开 Notebook,这已经是一个相当强的基线。
下面我们要列出我们解决方案的主要点以及与原始 Notebook 的不同之处:

  • 我们将所有视频的 FPS 标准化为 30fps,并使用众数 (mode) 来获取窗口中的标签。
  • 我们标准化所有传感器,仅使用 nose, ear_left, ear_right, body_centertail_base
    • 对于没有 body_center 的实验室,我们可以从 hip_left + hip_rightlateral_left + lateral_right 推导出来。作为最后的手段(仅 2 个实验室),我们从 tail_base + ears_l+r 插值得到。
    • 对于没有 nose 的实验室,我们简单地用 head 替换。
  • 我们分别为单鼠和双鼠设置训练独立的模型。
  • 我们为每个 lab_idaction 训练 3 组 4 个模型(4 折 CV,按视频分组并按动作标签分层),即每个动作一个二分类器。
    • 我们为每个模型组更改模型初始化和 KFold 种子,最后平均概率以获得动作的预测。
    • 我们通过优化该实验室袋外 (OOF) 预测的 F1 分数来计算单个 action 阈值。
    • 我们首先计算预测与其阈值之间的残差,将单个动作预测组合成多类,即 residual_action_i = pred_action_i - threshold_action_i,然后在所有 residual_action_i 中取 argmax。最后,对于最高残差,我们只需检查 residual_action_i > 0 以在 action_i 和无动作之间进行选择。
    • 由于我们为每个动作训练二元模型,我们简单地忽略所问动作标签为 NaN 的任何帧。
  • 对于 "CautiousGiraffe", "DeliriousFly", "GroovyShrew" 和 "TranquilPanther",我们通过跨帧时间插值 (group["x"] = group["x"].interpolate(method="linear", limit_direction="both")) 预处理关键点,以减少输入中大量的 NaN。
    • 这种预处理显著改善了上述实验室,但对其他实验室没有改善,我们怀疑这可能是由于跟踪系统中大量的 ID 切换(这使得插值结果很糟糕)。
    • 应用插值时,我们还为每个关键点添加二元特征,标记该值是否是插值的。

单鼠特征

对于单鼠模型,我们进行的特征工程侧重于以下主题:

  • 传感器关键点之间的成对距离
  • 耳朵和尾巴的速度
  • 伸长与紧凑度特征
  • 身体角度特征
  • 身体中心位移特征
  • 不同窗口内的身体中心加速度和加加速度 (jerk) 特征
  • 角速度和转向率
  • 梳理毛发特定特征
  • 老鼠元数据,例如性别、颜色、是否有设备等。
  • 竞技场边界特征,例如老鼠离中心或竞技场边缘有多近

双鼠特征

对于一对老鼠,我们 simply 尝试创建能够捕捉老鼠之间关系的特征:

  • 与上述类似的自鼠特征
  • 传感器关键点之间的跨鼠成对距离
  • 老鼠之间的相对速度
  • 相对加速度和加加速度
  • 相对方向
  • 异体理毛 (Allogroom) 特定特征
  • 配对元数据特征,例如 is_same_sex, is_same_color 等。

时间特征

虽然我们的特征工程管道的一部分已经捕捉到了不同窗口的一些特征,但我们发现简单地“借用”邻近帧的特征也非常有益。我们通过两种不同的方式做到了这一点:“简单复制”和“窗口统计”。

简单复制

我们尝试的第一件事是 simply 使用滑动窗口复制 frame_i 周围帧的特征。例如,我们应用 window=4stride=5,意味着对于 frame_i,我们将拼接来自帧 [frame_i-20, frame_i-15, frame_i-10, frame_i-5, frame_i, frame_i+5, frame_i+10, frame_i+15, frame_i+20] 的特征。

当然,这种方法导致特征数量急剧增加,但我们发现 XGB 对高维性非常 robust。我们在带有分数的图片中将使用这种“简单复制”方法训练的模型称为 "Matheus XGB"。

窗口统计

我们尝试的第二种时间特征选项是计算每个窗口的统计信息,而不是原样复制帧特征。我们使用 median, min, maxstd 作为每个窗口的聚合器。此模型使用 window=2stride=15,在图片中表示为 "Edu XGB"。

神经网络 (NN) 流程

与我们的 XGB 流程类似,我们通过以下方式标准化传感器关键点:

  • lateral_left -> hip_left
  • lateral_right -> hip_right
  • head -> nose
  • 移除 headpiecespine

对于每 24 帧,我们计算以下特征并将其作为主要输入提供给模型:

  • 身体部位可用性均值、最大值
  • X 轴均值、标准差
  • Y 轴均值、标准差
  • 插值缺失的 x, y 但保留可用性(非缺失)信息
  • 到竞技场边缘的最小距离作为第 7 个特征

在初始特征提取骨干网络之后,我们将额外特征后期注入到模型中:

  • 老鼠到老鼠身体部位的距离
  • 速度本身以及速度和 heading 向量相似度
  • 行为标签数组

关于我们的架构,我们选择了以下设计选择:

  • GroupNorms 后具有残差连接的不同膨胀率的卷积
  • 输入上的 InstanceNorm3d
  • ELU 激活函数
  • 大型平均池化和最大池化窗口馈送到最后一层
  • 对于部分层,对所有老鼠对(包括自身)取 softmax

对于我们的训练,主要考虑因素如下:

  • 数据表示为形状 (batch_size, features, n_mice, n_mice, seq_len) 的张量
  • BCEWithLogitsLoss 用作掩码目标的损失函数(不对 NaN 目标进行反向传播)
  • 损失由 sqrt(binary_label_mean) 加权以平衡稀有类别
  • 门控最大分类 (Gated max classification)
    • 我们允许模型在其分类或最大分类之间进行选择。这对于老鼠混合的情况非常有用。
  • 我们开始在所有实验室一起训练,然后为每个实验室微调
  • 作为后处理,我们将一些稀有/较难动作的 logits 乘以 1.5 以提高 F1,然后再应用 argmax

模型集成

对于我们的最终解决方案,我们 simply 为每个实验室选择了 CV 最高的模型(参见图片参考)。
唯一的例外是 "LyricalHare", "InvincibleJellyfish" 和 "ElegantMink",我们发现对所有 3 个模型执行多数投票是有益的。

同比赛其他方案