为什么 keras 神经网络为所有不同的图像预测相同的数字?
Why does keras neural network predicts the same number for all different images?
我正在尝试使用tensorflow的keras神经网络来识别手写数字。但是我不知道为什么当我调用 predict()
时,它 returns 所有输入图像的结果都相同。
代码如下:
### Train dataset ###
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train/255
x_test = x_test/255
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28)))
model.add(tf.keras.layers.Dense(units=128,activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(units=10,activation=tf.nn.softmax))
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(x_train, y_train, epochs=5)
结果如下所示:
Epoch 1/5
1875/1875 [==============================] - 2s 672us/step - loss: 0.2620 - accuracy: 0.9248
Epoch 2/5
1875/1875 [==============================] - 1s 567us/step - loss: 0.1148 - accuracy: 0.9658
Epoch 3/5
1875/1875 [==============================] - 1s 559us/step - loss: 0.0784 - accuracy: 0.9764
Epoch 4/5
1875/1875 [==============================] - 1s 564us/step - loss: 0.0596 - accuracy: 0.9817
Epoch 5/5
1875/1875 [==============================] - 1s 567us/step - loss: 0.0462 - accuracy: 0.9859
那么使用图片进行测试的代码如下:
img = cv.imread('path/to/1.png')
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img = cv.resize(img,(28,28))
img = np.array([img])
if cv.countNonZero((255-image)) == 0:
print('')
img = np.invert(img)
plt.imshow(img[0])
plt.show()
prediction = model.predict(img)
result = np.argmax(prediction)
print(prediction)
print(f'Result: {result}')
结果是:
plt 显示:
[[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]]
Result: 3
plt 显示
[[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]]
Result: 3
在推理时间内对数据进行归一化,与在训练集上所做的一样
img = np.array([img]) / 255
查看 了解更多详情。
根据您的第 3 条评论,这里有一些详细信息。
def input_prepare(img):
img = cv2.resize(img, (28, 28))
img = cv2.bitwise_not(img)
img = tf.cast(tf.divide(img, 255) , tf.float64)
img = tf.expand_dims(img, axis=0)
return img
img = cv2.imread('/content/1.png')
orig = img.copy() # save for plotting later on
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # gray scaling
img = input_prepare(img)
plt.imshow(tf.reshape(img, shape=[28, 28]))
plt.imshow(cv2.cvtColor(orig, cv2.COLOR_BGR2RGB))
plt.title(np.argmax(model.predict(img)))
plt.show()
它按预期工作。但是由于调整图像大小,数字被破坏并丢失了它们的空间信息。这对模型来说似乎没问题,但如果情况变得更糟,那么模型就会预测错误。一个案例
并且模型为此预测错误。
plt.imshow(cv2.cvtColor(orig, cv2.COLOR_BGR2RGB))
plt.title(np.argmax(model.predict(img)))
plt.show()
为了解决这个问题,我们可以应用 cv2.erode
在调整大小后添加一些像素,例如
def input_prepare(img):
img = cv2.resize(img, (28, 28))
img = cv2.erode(img, np.ones((2, 2)))
img = cv2.bitwise_not(img)
img = tf.cast(tf.divide(img, 255) , tf.float64)
img = tf.expand_dims(img, axis=0)
return img
也许不是最好的方法,但现在模型会更好地理解。
plt.imshow(cv2.cvtColor(orig, cv2.COLOR_BGR2RGB))
plt.title(np.argmax(model.predict(img)))
plt.show()
我正在尝试使用tensorflow的keras神经网络来识别手写数字。但是我不知道为什么当我调用 predict()
时,它 returns 所有输入图像的结果都相同。
代码如下:
### Train dataset ###
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train/255
x_test = x_test/255
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28)))
model.add(tf.keras.layers.Dense(units=128,activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(units=10,activation=tf.nn.softmax))
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(x_train, y_train, epochs=5)
结果如下所示:
Epoch 1/5
1875/1875 [==============================] - 2s 672us/step - loss: 0.2620 - accuracy: 0.9248
Epoch 2/5
1875/1875 [==============================] - 1s 567us/step - loss: 0.1148 - accuracy: 0.9658
Epoch 3/5
1875/1875 [==============================] - 1s 559us/step - loss: 0.0784 - accuracy: 0.9764
Epoch 4/5
1875/1875 [==============================] - 1s 564us/step - loss: 0.0596 - accuracy: 0.9817
Epoch 5/5
1875/1875 [==============================] - 1s 567us/step - loss: 0.0462 - accuracy: 0.9859
那么使用图片进行测试的代码如下:
img = cv.imread('path/to/1.png')
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img = cv.resize(img,(28,28))
img = np.array([img])
if cv.countNonZero((255-image)) == 0:
print('')
img = np.invert(img)
plt.imshow(img[0])
plt.show()
prediction = model.predict(img)
result = np.argmax(prediction)
print(prediction)
print(f'Result: {result}')
结果是:
plt 显示:
[[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]]
Result: 3
plt 显示
[[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]]
Result: 3
在推理时间内对数据进行归一化,与在训练集上所做的一样
img = np.array([img]) / 255
查看
根据您的第 3 条评论,这里有一些详细信息。
def input_prepare(img):
img = cv2.resize(img, (28, 28))
img = cv2.bitwise_not(img)
img = tf.cast(tf.divide(img, 255) , tf.float64)
img = tf.expand_dims(img, axis=0)
return img
img = cv2.imread('/content/1.png')
orig = img.copy() # save for plotting later on
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # gray scaling
img = input_prepare(img)
plt.imshow(tf.reshape(img, shape=[28, 28]))
plt.imshow(cv2.cvtColor(orig, cv2.COLOR_BGR2RGB))
plt.title(np.argmax(model.predict(img)))
plt.show()
它按预期工作。但是由于调整图像大小,数字被破坏并丢失了它们的空间信息。这对模型来说似乎没问题,但如果情况变得更糟,那么模型就会预测错误。一个案例
并且模型为此预测错误。
plt.imshow(cv2.cvtColor(orig, cv2.COLOR_BGR2RGB))
plt.title(np.argmax(model.predict(img)))
plt.show()
为了解决这个问题,我们可以应用 cv2.erode
在调整大小后添加一些像素,例如
def input_prepare(img):
img = cv2.resize(img, (28, 28))
img = cv2.erode(img, np.ones((2, 2)))
img = cv2.bitwise_not(img)
img = tf.cast(tf.divide(img, 255) , tf.float64)
img = tf.expand_dims(img, axis=0)
return img
也许不是最好的方法,但现在模型会更好地理解。
plt.imshow(cv2.cvtColor(orig, cv2.COLOR_BGR2RGB))
plt.title(np.argmax(model.predict(img)))
plt.show()