keras入门实战:手写数字识别

author author     2022-09-06     154

关键词:

近些年由于理论知识的硬件的快速发展,使得深度学习达到了空前的火热。深度学习已经在很多方面都成功得到了应用,尤其是在图像识别和分类领域,机器识别图像的能力甚至超过了人类。

本文用深度学习Python库Keras实现深度学习入门教程mnist手写数字识别。mnist手写数字识别是机器学习和深度学习领域的“hello world”,MNIST数据集是手写数字的数据集合,训练集规模为60000,测试集为10000。

本文的内容包括:

  • 如何用Keras加载MNIST数据集
  • 对于MNIST问题如何实现一个baseline的神经网络
  • 基于MNIST问题如何实现并评价一个卷积神经网络(CNN)
  • 基于MNIST问题如何实现一个接近最高准确率的深度学习模型

MNIST手写数字识别问题

MNIST问题是由Yann LeCun, Corinna Cortes 和Christopher Burges为了评估机器学习模型而设立的。问题的数据集是从一些National Institute of Standards and Technology (NIST)的文档中得来,是计算机视觉入门级的数据集,它包含各种手写数字图片:
技术分享

它也包含每一张图片对应的标签,告诉我们这个是数字几。比如,上面这四张图片的标签分别是5,0,4,1。
每张图片是28*28像素(共784个像素)。对于一般的图片像素通道通常是3维,即rgb,代表red、green、blue三个颜色通道,而MNIST数据集的像素通道只有一位即为灰度值,每一个像素值在0到1之间表示这个像素的灰度,0表示白色,1表示黑色。图片的类别标签是这个图片的数字,取值范围为0-9.因此MNIST问题是一个多分类的问题,类别为10。
现在好的分类结果可是使错误率降到1%以下。接近最好效果的错误率大约为0.2%,可用大规模的CNN实现。

加载MNIST数据集

Keras提供了实现深度学习所需要的绝大部分函数库,可实现多种神经网络模型,并可加载多种数据集来评价模型的效果。下面的代码会自动加载数据,如果是第一次调用,数据会保存在你的hone目录下~/.keras/datasets/mnist.pkl.gz,大约15MB。

# Plot ad hoc mnist instances
from keras.datasets import mnist
import matplotlib.pyplot as plt
# load (downloaded if needed) the MNIST dataset
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# plot 4 images as gray scale
plt.subplot(221)
plt.imshow(X_train[0], cmap=plt.get_cmap(‘gray‘))
plt.subplot(222)
plt.imshow(X_train[1], cmap=plt.get_cmap(‘gray‘))
plt.subplot(223)
plt.imshow(X_train[2], cmap=plt.get_cmap(‘gray‘))
plt.subplot(224)
plt.imshow(X_train[3], cmap=plt.get_cmap(‘gray‘))
# show the plot
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

上面的代码加载了数据集并画出了前4个图片:
技术分享

多层感知机的baseline模型

在实现卷积神经网络这种复杂的模型之前,先实现一个简单但效果也不错的模型:多层感知机。这种模型也叫含隐层的神经网络。模型的效果可以使错误率达到1.87%。
第一步是加载所需要的库

import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.utils import np_utils
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

设定随机数种子,保证结果的可重现性

seed = 7
numpy.random.seed(seed)
  • 1
  • 2
  • 1
  • 2

加载数据

(X_train, y_train), (X_test, y_test) = mnist.load_data()
  • 1
  • 1

数据集是3维的向量(instance length,width,height).对于多层感知机,模型的输入是二维的向量,因此这里需要将数据集reshape,即将28*28的向量转成784长度的数组。可以用numpy的reshape函数轻松实现这个过程。

num_pixels = X_train.shape[1] * X_train.shape[2]
X_train = X_train.reshape(X_train.shape[0], num_pixels).astype(‘float32‘)
X_test = X_test.reshape(X_test.shape[0], num_pixels).astype(‘float32‘)
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

给定的像素的灰度值在0-255,为了使模型的训练效果更好,通常将数值归一化映射到0-1。

X_train = X_train / 255
X_test = X_test / 255
  • 1
  • 2
  • 1
  • 2

最后,模型的输出是对每个类别的打分预测,对于分类结果从0-9的每个类别都有一个预测分值,表示将模型输入预测为该类的概率大小,概率越大可信度越高。由于原始的数据标签是0-9的整数值,通常将其表示成0ne-hot向量。如第一个训练数据的标签为5,one-hot表示为[0,0,0,0,0,1,0,0,0,0]。

y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1]
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

