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

PyTorch DataLoader遍历跳过循环问题求助

问题排查与解决方案

核心问题分析

遍历DataLoader时循环被跳过,但长度不为0,大概率是数据集构建逻辑存在隐性错误或DataLoader参数配置冲突,以下是具体排查步骤和修复方案:


1. 优先验证传入路径的合法性

你的BBoxDataset要求传入文件夹列表,但如果调用时传入的是单个文件夹字符串(而非列表),会导致update_img_paths中遍历字符串的每个字符作为"文件夹",最终只有极少数情况能匹配到文件(比如当前目录下的.jpg),甚至直接导致无效路径。

修复方式:

  • 调用时确保传入列表:
    # 错误写法
    infer_dataloader = get_dataloader("./single_folder", batch_size=1)
    # 正确写法
    infer_dataloader = get_dataloader(["./single_folder"], batch_size=1)
    
  • 或者在BBoxDataset的__init__中兼容单个路径的情况:
    def __init__(self, path_list):
        super().__init__()
        # 处理单个路径输入
        if isinstance(path_list, str):
            self.img_dirs = [path_list]
        else:
            self.img_dirs = path_list
        self.update_img_paths()
    

2. 修正DataLoader构建函数的参数逻辑

你的get_dataloader存在两处冗余/错误逻辑:

  • 返回类型注解错误(标注为-> None但实际返回DataLoader),虽不影响运行,但易引发混淆
  • 当sampler=None时,显式传入sampler=None可能与shuffle参数产生隐性冲突

修复后的get_dataloader:

from torch.utils.data import DataLoader, Sampler

def get_dataloader(image_paths, batch_size: int, shuffle: bool = dataset_settings.random_shuffle,
                   num_workers: int = 0, phase: str = 'infer', sampler: Sampler = None) -> DataLoader:
    dataset = BBoxDataset(path_list=image_paths)
    drop_last = False if phase == 'infer' else True
    # 推理阶段强制关闭shuffle
    shuffle = shuffle if phase != 'infer' else False
    
    kwargs_dl = dict(
        num_workers=num_workers,
        batch_size=batch_size,
        pin_memory=True,
        shuffle=shuffle,
        drop_last=drop_last
    )
    
    if sampler is not None: 
        kwargs_dl['sampler'] = sampler(dataset, shuffle=shuffle)
        del kwargs_dl['shuffle']
    
    dataloader = DataLoader(dataset, **kwargs_dl)
    return dataloader

3. 验证数据集的有效性

在遍历DataLoader前,先手动验证数据集是否能正常获取数据,排除文件读取异常:

infer_dataloader = get_dataloader(dataset_path, batch_size=1)
print(f"数据集总长度:{len(infer_dataloader.dataset)}")

# 尝试获取第一个样本
try:
    img, filepath = infer_dataloader.dataset[0]
    print(f"第一个样本路径:{filepath}")
    print(f"图片尺寸:{img.size}")
except Exception as e:
    print(f"读取样本出错:{str(e)}")

如果这里报错,说明:

  • 图片文件损坏或路径无效
  • glob.glob未匹配到文件(比如系统大小写敏感,文件是.JPG而非.jpg)

可在update_img_paths中添加打印日志,确认文件扫描情况:

def update_img_paths(self):
    self.img_paths = []
    for img_dir in self.img_dirs:
        scan_path = os.path.join(img_dir, "*.jpg")
        print(f"扫描路径:{scan_path}")
        files = glob.glob(scan_path)
        print(f"找到{len(files)}个文件")
        self.img_paths.extend(files)
    print(f"总样本数:{len(self.img_paths)}")

4. 验证DataLoader迭代器

直接尝试获取迭代器的第一个元素,确认是否为空:

try:
    batch_data = next(iter(infer_dataloader))
    print("获取到批次数据:", batch_data)
except StopIteration:
    print("DataLoader为空,无数据可迭代")

如果这里抛出StopIteration,说明即使len(dataloader)显示不为0,实际数据集仍无有效数据,回到步骤1和3排查路径匹配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:10:30