SuperGradients Trainer报错:'DataLoader' object is not subscriptable
解决SuperGradients训练时DataLoader不可下标访问的错误
错误原因
你遇到的TypeError: 'DataLoader' object is not subscriptable,根源是**coco_detection_yolo_format_train返回的是DataLoader对象,而非Dataset对象**。
你把这些DataLoader实例传入ConcatDataset后,ConcatDataset会尝试用下标([idx])访问每个元素,但DataLoader本身不支持下标操作,所以在DataLoader worker进程中触发了错误。而直接传入单个train_datasets[0]能正常运行,是因为它本身就是SuperGradients兼容的DataLoader,符合trainer的输入要求。
解决方案
核心思路:先获取每个数据集的原始Dataset对象,合并后再创建符合要求的DataLoader,同时保留数据集的独立状态。
方法1:从返回的DataLoader中提取Dataset
修改数据集加载代码,提取每个DataLoader内部的dataset属性,再合并:
from super_gradients.training.dataloaders.dataloaders import coco_detection_yolo_format_train, coco_detection_yolo_format_val from torch.utils.data import ConcatDataset, DataLoader yolo_folders = [f'{LOCATION}/dataset1', f'{LOCATION}/dataset2', f'{LOCATION}/dataset3', f'{LOCATION}/dataset4'] train_datasets = [] for folder in yolo_folders: # 先创建单个数据集的DataLoader single_dataloader = coco_detection_yolo_format_train( dataset_params={ 'data_dir': folder, 'images_dir': f'{folder}/train/images', 'labels_dir': f'{folder}/train/labels', 'classes': dataset_params['classes'], 'input_dim': (640, 640) }, dataloader_params={ 'batch_size': BATCH_SIZE, 'num_workers': 2 } ) # 提取内部的Dataset对象加入列表 train_datasets.append(single_dataloader.dataset) # 合并所有Dataset combined_train_dataset = ConcatDataset(train_datasets) # 创建合并后的DataLoader,同时保留原有的collate_fn(检测任务需要特定的数据拼接逻辑) train_dataloader = DataLoader( combined_train_dataset, batch_size=16, shuffle=True, num_workers=4, collate_fn=single_dataloader.collate_fn # 复用原有的拼接函数 )
方法2:直接实例化Dataset类
直接使用COCODetectionYoloFormatDataset类创建数据集,跳过DataLoader的中间步骤:
from super_gradients.training.datasets.detection_datasets import COCODetectionYoloFormatDataset from torch.utils.data import ConcatDataset, DataLoader yolo_folders = [f'{LOCATION}/dataset1', f'{LOCATION}/dataset2', f'{LOCATION}/dataset3', f'{LOCATION}/dataset4'] train_datasets = [] for folder in yolo_folders: # 直接创建Dataset实例 dataset = COCODetectionYoloFormatDataset( data_dir=folder, images_dir=f'{folder}/train/images', labels_dir=f'{folder}/train/labels', classes=dataset_params['classes'], input_dim=(640, 640) ) train_datasets.append(dataset) # 合并Dataset combined_train_dataset = ConcatDataset(train_datasets) # 创建DataLoader并指定检测任务的collate_fn train_dataloader = DataLoader( combined_train_dataset, batch_size=16, shuffle=True, num_workers=4, collate_fn=COCODetectionYoloFormatDataset.collate_fn )
验证集修改
验证集部分同理,将coco_detection_yolo_format_val返回的DataLoader提取dataset,或直接实例化对应的验证集Dataset类,再合并创建DataLoader。
这样修改后,既保留了每个数据集的独立状态(方便后续新增/移除数据集),又能让trainer正常接收DataLoader进行训练。
内容的提问来源于stack exchange,提问作者Jonathan Molina
相关产品推荐
相关产品推荐

