【神经网络与深度学习】使用MNIST数据集训练手写数字识别模型——[附完整训练代码]

一、MNIST数据集介绍

发现csdn平台上似乎还没有一篇完整的介绍MNIST数据集、完整训练代码和训练好的模型文件,故发此文来对MNIST做一个详细的整合。
MNIST 数据集(手写数字数据集)是一个公开的公共数据集,任何人都可以免费获取它。目前,它已经是一个作为机器学习入门的通用性特别强的数据集之一,所以对于想要学习机器学习分类的、深度神经网络分类的、图像识别与处理的小伙伴,都可以选择MNIST数据集入门。

MNIST数据集结构

MNIST 数据集包含70000(60000+10000)个样本,其中有60000个训练样本和10000个测试样本,每个样本的像素大小为28*28。
在这里插入图片描述
MNIST数据集有多种下载方式,本文仅介绍两种。
方法一:
下载地址:http://yann.lecun.com/exdb/mnist/
在这里插入图片描述
可以直接下载这四个文件,这四个文件分别为:
①训练样本的图像(60000个)
②对应训练样本上每一张图像上数字的标签(0~9)(60000个)
③测试样本的图像(10000个)
④对应测试样本上每一张图像上数字的标签(0~9)(10000个)

方法二:
在Keras中已经内置了多种公共数据集,其中就包含MNIST数据集,如图所示。
在这里插入图片描述
所以可以直接调用 tf.keras.datasets.mnist,直接下载数据集。

二、模型训练思路

这是数字识别模型的神经网络结构,如图所示。
·每个样本有2828像素点,输入样本有2828=784个像素值;
·故输入层设置784个节点;
·隐含层尽量设置成2的n次幂个节点,故选择128个节点,使用ReLu激活函数;
·输出层用于输出数字识别结果0~9,故输出层设置10个节点,

在这里插入图片描述

我们采用神经网络训练手写数字模型,分为以下几步:
注:这些分块的代码是用来分步讲解,不能单独运行,在结尾我会附上完整代码,可直接复制使用。

①加载数据

mnist = tf.keras.datasets.mnist
(train_x,train_y),(test_x,test_y) = mnist.load_data()
print('\n train_x:%s, train_y:%s, test_x:%s, test_y:%s'%(train_x.shape,train_y.shape,test_x.shape,test_y.shape)) 

运行结果

train_x:(60000, 28, 28), train_y:(60000,), test_x:(10000, 28, 28), test_y:(10000,)

从这里可以看出数据集的结构形状train_x存放了60000张28*28像素的数字图像,并有train_y有60000条标签值与之相对应,用于训练模型;test_x和test_y同理,用于测试模型。

②数据预处理

#归一化、并转换为tensor张量,数据类型为float32.
X_train,X_test = tf.cast(train_x/255.0,tf.float32),tf.cast(test_x/255.0,tf.float32)     
y_train,y_test = tf.cast(train_y,tf.int16),tf.cast(test_y,tf.int16)

③建立模型

由于数据集比较简单,使用单层隐含层的神经网络就可以达到足够低的损失和较高的准确率。

model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28)))     #添加Flatten层说明输入数据的形状
model.add(tf.keras.layers.Dense(128,activation='relu'))     #添加隐含层,为全连接层,128个节点,relu激活函数
model.add(tf.keras.layers.Dense(10,activation='softmax'))   #添加输出层,为全连接层,10个节点,softmax激活函数
print('\n',model.summary())     #查看网络结构和参数信息

④配置模型训练方法

#adam算法参数采用keras默认的公开参数,损失函数采用稀疏交叉熵损失函数,准确率采用稀疏分类准确率函数
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['sparse_categorical_accuracy'])   

⑤训练模型

#批量训练大小为64,迭代5次,测试集比例0.2(48000条训练集数据,12000条测试集数据)
history = model.fit(X_train,y_train,batch_size=64,epochs=5,validation_split=0.2)

⑥评估模型

model.evaluate(X_test,y_test,verbose=2)     #每次迭代输出一条记录,来评价该模型是否有比较好的泛化能力

⑦保存模型

保存模型的格式可分为两种:
·HDF5格式
·SavedModel格式

二者的区别我会在后续的文章中介绍,我采用的是HDF5格式,这里不赘述。

保存模型的方式也可分为两种:
·仅保存模型参数model.save_weights()
·保存整个模型model.save()

