返回列表

1st Place Winning Solution - Hungry for Gold

407. Mechanisms of Action (MoA) Prediction | lish-moa

开始: 2020-09-03 结束: 2020-11-30 药物研发 数据算法赛
第1名获奖方案 - Hungry for Gold

概述

感谢 Kaggle 团队以及来自哈佛大学创新科学实验室的 @srandazzo21@mrbhbsof 主办了这场充满挑战且有趣的 MoA(作用机制)竞赛!

作为 Hungry for gold🥇🥇 团队(成员包括 @nischaydnk, @kibuna, @poteman)的代表,在这篇文章中,我将详细解释我们的获奖方案。

我们获胜的融合模型由 7 个单模型组成:

  • 通过非评分和评分元特征的 3 阶段 NN 堆叠
  • 通过非评分元特征的 2 阶段 NN+TabNet 堆叠
  • 使用旧 CV(交叉验证)的 SimpleNN
  • 使用新 CV 的 SimpleNN
  • 双头 ResNet
  • DeepInsight EfficientNet B3 NS
  • DeepInsight ResNeSt

以下概览图展示我们获胜的融合模型。

图 1. 获胜的加权平均融合模型。
获胜融合模型概览

我们的两个最终提交基于加权平均。获胜的融合模型是 LB(排行榜)最佳(表 1),最佳 CV 融合(表 3)在私有 LB 上也能取得第 5 名。这表明两个最终提交都具有高性能和鲁棒性。

表 1. 由 7 个模型组成的获胜融合模型 (Private LB: 0.01599)。
表 1

对于我们的获胜融合,融合权重的选择基于两个因素:LB 分数和单模型之间的相关性。为了更好地理解,计算了每个模型预测值(不含对照组)相对于其他单模型的平均相关性(如表 2 所示)。选择是手动进行的,以最大化 LB 分数。平均相关性较低的模型被赋予较高的权重。此外,部分权重由之前的融合提交分数决定。更多细节可以在模型多样性部分找到。

表 2. 最佳单模型提交之间的平均相关性。
表 2

最佳 CV 融合中单模型的选择完全基于 OOF(袋外)预测。我们在 Optuna 中使用了 TPE(树形 Parzen 估计器)采样器,并在 Scipy 中使用了 SLSQP(序列最小二乘规划)方法来搜索 CV 优化的权重。Optuna(3000 或 5000 次试验)和 SLSQP 得出的权重几乎相同。

最佳 CV 的对数损失是 0.15107 (Private LB: 0.01601),来自 5 个模型。有趣的是,搜索结果排除了 2 阶段 NN+TabNet 和 Simple NN 模型,而它们对获胜融合有所贡献。

表 3. 由 5 个模型组成的最佳 CV 融合 (CV: 0.015107, Private LB: 0.01601)。
表 3

DeepInsight CNNs 的加入在我们最终的融合中扮演了重要角色,因为它们与其他浅层 NN 模型相比具有高度的多样性。出于好奇,我们比较了包含与不包含这些 CNN 模型的获胜融合的对数损失分数(如表 4 所示)。

包含 DeepInsight CNN 模型后,我们在私有 LB 分数上获得了近 0.00008 的提升

表 4. 包含/不包含 DeepInsight CNNs 的获胜融合对比。
表 4

交叉验证策略

我们的大多数模型基于 MultilabelStratifiedKFold(旧 CV),例外是一个 Simple NN 模型,它使用了由 @cdeotte 分享的使用 drug_id 信息的 新双重分层 CV。我们在模型的 CV 分割中使用了不同的种子。CV 策略的选择基于 CV 对数损失与 LB 对数损失的一致性。CV 的 K 值为 5 或 10。我们还使用多个种子训练模型以减少方差。

值得注意的是,我们注意到很难结合来自旧 CV 和新 CV 的 OOF 文件来搜索优化的 CV 权重,因为新 CV 模型的对数损失分数要高得多。我们最终只选择了旧 CV 模型作为最佳 CV 融合,其在旧 CV 上得分为 0.15107,在私有 LB 上得分为 0.01601

模型细节

