首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >keras教程:卷积神经网络(CNNs)终极入门指南

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

作者头像
AI传送门
发布2018-06-21 12:09:57
1.2K1
发布2018-06-21 12:09:57
举报
文章被收录于专栏:AI传送门AI传送门

本篇教程将会手把手教你使用keras搭建卷积神经网络(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像一个书柜,每本书都是一个“网络层”,只要有了“书柜”,你就可以把“书”一本本的堆叠上去。

之后,依次导入

卷积层 Convolution2D

池化层 MaxPooling2D

激活层 Activation

展开层 Flatten

全连接层 Dense

Dropout层

这些“网络层”,相当于上面书架中的“图书”。将这些“网络层”堆叠起来,就构成了文章开篇所提到的“最常见的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”一共十个不同的类标签。

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

如果分类标签为“5”,那么,

如果分类标签为“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张图片长得什么样子?

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

想要了解具体原理的同学,可以参考这里

接下来,我们再添加第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传送门,留言给我们,我们会定期为同学进行答疑。

长按上方二维码,关注我们

下面附上全部代码:

(可左右滑动此代码)

import numpy as np
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Flatten, Dense, Dropout
from keras.utils import np_utils
from keras.datasets import mnist
  
# 加载MNIST数据集,其中包含60,000个训练样本、10,000个测试样本
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# 调整加载数据的形态
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28)
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28)

X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255

Y_train = np_utils.to_categorical(y_train, 10)
Y_test = np_utils.to_categorical(y_test, 10)

model = Sequential()

# 添加第一个卷积层,其中,超参数32,3,3分别表示“过滤器的个数、过滤器的宽、过滤器的高”
# input_shape = (1, 28, 28)表示“输入图片的深度为1,宽度为28,高度为28”
model.add(Convolution2D(32, 3, 3, input_shape=(1, 28, 28)))

# 添加激活层(ReLU)
model.add(Activation('relu'))

# 添加第二个卷积层
# 除第1层卷积外,其余各层卷积均不再需要输入input_shape,算法会自动识别其形态
model.add(Convolution2D(32,  3,  3))

# 添加激活层(ReLU)
model.add(Activation('relu'))

# 添加池化层
model.add(MaxPooling2D(pool_size=(2, 2)))

# 添加展开层,因为,在“全连接层”之前,需要先将图片的像素值展开
model.add(Flatten())

# 添加第1个全连接层
# “128”表示神经元的个数,可以设置为任意数值
model.add(Dense(128, activation='relu'))

# 添加dropout层,防止过拟合
model.add(Dropout(0.5))

# 添加第2个全连接层
# “10”表示神经元的个数,但是由于本层为CNNs架构的最后一层(即“输出层”),
# 所以,此处的数值只能为“10”,对应“0-9”个数字分类
# “softmax”是非线性函数,输出的结果为“最初输入的图片,属于每种类别的概率”
model.add(Dense(10, activation='softmax'))

# 编译模型
# 告诉模型,我们的目标是要使得“误差损失:categorical_crossentropy”尽可能小
# 为了实现这一“目标”,所使用的优化方法是:adam
# 使用“准确率:accuracy”来评估模型的预测效果
model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

# 训练模型
# batch_size=32 表示一批处理32个样本
# nb_epoch=10 表示10个周期,每个周期都把全部60,000个样本遍历一遍
# validation_split=0.3 表示从训练样本中拿出30%作为交叉验证集
model.fit(X_train, Y_train,
          batch_size=32, nb_epoch=10, validation_split=0.3)

# 评估模型
score = model.evaluate(X_test,  Y_test)
print(score)

关于AI传送门

AI传送门是国内一家最易学习的AI平台。在这里:

● 国外课程一点即播——省去访问外国网站找资料的时间;

● 英语资料全中文呈现——降低学习门槛;

● 数学公式直观化展示——以鲜明的色彩加以标注,将天书般的公式,拆解成更易理解的小运算,只要你的语文理解没有问题,那么数学的理解,也将不是问题。

你需要做的:

每周拿出1-2天时间,学习平台上的新内容,记住,能学多少学多少,不要勉强自己

放下对英语的顾虑、对数学的恐惧——这些,都交给我们。

慢慢地积累,你会发现:

在这个平台上,你能看懂的东西越来越多,不明白的内容越来越少;直到有一天,你已不再需要我们,届时,你将拥有在AI时代生存下去的资本。

长按上方二维码,关注我们

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI传送门 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像识别
腾讯云图像识别基于深度学习等人工智能技术,提供车辆,物体及场景等检测和识别服务, 已上线产品子功能包含车辆识别,商品识别,宠物识别,文件封识别等,更多功能接口敬请期待。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档