604. The Learning Agency Lab - PII Data Detection | pii-detection-removal-from-educational-data
首先,感谢 Kaggle 和 The Learning Agency Lab 举办的这场比赛,既有趣又非常贴近实际应用!
感谢 @gauravbrills、@ympaik、@drpatrickchan、@evgeniimaslov2 的精彩合作!
业务背景:Kaggle PII 检测与去除
数据背景:数据说明
以下是我们使用的数据集:
每个实验使用 4 折训练(document % 4),随后进行 1 或 2 次全量拟合。
我们尝试了多种模型和架构。由于 Deberta 在推理速度快且在 LB 与 CV 上表现优秀,我们将多种 Deberta 变体加入集成。主要尝试包括:
帮助训练曲线更平滑,减少普通模型训练时出现的尖峰。
在分类器之前加入 BiLSTM 层,已在公开笔记本中使用。此举提升了多样性,训练更平稳,分数与 LB、CV 关联良好。训练时若出现 NaN 损失,初始化该层并使用 save_safetensors=False 保存可解决问题。
由于部分模型在不同的数据集上训练,我们尝试使用这些模型作为教师,对在另一数据集上训练的学生模型进行蒸馏,使用相同的验证折。此方法显著提升了 CV 与 LB,提升幅度约 0.005‑0.01。我们也曾尝试使用多个教师模型,但时间不足未能完成。
我们尝试在部分作文中进行姓名交换后再训练(例如文档 7779 中 “Leroy” 既是 B‑NAME_STUDENT 又是 I‑NAME_STUDENT),以此作为集成的一个实验。
感谢 @gauravbrills 提出的第 2、3 点,提升了我们集成的多样性。
class CustomTrainer(Trainer):
def __init__(self, *args, class_weights=None, teacher_model=None, **kwargs):
super().__init__(*args, **kwargs)
self.class_weights = class_weights
self.teacher_model = teacher_model.to(self.args.device)
self.temperature = 3
self.alpha = 0.5
def compute_loss(self, model, inputs, return_outputs=False):
labels = inputs.pop("labels").to(self.args.device)
inputs = {name: tensor.to(self.args.device) for name, tensor in inputs.items()}
outputs = model(**inputs)
with torch.no_grad():
teacher_outputs = self.teacher_model(**inputs)
teacher_logits = teacher_outputs.logits
logits = outputs.logits
loss_fct = torch.nn.CrossEntropyLoss(weight=self.class_weights.to(self.args.device))
loss_student = loss_fct(logits.view(-1, self.model.config.num_labels), labels.view(-1))
distillation_loss = torch.nn.KLDivLoss()(F.log_softmax(logits / self.temperature, dim=-1),
F.softmax(teacher_logits / self.temperature, dim=-1)) * self.temperature ** 2
loss = loss_student * self.alpha + distillation_loss * (1 - self.alpha)
return (loss, outputs) if return_outputs else loss
后处理是提升 CV 与 LB 的关键。我们根据 OOF 预测中的错误模式采用了以下步骤: