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

PyTorch自定义Dataset类触发IndexError索引越界错误排查

排查PyTorch Dataset的IndexError: list index out of range问题

可能的原因及修复方案

1. 路径分割逻辑存在鲁棒性问题

你的代码依赖固定路径格式提取类别:

name = image_path.split('/D')[1]
target = name.split('_')[0]

如果部分图片路径不符合Train/Dxx_xxx.jpg的格式(比如路径中没有/D、或/D后无下划线),split返回的列表长度会小于预期,取[1]或[0]时直接触发索引越界。
单独测试时可能只验证了合规样本,而计算均值标准差需要遍历全量数据集,刚好碰到异常路径。

修复方案:

  • 先批量检查所有图片路径,过滤或修正不符合格式的条目;
  • 改用更鲁棒的文件名提取方式,比如直接取路径最后一段文件名:
    import os
    # 从文件名直接提取类别前缀
    filename = os.path.basename(image_path)
    target = filename.split('_')[0]
    

2. 未正确引用实例属性self.class_to_idx

代码中__getitem__直接使用class_to_idx,但这个变量是__init__中定义的实例属性(需通过self.class_to_idx访问)。直接调用会引发未定义变量问题,在多进程加载场景下可能间接导致索引错误。

修复方案:
把所有class_to_idx替换为self.class_to_idx:

if target in self.class_to_idx : 
    target = [self.class_to_idx[target]]
else : 
    self.class_to_idx[target] = (int(target)-1)
    target = [self.class_to_idx[target]]

3. 多进程DataLoader的状态同步问题

计算均值标准差时通常会开启num_workers>0,多进程环境下Dataset的实例状态(如self.class_to_idx)可能出现同步异常,导致逻辑混乱触发索引错误。而单独测试时一般用单进程,不会暴露这个问题。

修复方案:

  • 提前离线生成class_to_idx映射,在__init__中直接初始化,避免动态添加:
    def __init__(self, imgs, transform=None):
        self.imgs = imgs
        self.transform = transform or transforms.ToTensor()
        # 提前生成D01-D35到索引的映射
        self.class_to_idx = {f"D{str(i).zfill(2)}": i-1 for i in range(1, 36)}
    

验证步骤

  1. 遍历所有self.imgs路径,打印split('/D')后长度为1的条目,确认是否存在异常路径;
  2. 替换class_to_idx为self.class_to_idx后,用单进程DataLoader遍历全量数据集,验证是否报错;
  3. 提前初始化class_to_idx,再用多进程DataLoader测试。

内容的提问来源于stack exchange,提问作者Nima

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 01:45:33