比较两个向量进行分类的损失函数

Loss function for comparing two vectors for categorization

我正在执行一项 NLP 任务,在该任务中我分析了一份文档并将其分为六类之一。但是,我在三个不同的时间段执行此操作。所以最终输出是一个由三个整数组成的数组(稀疏的),其中每个整数都是类别 0-5。所以标签看起来像这样:[1, 4, 5].

我正在使用 BERT 并试图决定我应该附加哪种类型的头,以及我应该使用哪种类型的损失函数。通过具有 18 个神经元的 Dense 层使用大小为 1024 和 运行 的 BERT 输出,然后重塑为大小为 (3,6) 的东西是否有意义?

最后,我假设我会使用稀疏分类交叉熵作为我的损失函数?

在典型设置中,您采用 BERT 的 CLS 输出(在 bert-base 的情况下长度为 768 的向量,在 bert-large 的情况下为 1024)并添加一个 classification head(它可能是一个带有 dropout 的简单 Dense 层)。在这种情况下,输入是单词标记,classification head 的输出是每个 class 的 logits 向量,通常使用常规的交叉熵损失函数。然后你对它应用 softmax 并获得每个 class 的类似概率的分数,或者如果你应用 argmax,你将获得获胜的 class。因此,结果可能是 class 化分数 [1x6] 的向量或主导 class 索引(整数)。

图片取自d2l.ai

您可以简单地连接 3 个这样的网络(针对每个时间段)以获得所需的结果。

显然,我只描述了一种可能的解决方案。但由于它通常会提供良好的结果,我建议您在转向更复杂的之前尝试一下。

最后,当输出稀疏时使用稀疏分类交叉熵损失(比如[4]),当输出是单热编码时使用常规分类交叉熵损失(比如[0 0 0 0 1 0] ).否则他们完全一样。

bert最终隐藏状态为(512,1024)。您可以采用第一个令牌,即 CLS 令牌,也可以采用平均池化。无论哪种方式,您的最终输出都是形状 (1024,) 现在只需像 nn.Linear(1024,6) 中那样放置 3 个形状 (1024,6) 的线性层并将其传递到下面的损失函数中。 (如果你愿意,你可以让它更复杂)

简单的把loss加起来,反向调用。请记住,您可以在任何标量张量上调用 loss.backward()。(pytorch)

def loss(time1output,time2output,time3output,time1label,time2label,time3label):
    loss1 = nn.CrossEntropyLoss()(time1output,time1label)
    loss2 = nn.CrossEntropyLoss()(time2output,time2label)
    loss3 = nn.CrossEntropyLoss()(time3output,time3label)

    return loss1 + loss2 + loss3