返回列表

20th place solution

446. CommonLit Readability Prize | commonlitreadabilityprize

开始: 2021-05-03 结束: 2021-08-02 智能评测 数据算法赛
第20名方案

第20名方案

作者: Trushant Kalyanpur (Force Awakens 团队)
比赛: CommonLit Readability Prize

首先,我要感谢 CommonLit 团队和 Kaggle 举办这场有趣的挑战赛,让我们得以探索最先进的 NLP 方法。训练数据的规模较小,且评审员对目标的标注存在差异,这使得这项挑战非常有趣。

宏观方法概述:

我们的团队 Force Awakens 在比赛截止日期前一个月合并成立,我们发现大家采用了两种截然不同的方法,这对我们非常有利。

  • 回归方法 - 我将概述这种回归方法,这也是许多公开 Kernel 所使用的方法。
  • 成对模型方法 - 在此处讨论。这非常独特,我在论坛上未曾见过相关讨论。

单独使用回归方法在 Public LB 上得分为 0.454,在 Private LB 上得分为 0.457。结合成对模型方法(Public 得分 0.454,Private 得分 0.454),我们的最终最佳得分为 Public LB 0.450 和 Private LB 0.452

回归方法:

我们训练了许多不同的架构,包括 base/large/x-large 等版本。正如许多人观察到的那样,我们发现 large 模型在这个数据集和目标分布上表现最好。我们尝试了非常多的架构,包括但不限于 Roberta/Electra/Funnel/Deberta/StructBERT/BERT/XLNET/BART/T5/AlBERT/Luke/DistilBERT 等。

在回归任务中表现最好的模型有:

  • Roberta-large - Public LB 0.464
  • Funnel-large - Public LB 0.465
  • Deberta-large - Public LB 0.466
  • Electra-large - Public LB 0.468
  • Roberta-base - Public LB 0.467

训练方法:

  • 我们花了很多时间尝试不同的学习率调度器、损失函数、BERT 模型的不同嵌入方式以及嵌入层之上的自定义头部。
  • 对于回归方法,效果最好的是使用 CLS token,然后接上一个包含 2 个线性层和 GELU 激活函数的自定义头部。
        self.whole_head = nn.Sequential(OrderedDict([
            ('dropout0', nn.Dropout(args.use_dropout)),
            ('l1', nn.Linear(args.fc_size, 256)),
            ('act1', nn.GELU()),
            ('dropout1', nn.Dropout(args.use_dropout)),
            ('l2', nn.Linear(256, 1))
        ]))
  • 训练每个模型本身就是一项挑战,因为没有一套通用的参数适用于所有架构。此外,不同折之间的得分差异很大,因此我们采用了一种方法,可以在训练脚本中指定折/种子,并使用不同的参数(如更改 LR、评估步数、MLM 的使用、Dropout)重新训练表现不佳的折。
  • 在比赛数据上进行 MLM 任务的预训练似乎有帮助,但我们并未在所有折上都使用它。利用前一点提到的方法,我们在少数折上使用了 MLM 预训练模型,这在 LB 上的效果优于在所有折上使用(可能防止了过拟合)。
  • 有效的方法:
    • 在部分折上使用预训练的 MLM 模型。
    • 使用较小的学习率 1e-5/2e-5 配合余弦调度器,训练 5 个 epoch,并在每个 epoch 中频繁运行评估。
    • 对 BERT 层使用差异化学习率。
  • 无效的方法:
    • 数据增强。
    • 将额外的可读性特征添加到 BERT 的最后 NN 层,或使用基于 SVR/GBM 的元学习模型。
    • 重新初始化最后 N 层 BERT 层 - 本地 CV 看起来很有希望,但至少对我们来说,这并没有带来更好的 LB 成绩。