返回列表

4th place solution

574. CommonLit - Evaluate Student Summaries | commonlit-evaluate-student-summaries

开始: 2023-07-12 结束: 2023-10-11 智能评测 数据算法赛
作者:chumajin
排名:第4名
团队成员:chumajin, kurokurob

非常感谢组织这场精彩竞赛的主办方和Kaggle团队。

这场竞赛正如我们所期待的那样,我们非常高兴能够获得第四名。

非常感谢@kurokurob与我组队,以及每日的讨论和实验。祝贺你获得第四枚金牌奖章。
(而且我将成为竞赛Grand Master!!!)
我们是一个伟大的团队!

1. 总结

我们的最佳私有解决方案是1个全训练集 × 7个模型的集成。

这场竞赛的训练数据只有4个提示词,而测试数据有122个提示词,可以预想会有很大的波动。而且公共排行榜非常不稳定。这些都让我们认为鲁棒性很重要,不仅仅是为了交叉验证。

我一开始使用了4折交叉验证。特别是那些使用提示文本的模型,因为我必须增加最大长度来提高分数,这导致推理时间增加,无法集成更多模型(只能包含2-3个模型)。

就在这时,我和kuro合并了团队。我们将他一直在研究的全训练集想法融合进来。通过用1个全训练集替代4折交叉验证,我们想到了将4折的信息压缩到1个全训练集中并集成更多模型的方案。

我们想象通过这样做,可以防止私有测试数据中每个提示词上的分数变化和下降,总体上获得更好的分数。

结果,我们相信我们成功防止了排名下滑,并取得了这个名次!

提交 类型 模型 CV Public LB Private LB 排名 备注
sub1 最佳LB 1全训练 × 9模型 0.4679 0.41991 0.45785 11 使用GBDT和扩展推理长度
sub2 最佳CV 1全训练 × 7模型 0.4639 0.42979 0.45515 4 纯NLP结果(扩展推理长度)
sub3 保险方案 1全训练 × 8模型 0.4693 0.43855 0.45597 6 纯NLP结果

sub2中的最佳CV是我们的最佳私有方案,以下是主要说明。

2. 训练

我们在sub2中的每个模型如下表所示。

模型编号 推理编号 模型 训练最大长度 推理最大长度 冻结 逐层 输入 池化 第二损失 预处理 4折早停CV
原始提示词 CLS 原始提示词注意力 仅文本部分均值
1 91 deberta-v3-large 768 1500 0.4818
2 22 deberta-v3-large 1050 950 0.4855
3 63 deberta-v3-large 850 1500 0.4984
4 72 deberta-v3-large 868 1024 Arcface 0.4919
5 2,3 deberta-v3-large 868 868 0.4880
6 259 deberta-v3-large-squad2 768 1500 0.4952
7 331 deberta-v3-large-squad2 1050 950 0.4993

下面详细描述各个模型。

2.1 模型1号:基础模型

这个模型是我们模型的典型基础。

首先,准备两个输入并将它们作为一对放入分词器中(数据集示例)。即使不将它们作为一对,也可以通过用[SEP]连接它们来获得相同的结果。

self.text = self.df["text"]
self.prompt = self.df["prompt_title"] + [SEP] + self.df["prompt_question"] + [SEP] + self.df["prompt_text"]

tokens = tokenizer.encode_plus(
            self.text, 
            self.prompt,
            ...
        )

现在所有我们要做的就是将其放入模型中,增加最大长度,并在全连接层输出CLS。

2.2 模型2号:原始提示词

在这个模型中,创建了一个原始提示词并用作输入。

self.text = "Evaluating the summarized text and calculating content and wording score : " + self.df["text"].values
self.prompt = prompt_title + [SEP] + prompt_question + [SEP] + prompt_text

tokens = tokenizer.encode_plus(
            self.text, 
            self.prompt,
            ・・・
        )

然后,仅对原始提示词部分(Evaluating the summarized...)进行注意力池化(模型示例)。

## init
self.pool = AttentionPooling(self.config.hidden_size)
...

## forward
output = self.model(ids, mask, token_type_ids)
output = output[0][:,:12,:]
output = self.pool(output, mask[:,:12])
output = self.fc(output)

2.3 模型4号:使用第二损失和预处理

正如讨论和notebook中所讨论的,训练数据可以分为38种类型。我认为可以很好地利用这一点,所以加入了Arcface作为辅助损失。我尝试很好地利用最后的嵌入,但不可行。然而,它确实有助于集成模型的多样性。

另外,作为预处理,我确保在句点和逗号后包含一个空格;在进行EDA后,我注意到如果一个句子在句点或逗号后没有空格,分词器会将其分割得不同。不过,我认为这对分数影响不大。

2.4 扩展推理最大长度

通过将推理长度增加到超过训练长度,分数得到了显著改善。示例如下。以下模型训练时最大长度为850,但通过在推理时设置最大长度为1500,CV和公共榜分数提高了(可能对私有榜贡献不大)。

训练最大长度 推理最大长度 39c16e折0 814d6b折1 ebad26折2 3b9047折3 CV
850 850 0.4505 0.5595 0.5051 0.5024 0.4984
850 1024 0.4524 0.5590 0.4836 0.5018 0.4927
850 1500 0.4527 0.5588 0.4614 0.5013 0.4867

然而,有些模型可能会退化。保险提交(sub3)只包含那些没有扩展推理最大长度的模型。结果,CV和公共榜受到影响,但私有榜几乎没有影响。

3. 推理(集成)

对于最佳CV提交,我们最初使用GBDT(LGBM + Catboost + XGboost)进行后处理,但最终,不使用GBDT的集成得到了更好的CV。产生最佳私有榜的提交没有使用GBDT后处理。我们也考虑了Nelder-Mead和Optuna,但因为担心它们肯定会过拟合而没有使用。所以我们使用简单的均值集成,采用爬山法(为了额外的推理时间,我们还添加了不同种子的全训练以进一步提高鲁棒性)。

最终CV(4折早停结果):0.46394,Public:0.42979,Private:0.45515 第4名

※ 此外,我们还准备了保险方案(sub3),其中推理最大长度与训练时相同。结果如下:

最终CV:0.4693,Public:0.43855,Private:0.45597 第6名

在这个结果中,CV和LB都很差,但私有榜很好,这说明了在这个竞赛中模型的鲁棒性有多重要。

4. 未奏效的方法

  • MLM
  • AWP
  • SVR
  • 其他模型
  • 从分类模型回归
  • 其他许多方法...

5. 致谢

我们无法独自取得这些成果。我们受到了过去合作过的人的很大影响,感谢他们的贡献。我们还要向那些通过以往竞赛分享知识和见解的人表示诚挚的感谢。非常感谢。

我们特别感谢以下人员在这次竞赛中的帮助!非常感谢。

6. 团队成员

团队照片

7. 代码

同比赛其他方案