使用卷积网络实现计算机图像识别:卷积和max pooling操作介绍

深度学习在计算机图像识别上的应用非常成功。利用深度学习,我们能够对图片进行高精度识别,实现这一功能的,主要依靠神经网络中的一种分支,名为卷积网络。卷积网络与我们前面实现的网络不通之处在于,它可以直接接受多维向量,而我们以前实现的网络只能接收一维向量。

我们在开始时,实现了一个能够识别手写数字图片的网络,网络接收数据时,必须把一张28*28的灰度图转换为784长的一维向量。在深入解析卷积网络前,我们直接用代码将其实现出来,通过卷积网络实现手写数字识别功能,先获得一个感性认识,为后续的深入研究打下基础,我们看看一个能直接接收手写数字图片的卷积网络是什么样子的:

from keras import layers
from keras import models

model = models.Sequential()
model.add(layers.Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1)))
model.add(layers.MaxPooling2D(2,2))
model.add(layers.Conv2D(64, (3,3), activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64, (3,3), activation='relu'))

model.summary()

上面代码运行后结果如下:

上面实现网络与以往不同在于,网络层使用了Conv2D和MaxPooling,而不是以往的Dense,同时Conv2D网络层可以直接接收二维向量(28,28,1),这对应的就是手写数字灰度图。卷积网络主要作用是对输入数据进行一系列运算加工,它输出的是中间形态的结果,该结果不能直接用来做最终结果,要得到最终结果,我们需要为上面的卷积网络添加一层输出层,代码如下:

model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
model.summary()

卷积网络在最后一层输出的是(3,3,64)的二维向量,Flatten()把它压扁成3364的一维向量,然后再传入一个包含64个神经元的网络层,由于我们要识别图片中的手写数字,其对应的结果有10种,也就是0到9,因此最后我们还添加了一个含有10个神经元的网络层。

我们把图片数据输入网络,对网络进行训练:

from keras.datasets import mnist
from keras.utils import to_categorical

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

train_images = train_images.reshape((60000, 28, 28, 1))
train_images = train_images.astype('float32') / 255

test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(train_images, train_labels, epochs = 5, batch_size=64)

test_loss, test_acc = model.evaluate(test_images, test_labels)
print(test_acc)

上面代码运行后,输出结果如下:

我们构造的卷积网络对手写数字图片的识别准确率为99%,而我们最开始使用的网络对图片识别的准确率是97%,也就是说最简单的卷积网络,对图片的识别效果也要比普通网络好得多。能取得这种好效果,主要是网络进行了两种特殊操作,分别是Conv2D和MaxPooling2D,接下来我们看看这两种操作的细节。

卷积操作,其实是把一张大图片分解成好多个小部分,然后一次对这些小部分进行识别,我们最开始实现的网络是一下子识别整张大图片,这是两种网络对图片识别精确度不一样的重要原因。通常我们会把一张图片分解成多个3*3或5*5的”小片“,然后分别识别这些小片段,最后把识别的结果集合在一起输出给下一层网络,例如下图:

上图中小方格圈中的区域就是我们抠出来的3*3小块。这种做法其实是一种分而治之的策略,如果一个整体很难攻克,那么我就把整体瓦解成多个弱小的局部,然后把每个局部攻克了,那么整体就攻克了。这种做法在图象识别中很有效就在于它能对不同区域进行识别,假设识别的图片是猫脸,那么我们就可以把猫脸分解成耳朵,嘴巴,眼睛,胡子等多个部位去各自识别,然后再把各个部分的识别结果综合起来作为对猫脸的识别。

每一小块识别后,会得到一个结果向量,例如语句:

layers.Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1))

它表示把一个28*28的灰度图片,(1表示颜色深度,对于灰度图其深度用一个数字就可以表示,对于RGB图,颜色深度需要用3个数字[R,G,B]表示),分解成多个3*3的小块,每个3*3小块识别后输出一个含有32个元素的一维向量。这个一维向量我们成为过滤器Filter,它蕴含着对图片的识别信息,例如“这部分对应猫脸的嘴巴”。

对于2828的图片,把它分解成3\3小块时,这些小块总共有26*26个,我们先看看分解方法,假定我有一个5*5的大图片,那么我们可以将它如下分解成多个3*3的小块:

如果你看不出分解规律,我们把左边大图片的每个小格标号后就清楚了,左边图片编号如下:

1,2,3,4,5
6,7,8,9,10
11,12,13,14,15,
16,17,18,19,20
21,22,23,24,25

于是右边第一行第一小块对应的编号为:

1,2,3
6,7,8
11,12,13

第一行第二小块为:

2,3,4
7,8,9
12,13,14