二者的区别我也会在后续的文章中介绍,这两种方式都可以尝试一下,代码如下。

#保存模型参数
#model.save_weights('C:\\Users\\xuyansong\\Desktop\\深度学习\\python\\MNIST\\模型参数\\mnist_weights.h5')
#保存整个模型
model.save('C:\\Users\\xuyansong\\Desktop\\深度学习\\python\\MNIST\\整个模型\\mnist_weights.h5')

其中( )里的路径根据自己需要自行修改,若省去路径,默认保存到当前的工作路径。

#保存模型参数
#model.save_weights('mnist_weights.h5')
#保存整个模型
model.save('mnist_weights.h5')

⑧结果可视化

#结果可视化
print(history.history)
loss = history.history['loss']          #训练集损失
val_loss = history.history['val_loss']  #测试集损失
acc = history.history['sparse_categorical_accuracy']            #训练集准确率
val_acc = history.history['val_sparse_categorical_accuracy']    #测试集准确率

plt.figure(figsize=(10,3))

plt.subplot(121)
plt.plot(loss,color='b',label='train')
plt.plot(val_loss,color='r',label='test')
plt.ylabel('loss')
plt.legend()

plt.subplot(122)
plt.plot(acc,color='b',label='train')
plt.plot(val_acc,color='r',label='test')
plt.ylabel('Accuracy')
plt.legend()

#暂停5秒关闭画布,否则画布一直打开的同时,会持续占用GPU内存
#plt.ion()       #打开交互式操作模式
#plt.show()
#plt.pause(5)	
#plt.close()

plt.show()

运行结果
在这里插入图片描述

⑨使用模型

从测试集样本中随机抽取10张图像,并展示结果:

plt.figure()
for i in range(10):
    num = np.random.randint(1,10000)	#在1~10000之间生成随机整数

    plt.subplot(2,5,i+1)
    plt.axis('off')
    plt.imshow(test_x[num],cmap='gray')
    demo = tf.reshape(X_test[num],(1,28,28))
    y_pred = np.argmax(model.predict(demo))
    plt.title('标签值:'+str(test_y[num])+'\n预测值:'+str(y_pred))

如果对这块代码中的demo语句和y_pred这两条语句看不懂,可以看我发的这篇文章:
网址:https://blog.csdn.net/weixin_45954454/article/details/114437165?spm=1001.2014.3001.5501(使用Keras的Sequential框架搭建神经网络模型,在使用模型分类时报错…

三、代码实现——直接用

本人使用的是Tensorflow2.2.0—gpu版本,就目前已更新的版本来看,2.0.0以上版本都可以直接使用。
如果你的GPU没有配置好,代码会在指定GPU那里报错的,如果是这种报错还不知道如何解决的话,就选择用CPU跑程序,即注释掉这两行代码:

gpus = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(gpus[0],True)

注释掉后,基本就能跑通啦。

3.1训练模型并保存模型

话不多说,完整代码附上:
再次强调:其中model.save( )里的路径根据自己需要自行修改,若省去路径,默认保存到当前的工作路径。

########手写数字数据集##########
###########保存模型############
########1层隐含层(全连接层)##########
#60000条训练数据和10000条测试数据,28x28像素的灰度图像
#隐含层激活函数:ReLU函数
#输出层激活函数:softmax函数(实现多分类)
#损失函数:稀疏交叉熵损失函数
#输入层有784个节点,隐含层有128个神经元,输出层有10个节点
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

import time
print('--------------')
nowtime = time.strftime('%Y-%m-%d %H:%M:%S')
print(nowtime)

#指定GPU
#import os
#os.environ["CUDA_VISIBLE_DEVICES"] = "0"
gpus = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(gpus[0],True)
#初始化
plt.rcParams['font.sans-serif'] = ['SimHei']

#加载数据
mnist = tf.keras.datasets.mnist
(train_x,train_y),(test_x,test_y) = mnist.load_data()
print('\n train_x:%s, train_y:%s, test_x:%s, test_y:%s'%(train_x.shape,train_y.shape,test_x.shape,test_y.shape)) 

#数据预处理
#X_train = train_x.reshape((60000,28*28))
#Y_train = train_y.reshape((60000,28*28))       #后面采用tf.keras.layers.Flatten()改变数组形状
X_train,X_test = tf.cast(train_x/255.0,tf.float32),tf.cast(test_x/255.0,tf.float32)     #归一化
y_train,y_test = tf.cast(train_y,tf.int16),tf.cast(test_y,tf.int16)

