首页 > 解决方案 > PyTorch 中加权随机采样器背后的直觉

问题描述

我正在尝试WeightedRandomSampler用于处理数据集中的不平衡(class1:2555,class 2:227,class 3:621,class 4:2552 图像)。但是,我调试了这些步骤,但它背后的直觉对我来说并不清楚。我的目标标签采用 one-hot 编码向量的形式,如下所示。

train_labels.head(5)

目标标签

我将标签转换为类索引:

labels = np.argmax(train_labels.loc[:, 'none':'both'].values, axis=1)
train_labels = torch.from_numpy(labels)
train_labels
tensor([0, 0, 1,  ..., 1, 0, 0])

以下是我用来计算加权随机采样器的步骤。如果我对任何步骤的解释有误,请纠正我。

  1. 计算数据集中每个类的样本数

    class_sample_count = np.array(train_labels.value_counts()) 
    class_sample_count
    array([2555, 2552,  621,  227])
    
  2. 计算与每个类别相关的权重

    weight = 1. / class_sample_count 
    weight
    array([0.00039139, 0.00039185, 0.00161031, 0.00440529])
    
  3. 计算数据集中每个样本的权重。

    samples_weight = np.array(weight[train_labels])
    print(samples_weight[1], samples_weight[2] )
    0.0003913894324853229 0.00039184952978056425 
    

将 np.array 转换为张量

     tensor([0.0004, 0.0004, 0.0004,  ..., 0.0004, 0.0004, 0.0004],
     dtype=torch.float64)

转换为张量后,所有样本在所有四个条目中似乎都具有相同的值?那么加权随机抽样如何帮助处理不平衡的数据集呢?

我将不胜感激。谢谢你。

标签: pythonpytorch

解决方案


这是因为您正在计算 one-hot 编码的权重,并且由于有四个组件(四个类),因此在 indexing 之后每个实例最终有四个相同的权重weight[train_labels]。您拥有相同的权重这一事实非常好,因为每个实例都应该被分配一个唯一的权重。对于采样器来说,这个权重对应于选择这个实例的概率。如果给定的类在数据集中很突出,则相关的频率(权重)会很低,因此该类的实例从数据集中被采样的概率会更低。

对于相当多的样本,这种加权方案的目标是在类表示不平衡的情况下进行平衡采样。

如果您坚持使用 one-hot 编码,则只需选择第一列:

>>> sample_weights = np.array(weight[train_labels])[:,0]

然后使用WeightedRandomSampler构造一个采样器:

>>> sampler = WeightedRandomSampler(sample_weights, len(train_labels))

最后,您可以将其插入数据加载器:

>>> DataLoader(dataset, batch_size, sampler=sampler)

推荐阅读