加权随机采样器-过采样还是欠采样



问题

我正在PyTorch中训练一个用于二进制分类的深度学习模型,我有一个包含不平衡类比例的数据集。我的少数族裔班级构成了关于给定观察的10%。为了避免模型学习只预测大多数类,我想在DataLoader中使用torch.utils.data中的WeightedRandomSampler

假设我有1000观测值(0类中的9001类中的100(,我的数据加载器的批量大小为100

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

问题

  • 使用此采样器时,每个历元只采样10个批次吗?因此,由于少数类现在在训练批次中的代表性过高,模型在每个历元期间会"遗漏"大部分多数类吗
  • 使用采样器是否会导致每个历元采样超过10个批次(这意味着相同的少数类观测可能会出现多次,而且训练速度会减慢(

使用WeightedRandomSampler的一小段代码
首先,定义函数:

def make_weights_for_balanced_classes(images, nclasses):
n_images = len(images)
count_per_class = [0] * nclasses
for _, image_class in images:
count_per_class[image_class] += 1
weight_per_class = [0.] * nclasses
for i in range(nclasses):
weight_per_class[i] = float(n_images) / float(count_per_class[i])
weights = [0] * n_images
for idx, (image, image_class) in enumerate(images):
weights[idx] = weight_per_class[image_class]
return weights

之后,以以下方式使用它:

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)  

这取决于您想要什么,请查看torch.utils.data.WeightedRandomSampler文档了解详细信息。

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

  • 如果将其设置为len(dataset),则会出现第一种情况
  • 如果您将其设置为1800(在您的情况下(,您将获得第二种情况

使用此采样器时,每个历元将只采样10个批次,因此,模型在每个历元期间是否会"错过"大部分类别[…]

是的,在该历元通过后将返回新样本

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

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

最新更新