CNN训练样本数量异常及IndexError索引越界问题求助
解决CNN训练数据集划分异常与IndexError问题
首先,咱们拆解你遇到的两个核心问题:样本数莫名翻倍(300变900、76变228),以及随之而来的索引越界错误。这俩问题本质是同一个原因——你的train_data实际长度不是你以为的376,而是原始样本数的3倍(1128),所以切片划分后才会出现900和228的结果,进而触发索引越界。
一、先定位问题根源:检查train_data的真实结构
先停下来,用几行代码确认train_data的实际情况:
- 如果是numpy数组:打印
print(train_data.shape),看第一个维度是不是376; - 如果是普通列表:打印
print(len(train_data)),看长度是不是376; - 如果是TensorFlow/PyTorch的Dataset对象:用
len(train_data)查看样本数,或者转成列表再看长度。
你得到的900=300×3、228=76×3,说明每个原始图像被重复生成了3次,大概率是数据加载/预处理环节出了问题:
- 是不是用了数据增强工具(比如
ImageDataGenerator、Albumentations),不小心把增强后的样本和原始样本合并到了同一个数据集里? - 有没有手动加载图像时,循环逻辑错误,导致每个图像被
append了3次? - 如果用了生成器(比如
flow_from_directory),是不是误把生成器的batch数当成了样本数?
二、修正数据集划分的正确流程
你现在的错误是先做数据增强,再划分数据集,正确的做法应该是先划分原始图像的路径/索引,再分别对训练、验证集做增强,这样能保证训练集对应300张原始图,验证集对应76张原始图,不会出现样本数混乱的情况。
举个实操示例(以TensorFlow为例):
# 1. 先获取所有原始图像的路径 import os import pandas as pd from sklearn.model_selection import train_test_split img_dir = "你的图像文件夹路径" all_image_paths = [os.path.join(img_dir, f) for f in os.listdir(img_dir) if f.endswith(('.jpg', '.png'))] # 按8:2划分原始路径(约300/76) train_paths, val_paths = train_test_split(all_image_paths, train_size=0.8, random_state=42) # 2. 分别创建训练、验证的增强生成器 from tensorflow.keras.preprocessing.image import ImageDataGenerator # 训练集做数据增强 train_datagen = ImageDataGenerator( rescale=1./255, rotation_range=20, width_shift_range=0.2, height_shift_range=0.2, horizontal_flip=True ) # 验证集只做归一化,不做增强 val_datagen = ImageDataGenerator(rescale=1./255) # 生成训练数据集 train_generator = train_datagen.flow_from_dataframe( dataframe=pd.DataFrame({'path': train_paths}), x_col='path', target_size=(224, 224), # 根据你的模型调整尺寸 batch_size=32, class_mode='categorical' # 根据你的任务调整分类模式 ) # 生成验证数据集 val_generator = val_datagen.flow_from_dataframe( dataframe=pd.DataFrame({'path': val_paths}), x_col='path', target_size=(224, 224), batch_size=32, class_mode='categorical' ) # 3. 训练模型 model.fit( train_generator, steps_per_epoch=len(train_generator), validation_data=val_generator, validation_steps=len(val_generator), epochs=10 )
三、解决IndexError问题
这个IndexError: index 525 is out of bounds for axis 0 with size 300,本质是你代码里某个环节用了错误的样本数(比如900)去做循环/索引,但实际划分后的数据集只有300个元素。按照上面的正确流程划分后,训练、验证集的样本数对应原始划分的数量,训练时用生成器的len()来设置steps_per_epoch,就不会再出现索引越界的问题了。
内容的提问来源于stack exchange,提问作者Simplicity
相关产品推荐
相关产品推荐

