据我了解,pytorch WeightedRandomSampler 'weights' 参数有点类似于 numpy.random.choice 'p' 参数,后者是样本被随机选择的概率。Pytorch 使用权重来随机抽样训练示例,他们在文档中声明权重不必总和为 1,所以这就是我的意思,它与 numpy 的随机选择不完全一样。权重越强,样本就越有可能被采样。
当你有replacement=True时,这意味着可以多次绘制训练样例,这意味着你可以在你的训练集中拥有训练样例的副本,用于训练你的模型;过采样。此外,如果与其他训练样本的权重相比,权重较低,则会发生相反的情况,这意味着这些样本被选中进行随机抽样的机会较低;欠采样。
我不知道 num_samples 参数在与火车装载机一起使用时如何工作,但我可以警告您不要将批量大小放在那里。今天,我尝试设置批量大小,结果很糟糕。我的同事把班级数*100,他的成绩要好得多。我所知道的是你不应该把批量大小放在那里。我还尝试将我的所有训练数据的大小用于 num_samples,它有更好的结果,但需要很长时间才能训练。无论哪种方式,玩弄它,看看什么最适合你。我想安全的赌注是使用 num_samples 参数的训练示例数。
这是我看到其他人使用的示例,我也将其用于二进制分类。它似乎工作得很好。您取每个类的训练样例数量的倒数,并为所有训练样例设置该类各自的权重。
使用您的 trainset 对象的快速示例
labels = np.array(trainset.samples)[:,1]
# 转到数组并获取所有列索引 1 作为标签
labels = labels.astype(int)
# 改为int
majority_weight = 1/num_of_majority_class_training_examples
minority_weight = 1/num_of_minority_class_training_examples
sample_weights = np.array([majority_weight, minority_weight
]) # 这是假设你的少数类是标签对象中的整数 1。如果不是,请切换位置,使其成为少数权重,多数权重。
weights = samples_weights[labels]
# 这将遍历每个训练示例,并使用标签 0 和 1 作为 sample_weights 对象中的索引,这是您想要该类的权重。
sampler = WeightedRandomSampler(weights=weights, num_samples=, replacement=True)
trainloader = data.DataLoader(trainset, batchsize = batchsize, sampler=sampler)
由于 pytorch 文档说权重不必总和为 1,我认为您也可以只使用不平衡类之间的比率。例如,如果您有 100 个多数类的训练样例和 50 个少数类的训练样例,则比例为 2:1。为了平衡这一点,我认为您可以为每个多数类训练示例使用 1.0 的权重,为所有少数类训练示例使用 2.0 的权重,因为从技术上讲,您希望少数类被选择的可能性是 2 倍,这将平衡您的随机选择期间的课程。
我希望这会有所帮助。抱歉写的草率,我很着急,看到没有人回答。我自己也为此苦苦挣扎,但也找不到任何帮助。如果没有意义,请直说,我会重新编辑它,并在我有空闲时间时使其更加清晰。