搭建神经网络模型对MNIST手写数字分类并测试模型性能

目录

一、MNIST数据集介绍

二、搭建神经网络模型对MNIST手写数据集分类

1.读取数据集

2.数据预处理

3.搭建神经网络

4.测试模型性能

三、报错解决

四、测试运行


一、MNIST数据集介绍


MNIST全称是Mixed National Institute of Standards and Technology database。这是一个非常庞大的手写数字数据库。
这些数据集有两个功能:一个功能是提供了大量的数据作为训练集和验证集,为一些学习人员提供了丰富的样 本信息一一这一点很宝贵,要知道在深度学习领域要想在一个方面有比较深的研究成果, 除了需要具备一定的网络设计和调优能力以外,还有一个就是要有丰富的训练样本。 另一 个功能就是可以形成一个在业内相对有普适性的 Benchmark 比对项目一一既然大家用的数 据集都是一样的,那么每个人设计出来的网络就可以在这些数据集上不断互相比较,从而验证谁家的网络设计得识别率更高。
大多数示例使用手写数字的MNIST数据集[1]。该数据集包含60,000个用于训练的示例和10,000个用于测试的示例。这些数字已经过尺寸标准化并位于图像中心,图像是固定大小(28x28像素),其值为0到1。为简单起见,每个图像都被平展并转换为784(28 * 28)个特征的一维numpy数组。

MNIST数据集 

二、搭建神经网络模型对MNIST手写数据集分类

搭建神经网络模型对MNIST手写数据集分类并用测试集测试模型性能,详细步骤如下:

1.读取数据集

from scipy.io import loadmat
from keras import models, layers, regularizers
from tensorflow import optimizers
from tensorflow.python.keras.utils.np_utils import to_categorical
test_data = loadmat('python_demo/main/mnist_test.mat')  # 读取训练集数据
train_data = loadmat('python_demo/main/mnist_train.mat')  # 读取测试集数据

train_x = train_data['train_X']
train_l = train_data['train_labels']
test_x = test_data['test_X']
test_l = test_data['test_labels']

2.数据预处理

train_images = train_x.reshape((60000, 28*28)).astype('float')  # 训练集图像,二维矩阵压缩成一维向量
train_labels = to_categorical(train_l)  # 训练集标签,进行one-hot编码

test_images = test_x.reshape((10000, 28*28)).astype('float')
test_labels = to_categorical(test_l)

3.搭建神经网络

# 搭建神经网络
network = models.Sequential()  # 训练式模型
network.add(layers.Dense(units=128, activation='relu', input_shape=(28*28, ),
                         kernel_regularizer=regularizers.l1(0.0001)))  # 隐藏层 128个神经元 relu函数 regularizers(正则化 解决过拟合问题)
network.add(layers.Dropout(0.01))
network.add(layers.Dense(units=32, activation='relu', input_shape=(28*28, ),
                         kernel_regularizer=regularizers.l1(0.0001)))  # 增加一个隐藏层优化性能 32个神经元 relu函数
network.add(layers.Dropout(0.01))
network.add(layers.Dense(units=10, activation='softmax'))  # 输出层
# 编译步骤
network.compile(optimizer=optimizers.RMSprop(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
# 训练网络 fit函数 epochs表示训练回合 batch_size 每次训练数据的大小
network.fit(train_images, train_labels, epochs=20, batch_size=128, verbose=2)

4.测试模型性能

# 测试集测试模型性能
pre = network.predict(test_images[:5])
print(pre, test_labels[:5])  # 测试前5张图片并对比
test_loss, test_accuracy = network.evaluate(test_images, test_labels)  # 测试集表现
print("test_loss", test_loss, "test_accuracy", test_accuracy)

三、报错解决

报错解决:ValueError: Shapes (None, 11) and (None, 10) are incompatible

在运行代码时,一直出现这个错误,大意为数据集形状不兼容,即维度不一样,找了很久一直没有找到问题的根源,最后灵机一动,想着打印一下训练集与测试集的标签看看,于是:

print("train_l", train_l)
print("test_l", test_l)

 发现:

 手写数字应该是0-9,为什么会出现10呢?原来是数据集的标签出了问题,0-9的取值变成了了1-10,而将数字1-10进行one-hot编码则会有0至10共11个维度,例如数字1将表示为:[0,1,0,0,0,0,0,0,0,0,0],当然会数据集维度不匹配。提供两种解决方法,

第一种即是更换数据源,可以选择keras的mnist数据集:

from keras.datasets import mnist

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28*28)).astype('float')
train_labels = to_categorical(train_labels)

