【问题标题】:Multi label classification in pytorchpytorch中的多标签分类
【发布时间】:2019-03-22 04:33:27
【问题描述】:

我有一个多标签分类问题。我有 11 个类,大约 4k 个示例。每个示例可以有 1 到 4-5 个标签。目前,我正在使用 log_loss 为每个类分别训练一个分类器。正如您所料,训练 11 个分类器需要相当长的时间,我想尝试另一种方法并只训练 1 个分类器。这个想法是这个分类器的最后一层将有 11 个节点,并且会按类输出一个实数,然后通过 sigmoid 将其转换为概率。我要优化的损失是所有类的 log_loss 的平均值。

不幸的是,我是 pytorch 的菜鸟,即使通过阅读损失的源代码,我也无法确定已经存在的损失之一是否完全符合我的要求,或者我是否应该创建一个新的损失,如果是这样的话,我真的不知道该怎么做。

具体来说,我想为批次的每个元素提供一个大小为 11 的向量(其中包含每个标签的实数(越接近无穷大,该类预测为 1 越接近),并且1 个大小为 11 的向量(每个真实标签都包含一个 1),并且能够计算所有 11 个标签的平均 log_loss,并根据该损失优化我的分类器。

任何帮助将不胜感激:)

【问题讨论】:

    标签: pytorch


    【解决方案1】:

    您正在寻找torch.nn.BCELoss。下面是示例代码:

    import torch
    
    batch_size = 2
    num_classes = 11
    
    loss_fn = torch.nn.BCELoss()
    
    outputs_before_sigmoid = torch.randn(batch_size, num_classes)
    sigmoid_outputs = torch.sigmoid(outputs_before_sigmoid)
    target_classes = torch.randint(0, 2, (batch_size, num_classes))  # randints in [0, 2).
    
    loss = loss_fn(sigmoid_outputs, target_classes)
    
    # alternatively, use BCE with logits, on outputs before sigmoid.
    loss_fn_2 = torch.nn.BCEWithLogitsLoss()
    loss2 = loss_fn_2(outputs_before_sigmoid, target_classes)
    assert loss == loss2
    

    【讨论】:

    • 感谢您的回答,我相信这实际上是我想要的损失。我不在网络中做 sigmoid,所以我选择使用 BCEWithLogitsLoss。但是,我仍然遇到一个问题,当我运行我的代码时,我得到一个错误“-> 1651 loss = input - input * target + max_val + ((-max_val).exp() + (-input - max_val)。 exp()).log() RuntimeError: Expected object of type torch.cuda.FloatTensor but found type torch.cuda.LongTensor for argument #2 'other' " 这个错误来自 BCEWithLogitsLoss 的源代码。有什么见解吗?
    • 我自己解决了这个问题,在加载目标时,我将他的类型更改为浮动,它修复了我的错误。
    猜你喜欢
    • 2022-01-07
    • 2020-02-01
    • 2018-12-01
    • 2021-01-26
    • 2020-08-14
    • 2020-09-04
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    相关资源
    最近更新 更多