命名实体识别中的不平衡类

数据挖掘 机器学习 阶级失衡 伯特 命名实体识别
2022-02-27 12:37:48

我目前正在研究一个 NER 问题,该问题试图从印度尼西亚语的地址字符串中提取 2 个实体 - 地点(POI)和街道。

我使用了 IndoBert(可在此处获得)并将 FC 层附加到 BERT 模型上,利用交叉熵损失来预测每个单词所属的类别。然而,我的数据集中的典型例句标签看起来像这样[1, 4, 5, 5, 1, 1, 2, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

其中 2-5 代表 POI 和街道类别,0 是 pad tokens,1 代表 O tags(BIO tagging)代码。然而,该模型最终会不断预测所有单词的多数类。然后我在损失函数中使用了忽略索引和权重,如下所示:

WEIGHTS = torch.Tensor([0.05, 0.2, 1, 1, 1, 1])
def loss(predicted, target):
    predicted = torch.rot90(predicted, -1, (1,2))
    criterion = nn.CrossEntropyLoss(weight = WEIGHTS,ignore_index=0, reduction='mean')
    return criterion(predicted, target)

然而,虽然这解决了上述问题。该模型也不会学习,损失只是在同一水平上波动。因此,我想知道是否有办法调整此类不平衡阻止模型预测 [PAD] 令牌的类别


这是我的模型的代码:

class aem(nn.Module):
    def __init__(self, no_class):
        super().__init__()
        self.bert = AutoModel.from_pretrained("sarahlintang/IndoBERT")
        self.drop1 = nn.Dropout(p=0.1)
        self.l1 = nn.Linear(self.bert.config.hidden_size, no_class)
        self.out = nn.GELU()     
    
    def forward(self, inputs, attn):
        hidden = self.bert(inputs, token_type_ids=None, attention_mask=attn, return_dict = True)
        L1out = self.out(self.l1(self.drop1(hidden[0])))
        return L1out
0个回答
没有发现任何回复~