多标签分类训练触发IndexError:疑CSV数据加载问题求排查
问题定位与修复方案
这个IndexError的核心原因是数据集的长度计算与实际加载的数据行数不匹配,导致DataLoader尝试访问超出数组范围的索引。让我一步步拆解问题并给出修复:
1. 长度不匹配的根源
在你的FashionData类中:
- 你通过
self.data_info.iloc[1:, 0]加载图像路径,这意味着你跳过了CSV的第一行(索引0),所以实际有效的图像数据行数是len(self.data_info) - 1 - 但你在
__len__方法中返回的是self.data_len = len(self.data_info.index),也就是CSV的总行数(包含第一行)
当DataLoader根据__len__返回的长度生成索引时,最大索引会是len(self.data_info) - 1,但你的image_arr和label_arr的长度只有len(self.data_info) - 1,索引范围是0到len(self.data_info) - 2。当DataLoader尝试访问索引len(self.data_info) - 1时,就会触发“索引超出范围”的错误。
2. 潜在的标签列选择错误
你提到“使用第1列至末尾的15个标签”,但代码中写的是self.label_arr = np.asarray(self.data_info.iloc[1:, 2:])。注意Pandas的iloc是0-based索引:
- 第0列:图像路径
- 第1列:第一个标签
- 第2列及以后:第二个标签及之后的内容
如果你的标签确实是从第1列(CSV中的第二列)开始的15个列,那这里应该写成iloc[1:, 1:],否则会丢失第一个标签列。
3. 修复后的代码片段
修改FashionData类的关键部分:
class FashionData(torch.utils.data.Dataset): def __init__(self, csv_file, mode='train', transform=None): self.mode=mode self.transform = transform self.data_info = pd.read_csv(csv_file, header=None) # 加载图像路径:跳过第一行(索引0) self.image_arr = np.asarray(self.data_info.iloc[1:, 0]) self.data_len = len(self.image_arr) # 用实际加载的图像数量作为数据集长度 if mode !='test': # 修复标签列选择:从第1列(索引1)开始取所有标签列 self.label_arr = np.asarray(self.data_info.iloc[1:, 1:]) self.label_arr=self.label_arr.astype('float32') def __getitem__(self, index): single_image_name = self.image_arr[index] img_as_img = Image.open(single_image_name) if self.transform is not None: img_as_img = self.transform(img_as_img) if self.mode=='test': return img_as_img single_image_label = self.label_arr[index] return (img_as_img, single_image_label) def __len__(self): return self.data_len # 返回正确的数据集长度
4. 额外检查点
- 确认你的CSV文件第一行确实是无效数据(比如表头或者空行),所以需要用
iloc[1:]跳过。如果第一行是有效数据,那应该去掉1:,直接用iloc[:, 0]和iloc[:, 1:] - 验证
label_arr的形状是否为(样本数, 15),确保标签列数量正确,可以在__init__中添加print(self.label_arr.shape)来检查
这样修改后,数据集的长度和实际加载的样本数一致,就不会再触发索引越界的错误了。
内容的提问来源于stack exchange,提问作者Jacky Lin
相关产品推荐
相关产品推荐