在我们的团队合作中,Nischay 和 Kibuna 贡献了特征工程以及 3 阶段 NN、2 阶段 NN+TabNet 和 Simple NN 模型的多阶段堆叠,而我则专注于 DeepInsight CNNs 和 2-heads ResNet 模型的复刻。

为了应对这个小型且高度不平衡的多标签数据集中的过拟合风险,我们在模型训练过程中施加了标签平滑和权重衰减作为正则化方法。标签平滑效果很好,它防止我们的模型对预测过于自信,从而大大降低了过拟合的几率。

为了让我们的模型在视觉上更易于理解,我们为每个单模型提供了模型架构图,以解释内部训练过程及其 NN 拓扑结构。在本节中,我们将详细介绍每个模型。

3 阶段 NN

这是我们要好的单模型 (CV: 0.01561, Public LB: 0.01823, Private LB: 0.01618),也是我们在 CV 和 LB 分数上最终融合的重要补充。Nischy 和 Kibuna 基于多阶段堆叠的思想,利用模型预测作为元特征和不同的工程特征,取得了很好的成果。训练集中移除了对照组行。

图 2. 3 阶段 NN 模型。
3 阶段 NN 模型

图 3. 3-FC 基础 NN 块拓扑。
基础 NN 块拓扑

图 3 描述了模型基础 NN 块的详细拓扑结构,类似于公共笔记本。训练设置进行了一些更改以提升性能。在多阶段训练中,除了调整 dropout 值外,使用了相同的架构。

第一阶段

首先,使用 UMAPFactor Analysis 从基因和细胞特征中生成额外特征。对所有特征(除了独热编码特征)应用 Quantile Transformer。在此阶段,使用大小为 2048 的隐藏神经元 NN 模型针对非评分目标(不包括零值,共 332 个目标)训练 15 个 epoch。非评分预测作为元特征用于下一阶段。

第二阶段

在第二阶段,我们再次对非评分元特征应用 Quantile Transformer,将其与前一阶段的原始特征结合,并训练另一个 NN 模型针对评分目标训练 25 个 epoch,隐藏神经元大小为 2048。同样,评分预测作为元特征用于下一阶段。

第三阶段

在最后阶段,我们也对评分元特征应用 Quantile Transformer,并仅基于这些元特征重新训练一个 NN 模型 25 个 epoch,隐藏神经元大小为 1024,同时训练数据中的目标值在标签平滑后被裁剪在 0.0005 和 0.9995 之间。

每个阶段使用类似的设置:Adam 优化器(学习率 5e-3),批次大小 256,权重衰减 1e-5,以及最大学习率为 1e-2 的 OneCycleLR 调度器。

最终模型的 CV 对数损失为 0.01561,由于对模型预测进行了裁剪,这比第二阶段模型略高,但在 LB 上得分非常好。

2 阶段 NN+TabNet

与 3 阶段 NN 类似,该模型也在多阶段训练中使用了非评分和评分目标。TabNet 仅用于第二阶段而不是第一阶段,因为它在非评分目标上效果不佳。训练集中移除了对照组行。

图 4 和 5 展示了模型架构和第一阶段使用的基础 NN 细节。

图 4. 2 阶段 NN+TabNet 模型。
2 阶段 NN+TabNet 模型

图 5. 2-FC 基础 NN 块拓扑。
基础 NN 块拓扑

第一阶段

在特征工程部分,对基因和细胞特征使用了 PCAUMAP 以及 QuantileTransformer,方差阈值为 0.5 以保留重要特征。使用大小为 2048 的隐藏神经元 NN 模型针对非评分目标训练 15 个 epoch。这些预测随后作为元特征用于下一阶段。

使用的训练设置如下:Adam 优化器(学习率 5e-4),批次大小 256,权重衰减 1e-5,以及最大学习率为 1e-2 的 OneCycleLR 调度器。

第二阶段

在第二阶段,我们再次对非评分元特征应用 Quantile Transformer,将其与前一阶段的原始特征结合,并训练一个带有标签平滑 (0.0001) 的 TabNet 模型针对评分目标。还使用了因子分析、K-Means 聚类以及一些统计特征(如基因和细胞特征的均值、偏度、峰度和标准差)。

