3

问题

我正在 PyTorch 中为二元分类训练深度学习模型,并且我有一个包含不平衡类比例的数据集。我的少数班10%由给定的观察组成。为了避免模型学习只预测多数类,我想WeightedRandomSamplertorch.utils.data我的DataLoader.

假设我有1000观察结果(900在 class中0100在 class 中1),以及我的数据加载器的批量大小100

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

问题

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

2 回答 2

1

要使用的一小段代码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)  
于 2021-07-07T12:06:56.390 回答
1

这取决于您所追求的,请查看torch.utils.data.WeightedRandomSampler文档以获取详细信息。

有一个参数允许您指定在与 组合num_samples时实际创建的样本数量(假设您正确加权它们):Datasettorch.utils.data.DataLoader

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

使用此采样器时,每个 epoch 只会对 10 个批次进行采样 - 因此,模型会在每个 epoch 期间“错过”大部分多数类别 [...]

是的,但是在这个 epoch 过去之后会返回新的样本

使用采样器是否会导致每个 epoch 采样超过 10 个批次(这意味着相同的少数类观察可能会出现多次,并且训练会减慢)?

训练不会减慢,每个 epoch 会花费更长的时间,但收敛应该大致相同(因为每个 epoch 中的数据更多,所以需要更少的 epoch)。

于 2021-06-02T09:33:13.840 回答