【问题标题】:Weighted random sampler - oversample or undersample?加权随机采样器 - 过采样还是欠采样?
【发布时间】:2021-08-20 06:22:42
【问题描述】:

问题

我正在 PyTorch 中训练一个用于二进制分类的深度学习模型,并且我有一个包含不平衡类比例的数据集。我的少数类占给定观察的10%。为了避免模型学习只预测多数类,我想在我的DataLoader 中使用来自torch.utils.dataWeightedRandomSampler

假设我有 1000 观察(900 在类 0100 在类 1),并且我的数据加载器的批量大小为 100

如果没有加权随机抽样,我希望每个训练 epoch 包含 10 个批次。

问题

  • 在使用此采样器时,每个 epoch 是否仅对 10 个批次进行采样 - 因此,模型是否会在每个 epoch 期间“错过”大部分多数类,因为少数类现在在训练批次中的比例过高?李>
  • 使用采样器是否会导致每个 epoch 采样超过 10 个批次(这意味着相同的少数类观察可能会出现多次,而且训练会减慢)?

【问题讨论】:

标签: pytorch oversampling pytorch-dataloader


【解决方案1】:

一个小sn-p代码使用WeightedRandomSampler
首先,定义函数:

def make_weights_for_balanced_classes(images, nclasses):                        
    count = [0] * nclasses                                                      
    for item in images:                                                         
        count[item[1]] += 1                                                     
    weight_per_class = [0.] * nclasses                                      
    N = float(sum(count))                                                   
    for i in range(nclasses):                                                   
        weight_per_class[i] = N/float(count[i])                                 
    weight = [0] * len(images)                                              
    for idx, val in enumerate(images):                                          
        weight[idx] = weight_per_class[val[1]]                                  
    return weight                         

                                  

在此之后,以下面的方式使用它:

import torch 
dataset_train = datasets.ImageFolder(traindir)                                                                         
                                                                                
# For unbalanced dataset we create a weighted sampler                       
weights = make_weights_for_balanced_classes(dataset_train.imgs, len(dataset_train.classes))                                                                
weights = torch.DoubleTensor(weights)                                       
sampler = torch.utils.data.sampler.WeightedRandomSampler(weights, len(weights))                     
                                                                                
train_loader = torch.utils.data.DataLoader(dataset_train, batch_size=args.batch_size, shuffle = True,                              
                                                             sampler = sampler, num_workers=args.workers, pin_memory=True)  

【讨论】:

    【解决方案2】:

    取决于您以后的内容,查看torch.utils.data.WeightedRandomSampler文档以获取详细信息。

    有一个参数num_samples @它允许您在Datasettorch.utils.data.DataLoader(假设您正确加权时,指定实际模拟的样本数量):

    • 如果将其设置为len(dataset)您将获得第一个案例
    • 如果将其设置为@ 987654327(在您的情况下),您将获得第二个案例

    在使用此采样器时,每个时期只会对10个批次进行采样 - 并因此将模型“小姐”在每个时期期间大部分类别的大部分时间[...]

    是的,新样本将在此时期通过后返回

    将使用采样器的结果超过10个批次被采样(意味着相同的少数群体观察可能出现多次,而且培训也会减缓)?

    训练不会放慢速度,每个时代都需要更长时间,但收敛应该大致相同(因为由于每个数据中的数据更多,因此需要较少的时期)。

    【讨论】:

      猜你喜欢
      • 2019-09-03
      • 2020-06-04
      • 2017-10-29
      • 2020-03-05
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 2023-01-29
      • 1970-01-01
      相关资源
      最近更新 更多