返回列表

41st Place Solution for the Child Mind Institute - Detect Sleep States Competition

586. Child Mind Institute - Detect Sleep States | child-mind-institute-detect-sleep-states

开始: 2023-09-05 结束: 2023-12-05 健康管理与公共卫生 数据算法赛
儿童思维研究所睡眠状态检测竞赛第41名解决方案

儿童思维研究所睡眠状态检测竞赛第41名解决方案

作者:YuYagi、Koba、Daikon99
竞赛排名:第41名
发布时间:2023年12月13日

首先,衷心感谢儿童思维研究所睡眠状态检测竞赛的组织者。本次竞赛提供了处理长一维序列的宝贵机会,在数据科学的重要领域带来了独特而富有教育意义的体验。

推理管道概述

我们的训练流程和模型基于@213tubo的优秀代码,可通过此页面访问。

我们的解决方案如下:

  • 数据分段:
    • 使用重叠时间窗口对输入特征进行分段推理
  • 模型:
    • 使用10个基于Unet的模型,每个模型在五个独特模型中的两个不同训练验证分割上进行训练
    • 5个模型分别采用不同的骨干网络
  • 单模型后处理:
    • 应用非极大值抑制(NMS)保留检测峰值在指定范围内的最高分预测
  • 预测集成:
    • 采用受加权框融合(WBF)启发的原创集成方法
    • 第一阶段集成同一折内的模型
    • 第二阶段合并不同折的结果
  • 集成结果后处理:
    • 移除周期性填充区间的冗余预测

提交详情

使用的模型:

我们训练了基于Unet的模型,采用五种不同的CNN骨干网络:ResNet101、MiT-B3、MiT-B5、ResNeXt101和ResNet152。模型使用两种不同的训练验证数据组合进行训练,每次分配约20%的训练集作为验证数据。

在每次模型训练中,我们改变种子值以增加多样性,从而提高交叉验证结果的可靠性并丰富提交集成。

推理数据分段:

对于输入数据分段,我们使用特定窗口大小,并将步长设为窗口大小的一半,创建重叠段进行推理。该方法有效利用了每个窗口的中心部分,减少了边缘段的误检测。

集成方法:

我们使用受加权框融合(WBF)启发的原创集成方法,算法步骤包括:

  • 按series_id和event对输入数据框分组,将每个事件按分数降序排序
  • 从不同数据框中提取指定范围内的其他事件
  • 计算加权步长为∑(步长×分数),新分数为分数/(数据框数量)
  • 移除指定范围内但分数较低的事件

核心代码:

def ensemble_predictions(df_list: list, series_ids: list, step_threshold: int=50) -> pd.DataFrame:
    grouped_list = [df.groupby(['event', 'series_id']) for df in df_list]
    events = ["onset", "wakeup"]
    ensemble_predictions = []
    
    for series_id in series_ids:
        for event in events:
            sorted_group_list = []
            for grouped in grouped_list:
                if (event, series_id) in grouped.groups:
                    sorted_group_list.append(
                        grouped.get_group((event, series_id)).sort_values(by='score', ascending=False)
                    )

            while any([not sorted_group.empty for sorted_group in sorted_group_list]):
                specific_index = next(
                    (index for index, sorted_group in enumerate(sorted_group_list) if not sorted_group.empty), None
                )
                highest = sorted_group_list[specific_index].iloc[0]
                ensemble_steps = [highest["step"]]
                ensemble_probas = [highest["score"]]
                probas_sum = highest["score"]
                highest_step = highest['step']

                for i, sorted_group in enumerate(sorted_group_list):
                    compared_prediction = sorted_group[
                        sorted_group['step'].sub(highest_step).abs() <= step_threshold
                    ]
                    condition = sorted_group['step'].sub(highest_step).abs() > step_threshold
                    filtered_group = sorted_group[condition]
                    sorted_group_list[i] = filtered_group
                    
                    if i != specific_index:
                        if not compared_prediction["score"].empty:
                            first_score = compared_prediction["score"].iloc[0]
                            first_step = compared_prediction["step"].iloc[0]
                        else:
                            first_score = 0 
                            first_step = 0
                        ensemble_steps.append(first_step)
                        ensemble_probas.append(first_score)
                        probas_sum += first_score

                ensemble_step = 0
                if probas_sum != 0:
                    for s, p in zip(ensemble_steps, ensemble_probas):
                        ensemble_step += s * (p / probas_sum)

                ensemble_predictions.append({
                    "series_id": series_id, 
                    "step": int(ensemble_step), 
                    "event": event, 
                    "score": probas_sum / len(grouped_list)
                })

    ensemble_df = pd.DataFrame(ensemble_predictions)
    ensemble_df['row_id'] = ensemble_df.index
    return ensemble_df

后处理:

对单模型和集成结果均实施了后处理步骤:

  • 单模型处理:
  • 集成模型处理:
    • 移除周期性填充区间冗余预测的方法参考了此 notebook

消融实验

详细分数如下表所示:

编号 描述 CV (Fold1) Public LB Private LB
(1) ResNet101 (无重叠) 0.756 0.722 0.748
(2) ResNet101 (重叠) 0.77 0.732 0.778
(3) ResNet101 (重叠) + NMS 0.773 未提交 未提交
(4) 5模型集成 (重叠, 同折) + NMS 0.7844 0.753 0.790
(5) 5模型集成 (重叠, 同折) + NMS + 移除填充区间预测 0.7847 0.756 0.801
(6) 5模型集成 (重叠) 跨2折 + NMS - 0.749 0.792
(7) 5模型集成 (重叠) 跨2折 + NMS + 移除填充区间预测 - 0.753 0.802
同比赛其他方案