Keras手写数字识别(初识MNIST数据集)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_41137655/article/details/83997684

这篇文章将会分成两个部分,第一部分将简单认识一下keras中的手写数据集MNIST,第二部分将会介绍用Keras建立多层感知器模型,然后训练模型,评估模型的准确率,最后用训练完成的模型识别MNIST的手写数字

1.MNIST简介

MNIST是深度学习的经典入门demo,它是由Yann LeCun搜集的,这个demo是由6万张训练图片和1万张测试图片构成的,每张图片都是28px*28px大小,而且都是黑白色构成,这些图片是采集的不同的人手写从0到9的数字。Keras将这个数据集和相关操作封装到了库中,下面我们将一步步了解MNIST的一些相关操作。

1.1下载MNIST数据

首先,导入相关模块和下载数据

import numpy as np
import pandas as pd
from keras.utils import np_utils      #导入keras.utils,在后面可以将label变迁转换为One-Hot Encoding(一位有效编码)
from keras.datasets import mnist  #Keras已集成MNIST模块,可直接导入
np.random.seed(10)                     #设置seed可以产生随机数

运行结果如下
在这里插入图片描述
因为Tensorflow是Keras的后端引擎,即以Tensorflow作为底层,所以可以看到Keras自动以Tensorflow作为Backend。

接着下载数据

(X_train_image,y_train_label),(X_test_image,y_test_label)=mnist.load_data()  

第一次执行load_data()这个方法,程序会自动帮用户下载MNIST文件,可能下载需要花点时间,第二次以后再调用这个方法就可以直接调用本地文件了。

以下为各变量说明

变量名 说明
X_train_image 训练样本图像
y_train_label 训练样本标签(即正确答案)
X_test_image 测试样本图像
y_test_label 测试样本答案

1.2查看下载的数据

print('X_train_image.shape:',X_train_image.shape)
print('y_train_label.shape:',y_train_label.shape)
print('X_test_image.shape:',X_test_image.shape)
print('y_test_label.shape:',y_test_label.shape)

运行结果
在这里插入图片描述
我们可以看到训练样本图像的数量是60000,代表有60000张图片,每张的大小为2828,测试样本有10000张图像,每张大小也是2828。

我们定义一个函数来显示数字图像

import matplotlib.pyplot as plt
def plot_image(image):
    fig=plt.gcf()   #gcf 返回当前Figure 对象的句柄值
    fig.set_size_inches(2,2)  #用于设置图形的尺寸,单位为英寸。这里设置显示的图像大小为(2*2)
    plt.imshow(image,cmap='binary')  #显示传进来的图形,cmap参数为binary,以黑白灰度显示
    plt.show() 显示图像

我们看下其中一个图像

plot_image(X_train_image[666])

运行结果
在这里插入图片描述
我们可以看到训练样本中索引为666的图像是一个手写的0。

当然,我们也可以看下训练样本标签索引为666的值是什么。

y_train_label[666]

运行结果
在这里插入图片描述
也是0。

1.3查看训练数据和测试数据的images和label

定义一个可以查看数字图形,标签(即正确答案)和预测结果的函数

def plot_images_labels_prediction(images,labels,prediction,idx,num=10):    #idx是索引,num是默认显示10个图形
    fig=plt.gcf()
    fig.set_size_inches(12,14)
    if num>25:                                                       #暂时设置最多显示25个图像
        num=25
    for i in range(0,num):
        ax=plt.subplot(5,5,1+i)                                      #建立一个子图形,大小为5行5列,1+i代表在子图形中的第几个位置
        ax.imshow(images[idx],cmap='binary')
        title="label="+str(labels[idx])                            #定义标题样式
        if len(prediction)>0:                                      #由于我们还没开始训练,所以没有预测结果,这里设置一个判断跳过,以后还会用到这个函数
            title+=",prediction="+str(prediction[idx]) 
        ax.set_title(title,fontsize=10)                      #设置标题
        ax.set_xticks([])                                    #设置x轴和y轴的标签,这里设置不显示
        ax.set_yticks([])
        idx+=1                                               #读取下一项
    plt.show()

看下训练样本的前25项数据是什么

plot_images_labels_prediction(X_train_image,y_train_label,[],0,25)

运行结果
在这里插入图片描述
顺便再看下测试样本的前25项数据

plot_images_labels_prediction(X_test_image,y_test_label,[],0,29)

运行结果
在这里插入图片描述
可以看到我传进去的是29,实际它只显示了25张图片。

1.4特征值预处理

我们将数据集中的图像原本是2828的二维数字图像转化为1维的向量,再把数字转换为float32,因为2828=784,所以转换后就是一个1*784的向量。

X_Train=X_train_image.reshape(60000,784).astype('float32')
X_Test=X_test_image.reshape(10000,784).astype('float32')

我们看下转换后的样子
在这里插入图片描述
可以看到大部分数字都是0,其实这里每个数字的范围都是0到255,代表图形每一个点灰度的深浅。

接下来我们可以对训练样本的图形和测试样本的图形进行数字标准化,意思就是说把每个数字除以255,这样做可以提高后续训练模型的准确率。

X_Train_normalize=X_Train/255
X_Test_normalize=X_Test/255

转换后随便找张图片看下转换的结果

X_Train_normalize[0]

运行结果
在这里插入图片描述
由于该array太长,只截了部分图,可以看到每个数字的大小都是介于0到1之间。

1.5标签数据预处理

label(数字图像真实的值)标签原本是0~9的数字,必须以One-Hot Encoding(一位有效编码)转换为10个0或1的组合,例如数字5经过转换后是0000010000,正好对应输出层的10个神经元。

我们先看下原本标签中的前5项的具体值是什么

y_train_label[:5]

运行结果
在这里插入图片描述
然后使用np.utils.to_categorical对y_train_label和y_test_label进行One-Hot Encoding转换,顺便看下转换后训练样本标签的前5项

y_TrainOneHot=np_utils.to_categorical(y_train_label)
y_TestOneHot=np_utils.to_categorical(y_test_label)
y_TrainOneHot[:5]

运行结果
在这里插入图片描述
可以看到,第一项代表5,第二项代表0,第三项代表4,第四项代表1,第五项代表9。

到这里我们第一部分简单认识MNIST就基本完成了,接下来就是第二部分,通过建立多层感知器来识别手写数字。由于篇幅有限,第二部分将会在下一篇文章详述。

展开阅读全文

没有更多推荐了,返回首页