美文网首页
(pytorch) 如何给每个样本赋予权重

(pytorch) 如何给每个样本赋予权重

作者: 井底蛙蛙呱呱呱 | 来源:发表于2020-12-29 11:11 被阅读0次

    在各种分类任务中,我们常常会遇到样本不均衡问题,这时需要对各个类别设置不同的权重,在pytorch中我们可以在初始化loss函数时传入权重,即:

    batch_size = 10
    nb_classes = 2
    
    model = nn.Linear(10, nb_classes)
    weight = torch.empty(nb_classes).uniform_(0, 1)
    # 初始化CrossEntropy函数时传入各个class的权重
    criterion = nn.CrossEntropyLoss(weight=weight)
    ce = nn.CrossEntropyLoss(ignore_index=255, weight=weight_CE)
    loss = ce(inputs,outputs)
    

    但有时候,我们不仅每个类别有权重,而且每个样本的权重也不相同。这时候需要更精细的控制了,可通过两步来达到此目的:

    • (1) 在初始化函数时设置 reduction='none', 此时loss函数返回的是一个array,表示各个sample的loss;reduction默认设置为mean,表示loss函数会默认对所有样本的loss取平均,返回一个标量;
    • (2) 手动加权,得到各个样本的loss array后,我们可以对每个loss赋予(乘以)相应的权重,这时即达到了对不同样本赋予不同权重的目的。
    batch_size = 10
    nb_classes = 2
    
    model = nn.Linear(10, nb_classes)
    weight = torch.empty(nb_classes).uniform_(0, 1)
    # 初始化CrossEntropy函数时传入各个class的权重, 
    # 且设置reduction为None表示不进行聚合,返回一个loss数组
    criterion = nn.CrossEntropyLoss(weight=weight, reduction='none')
    
    # This would be returned from your DataLoader
    x = torch.randn(batch_size, 10)
    target = torch.empty(batch_size, dtype=torch.long).random_(nb_classes)
    sample_weight = torch.empty(batch_size).uniform_(0, 1)
    
    output = model(x)
    loss = criterion(output, target)
    # 各个样本乘以其权重,然后求均值
    loss = loss * sample_weight
    loss.mean().backward()
    

    此外,还可以对每个样本的loss进行归一化,使得所有batch的loss大小范围较为相近:

    loss =(loss * sample_weight / sample_weight.sum()).sum()
    

    此步非必须,因为我们给定各个样本不同权重其实就是要使得各个样本的loss有区别的。

    最后,其实也可以不使用CrossEntropy,而使用softmax+nnl_loss函数来给各个样本添加权重,这种方式更灵活,也稍微麻烦一些。

    参考:
    Per-class and per-sample weighting

    相关文章

      网友评论

          本文标题:(pytorch) 如何给每个样本赋予权重

          本文链接:https://www.haomeiwen.com/subject/acrfoktx.html