现在需要做得就是搭建神经网络模型了,创建一个函数,建立含有一个隐层的神经网络。

# define baseline model
def baseline_model():
    # create model
    model = Sequential()
    model.add(Dense(num_pixels, input_dim=num_pixels, kernel_initializer=‘normal‘, activation=‘relu‘))
    model.add(Dense(num_classes, kernel_initializer=‘normal‘, activation=‘softmax‘))
    # Compile model
    model.compile(loss=‘categorical_crossentropy‘, optimizer=‘adam‘, metrics=[‘accuracy‘])
    return model
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

模型的隐含层含有784个节点,接受的输入长度也是784(28*28),最后用softmax函数将预测结果转换为标签的概率值。
将训练数据fit到模型,设置了迭代轮数,每轮200个训练样本,将测试集作为验证集,并查看训练的效果。

# build the model
model = baseline_model()
# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200, verbose=2)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Baseline Error: %.2f%%" % (100-scores[1]*100))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

训练和测试结果如下:

Train on 60000 samples, validate on 10000 samples
Epoch 1/10
6s - loss: 0.2789 - acc: 0.9210 - val_loss: 0.1416 - val_acc: 0.9578
Epoch 2/10
5s - loss: 0.1117 - acc: 0.9677 - val_loss: 0.0917 - val_acc: 0.9707
Epoch 3/10
5s - loss: 0.0717 - acc: 0.9796 - val_loss: 0.0787 - val_acc: 0.9767
Epoch 4/10
6s - loss: 0.0502 - acc: 0.9859 - val_loss: 0.0741 - val_acc: 0.9767
Epoch 5/10
5s - loss: 0.0372 - acc: 0.9890 - val_loss: 0.0681 - val_acc: 0.9788
Epoch 6/10
5s - loss: 0.0269 - acc: 0.9925 - val_loss: 0.0625 - val_acc: 0.9808
Epoch 7/10
5s - loss: 0.0208 - acc: 0.9948 - val_loss: 0.0619 - val_acc: 0.9814
Epoch 8/10
6s - loss: 0.0140 - acc: 0.9970 - val_loss: 0.0639 - val_acc: 0.9799
Epoch 9/10
5s - loss: 0.0108 - acc: 0.9978 - val_loss: 0.0597 - val_acc: 0.9812
Epoch 10/10
5s - loss: 0.0080 - acc: 0.9985 - val_loss: 0.0591 - val_acc: 0.9813
Baseline Error: 1.87%

简单的卷积神经网络

前面介绍了如何加载训练数据并实现一个简单的单隐层神经网络,并在测试集上取得了不错的效果。现在要实现一个卷积神经网络,想要在MNIST问题上取得更好的效果。

卷积神经网络(CNN)是一种深度神经网络,与单隐层的神经网络不同的是它还包含卷积层、池化层、Dropout层等,这使得它在图像分类的问题上有更优的效果。详细的CNN教程可以参见斯坦福大学的cs231n课程讲义,中文版链接

第一步依然是导入需要的函数库

import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
K.set_image_dim_ordering(‘th‘)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

设定随机数种子

seed = 7
numpy.random.seed(seed)
  • 1
  • 2
  • 1
  • 2

将数据集reshape,CNN的输入是4维的张量(可看做多维的向量),第一维是样本规模,第二维是像素通道,第三维和第四维是长度和宽度。并将数值归一化和类别标签向量化。

# load data
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# reshape to be [samples][pixels][width][height]
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype(‘float32‘)
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28).astype(‘float32‘)

X_train = X_train / 255
X_test = X_test / 255
# one hot encode outputs
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

接下来构造CNN。

  1. 第一层是卷积层。该层有32个feature map,或者叫滤波器,作为模型的输入层,接受[pixels][width][height]大小的输入数据。feature map的大小是5*5,其输出接一个‘relu’激活函数。
  2. 下一层是pooling层,使用了MaxPooling,大小为2*2。
  3. 下一层是Dropout层,该层的作用相当于对参数进行正则化来防止模型过拟合。
  4. 接下来是全连接层,有128个神经元,激活函数采用‘relu’。
  5. 最后一层是输出层,有10个神经元,每个神经元对应一个类别,输出值表示样本属于该类别的概率大小。
def baseline_model():
    # create model
    model = Sequential()
    model.add(Conv2D(32, (5, 5), input_shape=(1, 28, 28), activation=‘relu‘))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.2))
    model.add(Flatten())
    model.add(Dense(128, activation=‘relu‘))
    model.add(Dense(num_classes, activation=‘softmax‘))
    # Compile model
    model.compile(loss=‘categorical_crossentropy‘, optimizer=‘adam‘, metrics=[‘accuracy‘])
    return model
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

