【问题标题】:Weighted random sampler - oversample or undersample?加权随机采样器 - 过采样还是欠采样?
【发布时间】:2021-08-20 06:22:42
【问题描述】:
问题
我正在 PyTorch 中训练一个用于二进制分类的深度学习模型,并且我有一个包含不平衡类比例的数据集。我的少数类占给定观察的10%。为了避免模型学习只预测多数类,我想在我的DataLoader 中使用来自torch.utils.data 的WeightedRandomSampler。
假设我有 1000 观察(900 在类 0,100 在类 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 @它允许您在Dataset与torch.utils.data.DataLoader(假设您正确加权时,指定实际模拟的样本数量):
- 如果将其设置为
len(dataset)您将获得第一个案例
- 如果将其设置为@ 987654327(在您的情况下),您将获得第二个案例
在使用此采样器时,每个时期只会对10个批次进行采样 - 并因此将模型“小姐”在每个时期期间大部分类别的大部分时间[...]
是的,但新样本将在此时期通过后返回
将使用采样器的结果超过10个批次被采样(意味着相同的少数群体观察可能出现多次,而且培训也会减缓)?
训练不会放慢速度,每个时代都需要更长时间,但收敛应该大致相同(因为由于每个数据中的数据更多,因此需要较少的时期)。