test_images = test_images.reshape((10000, 28*28)).astype('float')
test_labels = to_categorical(test_labels)

第二种则是修改一下数据集标签:

把数字范围改到0-9

for i in range(0, len(train_l)):
    train_l[i] = train_l[i]-1
for i in range(0, len(test_l)):
    test_l[i] = test_l[i] - 1

四、测试运行

run一下,得到如下结果

我们可以看到训练集的准确率达到了99.8%,但测试集的准确率只有97左右%,两者之间相差了近3%,出现了明细的过拟合现象,即能够较好地预测训练集数据,但是用来实战效果较差。因此我们需要使用regularizers函数正则化对模型优化一下:

network.add(layers.Dense(units=128, activation='relu', input_shape=(28*28, ),
                         kernel_regularizer=regularizers.l1(0.0001)))  # 隐藏层 128个神经元 relu函数 regularizers(正则化 解决过拟合问题)
network.add(layers.Dropout(0.01))
network.add(layers.Dense(units=32, activation='relu', input_shape=(28*28, ),
                         kernel_regularizer=regularizers.l1(0.0001)))  # 增加一个隐藏层优化性能 32个神经元 relu函数
network.add(layers.Dropout(0.01))
network.add(layers.Dense(units=10, activation='softmax'))  # 输出层

完成后运行,最后可以得到训练集及测试集的准确率均大概在98%左右:

