返回列表

27th solution

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

开始: 2023-09-05 结束: 2023-12-05 健康管理与公共卫生 数据算法赛
第27名解决方案

第27名解决方案

作者: tenten (MASTER)

发布时间: 2023年12月6日

最后更新: 2023年12月20日

排名: 第27名

我基于@tubotubo的源代码实现了这个解决方案。感谢分享!

输入特征

  • anglez(归一化)
  • enmo(归一化)
  • hour_sin
  • hour_cos
  • minute_sin
  • minute_cos

模型结构

损失函数

  • 清醒状态 (awake):
    • 二元交叉熵损失 (BCEWithLogitsLoss)
  • 入睡时刻 (onset) 和醒来时刻 (wakeup):
    • 二元交叉熵损失 (BCEWithLogitsLoss)
  • 总损失: 总损失 = (清醒损失) × 0.12 + (入睡/醒来损失) × 0.88

数据增强

  • 高斯噪声:
    • 最小幅度: 0.01
    • 最大幅度: 0.1
  • Zebra Mixup

编码器结构对比

特征提取器 解码器 下采样率 CV分数
LSTM UNet1D 2 0.7611
CNN UNet1D 2 0.7628
频谱图 UNet1D 2 0.7463
CNN Transformer 6 0.7480
频谱图 Transformer 6 0.7725
2CNN+时间特征嵌入 UNet1D 2 0.7705

2CNN+时间特征嵌入模型

  • anglez 和 enmo 分别输入到独立的 CNN 特征提取器
  • 月份、小时和分钟作为分类变量输入
  • 时间特征通过嵌入层转换为向量,与编码器输出拼接后输入解码器
month = self.month_embedding(month) # (batch_size, 4, n_timesteps)
hour = self.hour_embedding(hour) # (batch_size, 8, n_timesteps)
minute = self.minute_embedding(minute) # (batch_size, 16, n_timesteps)
x = x[:, 3:, :] # (batch_size, n_channels, n_timesteps)
x1 = self.feature_extractor1(x[:, :x.shape[1]//2, :])  # (batch_size, n_kernel, height, n_timesteps)
x2 = self.feature_extractor2(x[:, x.shape[1]//2:, :])  # (batch_size, n_kernel, height, n_timesteps)
x = torch.cat([x1, x2], dim=2) # (batch_size, n_kernel, height*2, n_timesteps)

x = self.encoder(x).squeeze(1)  # (batch_size, height, n_timesteps)
x = torch.cat([x, month, hour, minute], dim=1) # (batch_size, height+28, n_timesteps)
logits = self.decoder(x)  # (batch_size, n_timesteps, n_classes)

后处理

  • 使用 scipy.signal 的 find_peaks 函数检测峰值(集成后执行)
    • 峰值高度阈值设为最小值 0.003
    • 峰值间距通过 Optuna 优化
  • 重叠推理策略

模型集成

  • 集成方案: 4折交叉验证 × 6个模型
  • 集成方法: 加权输出热图集成
    • 权重通过 Optuna 优化
    • 简单平均集成 CV 分数: 0.795
    • 加权平均集成 CV 分数: 0.7981
      • 公开榜分数: 0.753
      • 私有榜分数: 0.809
同比赛其他方案