386. Tweet Sentiment Extraction | tweet-sentiment-extraction
感谢我出色的队友 Shai @sgalib、Yasin @mykttu、Cooleel @cooleel。我们共同努力获得了金牌,我非常激动能拿到我的第5枚竞赛金牌,并成为 竞赛特级大师!
同时恭喜 Shai @sgalib 成为竞赛特级大师,以及 Cooleel @cooleel 成为竞赛大师!
我们最佳的最终提交是一个单一的 TensorFlow RoBERTa 模型。我们从我的公共 Notebook 开始,其 CV 为 0.705,Public LB 为 0.709,Private LB 为 0.713。然后我们做了 10 项改进,将分数提升至 CV 0.718,Public LB 0.724,Private LB 0.726。
我们测试了几十个甚至上百个想法。由于训练数据量很小,对于每个想法,我们使用 10 个不同的 K Fold 随机种子运行本地 CV 10 次并取平均分(即 5 折乘以 10 等于 50 次)。以下每项改进至少使 CV 平均分提高了 0.001。
多余的空格包含信号。例如,如果文本是 "that's awesome!",则选中文本为 awesome。然而,如果文本是 " that's awesome!"(开头有两个空格),则选中文本为 s awesome。第二个例子在文本开头有额外的空格,因此选中文本包含了一个额外的前置字母。
RoBERTa 会将 "..." 视为一个单独的 token,因此如果文本是 "This is fun...",你的模型无法选择 "fun."。所以在预处理阶段,将所有单个 [...] token 转换为三个 [.][.][.] token。类似地,拆分 "..", "!!", "!!!"。
相比于高估,低估目标会带来更高的 Jaccard 得分。因此,如果文本是 " Matt loves ice cream" 且选中文本是 "t love",请使用 "love" 而不是 "Matt love" 来训练模型。所有公共 Notebook 都采用后者,我们建议前者。
首先预测结束索引。然后将结束索引的 logits 与 RoBERTa 最后一层隐藏层连接起来,以预测开始索引。
# ROBERTA
bert_model = TFRobertaModel.from_pretrained('roberta-base')
x = bert_model(q_id,attention_mask=q_mask,token_type_ids=q_type)
# 结束索引头
x2 = tf.keras.layers.Dropout(0.1)(x[0])
x2b = tf.keras.layers.Dense(1)(x2)
x2 = tf.keras.layers.Flatten()(x2b)
x2 = tf.keras.layers.Activation('softmax')(x2)
# 开始索引头
x1 = tf.keras.layers.Concatenate()([x2b,x[0]])
x1 = tf.keras.layers.Dropout(0.1)(x1)
x1 = tf.keras.layers.Dense(1)(x1)
x1 = tf.keras.layers.Flatten()(x1)
x1 = tf.keras.layers.Activation('softmax')(x1)
# 模型
model = tf.keras.models.Model(inputs=[q_id, q_mask, q_type], outputs=[x1,x2])
loss = tf.keras.losses.CategoricalCrossentropy(label_smoothing=0.2)
使用数据加载