小样本学习/孪生网络:3通道图像40-shot训练批量数据维度错误排查
这个错误的核心逻辑很清晰:你试图把仅含300个元素的数组,强行转换成需要30000个元素的(100,100,3)形状——这说明你取到的X[category, idx_1]根本不是预期的100x100 RGB图像。我们一步步拆解问题根源:
1. 数据加载环节的致命问题
你的list_files函数里藏着几个直接导致图像加载异常的错误:
1.1 完全错误的文件路径构造
你构造文件路径的代码是:
full_path.append(str(dirs)+'\\'+str(root)+'\\'+str(f))
这里的dirs是os.walk返回的当前目录下的子目录列表,把它转成字符串会变成类似['subdir1', 'subdir2']的格式,最终生成的路径会是['subdir']\\train\\cat\\img.jpg这种完全无效的格式。后续你用v[3:]去掉前三个字符[',但依然是错误路径,大概率加载的不是图像文件,甚至加载失败后得到了异常的小尺寸数组。
正确的路径构造应该用Python内置的跨平台方法:
full_path.append(os.path.join(root, f))
1.2 多余的嵌套列表导致形状混乱
加载图像后你写了images = [images],这会把正常的图像列表再嵌套一层,变成[[img1, img2, ...]]的结构。后续即使你调用X.reshape(-1,100,100,3),如果其中混了加载错误的图像,就会出现元素尺寸不匹配的问题。直接删掉这行代码即可。
1.3 缺失图像形状校验
加载图像时你没有检查每张图的形状是否符合(100,100,3),建议添加校验逻辑过滤异常图像:
images = [] for path in full_path: img = np.array(Image.open(path)) if img.shape != (100, 100, 3): print(f"跳过异常图像:{path},实际形状为{img.shape}") continue images.append(img)
2. 批量生成环节的两处错误
再看get_batch函数,这里也有明显的逻辑问题:
2.1 通道数不匹配的重塑操作
你写了:
pairs[1][i,:,:,:] = X[category_2,idx_2].reshape(w, h,1)
把RGB图像强行转成单通道(100,100,1),但pairs[1]的形状是(batch_size, 100, 100, 3),通道数完全不匹配,应该改成:
pairs[1][i,:,:,:] = X[category_2,idx_2].reshape(w, h, chan)
2.2 错误的数组索引逻辑
你用X[category, idx_1]索引,假设X是(类别数, 每个类别样本数, 100,100,3)的三维结构,但你之前调用X.reshape(-1,100,100,3)会把它变成(总样本数, 100,100,3)的二维结构,这时候X[category, idx_1]的索引方式完全错误。
你需要先把数据按类别分组,比如:
# 假设你有train_labels列表,每个元素对应图像的类别索引 Xtrain = np.array(images) # 按类别重塑成(51, 40, 100, 100, 3)(51个类别,每个40样本) Xtrain = Xtrain.reshape(51, 40, 100, 100, 3)
3. 快速验证步骤
在调用get_batch前,先做两个关键验证:
- 打印
Xtrain.shape,确认是(51, 40, 100, 100, 3) - 随机取一个元素,打印
Xtrain[0,0].shape和Xtrain[0,0].size,前者应该是(100,100,3),后者是30000而非300
按照上面的步骤修正后,这个重塑错误应该就能解决了。
内容的提问来源于stack exchange,提问作者Sunshine

