卷积神经网络实例 —— 实现手写数字识别

本文介绍了卷积神经网络的基本结构,并通过Keras搭建了一个用于手写数字识别的CNN模型,包括特征提取和分类识别阶段。模型包含两个卷积层和最大池化层,最后通过全连接层进行分类。使用MNIST数据集训练模型,展示了训练过程及模型评估。此外,还展示了如何加载模型并进行预测,包括预测概率的输出。

1、卷积神经网络的基本结构

卷积神经网络是一种多层、前馈型神经网络。从功能上来说,可以分为两个阶段,特征提取阶段和分类识别阶段。
在这里插入图片描述
特征提取阶段能够自动提取输入数据中的特征作为分类的依据,它由多个特征层堆叠而成,每个特征层又由卷积层和池化层组成。处在前面的 特征层捕获图像中局部细节的信息,而后面的特征层能够捕获到图像中更加高层、抽象的信息。

分类识别阶段通常是一个简单的分类器,例如全连接网络或者支持向量机。它更加提取出的特征完成分类或识别任务。

2、使用 Keras 构建和训练卷积神经网络

在这节课中,我们以手写数字识别为例,介绍如何使用 Keras 构建和训练卷积神经网络。

2.1、构架卷积神经网络的结构

在这里插入图片描述

输入为手写数字图片,每张图片表示为 28 x 28 的二维张量,通道数为 1 。

这里,有两个特征层,其中,卷积核的尺寸均为 3 x 3,
在这里插入图片描述
池化层均采用最大池化,池化模板的尺寸为 2 x 2,
在这里插入图片描述
在卷积层 1 中,一共有 16 个卷积核。每个卷积核提取出图像中的一种特征,得到一张 28 x 28 的特征图。所有卷积运算的结果构成一个28 x 28 x 16 的三维张量。

由于使用 2 x 2 的池化模板,所有这 16 张特征图的尺寸都缩小为原来的 1/4 ,成为 14 x 14 的二维张量。所以这 16 张特征图就构成了一个 14 x 14 x 16 的三维张量。可以看成是有 16 个通道的、大小为 14 x 14 的图像。

卷积层 2 接收来自池化层 1 的输出,使用 32 个卷积核得到 32 个特征图。

这里要注意的是,由于上一步的输出结果有 16 个通道,因此,这里的每一个卷积核都有 16 个通道,经过池化层 2 ,得到 32 个 7 x 7 的特征图,依然是一个三维张量。

特征提取阶段结束。

下面,进入分类识别阶段。由于全连接网络只能接收一维的输入,因此,首先采用一个 flatten 层将池化层 2 输出的三维张量转化为一维张量后再传递给后面的隐含层,隐含层有一层,其中,有 128 个神经元。

手写数字识别是一个 10 分类的任务,因此输出层中有 10 个结点,分别对应 0~9 这十个数字。

2.2 使用 Keras 构建这个卷积神经网络

2.2.1 创建卷积层

在 Keras 中,使用下面这个函数来创建卷积层。
在这里插入图片描述
其中,

参数 filters 表示卷积核的数量,

参数 kernel_size 表示卷积核的大小。

参数 padding 表示扩充图像边界的方式,取值可以是 same 和 valid ,same 表示用 0 来扩充图像边界,valid 表示使用边界本来的值进行扩充。

参数 activation 用来设置激活函数,

参数 input_shape 表示输入卷积层的数据形状,是一个四维张量,分别是 samples(样本数),rows(行数),cols(列数),channels (通道数)。一般只需要给出后面三维即可。第一个维度是由 batch_size 自动指定。和全连接层一样,只有第一层卷积层需要设置输入数据的形状,后面的卷积层接收上一层的输出作为输入。

下图中的代码为创建卷积层 1 ,一共有 16 个卷积核,每个卷积核的大小为 3 x 3 ,
在这里插入图片描述
在进行卷积运算时,使用全 0 来扩充图像边界 ,采用 relu 函数作为激活函数,输入图像是 28 x 28 的。

因为 Mnist 数据集中的数据是灰度图像,所以通道数为 1 。

2.2.2 创建最大池化层

Keras 中使用
在这里插入图片描述
函数来创建最大池化层。

由参数 pool_size 来指定池化窗口的大小。

例如,
在这里插入图片描述
表示创建尺寸为 2 x 2的最大池化层。

2.2.3 构建卷积神经网络
# 首先创建一个 Sequential 对象 model, 添加卷积层 1 ,
model = tf.keras.Sequential([

    # unit 1
    # 添加卷积层 1 , 卷积核数量为 16, 卷积核的大小为 3 x 3,
    tf.keras.layers.Conv2D(16, kernel_size=(3, 3), padding="same", activation=tf.nn.relu, input_shape=(28, 28, 1)),
    # 添加池化层 1, 采用最大池化, 池化模板尺寸为 (2, 2)
    tf.keras.layers.MaxPool2D(pool_size=(2, 2)),

    # unit 2
    # 添加卷积层 2 , 卷积核数量为 32, 卷积核的大小为 3 x 3, 由于直接接收上一层的输出, 所以这里无需对输入形状进行设置
    tf.keras.layers.Conv2D(32, kernel_size=(3, 3), padding="same", activation=tf.nn.relu),
    # 添加池化层 2, 采用最大池化, 池化模板尺寸为 (2, 2)
    tf.keras.layers.MaxPool2D(pool_size=(2, 2)),
    # 至此, 特征层构建完成.

    # unit 3
    # 添加 Flatten 层, 将池化层的输出的三维张量转化为一维张量
    tf.keras.layers.Flatten(),

    # unit 4
    # 最后, 再添加一个隐含层核一个输出层, 隐含层中的结点个数为 128 ,
    tf.keras.layers.Dense(128, activation="relu"),
    # 输出层中的结点个数为 10 
    tf.keras.layers.Dense(10, activation="softmax")

])
2.2.4 查看构建的卷积神经网络结构和参数信息
model.summary()

输出结果如下,
在这里插入图片描述
可以看到每一层的名称、输出的形状以及每一层的参数个数。

其中,卷积层参数个数的计算公式如下:
在这里插入图片描述
(加的那个1是偏置项)

所以
在这里插入图片描述
池化层只比较大小,没有引入新的参数。参数个数为 0 .

全连接层的参数个数的计算公式如下:
在这里插入图片描述
所以,
在这里插入图片描述

最终,总共参数个数为:160 + 4640 + 200832 + 1290 = 206922.

2.2.5 完整代码如下:
# 一:导入库函数
import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt

# 二:参数配置
# 图片显示中文字体的配置
plt.rcParams["font.family"] = "SimHei", "sans-serif"
# GPU显存的分配配置
gpus = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(gpus[0], True)

# 三:加载数据
mnist = tf.keras.datasets.mnist
(train_x, train_y
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xuechanba

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

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

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

打赏作者

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

抵扣说明:

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

余额充值