返回列表

30th Sliver Solution (Post-Processing Magic Discovered)

362. Google QUEST Q&A Labeling | google-quest-challenge

开始: 2019-11-22 结束: 2020-02-10 自然语言处理 数据算法赛
第30名银牌方案 (发现后处理魔法)

第30名银牌方案 (发现后处理魔法)

作者: Mark Peng | 比赛排名: 第30名

恭喜所有获奖者!在这次比赛中,我学到了很多关于基于BERT的模型架构的知识,想分享一些我的心得体会。

文本预处理

我只在最后两周才参加比赛,因此没有在预处理步骤上花费太多时间,但一些简单的技巧确实提高了分数。假设预训练BERT的内置分词器可以很好地完成进一步的预处理工作。

  • 删除多余的空格以使文本更紧凑
  • 反转义HTML实体,如 & lt;, & equals;, & gt ;
  • 如果发现HTML标签,则提取纯文本(使用BeautifulSoup的 get_text()
  • 删除以 \$ 开头的单词(主要是Latex关键字和一些语法关键字)

用于集成的自定义BERT模型

作为集成学习的粉丝,我始终相信模型多样性是成功的关键。我训练了5个基于BERT的模型,它们具有略微不同的自定义层,但它们共享相同的BERT嵌入结构:问题文本采用 [CLS] title [SEP] question [SEP],答案文本采用 [CLS] answer [SEP]。我只使用了BERT模型中 [CLS] token 的最后隐藏状态输出嵌入与其他层结合(池化输出效果较差)。

  • 拓扑结构 1: Roberta-Base, Xlnet-Base-Cased

    • 2个BERT嵌入 (CLS): q_embed, a_embed
    • 3个分类嵌入: Concat(cate_embeds) -> Dense(128, relu)
    • 2个独立的全连接层路径
      • Concat(q_embed, cate_embeds_dense) -> Dense(256, relu) -> Dense(21, sigmoid)
      • Concat(a_embed, cate_embeds_dense) -> Dense(256, relu) -> Dense(9, sigmoid)
  • 拓扑结构 2: Roberta-Base, Bert-Base-Uncased, Bert-Base-Cased

    • 2个BERT嵌入 (CLS): q_embed, a_embed
    • 2个独立的全连接层路径
      • q_embed -> Dense(256, relu) -> Dense(21, sigmoid)
      • a_embed -> Dense(256, relu) -> Dense(9, sigmoid)

我还发现,将问题和答案分成两个独立的全连接层路径比混合在一起效果更好。这对我来说很有道理,因为投票者对类别的标记可能分别侧重于 title+questionanswer 的内容。hosthost的第一个token和 category 列的分类嵌入层对集成分数有贡献。

所有模型的学习率固定为 2e-5,同时应用了 ReduceLROnPlateau 进行学习率衰减(因子=0.1)以及基于验证集Spearman分数的自定义早停回调。

最终模型是这些模型的加权平均,并进行了后处理以优化排名。

TensorFlow 2.1 上的确定性

重现性一直是tensorflow/keras的一个问题,但Nvidia的这个仓库帮助我在很大程度上控制了确定性!现在我们可以使用相同的随机种子在多次运行中获得几乎相同的结果。这让我们可以清楚地了解所有实验的相对性能,然后通过正确的设置和方法逐步改进模型。

https://github.com/NVIDIA/tensorflow-determinism

后处理魔法

很多人都在讨论能够提升Spearman相关系数分数的实际技巧/魔法是什么。我最初对此毫无头绪,但在研究了Spearman相关的定义和训练集标签中的模式后,我发现我们可以利用标签值的固定百分位数来近似每个类别的最佳排名。

同比赛其他方案