【问题标题】:Why are my neural network predictions correct when applied to MNIST hand-drawn images, but incorrect when applied to my own hand-drawn images?为什么我的神经网络预测在应用于 MNIST 手绘图像时是正确的,但在应用于我自己的手绘图像时却不正确?
【发布时间】:2019-10-30 17:47:07
【问题描述】:

背景:

我正在尝试使用 MNIST 数据集创建一个基本的神经网络来识别手绘图像。在针对 MNIST 数据进行训练/预测时,我的工作正常。

目标:

我想开始将该模型应用于非 MNIST 图像(即我自己创建的手绘图像)。

问题:

我创建的对手绘图像的每个预测最终都是不正确的(这很奇怪,因为针对 MNIST 图像的预测准确率为 95%)。

代码:

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import cv2

mnist = tf.keras.datasets.mnist # 28x28 images of handwritten digits (0-9)

(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = tf.keras.utils.normalize(x_train, axis=1)
x_test = tf.keras.utils.normalize(x_test, axis=1)

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(10, activation=tf.nn.softmax))

model.compile(optimizer='adam',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy'])

model.fit(x_train, y_train, epochs=3)

val_loss, val_acc = model.evaluate(x_test, y_test)
print(val_loss, val_acc)

# prediction from MNIST dataset
index_of_mnist_img = 0
predictionsA = model.predict([x_test])
print(np.argmax(predictionsA[index_of_mnist_img]))
plt.imshow(x_test[index_of_mnist_img], cmap = plt.cm.binary)
plt.show()

# prediction from my own hand-drawn image (THIS IS WHERE THINGS START GOING WRONG)
img = cv2.imread('4.png')
img = cv2.resize(img, (28,28))
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = np.reshape(img, [1,28,28])
predictionsB = model.predict(img)
print(np.argmax(predictionsB[0]))
plt.imshow(predictionsB[0])
plt.show()

有什么想法吗?

【问题讨论】:

  • 您自己测试了多少张图片?它们的格式相同吗?它们看起来和 MNIST 一样吗?
  • mnist 数据集有 60,000 个训练图像和 10,000 个测试图像。训练图像、测试图像和我自己的图像都是 28x28 像素并且是灰度的。

标签: python tensorflow machine-learning keras deep-learning


【解决方案1】:

我认为您需要反转新(手绘)图像的颜色图。

当我查看 MNIST 示例图像时,我会看到如下内容:

# show mnist image
index_of_mnist_img = 0
plt.imshow(x_test[index_of_mnist_img], cmap = plt.cm.binary)
plt.show()

但是,如果我制作一个手写数字示例,并按照您的方式读入,我会看到一个倒置的图像。

img = cv2.imread("4.png")
img = cv2.resize(img, (28,28))
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.imshow(img, cmap = plt.cm.binary)

您可以通过添加一行cv2.bitwise_not() 来使用 OpenCV 反转图像。

img = cv2.imread(r"4.png")
img = cv2.resize(img, (28,28))
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img= cv2.bitwise_not(img) # invert image
plt.imshow(img, cmap = plt.cm.binary)

当我反转图像时,我会从您在上面训练的神经网络中得到正确的预测。

predictionsB = model.predict(img)
print(np.argmax(predictionsB[0]))
4

【讨论】:

    【解决方案2】:

    您是否需要考虑如何创建训练/测试。这种训练可能会被过度训练,这样,你就可以在训练中给出一个很好的准确性,但这并不是真正的测试数据。

    也可以使用图像增强来增加你的数据集,因为 MNIST 是一个相对较小的数据集,并且数字是集中的,图像没有噪声等。

    还可以使用另一个概念,例如 Dropouts:Dropouts 背后的想法是,它们会移除神经网络中随机数量的神经元。这很有效,原因有两个:首先是相邻神经元通常以相似的权重结束,这可能导致过度拟合,因此随机丢弃一些可以消除这种情况。

    另一件事是使用池化层来减少表示的大小,这样它会检测到更多的特征。

    【讨论】:

    • 感谢您让我考虑这一点,willteam。我将尝试从 MNIST 数据集中提取图像作为独立图像,并针对它测试上述代码。这将允许我确定它是代码还是我创建图像的方式。谢谢!
    猜你喜欢
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 2016-07-28
    • 2019-02-03
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    相关资源
    最近更新 更多