python - 手写数字识别AI模型的错误轮廓和错误输出
问题描述
在训练了一个手写数字识别模型后,当我提供输入图像时,它显示了错误的轮廓和错误的输出。输入数据包含 5 位,但输出为 10-15 位。即使它不会创建直角三角形。以下是训练模型的代码和提供新图像输入的代码
import cv2
import numpy as np
from keras.datasets import mnist
from keras.layers import Dense, Flatten
from keras.layers.convolutional import Conv2D
from keras.models import Sequential
from keras.utils import to_categorical
import matplotlib.pyplot as plt
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print ("Shape of X_train: {}".format(X_train.shape))
print ("Shape of y_train: {}".format(y_train.shape))
print ("Shape of X_test: {}".format(X_test.shape))
print ("Shape of y_test: {}".format(y_test.shape))
X_train = X_train.reshape(60000, 28, 28, 1)
X_test = X_test.reshape(10000, 28, 28, 1)
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
## Declare the model
model = Sequential()
## Declare the layers
layer_1 = Conv2D(32, kernel_size=3, activation='relu', input_shape=(28, 28, 1))
layer_2 = Conv2D(64, kernel_size=3, activation='relu')
layer_3 = Flatten()
layer_4 = Dense(10, activation='softmax')
## Add the layers to the model
model.add(layer_1)
model.add(layer_2)
model.add(layer_3)
model.add(layer_4)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=3)
model.save('Digit_Recognition_Model_2.model')
并提供新的图像输入并进行预测
import tensorflow as tf
import numpy as np
import cv2
import matplotlib.pyplot as plt
model=tf.keras.models.load_model('Digit_Recognition_Model_2.model')
image = cv2.imread('test_images/test3.jpeg')
grey = cv2.cvtColor(image.copy(), cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(grey.copy(), 75, 255, cv2.THRESH_BINARY_INV)
contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
preprocessed_digits = []
for c in contours:
x,y,w,h = cv2.boundingRect(c)
# Creating a rectangle around the digit in the original image (for displaying the digits fetched via contours)
cv2.rectangle(image, (x,y), (x+w, y+h), color=(0, 255, 0), thickness=2)
# Cropping out the digit from the image corresponding to the current contours in the for loop
digit = thresh[y:y+h, x:x+w]
# Resizing that digit to (18, 18)
resized_digit = cv2.resize(digit, (18,18))
# Padding the digit with 5 pixels of black color (zeros) in each side to finally produce the image of (28, 28)
padded_digit = np.pad(resized_digit, ((5,5),(5,5)), "constant", constant_values=0)
# Adding the preprocessed digit to the list of preprocessed digits
preprocessed_digits.append(padded_digit)
print("\n\n\n----------------Contoured Image--------------------")
plt.imshow(image, cmap="gray")
plt.show()
inp = np.array(preprocessed_digits)
for digit in preprocessed_digits:
prediction = model.predict(digit.reshape(1, 28, 28, 1))
print(prediction.argmax())
现在给定一个带有数字 504192 的图像,它输出 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 8 2 5 4 5 0 阈值和绘制轮廓后的输出是!https://drive.google.com/file/d/1-H5Ov3SKyuCCkUUsSuq9gXqyn99J2c7T/view?usp=sharing
解决方案
做一些改变
orig=cv2.imread('numbers.png')
img=cv2.imread('numbers.png',0)
ret, thresh = cv2.threshold(img.copy(), 150, 255, cv2.THRESH_BINARY_INV)
contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
digits=[]
for c in contours:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(orig, (x,y), (x+w, y+h), color=(0, 255, 0), thickness=2)
digit = thresh[y:y+h, x:x+w]
padded_digit = np.pad(digit, ((10,10),(10,10)), "constant", constant_values=0)
digit=cv2.resize(padded_digit,(28,28))
digits.append(digit)
inp = np.array(digits).reshape((len(digits),28,28,1))
y_pred = model.predict(inp) #instead of one by one predict, all at once
如果你愿意,你可以使用小膨胀以获得更好的结果
推荐阅读
- java - Spring过滤请求
- python - Googletrans API 错误 - 每日限制或阻止 IP?
- audiokit - AudioKit 可以在麦克风分析频率时播放声音吗?
- java - 如何将 Java Swing 应用程序与同一网络上的其他应用程序实例连接?
- python - 我有办法重写代码吗?,我似乎无法正确,我似乎无法正确获取输入
- authentication - 将文件中的自定义 JS 函数添加到 Svelte 应用程序的最佳方法是什么?
- git - 如果文件未更改,提交历史记录会丢失吗?
- r - kableExtra::collapse_rows 不适用于多行的长表头
- python - 如何将 Django asgi 项目部署到 Heroku?
- python - 有什么方法可以减少“嵌套”吗?