PyTorch TabNet 回归器训练设置:决策预测层宽度为 32,每个掩码的注意力嵌入宽度为 32,架构步骤为 1,gamma 值为 0.9,Adam 优化器(学习率 2e-2,权重衰减 1e-5),稀疏损失系数为 0,掩码函数使用 entmax。训练批次大小为 1024,虚拟批次大小为 128,训练 200 个 epoch,早停耐心为 50 个 epoch。最终 TabNet 模型的 CV 对数损失为 0.01615

Simple NN

Simple NN 的模型拓扑与 3 阶段 NN 模型中使用的 3-FC 基础 NN 相同。它仅在评分目标上进行单阶段训练。图 6 和 7 展示了模型架构和基础 NN 细节。训练集中移除了对照组行。

图 6. Simple NN 模型。
Simple NN 模型

图 7. 3-FC 基础 NN 块拓扑。
基础 NN 块拓扑

在特征工程部分,对基因和细胞特征(除独热编码外)使用了 Factor AnalysisQuantileTransformer。还使用了一些统计特征(如基因和细胞特征的均值、偏度、峰度和标准差)。使用大小为 2048 的隐藏神经元 NN 模型针对评分目标进行训练。

使用的训练设置如下:Adam 优化器(学习率 5e-4),批次大小 256,权重衰减 1e-5,早停耐心为 10 个 epoch,以及最大学习率为 1e-2 的 OneCycleLR 调度器。

我们总共训练了两个 Simple NN 模型,一个包含来自 K-Means 聚类的额外特征的旧 CV 模型,另一个使用新 CV 以增加多样性。

双头 ResNet (2-heads ResNet)

该模型复刻了由 @demetrypascal 分享的公共笔记本 "Fork of 2heads looper super puper plate",并对冻结/解冻训练循环进行了小幅更新。原始笔记本用 R 编写(Public LB: 0.01833, Private LB: 0.01624),我们制作了其 Tensorflow/Keras Python 版本(Public LB: 0.01836, Private LB: 0.01624)。训练集中移除了对照组行。

图 8 和 9 展示了模型架构和类 ResNet 残差 NN 的细节。

图 8. 双头 ResNet 模型。
双头 ResNet 模型

该架构基于类 ResNet 残差 NN,有两个输入:一个来自基因和细胞特征的均值及 PCA 分量,另一个包含通过 Student's t-test 选择的 447 个重要特征。所有特征通过 Standard Scaler 标准化。

图 9. 类 ResNet 残差 NN 拓扑。
类 ResNet 残差 NN 拓扑

使用类 ResNet 拓扑带来了 FC 层中跳跃连接的好处,允许信息从一层流向下一层。这样,模型获得了更好的学习能力,可以使用更多隐藏神经元和层而不会出现早期退化问题。

训练过程分为两个阶段。

首先,模型通过 Adam 优化器针对非评分目标训练 50 个 epoch,最小化二元交叉熵损失,学习率为 1e-3,批次大小为 128,早停耐心为 10 个 epoch,最小增量为 1e-5。使用 ReduceLROnPlateau 学习率调度器(因子 0.5,耐心 4 个 epoch)。标签平滑的 alpha 值设为 0.0005。

在第二阶段,来自非评分目标的模型权重被重用,通过冻结和解冻过程循环进行迁移学习,针对评分目标进行训练。除最后几层(图 9 中的 FC2 模块)外的权重被冻结训练若干 epoch,早停最小增量设为 1e-6,较小学习率为 1e-3/3。然后解冻整个模型权重,我们遵循类似的循环训练同一模型,使用更小的学习率 1e-3/5,直到早停。

还有另一个 V2 版本的模型,包含独热编码特征并使用较小的批次大小 64。它的公共 LB 较差,但在 CV 和私有 LB 上得分更好,是我们最佳 CV 融合的一部分。

DeepInsight CNNs

与大多数公共笔记本中分享的浅层 NN 模型以及我们添加了许多工程特征的其他单模型相比,我们的 DeepInsight CNNs 仅使用来自基因和细胞的原始特征!

