这是我在 Kaggle 的第一年,也是我的第一次 Kaggle 竞赛。在我的第一次 Featured 竞赛中,测试集反复出现错误,对于像我这样的新手来说非常不友好。当前版本的解决方案是根据邮件要求编写的。
起初,我尝试使用 Uni-Mol 进行预测,浪费了很多时间后才意识到我无法很好地使用它,而且我的本地计算能力完全不足,所以我别无选择,只能放弃。然而,使用 Uni-Mol 让我意识到了数据预处理的重要性,这使我在后来切换到使用 GNN 时更加熟练。
代码、PPT、数据在此:
https://github.com/fresnellll/kaggle-NeurIPS-polymer-prediction-solution
概述
我的获胜方法是一个融合方案,结合了图注意力网络 (GATv2Conv) 和选定的 Morgan 指纹特征。我认为我成功的主要因素是:
- GATv2 的注意力机制已经可以捕捉复杂的高层几何和化学环境信息。简单的、基于位的 Morgan 指纹提供了互补的低层子结构信息,而不会产生冲突信号。
- 认识到数据可能存在偏差,我使用验证集作为基准来校准数据,并使用 5 折交叉验证来减轻潜在数据异常带来的风险。
核心 GNN 骨干网络: 每个 GATv2Conv 层利用 8 个注意力头,允许模型同时关注不同的邻域信息模式。GNN 的隐藏维度为 384。拥有 8 个头,每个头处理 48 维特征空间 (384 / 8 = 48)。
残差连接 通过简单的元素相加实现,使得 6 层深度网络的训练更加稳定。
特征融合架构: 全局和局部特征的融合是关键一步。我们使用简单但有效的拼接。
| 图嵌入 (384 维) | Top 50 指纹 (50 维) |
|---|
独立 MLP 预测头:
在融合层之后,5 个目标属性中的每一个都有自己专用的预测头。
每个头都是一个 2 层 MLP,带有 ReLU 激活和 Dropout 正则化:
Linear(in=434, out=384)
ReLU()
Dropout(p=0.2)
Linear(in=384, out=1)
训练流程
带有 5 折交叉验证的稳健集成:
最终提交是 5 个模型预测的简单平均集成。每个模型赋予 20% 的相等权重。
训练超参数与优化:
优化器:我们使用 AdamW,与标准 Adam 相比,它通常为深度学习模型提供更好的正则化和性能。
学习率:整个训练过程中使用 1e-4 的恒定学习率。
早停:如果验证 wMAE 分数在 40 个连续 epoch 内没有改善 (patience=40),则停止训练。保存最佳 epoch 的模型。
批量大小:训练期间使用 64 的批量大小。
用于直接指标优化的自定义损失函数:
我们在 PyTorch 中实现了自定义的加权 MAE (wMAE) 损失函数。
这至关重要,因为它确保模型的训练目标与官方竞赛指标完美对齐,从而实现更直接和高效的优化。
事后校准详情:
线性校准器是来自 scikit-learn 的简单 LinearRegression() 模型。对于每个目标,它学习一个线性变换 (y = a*x + b) 将 GNN 的原始预测映射到真实值,有效地纠正简单的偏差。
特征选择/工程
基本转换:SMILES 到图表示
我们将 1D SMILES 字符串转换为丰富的图结构,其中原子是节点,键是边。
节点特征包括原子序数、度数、杂化等(共 7 个特征)。
这使得我们的 GNN 模型可以直接从聚合物的 2D 拓扑中学习,捕捉复杂的结构信息。
关键工程步骤:化学数据增强
我们实现了一个函数,以编程方式扩展单体重复单元 (A -> A-A-A)。
这创建了一个更大、更真实的训练集,迫使模型从更长、更具代表性的聚合物链中学习特征,从而显著提高泛化能力。
获胜策略:混合与特定任务的特征选择
我们结合了两种特征类型:来自 GNN 的学习全局嵌入和来自 Morgan 指纹的精选局部特征。
对于 5 个目标中的每一个,我们使用 F-regression 独立选择 Top 50 个最具预测性的 Morgan 指纹,为每个预测任务创建定制的特征集。
例如:
我们使用 F-regression 对所有 1024 个 Morgan 指纹位针对 Tg 目标进行评分,识别出最具预测性的化学子结构。
该图可视化了得分最高的前 20 个位。这些位,如 fp_587 和 fp_80,代表了对 Tg 预测影响最大的局部化学特征。
这种数据驱动的选择过程允许我们为 Tg 预测头创建一个紧凑而强大的 50 特征集,而不是使用完整的嘈杂的 1024 位向量。
与目标的关系:Top 特征 (fp_587) 对 Tg 的影响
为了可视化我们最重要特征的影响,我们比较了两组聚合物的 Tg 分布:那些拥有 fp_587 指纹位的聚合物和那些没有的。
小提琴图清楚地显示了显著的正相关性:具有 fp_587 子结构的聚合物的中位 Tg 明显更高(约 280°C 对 150°C)。
这一强有力的视觉证据验证了我们的特征选择方法,并确认我们的模型正在学习有意义的化学关系。
训练方法
带有 AdamW 优化器的自定义加权 MAE 损失。
我们在 PyTorch 中实现了一个自定义损失函数,完美镜像了官方 wMAE 竞赛指标。这确保模型直接针对最终分数进行优化。
使用 AdamW 优化器,恒定学习率为 1e-4。
稳健的 5 折交叉验证集成。
最终解决方案是 5 个模型的简单平均集成,这些模型是在不同的 80/20 数据分割上训练的。
训练期间使用 64 的批量大小。
带有早停和重新拟合的两阶段训练。
阶段 1:寻找最佳 Epoch。我们在 80% 的数据上训练,并使用剩余的 20% 作为验证集进行早停 (patience=40),防止过拟合。
阶段 2:在全量数据上重新拟合。然后从头开始在该 fold 的 100% 数据上重新训练一个新模型,epochs 数量正好是阶段 1 中发现的最佳数量。这最大化了每个最终模型的数据利用率。
事后线性校准。
训练后,针对每个目标在验证集的预测上拟合一个简单的 LinearRegression 模型。这有效地纠正了 GNN 模型的任何系统性偏差,提供了最后一点微小但至关重要的性能提升。
重要且有趣的发现
发现 1:聚合物链扩展优于异构体生成
我们尝试了两种不同的数据增强策略。
策略 A (链扩展): 通过扩展单体重复单元 (A -> A-A-A) 模拟聚合。这非常有效。
策略 B (异构体生成): 为同一单体创建多个不同但化学上有效的 SMILES 字符串 (异构体)。这没有带来性能提升。
发现 2:批量大小的“甜蜜点” - 越大并不总是越好
尽管有足够的 GPU 内存用于更大的批量大小 (128, 256),但我们发现较小的批量大小 64 始终产生最佳结果。
较大的批量大小导致最终 PB 分数下降。
发现 3:GNN 架构与特征类型之间令人惊讶的协同作用
我们测试了 GNN 骨干网络和辅助特征的不同组合。结果揭示了强烈且意想不到的交互效应。
GATv2 + Morgan 指纹是明显的赢家。
有趣的是,RDKit 描述符严重损害了 GATv2 的性能,但稍微帮助了 NNConv 的性能。
假设:
GATv2 的注意力机制已经捕捉到了复杂的高层几何和化学环境。简单的、基于位的 Morgan 指纹提供了互补的低层子结构信息,而不会产生冲突信号。
NNConv 作为一个更简单的消息传递网络,可能更多地受益于预计算的、人工设计的 RDKit 描述符,这些描述符为其提供了它难以自行学习的高层化学概念。
发现 4:通过事后校准进行系统性偏差纠正
对我们所有 5 个 fold 的折外 (OOF) 预测的分析揭示了一致的系统性偏差:模型的原始预测(蓝线)一致地高估了低 Tg 值并低估了高 Tg 值。
这种分布偏移是一个常见的挑战,纠正它是最大化分数的关键。
我们发现这种偏差可以通过在每个 fold 的验证预测上拟合一个简单的 LinearRegression 模型来有效纠正。
如表所示,这个简单的事后步骤为最终 wMAE 分数提供了显著的 5.47% 提升。这是一个微小的变化,却产生了至关重要的影响。我们的 PB 分数从 0.080 提升到了 0.078。我们要感谢 hengck23 在 讨论区 的分享。
简单模型
为了了解每个组件的贡献,我们评估了最终模型的几个简化版本。
单个模型 (1-fold) 在没有集成的情况下已经取得了有竞争力的分数。
赛后发现:RemoveHs 的未开发潜力
比赛结束后,我们在数据预处理步骤中测试了一个简单的变化:在图转换之前去除氢原子 (RDKit 中的 RemoveHs)。
令人惊讶的是,使用 RemoveHs 训练的单个模型取得了约 0.083 的 Public LB 分数,这甚至比我们带氢原子的单个模型还要好。
结论:这表明如果我们将 RemoveHs 预处理应用到完整的 5 折集成流程中,我们的最终分数可能会更高。当模型专注于聚合物的重原子骨架时,表现更好。
谢谢
hongyu Guo