You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MNIST训练的全连接神经网络测试自制手写数字样本效果差问题求助

MNIST全连接网络自制样本识别错误问题排查

问题描述

使用MNIST数据集训练了一个全连接神经网络,用于分类28*28像素的数字图像,自制样本测试时效果极差:在画图工具中绘制的数字“7”图像转换为数组后,识别结果完全不符合预期。

相关代码

模型训练代码(由François Chollet编写)

from tensorflow.keras.datasets import mnist

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

from tensorflow.keras import models
from tensorflow.keras import layers

network = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28*28,)))
network.add(layers.Dense(10, activation='softmax'))

network.compile(optimizer='rmsprop',
                loss='categorical_crossentropy',
                metrics=['accuracy'])


train_images = train_images.reshape((60000,28*28))
train_images = train_images.astype('float32') / 255

test_images = test_images.reshape((10000, 28*28))
test_images = test_images.astype('float32') / 255

from tensorflow.keras.utils import to_categorical

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

network.fit(train_images,train_labels,epochs=20,batch_size=512,validation_split=0.2)
print(network.evaluate(test_images,test_labels))

自制样本测试代码

from PIL import Image
import PIL.ImageOps
import os

direccio = 'C:/Users/marcc/OneDrive/Escritorio'
os.chdir(direccio)

myImage = Image.open("Image.PNG").convert('L')
myImage = PIL.ImageOps.invert(myImage)
myImage = myImage.resize((28,28))
myImage.show()

#transforming my image into an array (THE PROBLEM MUST BE HERE)
import numpy as np
myImage_array = np.array(myImage)
myImage_array = myImage_array.reshape((28*28))
myImage_array = myImage_array.astype('float32') / 255
myImage_array=myImage_array.reshape(1,784)
print(myImage_array.shape)


print(network.predict(myImage_array))

测试输出

[[6.9165975e-03 3.0256975e-03 4.9591944e-01 4.8350231e-03 5.6093242e-03
  8.6059235e-03 4.5295963e-01 8.3720963e-04 2.1008164e-02 2.8301307e-04]]

预测结果中,对应数字7的索引位置(第7位,索引从0开始计数)概率仅为8.3720963e-04,概率最高的两个类别分别为2和6,完全不符合预期。

可视化参考

  • MNIST数据集数字9样例:
    MNIST数字9样例
  • 预处理后自制数字7样例:
    自制数字7样例

问题原因

  • 预处理不匹配:MNIST数据集的图像为黑底白字,数字居中、笔画粗细均匀,背景像素值接近0,笔画像素值集中在0.5~1区间。若自制原始PNG带有透明通道,convert('L')操作会将透明区域填充为白色,反转后透明区域变为黑色,若绘制的数字本身为黑色,反转后会和背景色一致,导致输入特征完全错误。
  • 全连接网络特性限制:全连接网络对像素的位置、大小、倾斜度非常敏感,仅能学习到训练集分布内的固定像素特征,只要自制数字的位置、粗细和训练集有明显差异,就会出现识别错误。

解决方案

  1. 修正预处理逻辑,和MNIST数据集分布对齐:
    首先处理图像透明通道,避免透明区域像素值异常:
    myImage = Image.open("Image.PNG")
    # 处理透明通道,填充白色背景
    if myImage.mode == 'RGBA':
        white_bg = Image.new('L', myImage.size, 255)
        white_bg.paste(myImage, mask=myImage.split()[3])
        myImage = white_bg
    else:
        myImage = myImage.convert('L')
    
    反转后添加二值化操作,消除灰度渐变干扰:
    myImage = PIL.ImageOps.invert(myImage)
    # 二值化处理,和MNIST风格对齐
    threshold = 127
    myImage = myImage.point(lambda p: 255 if p > threshold else 0)
    
    调整数字位置和大小:计算前景数字的 bounding box,将数字裁剪后 resize 到20*20,周围填充4像素黑边,完全匹配MNIST的预处理逻辑。
  2. 若修正预处理后识别效果仍然不佳,可将模型替换为简单的CNN结构,CNN对位置、大小、倾斜变化的鲁棒性远高于全连接网络,更适合手写数字识别场景。

内容的提问来源于stack exchange,提问作者Noether

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:36:04