基于MNIST训练的手写数字神经网络无法识别自定义手写数字排查
问题分析与解决方案
你的代码核心问题是自定义图像的预处理流程和MNIST训练数据的预处理不匹配,导致模型无法识别。以下是具体问题和修复步骤:
1. 图像颜色反转问题
MNIST数据集的图像是黑字白底(像素值0=黑色数字,255=白色背景),但用画图工具绘制的图像通常是白字黑底,两者像素分布完全相反,模型无法匹配特征。
2. 缺少像素归一化
训练MNIST时通常会将像素值缩放到0-1区间(除以255),但你的代码直接使用了0-255的原始像素值,和训练数据的分布不一致。
3. 未做二值化处理
MNIST图像是高对比度的纯黑白,而画图工具绘制的图像可能存在灰色过渡像素,这些噪声会干扰模型识别。
修复后的代码
import cv2 import numpy as np import tensorflow as tf model = tf.keras.models.load_model("handwritten.model") # 自定义图像预处理流程 img = cv2.imread("Digits/digit11.png") gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 1. 反转图像:把白字黑底转成黑字白底 gray = cv2.bitwise_not(gray) # 2. 二值化:消除灰色过渡,生成纯黑白图像 _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 3. 归一化:和训练数据一致缩放到0-1区间 img_normalized = thresh / 255.0 # 4. 扩展维度匹配模型输入要求 prediction = model.predict(np.expand_dims(img_normalized, axis=0)) print(f"This digit is probably a {np.argmax(prediction)}") # MNIST Data prediction = model.predict(np.expand_dims(x_train[27]/255.0, axis=0)) # 确保x_train和训练时做了相同归一化 print(f"This digit is probably a {np.argmax(prediction)}")
额外检查点
- 确认自定义图像确实是28x28像素,可以用
print(gray.shape)验证。 - 确保图像没有多余的边框,数字尽量居中(和MNIST样本的数字位置一致)。
内容的提问来源于stack exchange,提问作者NonoTheGrappler
相关产品推荐
相关产品推荐