这个想法是为了充分利用预训练卷积神经网络的特征提取和迁移学习能力,与其他 NN 模型相比,生成高度独特和多样化的模型。

正如我在关于 DeepInsight 的帖子中介绍的那样,我们不是为收集的样本(N 个样本 x d 个特征)进行特征提取和选择,而是将相似或相关的特征排列到二维特征图的相邻区域(d 个特征 x N 个样本),以简化其复杂关系和交互的学习。

由于我们转换的是特征而不是样本,学习到的特征图形状对样本是静态的。然而,每个类别的特征图中的特征值分布(热图颜色)看起来不同。众所周知,CNN 可以通过在相邻层的神经元之间强制执行稀疏的局部连接模式来学习分层模式并利用空间局部相关性。即使特征图是固定的,特征值的方差和相邻弱特征的交互仍然是内核权重的可学习来源。

在本次比赛中,我们将 DeepInsight 应用于两个流行的预训练 CNN 模型:EfficientNetResNeSt(Split-Attention Networks)。事实证明它们都在 MoA 数据上运行得很好!

图 10 和 11 展示了 DeepInsight CNNs 的细节。

图 10. DeepInsight EfficientNet B3 NS 模型。
DeepInsight EfficientNet B3 NS 模型

图 11. DeepInsight ResNeSt 模型。
DeepInsight ResNeSt 模型

训练过程

两个 CNN 模型的整体训练过程相同。首先,原始基因、细胞和独热编码特征通过原始 DeepInsight 论文 中提到的 Norm-2 归一化 方法进行归一化,在我们的实验中,该方法对 CNNs 的效果优于 Standard Scaler、Robust Scaler 和 Min/Max Scaler。

其次,应用 t-SNE 将原始特征转换为非线性 2D 嵌入特征空间。然后使用凸包算法找到包含所有特征的最小矩形,并进行旋转以将框架对齐为水平或垂直形式。在此步骤之后,我们创建了一个 DeepInsight 特征图,其中包含来自基因和细胞的原始特征之间的相邻关系。

接下来,为了应对这个小型且高度不平衡数据集的过拟合风险,我们借鉴了 Swap Noise 的思想进行数据增强,即每个训练样本有 10% 的几率与训练集中的其他随机样本交换 15% 的特征。我们的实验结果表明,这个技巧大大降低了过拟合几率并提升了 CNNs 的预测性能。

第四,将增强后的原始特征值映射到特征图的像素坐标位置。注意,特征图的分辨率影响特征重叠率(映射到同一位置的特征取平均值),这是有损压缩程度和计算资源需求(如主机/GPU 内存、存储)之间的权衡。

在原始论文中,重叠的特征值通过平均值聚合,并且只为预训练 CNNs 提供复制到 3 个通道的单个灰度通道。因此,在最后一步,我想到了提取最小值和最大值作为其他两个通道的想法,以保留更多关于重叠值的统计信息。实验证明,这个技巧显著提升了预测性能(CV: -0.00013, Public LB: -0.00011)。

我们选择分辨率和图像大小使用相同的值,EfficientNet B3 NoisyStudent 为 300x300,删减版 ResNeSt 为 224x224。CNNs 的最后一个 FC 层替换为隐藏大小为 512 和 ELU 激活函数的新 FC 层。

对于 ResNeSt,我们选择了删减版本 (resnest50_fast_2s2x40d),它在相对较小的模型大小和较快的推理速度下提供了几乎最好的预测性能。我们还训练了另一个使用不同种子和在最终 FC 层增加 0.2 的 dropout 率的 V2 模型。

两个 CNNs 都使用由 PyTorch Lightning 框架实现的相同训练过程。我们在 16 位精度下通过 RAdam 优化器训练了 CNNs 约 35 个 epoch(10 折),学习率 0.000352(通过 Learning Rate Finder 获得),EfficientNet B3 NS 批次大小为 48,删减版 ResNet 为 128,早停耐心为 12 个 epoch,余弦退火 LR 调度器 T_max 设为 5 个 epoch,二元交叉熵损失的标签平滑为 0.001。

每个模型训练 10 折大约需要 12-25 小时。因此,它们都在我的本地机器(配备两个 2080-Ti GPU)上训练,而不是在运行时间限制为 9 小时的 Kaggle GPU 笔记本上。

