使用Keras模型预测时遇到问题

我使用GTSRB训练了一个神经网络,并尝试使用保存的模型(.h5),但在使用model.predict时遇到了以下错误:

ValueError: Input 0 of layer sequential is incompatible with the layer: : expected min_ndim=4, found ndim=3. Full shape received: (None, 30, 3)

训练代码如下:

import cv2import numpy as npimport osimport sysimport tensorflow as tffrom sklearn.model_selection import train_test_splitEPOCHS = 10IMG_WIDTH = 30IMG_HEIGHT = 30NUM_CATEGORIES = 43TEST_SIZE = 0.4def main():    # 检查命令行参数    if len(sys.argv) not in [2, 3]:        sys.exit("Usage: python traffic.py data_directory [model.h5]")    # 获取所有图像文件的图像数组和标签    images, labels = load_data(sys.argv[1])    # 将数据分割成训练集和测试集    labels = tf.keras.utils.to_categorical(labels)    x_train, x_test, y_train, y_test = train_test_split(        np.array(images), np.array(labels), test_size=TEST_SIZE    )    # 获取已编译的神经网络    model = get_model()    # 在训练数据上拟合模型    model.fit(x_train, y_train, epochs=EPOCHS)    # 评估神经网络性能    model.evaluate(x_test, y_test, verbose=2)    # 将模型保存到文件中    if len(sys.argv) == 3:        filename = sys.argv[2]        model.save(filename)        print(f"Model saved to {filename}.")def load_data(data_dir):    """    从目录`data_dir`加载图像数据。    假设`data_dir`有一个按每个类别命名的目录,编号从0到NUM_CATEGORIES - 1。每个类别目录中将有一些图像文件。    返回元组`(images, labels)`。`images`应该是数据目录中所有图像的列表,每个图像格式化为具有维度IMG_WIDTH x IMG_HEIGHT x 3的numpy ndarray。`labels`应该是整数标签的列表,表示每个对应`images`的类别。    """    images = list()    labels = list()    for folder in os.listdir(data_dir):        folder_path = os.path.join(data_dir, folder)        if os.path.isdir(folder_path):            for photo in os.listdir(folder_path):                img = cv2.imread(os.path.join(folder_path, photo))                img = cv2.resize(img, (IMG_WIDTH, IMG_HEIGHT))                images.append(img)                labels.append(int(folder))    return images, labelsdef get_model():    """    返回已编译的卷积神经网络模型。假设第一层的`input_shape`为`(IMG_WIDTH, IMG_HEIGHT, 3)`。    输出层应具有`NUM_CATEGORIES`个单元,每个类别一个。    """        # 创建一个卷积神经网络    model = tf.keras.models.Sequential([        # 卷积层。使用3x3的内核学习32个滤波器        tf.keras.layers.Conv2D(            32, (3, 3), activation="relu", input_shape=(IMG_WIDTH, IMG_HEIGHT, 3)        ),        # 最大池化层,使用2x2的池化大小        tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),        tf.keras.layers.Conv2D(            32, (3, 3), activation="relu", input_shape=(IMG_WIDTH, IMG_HEIGHT, 3)        ),        # 展平单元        tf.keras.layers.Flatten(),        # 添加一个带有丢弃的隐藏层        tf.keras.layers.Dense(NUM_CATEGORIES * 16, activation="relu"),        tf.keras.layers.Dropout(0.3),        # 添加一个具有所有10个数字输出单元的输出层        tf.keras.layers.Dense(NUM_CATEGORIES, activation="softmax")    ])    # 训练神经网络    model.compile(        optimizer="adam",        loss="binary_crossentropy",        metrics=["accuracy"]    )    return modelif __name__ == "__main__":    main()

使用保存的模型对照片进行分类的代码

from tensorflow.keras.models import load_modelfrom tensorflow.keras.preprocessing import imageimport numpyimport cv2PHOTO_PATH = r'C:\Users\m\ai50\projects\2020\x\traffic\gtsrb\x.ppm'MODEL_PATH = r'C:\Users\m\ai50\projects\2020\x\traffic\model.h5'model = load_model(MODEL_PATH, compile=True)img = cv2.imread(PHOTO_PATH)img = cv2.resize(img, (30, 30))img = numpy.array(img)print(img.shape)result = model.predict(img)print(result)

回答:

给你的图像数组增加一个维度。.predict()方法期望输入具有四个维度:(batch, height, width, channels)。增加一个维度实际上使其成为一个包含一张图像的批次。

result = model.predict(img[numpy.newaxis])

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注