接着开始训练模型

# build the model
model = baseline_model()
# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200, verbose=2)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Baseline Error: %.2f%%" % (100-scores[1]*100))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

训练和测试结果如下:

Train on 60000 samples, validate on 10000 samples
Epoch 1/10
137s - loss: 0.2329 - acc: 0.9340 - val_loss: 0.0820 - val_acc: 0.9742
Epoch 2/10
140s - loss: 0.0736 - acc: 0.9781 - val_loss: 0.0466 - val_acc: 0.9842
Epoch 3/10
138s - loss: 0.0531 - acc: 0.9839 - val_loss: 0.0432 - val_acc: 0.9860
Epoch 4/10
145s - loss: 0.0404 - acc: 0.9876 - val_loss: 0.0389 - val_acc: 0.9872
Epoch 5/10
135s - loss: 0.0335 - acc: 0.9893 - val_loss: 0.0341 - val_acc: 0.9886
Epoch 6/10
133s - loss: 0.0275 - acc: 0.9915 - val_loss: 0.0308 - val_acc: 0.9893
Epoch 7/10
133s - loss: 0.0233 - acc: 0.9926 - val_loss: 0.0363 - val_acc: 0.9880
Epoch 8/10
137s - loss: 0.0204 - acc: 0.9937 - val_loss: 0.0320 - val_acc: 0.9889
Epoch 9/10
139s - loss: 0.0167 - acc: 0.9945 - val_loss: 0.0294 - val_acc: 0.9893
Epoch 10/10
139s - loss: 0.0143 - acc: 0.9957 - val_loss: 0.0310 - val_acc: 0.9907
Baseline Error: 0.93%

可以看出相对于单隐层神经网络,CNN的效果有很大提升,error rate 从1.87%降到了0.93%。

上面实现了一个只含有一层卷积层和pooling层的CNN,为了实现更好的分类效果,可以添加多层的Convolution2D和MaxPooling2D,CNN会自动提取特征,学习到更好的分类效果。

















































keras深度学习实战(37)——手写文字识别(代码片段)

Keras深度学习实战(37)——手写文字识别0.前言1.手写文字识别相关背景1.1Connectionisttemporalclassification(CTC)1.2解码CTC1.3计算CTC损失值2.模型与数据集分析2.1数据集分析2.2模型分析3.实现手写文字识别模型3.1数据集加载与预处... 查看详情

tensorflow2.0入门教程实战案例

...TensorFlow2.0(五)-mnist手写数字识别(CNN卷积神经网络)TensorFlow入门(四)-mnist手写数字识别(制作h5py训练集)TensorFlow入门(三)-mnist手写数字识别(可视化训练)TensorFlow入门(二)-mnist手写数字识别(模型保存加载)TensorFlow入门(一)-mnist手写数字识... 查看详情

tensorflow入门实战|第1周:实现mnist手写数字识别(代码片段)

我的环境:语言环境:Python3.6.5编译器:jupyternotebook深度学习环境:TensorFlow2文章目录一、前期工作1.设置GPU(如果使用的是CPU可以忽略这步)2.导入数据3.归一化4.可视化图片5.调整图片格式二、构建CNN网络模型三、编译模型四、... 查看详情

tensorflow入门实战|第1周:实现mnist手写数字识别(代码片段)

我的环境:语言环境:Python3.6.5编译器:jupyternotebook深度学习环境:TensorFlow2文章目录一、前期工作1.设置GPU(如果使用的是CPU可以忽略这步)2.导入数据3.归一化4.可视化图片5.调整图片格式二、构建CNN网络模型三、编译模型四、... 查看详情

matlab从入门到精通:matlab识别自带手写数字集的cnn(lenet5)

...讲50篇 R语言函数解析及案例实战应用MATLAB-30天带你从入门到精通 MATLAB入门知识,函数原理解析及案例解析python快速学习实战应用系列课程 Python函数解析及实战应用案例MATLAB深入理解高级教程(附源码) 这个专栏... 查看详情

tensorflow从入门到精通——手写数字识别(代码片段)

