无法将Python列表转为TensorFlow Dataset:形状不匹配错误排查
问题排查:tf.data.Dataset.from_tensor_slices 形状不匹配错误
错误信息
InvalidArgumentError {{function_node __wrapped__Pack_N_3_device_/job:localhost/replica:0/task:0/device:GPU:0}} Shapes of all inputs must match: values[0].shape = [105,105,3] != values[2].shape = [1] [Op:Pack] name: 0
错误原因
- 图像存在冗余维度:你通过
tensorflow.expand_dims(..., 0)给每张图像添加了前置维度,导致x1/x2的shape为[1,105,105,3],而标签y是shape=[]的标量。TensorFlow在打包元素时无法将带前置维度的图像与标量标签对齐,触发形状不匹配。 - 数据结构解析混乱:你的样本结构是
[[x1,x2], y],from_tensor_slices会将其拆分为三个独立元素(x1、x2、y),而非预期的((x1,x2), y)特征-标签结构,进一步加剧了形状对齐矛盾。
解决方案
步骤1:移除图像冗余维度
删除tensorflow.expand_dims(..., 0)调用,让单张图像的shape直接为[105,105,3]。如果需要batch维度,后续通过Dataset的batch()方法添加即可。
步骤2:调整样本结构为((x1, x2), y)
将每个样本封装为特征元组+标签的结构,确保from_tensor_slices能正确识别输入的特征与标签部分。
修正后的数据读取代码
import tensorflow as tf import os td = [] for i in os.listdir("t"): for ii in os.listdir(os.path.join("t", i)): # 读取并处理第一张图像 img_dir = os.path.join("t", i, ii) img_path1 = os.path.join(img_dir, os.listdir(img_dir)[0]) x1 = tf.io.decode_jpeg(tf.io.read_file(img_path1)) / 255.0 # 读取并处理第二张图像 img_path2 = os.path.join(img_dir, "2.jpeg") x2 = tf.io.decode_jpeg(tf.io.read_file(img_path2)) / 255.0 # 生成标签Tensor y = tf.convert_to_tensor(float(os.listdir(img_dir)[0][0])) # 调整为((x1, x2), y)的结构 td.append(((x1, x2), y)) # 构建Dataset并添加训练必要操作 train_dataset = tf.data.Dataset.from_tensor_slices(td) train_dataset = train_dataset.shuffle(560).batch(32)
备选方案:使用from_generator处理大数据量
如果数据量过大无法提前加载到内存,用from_generator动态生成样本更高效:
import tensorflow as tf import os def data_generator(): for i in os.listdir("t"): for ii in os.listdir(os.path.join("t", i)): img_dir = os.path.join("t", i, ii) img_path1 = os.path.join(img_dir, os.listdir(img_dir)[0]) x1 = tf.io.decode_jpeg(tf.io.read_file(img_path1)) / 255.0 img_path2 = os.path.join(img_dir, "2.jpeg") x2 = tf.io.decode_jpeg(tf.io.read_file(img_path2)) / 255.0 y = tf.convert_to_tensor(float(os.listdir(img_dir)[0][0])) yield (x1, x2), y # 指定输出的类型与形状 output_signature = ( (tf.TensorSpec(shape=(105,105,3), dtype=tf.float32), tf.TensorSpec(shape=(105,105,3), dtype=tf.float32)), tf.TensorSpec(shape=(), dtype=tf.float32) ) train_dataset = tf.data.Dataset.from_generator( data_generator, output_signature=output_signature ) train_dataset = train_dataset.shuffle(560).batch(32)
内容的提问来源于stack exchange,提问作者Code7737
相关产品推荐
相关产品推荐

