返回列表

11th place solution

331. Jigsaw Unintended Bias in Toxicity Classification | jigsaw-unintended-bias-in-toxicity-classification

开始: 2019-03-29 结束: 2019-07-18 内容安全 数据算法赛
第11名方案
作者: toxu, tides | 排名: 第11名

感谢 Kaggle 和 Jigsaw 举办了这场精彩的比赛,我差点就赢得了我的 Titan RTX 显卡😔。在与 @tides 组队后,我们互相学习了很多,通过简单地平均我们的提交结果,LB 分数提高了很多。我们发现方法的多样性导致了分数的提升。我专注于语言模型的微调,而 tides 则专注于更合理的损失函数。

总结

toxu:

在这次比赛中,我没有在自定义损失函数上花费太多时间。我主要专注于训练更多不同种类的语言模型,并试图让推理更快。

模型

几个基于 RNN 的模型,使用了不同的嵌入(glove, fasttext, word2vec, para 及其拼接)。通过平均所有结果,LB 分数达到了 0.938+。

BERT 模型:

  • uncased bert base
  • cased bert base
  • uncased bert large
  • cased bert large

以上所有 BERT 模型都进行了语言模型微调。我发现语言模型微调很有帮助,但很耗时。

对我有效的方法

  • 预处理(来自公共 kernel
  • 语言模型微调。
  • 将句子填充到不同的长度,并将长度相似的句子放在一个批次中。这也帮助我们在推理时放入更多的模型。

对我无效的方法

  • lexvec 嵌入
  • NumberBatch 嵌入
  • 基于之前 Jigsaw 比赛的堆叠
  • 句子的统计特征

tides:

模型总结

  • bilstm + cnn:12个模型,使用不同的嵌入和损失 (0.94163) + 6个模型,使用不同的分词器
  • 3个 bert uncased base (最佳 0.94346)
  • 1个 bert cased base (0.94184)
  • 1个 bert uncased large
  • 1个 gpt2

关于 bert,实际上在使用分桶技术时,我犯了一个错误,导致 '[SEP]' 被截断了。在我修改了错误并添加了另一个技巧后,本地分数从 0.9390 提升到了 0.9410(95万训练集,20万验证集)。但我没有时间更新模型了。

损失函数:

我更关注损失函数。经过一些实验,我尝试绘制4种样本(sp, sn, bp, bn)的预测分布,并设计损失函数来调整这些分布。以下是设计的损失函数。每部分的验证并不是很稳固,所以要小心。

class MyFocalLoss(nn.Module):
    def __init__(self, alpha=1, gamma=1, logits=True, reduce=True):
        super(FocalLoss, self).__init__()
        self.alpha = alpha
        self.gamma = gamma
        self.logits = logits
        self.reduce = reduce
        
    def forward(self, inputs, targets, weight, focal_weights, penalty_weights, focal_alpha, penalty_alpha):
        if self.logits:
            BCE_loss = nn.BCEWithLogitsLoss(weight=weight, reduce=False)(inputs, targets)
        else:
            BCE_loss = nn.BCELoss(weight=weight, reduce=False)(inputs, targets) 
        pt = torch.exp(-BCE_loss)
        
        # 设计的部分
        bias_weights = (1.0 + targets.detach() - torch.sigmoid(inputs).detach())
    
        F_loss = (1-pt)**(focal_weights) * BCE_loss * (bias_weights ** penalty_weights) * focal_alpha * penalty_alpha
        
        if self.reduce:
            return torch.mean(F_loss)
        else:
            return F_loss
IDENTITY_COLUMNS_WEIGHTS= {
    'black': 4.5,
    'white': 3.5,
    'homosexual_gay_or_lesbian': 5,
    'muslim': 2.5,
    'jewish': 0.2,
    'female': 1,
    'christian': -0.1,
    'male': 0.5,
    'psychiatric_or_mental_illness': 4.5
}
def get_sample_weight_and_scale(train):
    sample_weights = np.ones((len(train),))
    
    # sn(子群, 负样本) 样本会有更多的权重,权重被调整以平衡 'bnsp_auc' 和 'bpsn_auc'