问题
我正在PyTorch中训练一个用于二进制分类的深度学习模型,我有一个包含不平衡类比例的数据集。我的少数族裔班级构成了关于给定观察的10%
。为了避免模型学习只预测大多数类,我想在DataLoader
中使用torch.utils.data
中的WeightedRandomSampler
。
假设我有1000
观测值(0
类中的900
,1
类中的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
,它允许您指定当Dataset
与torch.utils.data.DataLoader
组合时实际创建的样本数量(假设您正确加权(:
- 如果将其设置为
len(dataset)
,则会出现第一种情况 - 如果您将其设置为
1800
(在您的情况下(,您将获得第二种情况
使用此采样器时,每个历元将只采样10个批次,因此,模型在每个历元期间是否会"错过"大部分类别[…]
是的,但在该历元通过后将返回新样本
使用采样器是否会导致每个历元采样超过10个批次(这意味着相同的少数类观测可能会出现多次,而且训练速度会减慢(?
训练不会减慢,每个历元需要更长的时间,但收敛应该大致相同(因为每个历元中需要更多的数据,所以需要更少的历元(。