importtensorflowastfprint(tf.__version__)2.6.0一、数据集mnist=tf.keras.datasets.mnist(train_images,train_labels),(test_images,test_labels)=mnist.load_data()train_images.shape,train_labels.shape((60 查看详情

matlab从入门到精通:matlab识别自带手写数字集的cnn(lenet5)

...讲50篇 R语言函数解析及案例实战应用MATLAB-30天带你从入门到精通 MATLAB入门知识,函数原理解析及案例解析python快速学习实战应用系列课程 Python函数解析及实战应用案例MATLAB深入理解高级教程(附源码) 这个专栏... 查看详情

使用keras训练lenet网络来进行手写数字识别(代码片段)

使用Keras训练Lenet网络来进行手写数字识别这篇博客将介绍如何使用Keras训练Lenet网络来进行手写数字识别。LeNet架构是深度学习中的一项开创性工作,演示了如何训练神经网络以端到端的方式识别图像中的对象(即不必进... 查看详情

matlab可视化实战系列(四十)-基于matlab自带手写数字集的cnn(lenet5)手写数字识别-图像处理(附源代码)(代码片段)

...阅,你的支持就是我不断更新的动力哟!MATLAB-30天带你从入门到精通MATLAB深入理解高级教程(附源码)tableau可视化数据分析高级教程MATLAB2021版可以直接调用MNIST部分数据进行CNN手写数字识别实践。直接上程序。%CNN手写数字识别... 查看详情

keras实现mnist数据集手写数字识别(代码片段)

一.Tensorflow环境的安装这里我们只讲CPU版本,使用Anaconda进行安装a.首先我们要安装Anaconda链接:https://pan.baidu.com/s/1AxdGi93oN9kXCLdyxOMnRA密码:79ig过程如下:第一步:点击next第二步:IAgree第三步:JustME第四步:自己选择一个恰当位置... 查看详情

[python人工智能]三十九.vscode配置python编程和keras环境及手写数字识别(基础篇)

...ras深度学习环境,并对比常用的深度学习框架,最后普及手写数字识别案例。基础性文章,希望对您有所帮助!文章目录一.VSCode安装Python二.TensorFlow、Kera 查看详情

tensorflow快速入门2--实现手写数字识别

Tensorflow快速入门2–实现手写数字识别环境:虚拟机ubuntun16.0.4Tensorflow(仅使用cpu版)Tensorflow安装见:http://blog.csdn.net/yhhyhhyhhyhh/article/details/54429034或者:http://www.tensorfly.cn/tfdoc/get_started/os_setup.html本文将利用Ten 查看详情

[python人工智能]三十九.vscode配置python编程和keras环境及手写数字识别(基础篇)

...ras深度学习环境,并对比常用的深度学习框架,最后普及手写数字识别案例。基础性文章,希望对您有所帮助!文章目录一.VSCode安装Python二.TensorFlow、Keras和PyTorch框架1.TensorFlow2.Keras3.PyTorch三.VSCode安装Keras四.Keras基础知识五.Keras... 查看详情

ai常用框架和工具丨8.keras实现基于cnn的手写数字识别

...1.3CNN网络搭建1.4进行训练1.5模型保存1.6完整代码二、本地手写数字批量识别2.1导入相关依赖2.2数据和模型准备2.3批量预测并显示2.4完整代码2.5运行结果环境说明操作系统:Windows10CUDA版本为:10.0cudnn版本为:7.6.5Python版本为:Python3.6.... 查看详情

用keras搭建神经网络简单模版——cnn卷积神经网络(手写数字图片识别)(代码片段)

#-*-coding:utf-8-*-importnumpyasnpnp.random.seed(1337)#forreproducibility再现性fromkeras.datasetsimportmnistfromkeras.utilsimportnp_utilsfromkeras.modelsimportSequential#按层fromkeras.layersimportDense,Act 查看详情

tensorflow实战之softmaxregression识别手写数字

    关于本文说明,本人原博客地址位于http://blog.csdn.net/qq_37608890,本文来自笔者于2018年02月21日23:10:04所撰写内容(http://blog.csdn.net/qq_37608890/article/details/79343860)。     本文根据最近 查看详情

opencv-python实战(番外篇)——利用svm算法识别手写数字(代码片段)

OpenCV-Python实战(番外篇)——利用SVM算法识别手写数字前言使用SVM进行手写数字识别参数C和γ对识别手写数字精确度的影响完整代码相关链接前言支持向量机(SupportVectorMachine,SVM)是一种监督学习技术,它通过根据指定... 查看详情

keras篇---利用keras改写vgg16经典模型在手写数字识别体中的应用(代码片段)

一、前述VGG16是由16层神经网络构成的经典模型,包括多层卷积,多层全连接层,一般我们改写的时候卷积层基本不动,全连接层从后面几层依次向前改写,因为先改参数较小的。二、具体1、因为本文中代码需要依赖OpenCV,所以第... 查看详情