返回列表

4th place solution overview

386. Tweet Sentiment Extraction | tweet-sentiment-extraction

开始: 2020-03-23 结束: 2020-06-16 自然语言处理 数据算法赛
第4名方案概述

解决方案的主要部分:

  • 预处理
  • 预测3个(起始,结束)候选并为其分配分数
  • 使用外部模型对其进行评分,并为每个候选增加一个分数
  • 混合来自不同模型的候选分数
  • 选择最佳候选
  • 后处理

预处理和后处理。

这是“神奇”的部分。我想出的算法与其他解决方案中已经详细描述的算法相似,所以我只简要解释一下。

预处理是减少初始数据中“噪声”数量的过程,而后处理的目标是将其恢复。它们基于计算推文中选定文本之前的部分中的额外空格。额外空格是指推文中存在但在 ' '.join(tweet.split()) 中不存在的任何空格。

因此,在预处理中,我将选定文本的索引向右移动额外空格的数量,而在后处理中向左移动。这里的细微差别是选定文本的长度应该用其周围的单个空格来计算。所以在后处理中,通常目标 end_idxstart_idx + len(selected_text)+2,但如果 selected_text 以点、逗号、问号等结尾,则只应考虑文本之前的空格,end_idxstart_idx + len(selected_text)+1

预测3个(起始,结束)候选

架构

这种情况下的模型是Transformer。我使用了BERT、RoBERTa和ELECTRA。

模型的输入如下:

BERT或ELECTRA:[CLS] [POSITIVE] tweet [SEP]

RoBERTa:<s> [POSITIVE] tweet </s>

‘[POSITIVE]’也可以是‘[NEUTRAL]’和‘[NEGATIVE]’,这些是添加的情感标记。

它们的嵌入使用对应单词‘positive’、‘neutral’和‘negative’的嵌入进行初始化。在早期阶段,我也尝试在情感标记和推文之间放置[SEP],但效果稍差。后来没有对此设置进行实验。

作为目标,每个模型获取选定文本的起始和结束标记的索引。

模型有四个头:

1) QA密集头(只是一个没有任何dropout的线性层),用于预测起始和结束标记。将标记表示作为Transformer最后两层相应隐藏状态的连接。在这里尝试用可学习权重对所有层的隐藏状态进行加权求和,但效果稍差。

损失通过KL散度计算以添加标签平滑:真实目标标记被赋予0.9的概率,其两个邻居(左和右)各取0.05。如果真实目标标记在句子开头并且我们正在计算起始logits的损失,那么真实标记仍然得到0.9,但接下来的两个分别取0.06和0.04。如果真实结束标记是最后一个,则实施类似的事情:其概率为0.9,但前两个分别为0.06和0.04。

2) 线性层预测每个标记的二元目标:它是否应该在选定文本中。取最后一层的隐藏状态。尝试了很多其他层,但没有提高性能。损失为二元交叉熵。

3) 线性层预测每个标记的情感。也只使用Transformer的最后一层。预测3个类别——中性、积极和消极。选定文本中的标记被标记为具有与推文相同的情感,而所有其他标记被分配中性类别。这里的损失是每个标记单独的通常交叉熵。

4) 两个线性层,中间有ReLU,用于预测整个推文的情感。连接推文中所有标记的平均池化和最大池化,跳过cls和情感标记。然后连接Transformer最后两层的这种表示,并通过多样本dropout。在用交叉熵计算损失之前,还利用了动量交换(arxiv 2002.11102)。

训练阶段

在训练期间,总损失计算为来自所有四个头的损失的加权和。训练在8个折叠上进行,使用AdamW优化器,并在 get_cosine_with_hard_restarts_schedule_with_warmup 调度器上使用SWA进行10个epoch。SWA快照在每个epoch结束时拍摄,尽管此步骤与我使用的参数组合(num_warmup_steps, num_cycles)的最小学习率步骤不一致。出于某种原因(也许它增加了快照之间的多样性?),它比在每个学习率周期结束时拍摄快照效果更好。

尝试实现2002.10345的自蒸馏,看起来非常有趣并承诺增加训练的稳定性,但它只使性能显著变差。可能在实现中做错了什么。

推理阶段

1) 在推理时,第一个头用于创建一组(起始,结束)候选。首先,每一对 end >= start 的(起始,

同比赛其他方案