返回列表

7th place solution

386. Tweet Sentiment Extraction | tweet-sentiment-extraction

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

第7名方案

作者: Xuan Cao (naivelamb)
比赛: Tweet Sentiment Extraction

首先,我们要感谢 Kaggle 举办这次比赛。感谢我的队友 @murphy89 @wuyhbb 的辛勤工作。感谢 @abhishek 提供了一个非常坚实的基础。这是我获得的第一个 NLP 金牌,我非常高兴!

TLDR(太长不看版)

使用模型预测真实的起始/结束索引,使用后处理来捕获噪声

模型

我们的模型是基于 RoBERTa-base 并定制了头部。我们有两种模型结构:

1. 模型-1

  • Concat([BERT 最后 2 个隐藏层]) -> Conv1D -> Linear
  • 结束位置依赖于起始位置(取自 这里),代码如下:
# x_head, x_tail 是 Conv1D 之后的结果
logit_start = linear(x_start)
logit_end = linear(torch.cat[x_start, x_end], dim=1) 

2. 模型-2

  • Concat([BERT 最后 3 个隐藏层]) -> Conv1D -> Linear
  • 辅助任务:判断预测是否为整段文本(分类)以及该 token 是否在选定文本中(分割)。

预处理与分词

我们使用了两种方法来预处理文本和 selected_text:

方法-1

  1. 清理文本 & selected_text:" ".join(text.split())
  2. 如果情感不是 "neutral",拆分标点符号:'...' ==> '. . .'(如果 sentiment != 'neutral' 则有 50% 概率执行)。
  3. 修正 "�" 的错误偏移量(如果你使用 tokenizers 0.7.0 则不需要此步骤)。
  4. 如果 len(selected_text) > 4token 的 char_target_pct >= 0.5,则该 token 被视为目标。
  5. Max_len = 192。

方法-2

  1. 基于后处理方法清理标签(稍后讨论)。
  2. 使用原始文本 & selected_text,在单词级别进行分词,对所有空格使用 "Ġ"。
  3. 动态填充。

我们使用两种模式为这两种方法构建训练样本:[sentiment][text] 和 [sentiment][raw sentiment][text],其中 raw sentiment 来自原始完整数据集。我们在预处理过程中没有将文本转换为小写,而是将其用作数据增强。方法-1 用于模型-1,而方法-2 用于模型-2。

训练相关

  • Batch size: 32
  • Optimizer AdamW, weight decay 0.01
  • Scheduler: cosine scheduler with warmup
  • Loss: CrossEntropy with label smoothing

我们使用线性调度器和 warmup(lr=1e-5)对模型-1(仅头部)进行了另外 3 个 epoch 的微调。模型-2 使用 Fast Gradient Method (FGM) 进行训练。我们在公共 LB 上最好的单模型:[sentiment][raw sentiment][text] + 方法-1 + 模型-1,在 10 折设置上训练(CV 0.7177, LB 0.719)。

后处理

后处理分为两部分:将 "neutral" 预测设置为文本(所有 CV 分数均在此处理之后),以及处理噪声。第一部分很简单,所以我们在这里重点讨论第二部分。实际上许多人在比赛期间注意到了很多神秘的 selected_texts。例如:

[text]           : [ hey mia!  totally adore your music.  when will your cd be out?]
[selected_text]  : [y adore]

以方法-1 为例,它把 [y] 丢掉了,只在目标范围内留下了 [ adore]。因此,训练好的模型擅长预测 [ adore] 作为结果(jaccard(decode_target, pred) = 1),但由于噪声 [y],最终的 jaccard 只有 0.5。实际上,对于验证集 jaccard 分数约为 0.717 的模型,预测与解码目标之间的 jaccard 分数约为 0.724。因此,如果我们能以某种方式加回噪声,我们就能提高模型性能。对于上面的例子,人们可能会自然地认为原始标签是 [ adore ],因此给定的标签可以通过将范围向左移动一个位置来实现。后来,如果我们比较文本和清理后的文本,我们意识到了这些偏移的来源:

[text]           : [ hey mia!  totally adore your music.  when will your cd be out?]
[clean text]     : [hey mia! totally adore your music. when will your cd be out?]

你会意识到文本中有 3 个额外的空格,一个在开头,两个在中间。忽略开头的空格和 selected_text 范围后的那个,中间有一个额外的空格,这正是偏移位置的数量。

[text_no_leading]: [hey mia!  totally adore your music.  when will your cd be out?]
[selected text]  :                 [y adore]
[clean text]     : [hey