与其他在训练前从 MoA 训练集中移除对照组行的模型相反,我对此有不同的想法。从竞赛论坛的一个讨论帖中,主办方提到:

……然而,在实际应用中,空白对照是评估药物疗效的一种方法,并且可用于建模其他 MoA。

这个提示让我认为,对照组行可能为 CNNs 提供一些有用的信息,因为它们正在建模基因表达和细胞活力特征之间的关系。因此,在我们的 CNNs 中,它们都使用了对照组行进行训练。在实验中,移除这些行在 CV 和 LB 上都产生了更差的分数。

我曾尝试过但未成功的尝试:

  • EfficientNet B0, B5, B7 NS(在这个小数据集中,较小的模型较弱,较大的模型更快过拟合)
  • PCA 或 Kernel-PCA 配合 Norm-2 归一化、Quantile Transformer 或 Standard Scaler
  • 最后 FC 层更高的 dropout
  • ImageNet 归一化的 RGB 通道
  • 带热重启的余弦退火
  • 最后 FC 层使用其他激活函数如 ReLU, SELU, GELU 等

模型多样性

为了更好地了解我们模型的多样性,这里是我们最佳单模型的平均相关性热图。相关系数通过 Pearson 方法计算每对模型之间。我们将目标级相关系数的平均值作为每个模型的最终值。

对于我们的最佳 LB 模型提交,即使它们在 LB 上得分很高,它们的相关性却低得惊人!特别是 DeepInsight CNNs,与其他 NN 模型的相关性仅为 0.63-0.73。这有力地证明了高度多样性以及作为集成提升的重要来源。

图 12. 最佳 LB 模型提交预测的平均相关性热图。
最佳 LB 模型相关性

我们最佳 CV 模型的 OOF(袋外)预测也显示了类似现象,模型相关性甚至更低,系数仅为 0.52-0.70

图 13. 最佳 CV 模型 OOF 预测的平均相关性热图。
最佳 CV 模型相关性

在我以往的经验中,相关性在 0.85-0.95 左右的多样化模型通常是集成的很好来源。在这次比赛中,我们最好的单模型证明了它们强大的预测性能,同时具有比平时低得多的相关性!

推理效率

为了确保我们可以在 2 小时执行限制内安全地将所有最佳模型放入最终融合提交中,我们通过从 pickle 文件加载所有缩放器和拟合的转换器来优化推理脚本。此外,由于 Kaggle GPU 笔记本的计算资源有限(2 核 CPU,13GB 主机内存和 16GB GPU 内存),我们进行了多次试验,通过调整工作进程数和批次大小为每个模型找到最佳点,以最大化推理吞吐量。

关于批次大小,我们的最佳设置是 NN 模型为 2048,CNN 模型为 512(因为 CNN 模型更大且更耗内存)。由于 CPU、GPU 和 I/O 资源的饱和,设置更大的数字无助于推理速度。

最终提交的总运行时间在公共测试集上分别为 1923 秒(最佳 LB)和 1829 秒(最佳 CV),它们都在私有测试集上的 2 小时内完成。

源代码

我们所有的训练笔记本、融合笔记本和推理脚本都在以下 Github 仓库中开源:
https://github.com/guitarmind/kaggle_moa_winner_hungry_for_gold

请注意,该仓库的结构将在未来几天更新,以遵循 Kaggle 团队的 获奖模型文档指南

我们最终提交模型的训练和推理源代码可以在 final 文件夹下找到。

结论

在没有任何关于 MoA 或医学领域的先验知识的情况下,我们尽力将我们知道的 ML/DL 技术应用到了这个小而高度不平衡的数据集中。我们对最终排名感到惊讶,事实证明,通用的 AI 方法几乎可以在任何领域发挥作用。

不同架构的浅层 NN 模型、深入的特征工程、多阶段堆叠、标签平滑、迁移学习以及多样化 DeepInsight CNNs 的结合是我们团队最终提交的关键获胜因素。

感谢您阅读这篇长文,希望您从中获得了一些有趣和有用的东西!

同比赛其他方案