创作不易,觉得有用的话点个赞吧!

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
利用tensorflow实现的卷积神经网络来进行MNIST手写数字图像的分类。 #导入numpy模块 import numpy as np #导入tensorflow模块,程序使用tensorflow来实现卷积神经网络 import tensorflow as tf #下载mnist数据集,并从mnist_data目录中读取数据 from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('mnist_data',one_hot=True) #(1)这里的“mnist_data” 是和当前文件相同目录下的一个文件夹。自己先手工建立这个文件夹,然后从https://yann.lecun.com/exdb/mnist/ 下载所需的4个文件(即该网址中第三段“Four files are available on this site:”后面的四个文件),并放到目录MNIST_data下即可。 #(2)MNIST数据集手写数字字符的数据集。每个样本都是一张28*28像素的灰度手写数字图片。 #(3)one_hot表示独热编码,其值被设为true。在分类问题的数据集标注时,如何不采用独热编码的方式, 类别通常就是一个符号而已,比如说是9。但如果采用独热编码的方式,则每个类表示为一个列表list,共计有10个数值,但只有一个为1,其余均为0。例如,“9”的独热编码可以为[00000 00001]. #定义输入数据x和输出y的形状。函数tf.placeholder的目的是定义输入,可以理解为采用占位符进行占位。 #None这个位置的参数在这里被用于表示样本的个数,而由于样本个数此时具体是多少还无法确定,所以这设为None。而每个输入样本的特征数目是确定的,即为28*28。 input_x = tf.placeholder(tf.float32,[None,28*28])/255 #因为每个像素的取值范围是 0~255 output_y = tf.placeholder(tf.int32,[None,10]) #10表示10个类别 #输入层的输入数据input_x被reshape成四维数据,其中第一维的数据代表了图片数量 input_x_images = tf.reshape(input_x,[-1,28,28,1]) test_x = mnist.test.images[:3000] #读取测试集图片的特征,读取3000个图片 test_y = mnist.test.labels[:3000] #读取测试集图片的标签。就是这3000个图片所对应的标签
利用tensorflow实现的卷积神经网络来进行MNIST手写数字图像的分类。 #导入numpy模块 import numpy as np #导入tensorflow模块,程序使用tensorflow来实现卷积神经网络 import tensorflow as tf #下载mnist数据集,并从mnist_data目录中读取数据 from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('mnist_data',one_hot=True) #(1)这里的“mnist_data” 是和当前文件相同目录下的一个文件夹。自己先手工建立这个文件夹,然后从https://yann.lecun.com/exdb/mnist/ 下载所需的4个文件(即该网址中第三段“Four files are available on this site:”后面的四个文件),并放到目录MNIST_data下即可。 #(2)MNIST数据集手写数字字符的数据集。每个样本都是一张28*28像素的灰度手写数字图片。 #(3)one_hot表示独热编码,其值被设为true。在分类问题的数据集标注时,如何不采用独热编码的方式, 类别通常就是一个符号而已,比如说是9。但如果采用独热编码的方式,则每个类表示为一个列表list,共计有10个数值,但只有一个为1,其余均为0。例如,“9”的独热编码可以为[00000 00001]. #定义输入数据x和输出y的形状。函数tf.placeholder的目的是定义输入,可以理解为采用占位符进行占位。 #None这个位置的参数在这里被用于表示样本的个数,而由于样本个数此时具体是多少还无法确定,所以这设为None。而每个输入样本的特征数目是确定的,即为28*28。 input_x = tf.placeholder(tf.float32,[None,28*28])/255 #因为每个像素的取值范围是 0~255 output_y = tf.placeholder(tf.int32,[None,10]) #10表示10个类别 #输入层的输入数据input_x被reshape成四维数据,其中第一维的数据代表了图片数量 input_x_images = tf.reshape(input_x,[-1,28,28,1]) test_x = mnist.test.images[:3000] #读取测试集图片的特征,读取3000个图片 test_y = mnist.test.labels[:3000] #读取测试集图片的标签。就是这3000个图片所对应的标签
好的,这是一个关于实现MNIST手写数字图像识别的问题。首先,我们需要了解MNIST数据集是什么。MNIST数据集是一个手写数字的数据库,由60,000个训练图像和10,000个测试图像组成。每个图像都是28×28像素,灰度图像,表示0到9之间的数字。 为了实现MNIST手写数字图像识别,我们可以使用Python编程语言及其深度学习框架Keras。以下是实现步骤: 1. 导入MNIST数据集 我们可以使用Keras提供的mnist模块来导入MNIST数据集。首先,我们需要安装Keras:`pip install keras`。然后,通过以下代码导入MNIST数据集: ```python from keras.datasets import mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() ``` 这里,x_train和x_test是训练集和测试集中的图像数据,y_train和y_test是相应的标签。 2. 数据预处理 我们需要对数据进行预处理,以便在神经网络中使用。首先,我们将图像数据从二维数组(28×28像素)转换为一维数组(784像素)。然后,我们将像素值缩放到0到1之间。 ```python x_train = x_train.reshape(60000, 784) x_test = x_test.reshape(10000, 784) x_train = x_train.astype('float32') / 255 x_test = x_test.astype('float32') / 255 ``` 3. 构建神经网络模型 我们可以使用Keras的Sequential模型来构建神经网络模型。我们将使用两个密集层,每个层包含128个神经元,并使用ReLU激活函数。最后,我们在输出层使用softmax激活函数,以获得0到9之间每个数字的预测概率。 ```python from keras.models import Sequential from keras.layers import Dense model = Sequential() model.add(Dense(128, activation='relu', input_shape=(784,))) model.add(Dense(128, activation='relu')) model.add(Dense(10, activation='softmax')) ``` 4. 编译和训练模型 我们需要编译模型,并指定损失函数、优化器和评估指标。我们使用交叉熵损失函数、Adam优化器和准确率评估指标。 ```python model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) ``` 然后,我们可以使用训练集对模型进行训练。 ```python model.fit(x_train, y_train, batch_size=128, epochs=10, validation_data=(x_test, y_test)) ``` 5. 评估模型 最后,我们可以使用测试集评估模型性能。 ```python score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) ``` 这将输出模型测试集上的损失和准确率。 希望这个回答对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值