keras教程:卷积神经网络(CNNs)终极入门指南

【摘要】本篇教程将手把手地教你使用keras搭建卷积神经网络(CNNs)。利用MNIST数据集,从导入模块开始,到 “预处理数据 → 定义模型架构 → 编译模型 → 训练模型 → 评估效果”,每个环节都充分讲解参数细节。即使没有数学基础,也能毫无障碍地构建起属于自己的图像识别模型。

导读

本篇教程将会手把手教你使用keras搭建卷积神经网络(CNNs)。为了使你能够更快地搭建属于自己的模型,这里并不涉及有关CNNs的原理及数学公式,感兴趣的同学可以查阅系列教程:

《吊炸天的CNNs,这是我见过最详尽的图解!(上)

《吊炸天的CNNs,这是我见过最详尽的图解!(下)》

写在程序之前

为了学习得更快,一些背景知识需要你了解

•  最常见的 CNNs架构

上述模式,是一个最为常见的卷积网络架构模式。如果上述链条理解起来比较吃力,你可以到这里恶补下基础知识。我们后面的代码,都是遵循上述模式来编写的。

•  MNIST 数据集

在MNIST数据集中,包含着70,000个从0~9的手写体数字。每个图像的大小都是28*28,这里列举几张灰度图:

在本教程中,我们的训练样本,就来自于MNIST数据集,它是初学者入门图像识别时,最好用、最便捷的数据集。数据的加载方法,我会在下文中详细讲解,此处你只需要了解,我们的数据源自MNIST就可以了。

•  本教程使用的是

Python 3.5.2, Theano 0.8.2

下面,我们就开始正式的课程。


使用Keras建立你的第一个CNNs模型的具体步骤:

 1. 导入库和模块

2. 从 MNIST 加载图像数据

3. 预处理图像数据

4. 预处理分类标签

5. 定义模型架构

6. 编译模型

7. 训练模型

8. 评估模型

第一步:导入库和模块

导入numpy。numpy可用于进行数组运算。

接下来,我们从Keras中导入Sequential,它是多个网络层的线性堆叠。

简单来说,把 Sequential 想象成一个书架,每本书都是一个“网络层”,只要有了“书架”,你就可以把“书”一本本的堆叠上去。

 

之后,依次导入

这些“网络层”,相当于上面书架中的“图书”。将这些“网络层”堆叠起来,就构成了文章开篇所提到的“最常见的CNNs架构”模式。

最后,我们从Keras导入np_utils,它能帮助我们将数据形态转换为我们想要的样子。

 

第二步:从MNIST加载图像数据

通过print,我们能够看到数据集的形态:

X_train是一个含有60,000个训练样本的数据集,并且,每一个样本图像的尺寸都是28*28,例如,第1个训练样本为:

看样子,上面的数字有可能是3,有可能是5。但是不管怎样,我们已经清楚地看到,X_train中的每一个样本,都是一张28*28的手写数字图。

接下来,我们再来看看y_train:

y_train是60,000个训练样本的标签,例如,第1个训练样本的标签为“5”:

好吧,原来上面那张歪歪扭扭的数字,不是3……

使用同样的方法,我们还可以查看测试集的数据形态,在这里,我们有10,000个测试样本:

 

温馨提示:

无论是训练集,还是测试集,这里y的形态,都与X的不太一样

例如,

X_train.shape=(60000, 28, 28)

而 y_train.shape=(60000, )

后面我们会将它们的形态进行调整,使它们保持一致,并符合图像识别的格式要求。

 

第三步:预处理图像数据

在CNNs中,图像不仅有“宽度”和“高度”,而且还有深度。

对于彩色图片,图像的深度为3,即有“红R,绿G,蓝B”3个通道;

对于像MNIST这样的灰度图片,其图像深度仅为1:

所以,我们数据集的形态,应该从

 (样本数量, 图片宽度, 图片高度)

转换为 

(样本数量, 图片深度, 图片宽度, 图片高度)

实现这一转换的方式很简单:

