求解:加载叶片图像数据集时出现ValueError: too many values to unpack错误
ValueError: too many values to unpack 错误分析与解决
错误原因
- 解包不匹配:
os.listdir(main_data_dir)返回的是目标目录下40个叶片类别子文件夹的名称列表,而你试图将这个包含40个元素的列表解包为(trainX, trainY), (testX, testY)的4变量结构,元素数量远多于预期,直接触发too many values to unpack错误。 - 逻辑错误:
os.listdir仅返回文件/文件夹名称,不会加载图像数据或生成标签,你的代码完全跳过了图像读取、标签映射的核心步骤,逻辑从根源上不成立。
解决方法
下面提供两种可行的数据集加载方案,适配你的叶片分类(成对数据生成)场景:
方案一:使用Keras内置工具(推荐,简洁高效)
利用image_dataset_from_directory自动处理文件夹结构、划分数据集、加载图像:
import tensorflow as tf from tensorflow.keras.utils import image_dataset_from_directory import numpy as np # 配置参数 IMAGE_SIZE = (224, 224) # 根据你的模型需求调整尺寸 VALIDATION_SPLIT = 0.2 SEED = 123 # 加载并划分训练/测试集 train_ds = image_dataset_from_directory( main_data_dir, validation_split=VALIDATION_SPLIT, subset="training", seed=SEED, image_size=IMAGE_SIZE, batch_size=32 ) test_ds = image_dataset_from_directory( main_data_dir, validation_split=VALIDATION_SPLIT, subset="validation", seed=SEED, image_size=IMAGE_SIZE, batch_size=32 ) # 将Dataset对象转换为numpy数组(适配make_pairs函数) def dataset_to_numpy(dataset): images = [] labels = [] for img_batch, lbl_batch in dataset: images.append(img_batch.numpy()) labels.append(lbl_batch.numpy()) return np.concatenate(images), np.concatenate(labels) trainX, trainY = dataset_to_numpy(train_ds) testX, testY = dataset_to_numpy(test_ds) # 归一化处理(你的原有逻辑) trainX = 1 - (trainX / 255.0) testX = 1 - (testX / 255.0) # 如果需要转为单通道灰度图(可选,根据模型需求) # trainX = tf.image.rgb_to_grayscale(trainX).numpy() # testX = tf.image.rgb_to_grayscale(testX).numpy() # 生成成对数据 (pairTrain, labelTrain) = make_pairs(trainX, trainY) (pairTest, labelTest) = make_pairs(testX, testY) print(f'\nTrain Data Shape: {pairTrain.shape}') print(f'Test Data Shape: {pairTest.shape}\n\n')
方案二:手动加载(灵活可控)
使用PIL和sklearn手动处理图像读取、标签映射和数据集划分:
import os import numpy as np from PIL import Image from sklearn.model_selection import train_test_split # 配置参数 IMAGE_SIZE = (224, 224) TEST_SIZE = 0.2 SEED = 123 # 自定义加载函数 def load_leaf_dataset(data_dir, img_size=IMAGE_SIZE): images = [] labels = [] # 获取类别名称并排序 class_names = sorted(os.listdir(data_dir)) class_idx_map = {name: idx for idx, name in enumerate(class_names)} for class_name in class_names: class_dir = os.path.join(data_dir, class_name) # 遍历类别下的所有图像 for img_filename in os.listdir(class_dir): img_path = os.path.join(class_dir, img_filename) # 读取并调整图像尺寸 img = Image.open(img_path).resize(img_size) img_array = np.array(img) images.append(img_array) labels.append(class_idx_map[class_name]) return np.array(images), np.array(labels) # 加载全部数据 X, Y = load_leaf_dataset(main_data_dir) # 划分训练/测试集 trainX, testX, trainY, testY = train_test_split(X, Y, test_size=TEST_SIZE, random_state=SEED) # 归一化处理 trainX = 1 - (trainX / 255.0) testX = 1 - (testX / 255.0) # 转为单通道灰度图(可选) # trainX = np.mean(trainX, axis=-1, keepdims=True) # testX = np.mean(testX, axis=-1, keepdims=True) # 生成成对数据 (pairTrain, labelTrain) = make_pairs(trainX, trainY) (pairTest, labelTest) = make_pairs(testX, testY) print(f'\nTrain Data Shape: {pairTrain.shape}') print(f'Test Data Shape: {pairTest.shape}\n\n')
内容的提问来源于stack exchange,提问作者Jeeva Joslin
相关产品推荐
相关产品推荐