以此类推,一个28*28的图片可以分解成26个3*3小块,每个小块又计算出一个含有32个元素的向量,这个计算其实是将3*3矩阵乘以一个链路参数矩阵,它跟我们前面讲过的数据层上一层网络经过神经元链路输入下一层网络的原理是一样的,于是第一层网络输出结果是26*26*32的三维矩阵。我们可以用下图形象的表示输出结果:

上面描述的操作流程就叫卷积,接下来我们看看另一种操作:max pooling。从我们的代码中看到,第一层网络叫Conv2D,第二层就是MaxPooling2D,max pooling 的目标是把卷积操作得到的结果进一步“挤压”出更有用的信息,有点类似于用力拧毛巾,把不必要的水分给挤兑掉。max pooling 其实是把一个二维矩阵进行2*2的分块,这部分跟前面描述的卷积很像,具体操作如下图:

一定要注意上面分块与卷积分块的区别,上面分出的块与块之间是没有重叠的,而卷积分出的3*3小块之间是相互重叠的!2*2分块后,把每块中的最大值抽出来最后组合成右边的小块,注意看完成后矩阵的维度缩减了一半,原来4*4的矩阵变成了2*2的矩阵。

回到我们的代码例子,第一层卷积网络输出了26*26*32的结果,我们可以看成由32 个 26*26个二维矩阵的集合。每个26*26的二维矩阵都经过上面的max pooling处理变成13*13的二维矩阵,因此经过第二层max pooling后,输出的结果是 13*13*32的矩阵集合,也就是下面代码产生了32个13*13的矩阵集合:

layers.MaxPooling2D(2,2)

其他代码以此类推。卷积操作产生了太多的数据,如果没有max pooling对这些数据进行压缩,那么网络的运算量将会非常巨大,而且数据参数过于冗余就非常容易导致过度拟合。

以上就是我们这节需要介绍的内容,有了卷积网络,我们可以通过很少的训练数据就能教会计算机识别图片里面的物体,所以它的功能非常强大,下一节我们将运用卷积网络识别猫狗图片。

原文发布于微信公众号 - Coding迪斯尼(gh_c9f933e7765d)

原文发表时间:2018-07-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏人工智能LeadAI

数据预处理 | 机器学习之特征工程

作者:苏小保(jacksu) 华为工程师 擅长分布式系统、大数据、机器学习。github地址:https://github.com/jacksu 通过特征提取,...

4219
来自专栏YoungGy

词向量综述

词向量综述 one-hot by neighbor 基于全文档的词向量 基于window的词向量 SVD Skip-Gram 结构 输入输出 学习算法 优化角度...

4776
来自专栏ml

神经网络模型之AlexNet的一些总结

说明: 这个属于个人的一些理解,有错误的地方,还希望给予教育哈~ 此处以caffe官方提供的AlexNet为例. 目录: 1.背景 2.框架介绍 3.步骤详细说...

3365
来自专栏PaddlePaddle

【结构化语义模型】深度结构化语义模型

导语 PaddlePaddle提供了丰富的运算单元,帮助大家以模块化的方式构建起千变万化的深度学习模型来解决不同的应用问题。这里,我们针对常见的机器学习任务,提...

5328
来自专栏企鹅号快讯

常用的像素操作算法:Resize、Flip、Rotate

Resize 图像缩放是把原图像按照目标尺寸放大或者缩小,是图像处理的一种。 图像缩放有多种算法。最为简单的是最临近插值算法,它是根据原图像和目标图像的尺寸,计...

44310
来自专栏机器学习、深度学习

人脸检测--Grid Loss: Detecting Occluded Faces

Grid Loss: Detecting Occluded Faces ECCV2016 遮挡问题还是要通过区域分块来解决 针对有遮挡的人脸检测,如果从训练...

3429
来自专栏机器学习算法与理论

基于LDA KNN的人脸识别详解

人脸识别(LDA+KNN方法): dataTrain=creatData(TrainDatabasePath); dataTest=creatData(Tes...

8044
来自专栏机器人网

图解机器学习(清晰的路线图)

每当提到机器学习,大家总是被其中的各种各样的算法和方法搞晕,觉得无从下手。确实,机器学习的各种套路确实不少,但是如果掌握了正确的路径和方法,其实还是有迹可循的,...

5259
来自专栏橙、

用Keras通过Python进行卷积神经网络的手写数字识别

图像识别是深度学习技术的一个普遍具有的功能。

2.4K7
来自专栏Petrichor的专栏

深度学习: 学习率 (learning rate)

ωn←ωn−η∂L∂ωnωn←ωn−η∂L∂ωn\omega^{n} \leftarrow \omega^{n} - \eta \frac{\partial ...

1.3K2

扫码关注云+社区

领取腾讯云代金券