{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3649,"databundleVersionId":46718,"sourceType":"competition"},{"sourceId":7172886,"sourceType":"datasetVersion","datasetId":4144509}],"dockerImageVersionId":29862,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 模型是在kaggle平台上搭建的\n下面进行演示，并说明关键步骤","metadata":{}},{"cell_type":"code","source":"from __future__ import print_function  # 导入 Python 3 的 print 函数\n\nimport keras  # 导入 Keras 库\nfrom keras.datasets import cifar10  # 导入 CIFAR-10 数据集\nfrom keras.preprocessing.image import ImageDataGenerator  # 导入图像数据生成器\nfrom keras.models import Sequential  # 导入序贯模型\nfrom keras.layers import Dense, Dropout, Activation, Flatten  # 导入各种层类型\nfrom keras.layers import Conv2D, MaxPooling2D  # 导入各种卷积和池化层类型\nimport os  # 导入操作系统模块\n\nimport numpy as np  # 导入 NumPy 库\n\nimport seaborn as sns  # 导入 seaborn 库\nimport matplotlib  # 导入 matplotlib 库\nimport matplotlib.pyplot as plt  # 导入 pyplot 模块\n\nfrom sklearn.metrics import confusion_matrix, classification_report  # 导入评估指标\nimport itertools  # 导入工具函数\n# 在 Jupyter Notebook 中显示绘图\n%matplotlib inline  ","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:12:21.666119Z","iopub.execute_input":"2023-12-14T03:12:21.666603Z","iopub.status.idle":"2023-12-14T03:12:21.679123Z","shell.execute_reply.started":"2023-12-14T03:12:21.666538Z","shell.execute_reply":"2023-12-14T03:12:21.678078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 32  # Keras的默认批大小。\nnum_classes = 10  # 数据集的类别数量。\nepochs = 100  # 训练的轮数。\ndata_augmentation = False  # 是否进行数据增强。","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-14T03:12:21.681478Z","iopub.execute_input":"2023-12-14T03:12:21.681960Z","iopub.status.idle":"2023-12-14T03:12:21.691404Z","shell.execute_reply.started":"2023-12-14T03:12:21.681899Z","shell.execute_reply":"2023-12-14T03:12:21.690476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 加载数据，将其分为训练集和测试集：\n(x_train, y_train), (x_test, y_test) = cifar10.load_data()\n\n# 打印训练集和测试集的形状：\nprint('x_train shape:', x_train.shape)\nprint('y_train shape:', y_train.shape)\nprint(x_train.shape[0], 'train samples')\nprint(x_test.shape[0], 'test samples')","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:12:21.692740Z","iopub.execute_input":"2023-12-14T03:12:21.693068Z","iopub.status.idle":"2023-12-14T03:12:22.036807Z","shell.execute_reply.started":"2023-12-14T03:12:21.693012Z","shell.execute_reply":"2023-12-14T03:12:22.035823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axs = plt.subplots(1, 2, figsize=(15, 5)) \n# Count plot for training set\nsns.countplot(y_train.ravel(), ax=axs[0])\naxs[0].set_title('Distribution of training data')\naxs[0].set_xlabel('Classes')\n# Count plot for testing set\nsns.countplot(y_test.ravel(), ax=axs[1])\naxs[1].set_title('Distribution of Testing data')\naxs[1].set_xlabel('Classes')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:12:22.038668Z","iopub.execute_input":"2023-12-14T03:12:22.039045Z","iopub.status.idle":"2023-12-14T03:12:22.639342Z","shell.execute_reply.started":"2023-12-14T03:12:22.038987Z","shell.execute_reply":"2023-12-14T03:12:22.637981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 数据归一化。在进行计算之前，我们需要将数据类型转换为浮点型。\nx_train = x_train.astype('float32')\nx_test = x_test.astype('float32')\n\n# 数据归一化，将像素值缩放到0到1之间。\nx_train /= 255\nx_test /= 255\n\n# 将类别向量转换为二进制类别矩阵。这称为独热编码。\ny_train = keras.utils.to_categorical(y_train, num_classes)\ny_test = keras.utils.to_categorical(y_test, num_classes)","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:12:22.644564Z","iopub.execute_input":"2023-12-14T03:12:22.645355Z","iopub.status.idle":"2023-12-14T03:12:22.934539Z","shell.execute_reply.started":"2023-12-14T03:12:22.645285Z","shell.execute_reply":"2023-12-14T03:12:22.933444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 定义卷积神经网络模型\nmodel = Sequential()\n\n# 第一层卷积层：CONV => RELU => CONV => RELU => POOL => DROPOUT\nmodel.add(Conv2D(32, (3, 3), padding='same', input_shape=x_train.shape[1:]))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(32, (3, 3)))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\n# 第二层卷积层：CONV => RELU => CONV => RELU => POOL => DROPOUT\nmodel.add(Conv2D(64, (3, 3), padding='same'))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(64, (3, 3)))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\n# 全连接层：FLATTEN => DENSE => RELU => DROPOUT\nmodel.add(Flatten())\nmodel.add(Dense(512))\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.5))\n\n# 输出层：一个softmax分类器\nmodel.add(Dense(num_classes))\nmodel.add(Activation('softmax'))\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:12:22.937662Z","iopub.execute_input":"2023-12-14T03:12:22.938002Z","iopub.status.idle":"2023-12-14T03:12:23.063559Z","shell.execute_reply.started":"2023-12-14T03:12:22.937956Z","shell.execute_reply":"2023-12-14T03:12:23.062582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 初始化RMSprop优化器\nopt = keras.optimizers.RMSprop(learning_rate=0.0001, decay=1e-6)\n\n# 使用RMSprop优化器进行模型训练\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=opt,\n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:12:23.065052Z","iopub.execute_input":"2023-12-14T03:12:23.065448Z","iopub.status.idle":"2023-12-14T03:12:23.117368Z","shell.execute_reply.started":"2023-12-14T03:12:23.065380Z","shell.execute_reply":"2023-12-14T03:12:23.116401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 此时已经开始训练模型了\n由于训练的时间比较长，下面展示之后的代码","metadata":{}},{"cell_type":"code","source":"history = model.fit(x_train, y_train,\n                    batch_size=batch_size,\n                    epochs=epochs,\n                    validation_data=(x_test, y_test),\n                    shuffle=True,\n                    verbose=1)\n\n# 绘制模型的准确率和损失曲线\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('Model Accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper left')\nplt.show()\n\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Model Loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:12:23.119248Z","iopub.execute_input":"2023-12-14T03:12:23.119782Z","iopub.status.idle":"2023-12-14T03:28:19.221570Z","shell.execute_reply.started":"2023-12-14T03:12:23.119715Z","shell.execute_reply":"2023-12-14T03:28:19.220086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 评估模型\nscores = model.evaluate(x_test, y_test, verbose=1)  # 在测试集上评估模型\nprint('Test loss:', scores[0])  # 打印测试集上的损失值\nprint('Test accuracy:', scores[1])  # 打印测试集上的准确率\n\n# 进行预测\npred = model.predict(x_test)  # 对测试集进行预测","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:19.223552Z","iopub.execute_input":"2023-12-14T03:28:19.224126Z","iopub.status.idle":"2023-12-14T03:28:20.905952Z","shell.execute_reply.started":"2023-12-14T03:28:19.224041Z","shell.execute_reply":"2023-12-14T03:28:20.905101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def heatmap(data, row_labels, col_labels, ax=None, cbar_kw={}, cbarlabel=\"\", **kwargs):\n    \"\"\"\n    Create a heatmap from a numpy array and two lists of labels.\n    \"\"\"\n\n    if not ax:\n        ax = plt.gca()\n\n    # 绘制热力图\n    im = ax.imshow(data, **kwargs)\n\n    # 创建颜色条\n    cbar = ax.figure.colorbar(im, ax=ax, **cbar_kw)\n    cbar.ax.set_ylabel(cbarlabel, rotation=-90, va=\"bottom\")\n\n    # 让水平坐标轴标签显示在顶部\n    ax.tick_params(top=True, bottom=False, labeltop=True, labelbottom=False)\n\n    # 设置刻度和标签\n    ax.set_xticks(np.arange(data.shape[1]))\n    ax.set_yticks(np.arange(data.shape[0]))\n    ax.set_xticklabels(col_labels)\n    ax.set_yticklabels(row_labels)\n    \n    ax.set_xlabel('Predicted Label') \n    ax.set_ylabel('True Label')\n    \n    return im, cbar\n\n\ndef annotate_heatmap(im, data=None, fmt=\"d\", threshold=None):\n    \"\"\"\n    A function to annotate a heatmap.\n    \"\"\"\n\n    # 根据数据的大小改变文本的颜色\n    texts = []\n    for i in range(data.shape[0]):\n        for j in range(data.shape[1]):\n            text = im.axes.text(j, i, format(data[i, j], fmt), horizontalalignment=\"center\",\n                                 color=\"white\" if data[i, j] > threshold else \"black\")\n            texts.append(text)\n\n    return texts","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:20.907459Z","iopub.execute_input":"2023-12-14T03:28:20.907785Z","iopub.status.idle":"2023-12-14T03:28:20.923617Z","shell.execute_reply.started":"2023-12-14T03:28:20.907741Z","shell.execute_reply":"2023-12-14T03:28:20.922572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = ['Airplane', 'Automobile', 'Bird', 'Cat', 'Deer', 'Dog', 'Frog', 'Horse', 'Ship', 'Truck']\n\n# 将预测的类别转换为独热向量\nY_pred_classes = np.argmax(pred, axis=1)\n# 将验证集的观测值转换为独热向量\nY_true = np.argmax(y_test, axis=1)\n# 错误是预测标签和真实标签不一致的样本\nerrors = (Y_pred_classes - Y_true != 0)\n\nY_pred_classes_errors = Y_pred_classes[errors]\nY_pred_errors = pred[errors]\nY_true_errors = Y_true[errors]\nX_test_errors = x_test[errors]\n\n# 计算混淆矩阵\ncm = confusion_matrix(Y_true, Y_pred_classes)\nthresh = cm.max() / 2.\n\n# 创建图形和坐标轴\nfig, ax = plt.subplots(figsize=(12, 12))\nim, cbar = heatmap(cm, labels, labels, ax=ax, cmap=plt.cm.Blues, cbarlabel=\"count of predictions\")\ntexts = annotate_heatmap(im, data=cm, threshold=thresh)\n\n# 调整图形布局并显示图形\nfig.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:20.925230Z","iopub.execute_input":"2023-12-14T03:28:20.925715Z","iopub.status.idle":"2023-12-14T03:28:22.161445Z","shell.execute_reply.started":"2023-12-14T03:28:20.925654Z","shell.execute_reply":"2023-12-14T03:28:22.160572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(classification_report(Y_true, Y_pred_classes))","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:22.162811Z","iopub.execute_input":"2023-12-14T03:28:22.163189Z","iopub.status.idle":"2023-12-14T03:28:22.195597Z","shell.execute_reply.started":"2023-12-14T03:28:22.163133Z","shell.execute_reply":"2023-12-14T03:28:22.194663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 下面的代码是将预测好的图像展示出来，PPT上模型运行的结果","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:22.196981Z","iopub.execute_input":"2023-12-14T03:28:22.197309Z","iopub.status.idle":"2023-12-14T03:28:22.201382Z","shell.execute_reply.started":"2023-12-14T03:28:22.197266Z","shell.execute_reply":"2023-12-14T03:28:22.200219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"R = 5  # 行数\nC = 5  # 列数\n\n# 创建包含子图的图形\nfig, axes = plt.subplots(R, C, figsize=(12, 12))\naxes = axes.ravel()  # 将子图对象展平为一维数组\n\n# 遍历子图数组\nfor i in np.arange(0, R * C):\n    # 在子图中显示测试集的图像\n    axes[i].imshow(x_test[i])\n    \n    # 设置子图标题，包括真实标签和预测标签的信息\n    axes[i].set_title(\"True: %s \\nPredict: %s\" % (labels[Y_true[i]], labels[Y_pred_classes[i]]))\n    \n    # 关闭子图的坐标轴显示\n    axes[i].axis('off')\n    \n    # 调整子图之间的水平间距\n    plt.subplots_adjust(wspace=1)","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:22.202855Z","iopub.execute_input":"2023-12-14T03:28:22.203182Z","iopub.status.idle":"2023-12-14T03:28:23.765739Z","shell.execute_reply.started":"2023-12-14T03:28:22.203139Z","shell.execute_reply":"2023-12-14T03:28:23.764831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### - Check the wrong predictions.","metadata":{}},{"cell_type":"code","source":"R = 3  # 行数\nC = 5  # 列数\n\n# 创建包含子图的图形\nfig, axes = plt.subplots(R, C, figsize=(12, 8))\naxes = axes.ravel()  # 将子图对象展平为一维数组\n\n# 找到预测错误的样本索引\nmisclassified_idx = np.where(Y_pred_classes != Y_true)[0]\n\n# 遍历子图数组\nfor i in np.arange(0, R * C):\n    # 在子图中显示预测错误的测试集图像\n    axes[i].imshow(x_test[misclassified_idx[i]])\n    \n    # 设置子图标题，包括真实标签和预测标签的信息\n    axes[i].set_title(\"True: %s \\nPredicted: %s\" % (labels[Y_true[misclassified_idx[i]]], \n                                                    labels[Y_pred_classes[misclassified_idx[i]]]))\n    \n    # 关闭子图的坐标轴显示\n    axes[i].axis('off')\n    \n    # 调整子图之间的水平间距\n    plt.subplots_adjust(wspace=1)","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:23.766966Z","iopub.execute_input":"2023-12-14T03:28:23.767343Z","iopub.status.idle":"2023-12-14T03:28:24.584434Z","shell.execute_reply.started":"2023-12-14T03:28:23.767290Z","shell.execute_reply":"2023-12-14T03:28:24.583448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_errors(errors_index, img_errors, pred_errors, obs_errors):\n    \"\"\"该函数显示10个图像及其预测和真实标签\"\"\"\n    n = 0  # 计数器\n    nrows = 2  # 行数\n    ncols = 5  # 列数\n    fig, ax = plt.subplots(nrows, ncols, sharex=True, sharey=True, figsize=(12, 6))\n    for row in range(nrows):\n        for col in range(ncols):\n            error = errors_index[n]  # 获取错误索引\n            ax[row, col].imshow((img_errors[error]).reshape((32, 32, 3)))\n            ax[row, col].set_title(\"Predicted:{}\\nTrue:{}\".format(labels[pred_errors[error]], labels[obs_errors[error]]))\n            n += 1\n            ax[row, col].axis('off')\n            plt.subplots_adjust(wspace=1)\n\n# 错误预测数字的概率\nY_pred_errors_prob = np.max(Y_pred_errors, axis=1)\n\n# 错误集中真实值的预测概率\ntrue_prob_errors = np.diagonal(np.take(Y_pred_errors, Y_true_errors, axis=1))\n\n# 预测标签和真实标签之间的概率差异\ndelta_pred_true_errors = Y_pred_errors_prob - true_prob_errors\n\n# 按照概率差异排序的错误列表\nsorted_dela_errors = np.argsort(delta_pred_true_errors)\n\n# 前10个错误\nmost_important_errors = sorted_dela_errors[-10:]\n\n# 显示前10个错误\ndisplay_errors(most_important_errors, X_test_errors, Y_pred_classes_errors, Y_true_errors)","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:24.585738Z","iopub.execute_input":"2023-12-14T03:28:24.586038Z","iopub.status.idle":"2023-12-14T03:28:25.158329Z","shell.execute_reply.started":"2023-12-14T03:28:24.585998Z","shell.execute_reply":"2023-12-14T03:28:25.157518Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_test(number):\n    fig = plt.figure(figsize = (3,3))\n    test_image = np.expand_dims(x_test[number], axis=0)\n    test_result = model.predict_classes(test_image)\n    plt.imshow(x_test[number])\n    dict_key = test_result[0]\n    plt.title(\"Predicted: {} \\nTrue Label: {}\".format(labels[dict_key],\n                                                      labels[Y_true[number]]))","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:25.159559Z","iopub.execute_input":"2023-12-14T03:28:25.159879Z","iopub.status.idle":"2023-12-14T03:28:25.167491Z","shell.execute_reply.started":"2023-12-14T03:28:25.159838Z","shell.execute_reply":"2023-12-14T03:28:25.166375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_test(20)","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:25.169475Z","iopub.execute_input":"2023-12-14T03:28:25.169973Z","iopub.status.idle":"2023-12-14T03:28:25.345999Z","shell.execute_reply.started":"2023-12-14T03:28:25.169860Z","shell.execute_reply":"2023-12-14T03:28:25.344843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"save_dir = os.path.join(os.getcwd(), 'saved_models')\nmodel_name = 'keras_cifar10_trained_model.h5'\n\n# Save model and weights\nif not os.path.isdir(save_dir):\n    os.makedirs(save_dir)\nmodel_path = os.path.join(save_dir, model_name)\nmodel.save(model_path)\nprint('Saved trained model at %s ' % model_path)\n\n# Score trained model.\nscores = model.evaluate(x_test, y_test, verbose=1)\nprint('Test loss:', scores[0])\nprint('Test accuracy:', scores[1])\n","metadata":{"_cell_guid":"","_uuid":"","execution":{"iopub.status.busy":"2023-12-14T03:28:25.347884Z","iopub.execute_input":"2023-12-14T03:28:25.351368Z","iopub.status.idle":"2023-12-14T03:28:26.331267Z","shell.execute_reply.started":"2023-12-14T03:28:25.351222Z","shell.execute_reply":"2023-12-14T03:28:26.330361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom tensorflow import keras","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:26.332690Z","iopub.execute_input":"2023-12-14T03:28:26.333023Z","iopub.status.idle":"2023-12-14T03:28:26.544373Z","shell.execute_reply.started":"2023-12-14T03:28:26.332973Z","shell.execute_reply":"2023-12-14T03:28:26.543500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = keras.models.load_model('/kaggle/working/saved_models/keras_cifar10_trained_model.h5')  # 替换为您训练好的模型的路径","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:28:26.545771Z","iopub.execute_input":"2023-12-14T03:28:26.546100Z","iopub.status.idle":"2023-12-14T03:28:27.405775Z","shell.execute_reply.started":"2023-12-14T03:28:26.546056Z","shell.execute_reply":"2023-12-14T03:28:27.404659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 上面那步模型已经训练好了，接下来是使用自己准备的图片进行预测\n自己准备的图片就是右侧【input】的【cifar-test】","metadata":{}},{"cell_type":"code","source":"import os\n\ndef preprocess_image(image_path):\n    image = cv2.imread(image_path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 将图像从BGR转为RGB格式\n    image = cv2.resize(image, (32, 32))  # 调整图像大小为模型输入的尺寸\n    image = image.astype('float32') / 255.0  # 归一化处理，像素值缩放到0到1之间\n    return image","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:34:32.809224Z","iopub.execute_input":"2023-12-14T03:34:32.809650Z","iopub.status.idle":"2023-12-14T03:34:32.816283Z","shell.execute_reply.started":"2023-12-14T03:34:32.809599Z","shell.execute_reply":"2023-12-14T03:34:32.815009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 加载图片\ndef deal_image(image_filename):\n    image_folder = '/kaggle/input/cifar-test'  # 替换为您自己的图像文件夹路径\n    image_filename += '.jpg'  # 替换为您的图像文件名\n    image_path = os.path.join(image_folder, image_filename)  # 构建完整的图像文件路径\n    image = preprocess_image(image_path)\n    image = np.expand_dims(image, axis=0)  # 增加一个维度，适配模型输入的形状\n    return image_path, image","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:34:35.877565Z","iopub.execute_input":"2023-12-14T03:34:35.877969Z","iopub.status.idle":"2023-12-14T03:34:35.884522Z","shell.execute_reply.started":"2023-12-14T03:34:35.877921Z","shell.execute_reply":"2023-12-14T03:34:35.883339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filenames = ['brid', 'brid1', 'car', 'car1', 'cat', 'cattle', 'deer', 'dog', 'dog1', 'duck', 'horse', 'plane', 'ship']\nclass_labels = ['Airplane', 'Automobile', 'Bird', 'Cat', 'Deer', 'Dog', 'Frog', 'Horse', 'Ship', 'Truck']  # 替换为您模型所用的类别标签","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:34:39.012783Z","iopub.execute_input":"2023-12-14T03:34:39.013220Z","iopub.status.idle":"2023-12-14T03:34:39.018940Z","shell.execute_reply.started":"2023-12-14T03:34:39.013155Z","shell.execute_reply":"2023-12-14T03:34:39.018013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for name in filenames:\n    image_path, image = deal_image(name)\n    predictions = model.predict(image)\n    predicted_label = np.argmax(predictions[0])\n    predicted_class = class_labels[predicted_label]\n    print(f'True class:{name}   Predicted class:{predicted_class}')\n    plt.imshow(cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB))\n    plt.title('Predicted class: ' + predicted_class)\n    plt.axis('off')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-14T03:34:41.036607Z","iopub.execute_input":"2023-12-14T03:34:41.037038Z","iopub.status.idle":"2023-12-14T03:34:45.504644Z","shell.execute_reply.started":"2023-12-14T03:34:41.036990Z","shell.execute_reply":"2023-12-14T03:34:45.503550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"演示结束","metadata":{}}]}