#建立模型
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28)))     #添加Flatten层说明输入数据的形状
model.add(tf.keras.layers.Dense(128,activation='relu'))     #添加隐含层,为全连接层,128个节点,relu激活函数
model.add(tf.keras.layers.Dense(10,activation='softmax'))   #添加输出层,为全连接层,10个节点,softmax激活函数
print('\n',model.summary())     #查看网络结构和参数信息

#配置模型训练方法
#adam算法参数采用keras默认的公开参数,损失函数采用稀疏交叉熵损失函数,准确率采用稀疏分类准确率函数
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['sparse_categorical_accuracy'])   

#训练模型
#批量训练大小为64,迭代5次,测试集比例0.2(48000条训练集数据,12000条测试集数据)
print('--------------')
nowtime = time.strftime('%Y-%m-%d %H:%M:%S')
print('训练前时刻:'+str(nowtime))

history = model.fit(X_train,y_train,batch_size=64,epochs=5,validation_split=0.2)

print('--------------')
nowtime = time.strftime('%Y-%m-%d %H:%M:%S')
print('训练后时刻:'+str(nowtime))
#评估模型
model.evaluate(X_test,y_test,verbose=2)     #每次迭代输出一条记录,来评价该模型是否有比较好的泛化能力

#保存模型参数
#model.save_weights('C:\\Users\\xuyansong\\Desktop\\深度学习\\python\\MNIST\\模型参数\\mnist_weights.h5')
#保存整个模型
model.save('mnist_weights.h5')


#结果可视化
print(history.history)
loss = history.history['loss']          #训练集损失
val_loss = history.history['val_loss']  #测试集损失
acc = history.history['sparse_categorical_accuracy']            #训练集准确率
val_acc = history.history['val_sparse_categorical_accuracy']    #测试集准确率

plt.figure(figsize=(10,3))

plt.subplot(121)
plt.plot(loss,color='b',label='train')
plt.plot(val_loss,color='r',label='test')
plt.ylabel('loss')
plt.legend()

plt.subplot(122)
plt.plot(acc,color='b',label='train')
plt.plot(val_acc,color='r',label='test')
plt.ylabel('Accuracy')
plt.legend()

#暂停5秒关闭画布,否则画布一直打开的同时,会持续占用GPU内存
#根据需要自行选择
#plt.ion()       #打开交互式操作模式
#plt.show()
#plt.pause(5)
#plt.close()

#使用模型
plt.figure()
for i in range(10):
    num = np.random.randint(1,10000)

    plt.subplot(2,5,i+1)
    plt.axis('off')
    plt.imshow(test_x[num],cmap='gray')
    demo = tf.reshape(X_test[num],(1,28,28))
    y_pred = np.argmax(model.predict(demo))
    plt.title('标签值:'+str(test_y[num])+'\n预测值:'+str(y_pred))
#y_pred = np.argmax(model.predict(X_test[0:5]),axis=1)
#print('X_test[0:5]: %s'%(X_test[0:5].shape))
#print('y_pred: %s'%(y_pred))

#plt.ion()       #打开交互式操作模式
plt.show()
#plt.pause(5)
#plt.close()

运行结果
在这里插入图片描述

卷积神经网络训练模型

关于卷积神经网络的介绍和使用,我写过写篇文章【神经网络与深度学习】CIFAR10数据集介绍,并使用卷积神经网络训练图像分类模型——附完整代码训练好的模型文件——直接用:https://blog.csdn.net/weixin_45954454/article/details/114519299?spm=1001.2014.3001.5501
对于MNIST数据集的使用方式与上文相似,如需MNIST数据集的卷积神经网络训练的源代码,在本文的结尾(第四章节)[四、训练好的模型文件——直接用]下载。

3.2加载训练好的模型

3.2.1采用model.save_weights()方式保存的模型

采用model.save_weights()方式保存的模型,使用以下完整代码加载模型:

########手写数字数据集##########
###########加载模型参数方法############
########1层隐含层(全连接层)##########
#60000条训练数据和10000条测试数据,28x28像素的灰度图像
#隐含层激活函数:ReLU函数
#输出层激活函数:softmax函数(实现多分类)
#损失函数:稀疏交叉熵损失函数
#输入层有784个节点,隐含层有128个神经元,输出层有10个节点
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

