多维度Batch场景下PyTorch WeightedRandomSampler使用报错解决问询
解决多标签样本下的WeightedRandomSampler类别不平衡问题
你的核心问题是混淆了采样对象:WeightedRandomSampler是对数据集的样本索引(共5000个)进行采样,而非对单个标签(共5000×8个)采样。原代码中权重数组长度为40000,和样本数5000不匹配,因此触发索引错误。
正确实现思路
需要为每个样本(对应一个索引)计算一个权重值,而非为每个标签单独计算。权重的计算可以基于样本内所有标签的类别权重聚合,具体有两种常用策略:
策略1:样本内标签权重的平均值
基于所有标签的平衡权重,取每个样本8个标签对应权重的平均值作为该样本的权重,能均衡考虑样本内所有类别的贡献:
import numpy as np from sklearn.utils.class_weight import compute_class_weight from torch.utils.data import WeightedRandomSampler y_org = np.load('target.npy') # shape (5000, 8) # 1. 基于所有标签统计计算类别平衡权重 unique_classes = np.unique(y_org.ravel()) class_weights = compute_class_weight( class_weight='balanced', classes=unique_classes, y=y_org.ravel() ) # 建立类别到权重的映射字典 class_weight_map = dict(zip(unique_classes, class_weights)) # 2. 计算每个样本的权重:取样本内8个标签权重的平均值 sample_weights = [] for sample_labels in y_org: # 获取当前样本每个标签对应的权重 label_weights = [class_weight_map[label] for label in sample_labels] # 聚合为样本权重 sample_weight = np.mean(label_weights) sample_weights.append(sample_weight) # 3. 初始化采样器,权重数组长度与样本数一致(5000) sampler = WeightedRandomSampler( weights=sample_weights, num_samples=len(y_org), # 可按需调整采样总数,比如设置为原样本数的2倍增强少数类 replacement=True )
策略2:优先提升少数类样本的权重
如果希望重点强化少数类的采样概率,可以给包含少数类标签的样本赋予更高权重:
# 1. 先找出少数类(以类别样本数低于中位数为例) class_counts = np.unique(y_org.ravel(), return_counts=True)[1] minority_classes = unique_classes[class_counts < np.median(class_counts)] max_class_weight = max(class_weights) # 2. 计算样本权重:含少数类的样本用最高权重,其余用平均值 sample_weights = [] for sample_labels in y_org: has_minority = any(label in minority_classes for label in sample_labels) if has_minority: sample_weight = max_class_weight else: label_weights = [class_weight_map[label] for label in sample_labels] sample_weight = np.mean(label_weights) sample_weights.append(sample_weight) # 3. 初始化采样器 sampler = WeightedRandomSampler( weights=sample_weights, num_samples=len(y_org), replacement=True )
关键说明
- 无论哪种策略,最终
sample_weights的长度必须等于数据集的样本总数(5000),这样WeightedRandomSampler才能正确对每个样本索引分配采样概率。 replacement=True是过采样的核心,允许少数类样本被重复选中,从而平衡训练时的类别分布。
内容的提问来源于stack exchange,提问作者theodre7
相关产品推荐
相关产品推荐

