返回列表

7th place solution

617. LEAP - Atmospheric Physics using AI (ClimSim) | leap-atmospheric-physics-ai-climsim

开始: 2024-04-18 结束: 2024-07-15 气象预报 数据算法赛
第 7 名解决方案 - LEAP 大气物理 AI 竞赛

标题:第 7 名解决方案

作者:Ryota (Grandmaster)

团队成员:@nomorevotch, @masatomatsui, @rheinmetall

发布时间:2024 年 8 月 4 日

竞赛排名:第 7 名

最终得分:公共榜 0.78560 / 私有榜 0.79080

首先,我要感谢主办方 @jerrylin96 和 Kaggle 工作人员组织了这场有趣的比赛。这是一场激烈的比赛,存在数据泄露的问题,但比赛任务非常有趣,是一次很棒的学习经历。我还要感谢社区在讨论区分享了这么多内容,包括泄露的发现。感谢我的团队成员 @nomorevotch, @masatomatsui, @rheinmetall,我从你们身上学到了很多。

[总结]

  • 我们使用了多种模型,包括 LSTM、Transformer、Conv1D 和 Squeezeformer。LSTM 和 Squeezeformer 表现特别强。
  • 基于领域知识的额外特征有助于提高准确率。
  • 使用 MAE 或 SmoothL1Loss 训练,随后使用 MSE 进行额外训练,提高了准确率。
  • 对于集成,我们使用了通过 Nelder-Mead 方法优化权重的加权平均。(公共榜:0.78560 / 私有榜:0.79080)
  • 在集成中,关键是要包含少数几个强大的单一模型,而不是许多模型。
  • 重要的是通过在最后一周之前不使用 HF 的完整数据来加快实验速度。

[Ryota 的部分]

数据准备

  • 使用 HF 上的完整低分辨率数据集
  • 我们从 [0008-02, 0009-01] 期间以 1/7 的比例采样数据,类似于竞赛数据,仅使用 625,000 个样本进行验证。
  • 使用 StandardScaler 对输入和目标进行缩放。
  • 额外特征
    • 沿垂直轴取差值计算的 Diff 特征
    • 取上述 diff 特征的差值计算的 Diff 特征
    • 相对湿度比
    • 气压差
    • 水汽压
    • 冰率
    • (lat, lon)
      • 由于担心这可能被视为泄露,我最终没有使用它,但它带来了轻微的提升 (~0.0002)
  • 尝试了以下沿垂直轴计算的额外特征,但无效
    • 移动统计量(均值、标准差、最大值、最小值、中位数)
    • 滞后特征 (Lag features)

模型

模型类型 交叉验证 (CV) 公共榜 私有榜
Transformer + LSTM 0.78734 0.78567 0.78058
LSTM 0.78794 0.78682 0.78120
Conv1D 0.78635 0.78301 0.77506
模型架构图
  • 输入 / 输出
    • 在序列方向重复 scaler 特征,形状为 (batch, 60, 25)
    • 输出形状为 (batch, 60, 14)
      • Scaler 特征在整个序列上取平均
  • 获取 diff 特征
    • 在 forward 方法中计算上述 diff 特征
    • 形状为 (batch, 60, 86)
  • 卷积特征提取器
    • 使用 2 层卷积,前后带有 Linear 层
  • 位置嵌入 (Positional Embedding)
    • 与正弦位置编码相同,但用作可学习参数
  • Transformer 编码器
    • PyTorch 的 Transformer Encoder
  • Bi-LSTM 块
    • 每个 LSTM 层后跟一个 Linear 层,每层应用 skip_connections,类似于 Transformer 块
  • ResNet 块
    • 类似于 ResNet,每个块包含两个卷积层,并带有到输入的 skip connection
    • 在 Conv1D 的后 7 个块中,使用了类似 Inception 的结构,应用瓶颈结构和多个具有不同内核大小 (1, 3, 5, 7) 的并行卷积层。
    • 使用 SE-Block
  • 头部 (Head)
    • 2 层 Linear
  • 激活函数
    • Conv1D 使用 ELU
    • Transformer 和 LSTM 使用 GELU
    • Head 使用 ReLU
  • 归一化
    • Conv1D 使用批归一化 (Batch Normalization)
    • Transformer 和 LSTM 使用层归一化 (Layer Normalization)
  • 无 Dropout

损失函数

  • MAE
    • MAE 的表现优于 HuberLoss 或 MSELoss。
  • 掩蔽权重为 0 或包含在 ptend_q0002_[12, 26] 中的目标列
  • 通过 MSE 微调
    • 这个技巧 consistently 带来了约 0.002 的提升

训练

  • epoch
    • MAE : 13 epochs
    • MSE(微调) : 5 epochs
  • 优化器
    • AdamW
      • lr=[5e-4, 5e-6]
      • weight_decay=0.01
  • 调度器
    • 带热身的余弦调度 (Cosine schedule with warmup)

