返回列表

11th Place Solution for the LEAP - Atmospheric Physics using AI (ClimSim) Competition

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

开始: 2024-04-18 结束: 2024-07-15 气象预报 数据算法赛
LEAP - 使用 AI 进行大气物理 (ClimSim) 竞赛第 11 名解决方案

LEAP - 使用 AI 进行大气物理 (ClimSim) 竞赛第 11 名解决方案

作者: Uesugi Erii (MASTER)
发布时间: 2024-07-30
竞赛排名: 第 11 名

感谢 Learning the Earth with Artificial Intelligence and Physics (LEAP) NSF 科学技术中心和 Kaggle 举办这场有趣的竞赛,这场竞赛的交叉验证 (CV)、公共排行榜 (LB) 和私人排行榜 (PB) 都非常稳定。

考虑到我的英语不是特别好,这篇文章是在 chatgpt 的辅助翻译下写的。我会检查并进行修正。

推理代码以证明无泄漏:LEAP_11th_PB0.78491

背景 (Context)

方法概述 (Overview of the approach)

我的最终提交由 6 个模型(具有 5 种不同的架构)集成在一起(重要)。所有模型都使用残差结构。所有模型都在 0001-02 到 0008-01 的完整数据集(低分辨率)上进行训练,并在从 0008-02 到 0009-01 采样的约 170 万行数据上进行验证。输入处理同时使用了标准化、对数变换和嵌入。模型经过了多阶段的精心训练(重要)。模型集成的权重是使用基于 0008-02 到 0009-01 数据的爬山算法确定的。

模型架构 块数量 嵌入维度 参数数量 CV 文件名
bi-LSTM + MLP 7 8 5070534 0.71969 v4_1
bi-LSTM + MLP 17 16 49089054 0.72703 v4_1
bi-LSTM + MLP + BN 7 8 5238534 0.72493 v4_8
bi-GRU + MLP + BN 9 8 5286134 0.72536 v5_1
bi-RNN + MLP + BN 17 8 4511734 0.71692 v8_1
1D-CNN + BN 11 8 16854334 0.71459 v6
集成 (Ensemble) 0.73472 (PB: 78491)

方案细节 (Solution Detail)

数据处理细节 (data process detail)

根据我的对抗验证实验,年份之间的数据存在显著差异 (AUC=1)。根据组织者的信息,理论上应该有十亿条数据(但 HuggingFace 上只有约 8000 万条)。因此,可以推测测试集来自后几年的数据。考虑到上述信息,我使用 0001-02 到 0008-01 的数据进行训练,使用 0008-02 到 0009-01 的数据进行验证。也许这就是为什么我能够攀升 PB 排名并进入金牌区的原因。

原始输入有 556 列。我删除了只有 1 个值的 66 列,剩下 490 列。对于每一列数据,我执行两个操作:一个是直接标准化它 (X - x_mean) / x_std,另一个是取绝对值后应用对数然后标准化 (CV +0.003)。(log_X - log_x_mean) / log_x_std 所以我模型的输入形状是 (980,)

对于模型的 980 个输入中的每一个,都分配了一个嵌入,初始化范围为 [-0.05, 0.05]。这个初始化范围至关重要,因为其他初始化方法可能会导致性能较差。

通过填充和重塑,输入最终变为 (bs, 60, 25*emb_dim)。

模型细节 (model detail) (重要)

对于 bi-LSTM + MLP + BNbi-GRU + MLP + BNbi-RNN + MLP + BN,模型结构都按以下方式排列,唯一不同的是编码层。

pre_seq = seq  # (bs, 60, 25*emb_dim)
for i in range(len(self.encoder_layers)):
    encoder_layer = self.encoder_layers[i]
    seq, _ = encoder_layer(seq)  # (bs, 60, 25*emb_dim*2)
    ffn = self.mlp[i]
    seq = ffn(seq)  # (bs, 60, 25*emb_dim)
    seq = seq.contiguous().view(bs, -1)  # (bs, 60*25*emb_dim)
    seq = self.mlp_bn[i](seq)  # (bs, 60*25*emb_dim)
    seq = seq.contiguous().view(bs, 60, -1)  # (bs, 60, 25*emb_dim)
    seq = F.gelu(seq)
    seq = seq + pre_seq  # (bs, 60*25*emb_dim)
    pre_seq = seq

对于 1D-CNN + BN,模型结构如下

pre_x = x
for i in range(len(self.cnns)):
    x = self.cnns[i](x) + pre_x
    pre_x = x

模型的完整代码可以在这里的 'model' 文件夹中找到。https://www.kaggle.com/datasets/uesugierii/leap-final?select=model

训练细节 (training detail) (重要)

在训练过程中,发现直接在完整数据集(低分辨率)上训练会导致分数较低。经过 EDA 后发现,训练不稳定的主要原因是异常值。

为了解决这个问题,我采用了两种独立的方法来缓解:

  1. 第一种方法涉及裁剪输入和目标的值范围 (np.clip(x, -10, 10), np.clip(y, -10, 10)),首先在较小的范围内拟合(15 个 epoch,学习率 1e-3),然后在原始数据上拟合(15 个 epoch,学习率 1e-4)。这背后的理由是首先让模型学习并适应相对正常的天气条件,然后再推广到更极端的天气变化。
  2. 第二种方法:首先让模型在一个月的数据上训练(15 个 epoch,学习率 1e-3),然后在一年的数据上训练(15 个 epoch,学习率 1e-3),最后在所有可用数据上训练(15 个 epoch,学习率 1e-4)。这背后的主要思想是让模型最初学习短时间跨度的气候变化,然后逐渐扩大时间范围,以确保更平滑的学习过程并降低学习难度。

为了在最后获得轻微的性能提升,我会在极大的批量大小 (10240) 和非常低的学习率 (1e-5) 下训练模型几个 epoch。一些模型能够实现进一步的增强 (CV +0.004)。

对我无效的方法 (What didn't work for me)

  • 物理知识,求解偏微分方程的神经网络方法
    • 我不确定是因为我缺乏对这些知识的理解导致没有效果,还是它们真的不起作用
  • U-Net, U-Net++
  • Transformers
  • Squeezeformer
  • 使用权重为 0 的目标列辅助训练
  • 更复杂的嵌入方案,例如 bucketing + embedding, AutoDis 等
同比赛其他方案