为了确保我们的确已经将格式转换过来了,再次打印X_train.shape查看:

OK,(样本数量,  图片深度, 图片宽度,  图片高度)我们已全都具备。

预处理的最后一步,是将我们输入的数据,转换为float32类型,并且,将数值范围从[0, 255]标准化到[0, 1]范围内:

 

第四步:预处理分类标签

在第二步的时候,我们已经提到了,分类标签y的数据形态,似乎与图像X的有些不同。

实际上,我们有“0~9”一共十个不同的类标签。

我们期待看到这样的格式:

以此类推……
但是,我们现在的y值,一上来就是 0,1,2, …… , 9。
因此,我们需要对其进行转换:

转换后的结果,我们来看一下:

还记得我们将X_train形态转换后,得到的样子吗?

X_train.shape=(60000, 1, 28, 28)

表示“有60,000个样本,每个样本的维度为(1*28*28)”

这里,经过转换后的Y_train的形态为

Y_train.shape=(60000, 10)

表示“有60,000个样本,每个样本的维度为10”

请记住上面的数据形态,只有当我们输入数据(X,Y)符合上述形态时,代码才会正常运行。

 

第五步:定义模型架构

经过前四步,我们已经把所有的准备工作都做好了。现在,我们开始定义模型。

回忆我们在开篇提到的“CNNs架构”

再次祭上这张神图……

“定义模型架构”,意味着我们要确定图中“若干次”的具体次数。

在本例中,我们将使用这样的架构:

当然,“若干次”的具体次数该如何来设定,并没有硬性的规定。

你可以尝试构建不同的模式,并从中选择一个预测准确度最高的模型来使用。

我们在这里使用了“2次 – 1次 – 2次”的结构。

好啦,废话不多说,直接上代码。

先搭一个“书架”:

再往“model”中,添加各层。

添加第1个“卷积 → ReLU”:

过滤器的作用是提取图片的特征,通常情况下,过滤器的个数由你自己来决定,这里设置了32个过滤器。

过滤器的大小,你可以设置为3*3,也可以设置为5*5,都是较为常用的尺寸。

经过第1个“卷积 → ReLU”的处理,我们来看看得到了什么:

输出的结果是,大小为26*26,一共32张图片。

为什么是32张图片?

这32张图片长得什么样子?

为什么图片尺寸比输入时变小了?

想要了解具体原理的同学,可以参考下面两篇教程:

《吊炸天的CNNs,这是我见过最详尽的图解!(上)》

《吊炸天的CNNs,这是我见过最详尽的图解!(下)》

 

接下来,我们再添加第2个“卷积 → ReLU”:

然后是“池化层”:

池化层的作用是将图片缩小。

举个例子:

经过上面第2个“卷积 → ReLU”的处理后,输出结果的形态为

(None, 32, 24, 24)

表示“有32张24*24大小的图片”。

经过“最大池化”的处理后,得到的是

(None, 32, 12, 12)

表示“有32张12*12大小的图片”,

可以看到,图片的宽、高都缩小了一半。

 

最后,我们来添加2个全连接层:

 

第六步:编译模型

刚刚的第五步,我们只是搭起了一个模型的架子,而现在我们需要做的工作是,让模型能够跑起来。

 

第七步:训练模型

好啦,构建CNNs,所有最难的部分都已经过去了。

下面,我们就要把数据“喂给”模型,让它开始为我们干活儿了!

你的屏幕会显示这么一大堆东西:

(点击图片,查看大图)

 

第八步:评估模型

还记得我们在最初加载MNIST数据时,其中含有10,000个测试样本吗?

在代码的最后,我们可以充分利用这10,000个测试样本,来评估我们构建的模型其预测效果:

输出结果为:

预测准确度高达0.989。

恭喜你!现在,你已经会用keras做图像分类了~~

如果在本文中,有任何疑问,可以关注 微信公众号:AI传送门,留言给我们,我们会定期为同学进行答疑。

下面附上全部代码:

 

发表评论

电子邮件地址不会被公开。