import time
print('--------------')
nowtime = time.strftime('%Y-%m-%d %H:%M:%S')
print(nowtime)

#指定GPU
#import os
#os.environ["CUDA_VISIBLE_DEVICES"] = "0"
gpus = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(gpus[0],True)
#初始化
plt.rcParams['font.sans-serif'] = ['SimHei']

#加载数据
mnist = tf.keras.datasets.mnist
(train_x,train_y),(test_x,test_y) = mnist.load_data()
print('\n train_x:%s, train_y:%s, test_x:%s, test_y:%s'%(train_x.shape,train_y.shape,test_x.shape,test_y.shape)) 

#数据预处理
#X_train = train_x.reshape((60000,28*28))
#Y_train = train_y.reshape((60000,28*28))       #后面采用tf.keras.layers.Flatten()改变数组形状
X_train,X_test = tf.cast(train_x/255.0,tf.float32),tf.cast(test_x/255.0,tf.float32)        #归一化
y_train,y_test = tf.cast(train_y,tf.int16),tf.cast(test_y,tf.int16)

#建立模型
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28)))     #添加Flatten层说明输入数据的形状
model.add(tf.keras.layers.Dense(128,activation='relu'))     #添加隐含层,为全连接层,128个节点,relu激活函数
model.add(tf.keras.layers.Dense(10,activation='softmax'))   #添加输出层,为全连接层,10个节点,softmax激活函数
print('\n',model.summary())     #查看网络结构和参数信息

#配置模型训练方法
#adam算法参数采用keras默认的公开参数,损失函数采用稀疏交叉熵损失函数,准确率采用稀疏分类准确率函数
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['sparse_categorical_accuracy'])   

#加载模型参数
history = model.load_weights('C:\\Users\\xuyansong\\Desktop\\深度学习\\python\\MNIST\\模型参数\\mnist_weights.h5') #路径根据文件实际位置修改,不然会报错


#评估模型
model.evaluate(X_test,y_test,verbose=2)     #每次迭代输出一条记录,来评价该模型是否有比较好的泛化能力

#使用模型
plt.figure()
for i in range(10):
    num = np.random.randint(1,10000)

    plt.subplot(2,5,i+1)
    plt.axis('off')
    plt.imshow(test_x[num],cmap='gray')
    demo = tf.reshape(X_test[num],(1,28,28))
    y_pred = np.argmax(model.predict(demo))
    plt.title('标签值:'+str(test_y[num])+'\n预测值:'+str(y_pred))
#y_pred = np.argmax(model.predict(X_test[0:5]),axis=1)
#print('X_test[0:5]: %s'%(X_test[0:5].shape))
#print('y_pred: %s'%(y_pred))

plt.ion()       #打开交互式操作模式
plt.show()
plt.pause(5)
plt.close()

运行结果:
在这里插入图片描述

3.2.2采用model.save()方式保存的模型

采用model.save()方式保存的模型,使用以下完整代码加载模型:

########手写数字数据集##########
###########加载整个模型方法############
########1层隐含层(全连接层)##########
#60000条训练数据和10000条测试数据,28x28像素的灰度图像
#隐含层激活函数:ReLU函数
#输出层激活函数:softmax函数(实现多分类)
#损失函数:稀疏交叉熵损失函数
#输入层有784个节点,隐含层有128个神经元,输出层有10个节点
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

import time
print('--------------')
nowtime = time.strftime('%Y-%m-%d %H:%M:%S')
print(nowtime)

#指定GPU
#import os
#os.environ["CUDA_VISIBLE_DEVICES"] = "0"
gpus = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(gpus[0],True)
#初始化
plt.rcParams['font.sans-serif'] = ['SimHei']

#加载数据
mnist = tf.keras.datasets.mnist
(train_x,train_y),(test_x,test_y) = mnist.load_data()
print('\n train_x:%s, train_y:%s, test_x:%s, test_y:%s'%(train_x.shape,train_y.shape,test_x.shape,test_y.shape)) 

#数据预处理
#X_train = train_x.reshape((60000,28*28))
#Y_train = train_y.reshape((60000,28*28))       #后面采用tf.keras.layers.Flatten()改变数组形状
X_train,X_test = tf.cast(train_x/255.0,tf.float32),tf.cast(test_x/255.0,tf.float32)     #归一化
y_train,y_test = tf.cast(train_y,tf.int16),tf.cast(test_y,tf.int16)


