返回列表

23rd place solution: ensemble, rank passage and predict span

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

开始: 2019-10-28 结束: 2020-01-22 自然语言处理 数据算法赛
第23名方案:集成学习、段落排序与片段预测

第23名方案:集成学习、段落排序与片段预测

作者:cfiken | 比赛:TensorFlow 2.0 Question Answering

首先,感谢 Kaggle 举办这场极具挑战性的比赛,并祝贺获奖者。这是我第一次处理问答(QA)任务,从大家身上学到了很多东西。

其次,感谢所有在这里进行讨论和分享想法的 Kaggler 们,特别是 @christofhenkel, @boliu0, @higepon@kashnitsky

这是我简明的解决方案,欢迎提问和建议。

我的解决方案

结合了 1 个排序模型(Ranker Model)和 4 个片段预测集成模型。

整体预测流程

  1. 计算测试数据集中所有长答案候选段落的分数。
  2. 为每条记录选择得分最高的 10 个段落。
  3. 将选出的段落输入片段预测模型。
  4. 获取各模型的平均得分。

排序模型

问题之一是 NQ 数据集中有非常多的长答案候选。其中包含明显的负样本(无关段落),对所有候选进行预测非常耗时。

我使用了 bert-base-uncased 预训练模型,构建了一个二分类模型来预测段落是否包含长/短答案。

在我的验证数据集上,该模型的 Recall@10 分数约为 0.98。处理公开测试集大约需要 5 分钟。其他设置与片段预测模型相同。

通过该模型,我为训练数据和测试数据创建了 ranker-selected 数据集,即每条记录选择得分最高的前 10 个候选。

片段预测模型

我使用了 4 个模型进行集成:

  1. bert-large-uncased-squad1 预训练 + 在 NQ 数据集上微调 1 个 epoch
  2. bert-large-uncased-squad2 预训练 + 在 NQ 数据集上微调 1 个 epoch
  3. spanbert-large-cased-squad2 预训练 + 在 NQ 数据集上微调 1 个 epoch
  4. bert-large-uncased-squad2 预训练 + 在 ranker-selected NQ 数据集上微调 1 个 epoch

所有模型均基于 bert-joint 模型。

训练

对于第 1~3 个模型,我使用了完整的 NQ 数据集。

在训练中,正如 Frustratingly Easy Natural Question Answering 论文中所述,我使用 196 作为步长,对可回答和不可回答的问题使用不同的下采样率(分别为 0.01 和 0.04)。

Batch size 为 32,最大学习率为 3e-5。

对于第 4 个模型,我使用了 ranker-selected NQ 训练数据集,并将采样率调整为可回答 0.03,不可回答 0.12。

推理

我只使用了 ranker-selected 测试数据集。这比预测所有候选在验证分数上略有提升,更重要的是,这使得预测速度更快。

每个模型的预测大约需要 3 分钟。

单模型的 Private LB 分数为 0.65,集成模型的 Private LB 分数为 0.67。

尝试过但无效的方法

  • 使用 ALBERT、XLNet 没有提高分数,也许我需要更多的调优。
  • Attention over Attention 没有产生正面影响,但我对实现不太有信心。
  • 结合 BERT 最后 2、4、8、12 层。虽有微弱提升,但不如 SQuAD 预训练模型效果好。
  • 在全连接层尝试各种 Dropout。
  • 在起始和结束位置使用标签平滑。
  • 将排序模型的分数结合到片段预测中导致了更差的结果。
  • 区分短片段和长片段预测,或者只预测短片段,结果都变差了。
  • 各种预处理尝试:
    • 无特殊标记。
    • 在 BERT-joint 中部分使用特殊标记。
  • 各种后处理尝试:
    • 仅使用最大上下文位置作为分数。
    • 获取所有 logits 分数并获取前 k 个候选。

谢谢。

同比赛其他方案