彩色JPEG图像数组输入CNN的形状要求及调整转换方法
问题原因
- 数组形状为(10,)的成因:你加载的原始JPEG图像分辨率不是统一的32*32,执行
np.array(x_train)时,Numpy无法将不同尺寸的图像数组合并为高维张量,因此生成了长度为训练集样本数(10)的一维对象数组,每个元素对应一张不同尺寸的图像数组。 - 适配要求的目标形状:Conv2D输入层要求单张图像维度为
(32, 32, 3),传入fit的训练集需要为4维张量,形状为(样本数, 32, 32, 3),标签保持(样本数,)的一维格式即可匹配你选择的稀疏分类交叉熵损失。
修复步骤
- 新增图像缩放逻辑,将所有加载的图像统一调整为32*32分辨率
- 对像素值做归一化处理,将0255的整数转换为01的浮点数,提升模型训练稳定性
- 可选优化:你当前只有飞机、汽车2个分类,输出层
Dense(10)建议改为Dense(2),匹配分类数量
修正后的完整代码
import tensorflow as tf from tensorflow.keras import layers, models from PIL import Image from matplotlib import pyplot import random import numpy as np from os import listdir from matplotlib import image # 加载所有图像 imagesWithLabels = [] for filename in listdir('C:/AI/images/airplanes'): img_data = image.imread('C:/AI/images/airplanes/' + filename) # 统一缩放为32*32分辨率 img = Image.fromarray(img_data) img = img.resize((32, 32), Image.Resampling.LANCZOS) img_data = np.array(img) imagesWithLabels.append((img_data,0)) print('> loaded %s %s' % (filename, img_data.shape)) for filename in listdir('C:/AI/images/automobiles'): img_data = image.imread('C:/AI/images/automobiles/' + filename) # 统一缩放为32*32分辨率 img = Image.fromarray(img_data) img = img.resize((32, 32), Image.Resampling.LANCZOS) img_data = np.array(img) imagesWithLabels.append((img_data,1)) print('> loaded %s %s' % (filename, img_data.shape)) random.shuffle(imagesWithLabels) train = imagesWithLabels[:10] test = imagesWithLabels[10:] x_train, y_train = zip(*train) x_test, y_test = zip(*test) # 转为numpy数组并做归一化处理 x_train = np.array(x_train).astype('float32') / 255.0 x_test = np.array(x_test).astype('float32') / 255.0 y_train = np.array(y_train) y_test = np.array(y_test) # 可打印验证形状,此时x_train应为(10, 32, 32, 3) print(x_train.shape) CNN_model = models.Sequential() CNN_model.add(layers.Conv2D(50, (2, 2), activation='relu', input_shape=(32, 32, 3))) CNN_model.add(layers.MaxPooling2D((3, 3))) CNN_model.add(layers.Flatten()) CNN_model.add(layers.Dense(50, activation='relu')) CNN_model.add(layers.Dropout(.1)) # 匹配2分类修改输出层,保留原10类设置也可正常运行 CNN_model.add(layers.Dense(2, activation='softmax')) optimizer = tf.optimizers.Adam(learning_rate = .005) CNN_model.compile(optimizer=optimizer, loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False), metrics=['accuracy']) history = CNN_model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test))
内容的提问来源于stack exchange,提问作者user12862298
相关产品推荐
相关产品推荐

