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
相关产品推荐
相关产品推荐

