返回列表

3rd place solution

361. TensorFlow 2.0 Question Answering | tensorflow2-question-answering

开始: 2019-10-28 结束: 2020-01-22 自然语言处理 数据算法赛
第三名方案

第三名方案

作者:Dieter (Grandmaster)
队友:CPMP (Grandmaster)
比赛排名:第3名

感谢赞助商和 Kaggle 主办了如此有趣且充满挑战的比赛。也非常感谢 @cpmpml 成为我的队友。

简要总结

正如我们的队名所暗示的,我们所有的操作都使用 PyTorch 完成。总之,我们使用了 3 个 RoBERTa-Large 模型,并通过投票进行集成。总的来说,我们模型的输入特征非常接近 BertJoint 基线。我们使用的学习率为 1e-5,批次大小为 16,使用简单的 Adam 优化器且无学习率调度。所有模型均训练了 1 个 Epoch。

RoBERTa 1:

  • 使用 RoBERTa-Large 权重初始化
  • 步长 128
  • 预测跨度 & 5 种答案类型

RoBERTa 2:

  • 使用 RoBERTa-Large 权重初始化,然后在 SQuAD 2.0 上预训练
  • 步长 192
  • 预测跨度 & 2 种答案类型(短答案,长答案)

RoBERTa 3:

  • 使用 RoBERTa-Large 权重初始化,然后在 SQuAD 2.0 上预训练
  • 在预测开始和结束标记之前增加了一个线性层 (768→768 + relu)
  • 步长 192
  • 预测跨度 & 2 种答案类型(短答案,长答案)

我们优化了每个模型的阈值,并将低于阈值的预测设为空白。然后我们使用多数投票来集成这 3 个模型。除了一些小技巧外,我们使用 224 的步长预测测试集,以便在 Kernel 中容纳 3 个模型的推理。

详细总结

验证方案

像往常一样,我首先建立一个可靠的验证方案,理想情况下与排行榜有很高的相关性。结果比预期的要难,因为组织者没有分享关于预期指标的足够信息,而且实施也是错误的。第一阶段非常令人沮丧,我花了相当多的时间逆向工程他们的错误,以便调和排行榜分数。在我弄清楚指标并在论坛分享后,组织者更改了指标。想象一下我当时的表情……信不信由你,我又花了 6 周时间才弄清楚新的指标。最后,我们使用原始 NQ 数据集的开发集作为我们的验证集,并且与 LB 有非常高的相关性。

软件

我重用了组织者分享的 BertJoint 基线中的许多预处理脚本,并使用 PyTorch 进行所有训练,依赖 HuggingFace 获取 Transformer 权重和代码,并使用 PyTorch-Lightning 编写训练流程。

硬件

我在家里的台式机(3 块 GTX1080Ti)上进行了所有训练,@cpmpml 在他的电脑(2 块 GTX 1080Ti)上进行。训练一个 Epoch 需要相当长的时间,因此我们没有在超参数调整上花费太多时间。RoBERTa 1 的训练时间为 35 小时。在 SQuAD 2.0 上微调 RoBERTa-Large 花了 30 小时,当使用 192 的步长时,将结果模型微调到本次比赛的数据大约花了 24 小时。

架构和预训练模型

我完全同意 @boliu0 的观点,击败 BertJoint 基线异常困难。我对不同的预处理以及使用不同的(我认为更适合的)目标进行了大量实验。但我所做的 99% 都比基线差。所以最后我们保留了预处理,只稍微调整了答案类型目标。我在很多实验中使用了 DistilBERT,因为由于它的尺寸小,有助于快速迭代,同时能合理地指示一个想法是否有效。

通常,BertJoint 基线建议使用窗口方法对完整答案进行步进,并将这些窗口与问题连接起来,以查找短答案是否包含在窗口中。一个主要有趣的问题是如何聚合结果预测。这就是我们花费时间的地方,因为我们看到有很大的改进空间。我们所做的是将每个窗口的开始和结束标记预测映射回原始答案,并创建一个答案长度 x 答案长度的热力图。然后我们应用一些限制,例如短跨度长度应小于 30 个标记,并得到以下结果。

同比赛其他方案