后处理

  • 对 ptend_q0002_[12, 26] 应用了此处描述的后处理
  • 作为额外的后处理,在从预测值计算 next_state_[q0002, q0003]_[all_levels] 后,如果值低于阈值,则应用上述后处理。
    • 当仅使用竞赛数据时,这带来了约 0.001 的提升,但在使用所有低分辨率数据后提升微不足道。

源代码

[sqrt4kaido 的部分]

概述

概述图

验证

从低分辨率数据中,我提取了 625,000 行来自相对于 Kaggle 数据的未来时期(2008 年 2 月至 2009 年 1 月)的数据,并将其用于验证。

特征工程

对于具有序列的特征,我们使用了以下内容:

"state_t",
"state_q0001",
"state_q0002",
"state_q0003",
"state_u",
"state_v",

对于非序列特征,我们使用了所有特征。
除了数据之外,还计算了以下内容:

  • dp: 气压差
  • RH: 相对湿度
  • vp: 水汽压
  • state_ice_rate: 云水含量中冰的比例 (水 + 冰)
  • ice_rate_diff: 从温度 derived 的冰率与 state_ice_rate 之间的差值

添加上述特征后,应用标准缩放器 (standard scaler)。对于 std 使用 max(1e-6, std)。
然后,应用以下过程:

  • 序列特征
    shaping 为 (60, num_feature) 形式。添加 Diff 和 diff 的 diff 特征(负方向和正方向)。

  • 非序列特征
    重复 60 次以匹配序列特征。

最后,我们使用了 11*5 个序列特征和 16 个非序列特征。

模型

我使用了 1D 序列模型。

使用 SmoothL1Loss 作为损失函数。仅针对测试集中目标的列计算损失。

后处理

  • 替换
    "ptend_q0002_12 ~ ptend_q0002_28" 列被替换为 "state_q0002_12 ~ state_q0002_28"。

  • 调整以确保百分比值不低于 0
    由于 state_q0002 和 state_q0003 必须始终为非负数,我调整了 ptend_q0002 和 ptend_q0003,以确保下一个时间步的 state_q0002 和 state_q0003 不低于 0。

其他说明

  • 作为第二阶段,使用 MSELoss 进行额外训练可将性能提高约 0.002。
  • 使用低分辨率数据集时,通过使用 hdf5py 可以在不将所有数据加载到内存的情况下进行训练。
  • 直到最后一周我才使用完整的低分辨率数据集,仅使用 Kaggle 数据进行实验。(结果:最后一天排名跃升)

分数

模型 公共榜 私有榜
squeezeformer 0.78511 0.78056
LSTM 0.78094 0.77629

[e-toppo 的部分]

特征工程

除了数据之外,还计算了以下内容:

  • dp: 气压差
  • RH: 相对湿度 (参考:Climate-invariant machine learning)
  • vp: 水汽压
  • state_ice_rate: 云水含量中冰的比例 (水 + 冰)
  • ice_rate_diff: 从温度 derived 的冰率与 state_ice_rate 之间的差值
  • q0005: q0002 + q0003

模型与训练

  • 模型:LSTM
  • 损失:Smooth L1
  • 辅助损失:ptend_RH

后处理

  • 调整以确保百分比值不低于 0。由于 state_q0002 和 state_q0003 必须始终为非负数,我调整了 ptend_q0002 和 ptend_q0003,以确保下一个时间步的 state_q0002 和 state_q0003 不低于 0。
  • 温度调整。由于对于高于 274 度的温度,state_q0003 必须为 0,因此调整 ptend_0003 以满足此条件。

[Rheinmetall 的部分]

数据

使用 Hugging Face 上的所有 ClimSim_low-res 数据。

预处理

对特征和目标都应用 StandardScaler。

输入

  • 特征和目标有两种类型,一种具有高度维度,另一种是标量。因此,对于 556 维特征和 368 维目标,我们将它们分为序列特征和标量特征。
  • 不创建额外的输入特征。

验证

  • 随机洗牌后,将尾部 625,000 行作为验证数据。

模型

模型图
  • 序列特征嵌入到 linear 层中,然后输入到 LSTM,而标量特征也嵌入到 linear 层中,然后用作 LSTM 的隐藏状态输入。
  • LSTM 块有六层,这是由模型训练时间和准确率之间的权衡决定的。

输出

  • 由于我的模型有两个输出,一个序列头和一个标量头,我将其重建为竞赛格式,368 维。

损失函数

  • 基于每个头的 MSEloss 计算,但标量头损失乘以 0.1。(以优先训练序列头)

后处理

  • 检查所有数据,如果非负列为负数,则填充为 0。

[集成]

  • 集成方法是前 6 个单一模型的加权平均,权重通过 Nelder-Mead 方法优化。
  • 公共榜最佳和私有榜最佳是相同的提交。(公共榜:0.78560 / 私有榜:0.79080)
  • 在集成中包含具有较低单一分数的衍生模型并没有导致准确率的提高。关键是生成强大的单一模型。
同比赛其他方案