返回列表

Worst place writeup (15th solution) with code

386. Tweet Sentiment Extraction | tweet-sentiment-extraction

开始: 2020-03-23 结束: 2020-06-16 自然语言处理 数据算法赛
第15名解决方案:没有魔法的最差名次写法

第15名解决方案:没有魔法的最差名次写法

作者:CPMP (Grandmaster) | 发布时间:2020-06-17

哇,真没想到我会以一名之差错失金牌的成绩结束比赛。比赛最后一天的早上我还排在第49名,并且在排行榜上停滞了好几周。幸运的是,我在前一天晚上决定在未处理的数据上训练我最好的模型,睡觉前第一折的分数显示很有希望。尽管如此,要在Kaggle上成功提交还是在最后一天引发了手忙脚乱的工作。而且我最好的一次提交的评分是在比赛的最后一分钟才结束的。我在别处记录了最后一天遇到的挫折和问题,这里就不重复了。只能说我认为自己对这个最终结果感到很幸运。

在这篇文章中,我将描述我的解决方案,以及我尝试过但没有太大帮助的内容。

在深入细节之前,我要感谢Kaggle举办了这场充满挑战的比赛。它将相当经典的NLP比赛与解谜元素结合在了一起。这个谜题(也就是魔法)来自于标记前对文本的一些隐藏预处理。如果没有这个,比赛可能会有些无聊。

不要过拟合

早期的实验清楚地让我确信,过拟合将是这里的主要问题。当你改变折的定义方式时,交叉验证分数的高变异性显示了这种危险。@cdeotte 在这里的一个帖子中也清楚地记录了这一点。一种解决方法是增加数据(通过额外的外部数据、伪标签或使用一些数据增强技术)。我尝试过的这些方法都没有真正起到作用(见下文)。另一种补充方法是整合多次运行。根据大数定律,分数的方差会减小。因此,我决定使用7组不同的5折数据来训练模型。折是按情感和“选定文本等于全文”的比例进行分层的。据此,我计算了两个指标:7个CV分数的平均值,以及平均所有预测值时的CV分数。在后一种情况下,每个样本预测是7个折外预测的混合。这两个指标的改善转化为LB(排行榜)的改善,噪音最多为0.002。只有在至少一个指标有显著改善时我才提交,并且只有在LB也有所改善时才保留修改。

高效的代码

为了实现这一点,我优化了代码。在V100 GPU上,使用4/5的训练数据训练roberta-base每个epoch只需不到2分钟。关键是调整批次数据大小。基本上,我将输入大小截断为批次中未填充输入的最大值。我的推理脚本展示了如何做到这一点:https://www.kaggle.com/cpmpml/ensemble?scriptVersionId=36550365

推理也非常高效,在Kaggle P100 GPU上预测公共测试数据上的roberta-base模型大约需要14秒。

不过问题是,与固定大小相比,CV和LB分数下降了。我通过屏蔽所有填充的logits恢复到了相同的性能水平。这使得预测对填充长度不敏感。

一个关键组件是使用huggingfaces tokenizers库。我是从 @abhishek 的代码开始的。

模型

我最终在robert和roberta large模型上使用了一个简单的CNN头部。有一个用于起始logits的CNN头部和一个用于结束logits的CNN头部。起始logits的头部是对一个token的最后隐藏状态和输入序列中前一个token的最后隐藏状态进行卷积。目标是检测从前一个与情感无关的token到与情感相关的token的过渡。类似地,结束logits是一个token和其后继token之间的卷积。

我尝试了更复杂的头部,但它们导致了过拟合。

我也尝试了许多huggingfaces模型,最后只保留了roberta-base和roberta-large-squad2。

训练设置

我尝试了各种优化器和调度器,但最后保留了 @abhishek 的设置,只是我运行了5个epoch。增加2个epoch给了我0.002的LB和CV提升。简而言之,设置是:huggingfaces AdamW优化器,学习率为3e-5,线性调度且无预热。我使用早停只保留最好的检查点。

Roberta large在这个数据集上很容易过拟合。我有CV分数为0.1或更低的运行。我尝试了各种正则化(见下文),但最后使用了一个非常简单的方法:如果第一个epoch的jaccard分数小于0.695,则在同一折上用不同的pytorch种子重新开始。这导致了CV平均值为0.7195,混合CV为0.726,公共LB为0.726,这是最后一天晚上的情况...

我用7x5折训练了roberta-base,但也用7个不同的pytorch种子在完整数据上训练了它。对于这些,我保留了第3、4和5个epoch的检查点,因为运行交叉验证时最好的检查点总是在这些epoch中。像swa那样平均它们的权重在我的待办事项列表中,我认为这比平均预测要好一点。

我使用了平滑交叉熵损失。它似乎比交叉熵更好、更稳定。

数据准备

我应该早点花时间尝试变体。直到最后一天

同比赛其他方案