#加载整个模型 
model = tf.keras.models.load_model('C:\\Users\\xuyansong\\Desktop\\深度学习\\python\\MNIST\\整个模型\\mnist_weights.h5')	#路径根据文件实际位置修改,不然会报错
model.summary()     #查看摘要

#评估模型
model.evaluate(X_test,y_test,verbose=2)     #每次迭代输出一条记录,来评价该模型是否有比较好的泛化能力

#使用模型
plt.figure()
for i in range(10):
    num = np.random.randint(1,10000)

    plt.subplot(2,5,i+1)
    plt.axis('off')
    plt.imshow(test_x[num],cmap='gray')
    demo = tf.reshape(X_test[num],(1,28,28))
    y_pred = np.argmax(model.predict(demo))
    plt.title('标签值:'+str(test_y[num])+'\n预测值:'+str(y_pred))
#y_pred = np.argmax(model.predict(X_test[0:5]),axis=1)
#print('X_test[0:5]: %s'%(X_test[0:5].shape))
#print('y_pred: %s'%(y_pred))

plt.ion()       #打开交互式操作模式
plt.show()
plt.pause(5)
plt.close()

运行结果
在这里插入图片描述

:对比这三个运行的结果,细心的你会注意到:为什么我展示的loss损失函数和sparse_categorical_accuracy准确率的结果都不一样?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这是因为在每次训练模型时,由于神经网络参数初始值随机,神经网络在学习的过程中即使使用的方法相同,学习的过程和结果也会不同。不信你可以查看每次训练的结果都会有细微的差别(即每次训练出的都不是同一个模型),这就是深度学习的魅力所在。
由于我在保存这两种模型时,并不是在同一个训练模型下保存的,所以会有模型结果会有差别。但如果你是在同一个训练模型下保存的这两种模型(即保存了模型参数,这个模型就定下来了),只要测试集不变,其测试结果一定是相同的,且永远不会变。

四、训练好的模型文件——直接用

全连接神经网络模型

csdn资源下载链接:使用MNIST数据集训练手写数字识别模型——附完整代码训练好的模型文件——直接用.:https://download.csdn.net/download/weixin_45954454/15621509?spm=1001.2014.3001.5501

卷积神经网络模型

csdn资源下载链接:【神经网络与深度学习】MNIST数据集介绍,并使用卷积神经网络训练手写数字识别模型——附完整代码训练好的模型文件——直接用:https://download.csdn.net/download/weixin_45954454/15650033?spm=1001.2014.3001.5503

<本文主要参考于《神经网络与深度学习-Tensorflow实践》>

出现问题可私信我解决,不定期查看。

<后续还会继续整理【神经网络与深度学习】相关内容,如果需要,可持续关注我哦~>

<整理不易,留个赞或评论支持一下我吧^^>

如有疑问,欢迎批评指正^^

  • 171
    点赞
  • 527
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 29
    评论
好的,我可以为您提供一个基于Python手写数字识别模型训练代码示例,使用的是MNIST数据集。 首先,需要安装必要的库,包括TensorFlow和Keras。您可以使用以下命令来安装它们: ``` pip install tensorflow keras ``` 下面是代码示例: ```python import tensorflow as tf from tensorflow import keras from keras.datasets import mnist # 加载MNIST数据集 (x_train, y_train), (x_test, y_test) = mnist.load_data() # 将像素值缩放到0-1范围内 x_train = x_train / 255.0 x_test = x_test / 255.0 # 定义模型 model = keras.Sequential([ keras.layers.Flatten(input_shape=(28, 28)), # 将28x28的图像展平成一维向量 keras.layers.Dense(128, activation='relu'), # 添加一个128个神经元的隐藏层 keras.layers.Dense(10, activation='softmax') # 添加一个10个神经元的输出层,使用softmax激活函数 ]) # 编译模型 model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) # 训练模型 model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test)) # 评估模型 test_loss, test_acc = model.evaluate(x_test, y_test) print('Test accuracy:', test_acc) ``` 在这个示例中,我们首先加载MNIST数据集,并将像素值缩放到0-1范围内。然后定义一个包含一个隐藏层和一个输出层的神经网络模型使用softmax激活函数对输出进行分类。我们编译模型,并使用训练集对其进行训练。最后,我们评估模型的性能。 请注意,训练模型可能需要一些间,具体取决于您的计算机性能和所使用数据集大小。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路遥_.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值