You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多维度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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:15:28