20.15 图像分类
问题描述
使用卷积神经网络对一组图像分类。
解决方案
使用Keras创建至少有一个卷积层的神经网络:



讨论
卷积神经网络(Convolutional Neural Networks,又被简写为ConvNets)是一种流行的神经网络,而且被证明在计算机视觉领域非常有效(比如能识别猫、狗、飞机甚至热狗)。对图像使用前馈神经网络是完全可行的,图像的每个像素都是一个特征。但是如果这么做,会遇到两个大问题。首先,前馈神经网络并没有考虑像素之间的空间结构。比如对于一张10×10像素的图像,我们可能会把它转换成一个有100个像素特征的向量,这样的话在前向传播时,就会认为第1个特征(比如像素值)和第10个特征之间的空间关系与它和第11个特征之间的空间关系是一样的。
但事实上第10个特征代表的是处在图片远端的像素,距离第1个特征代表的像素较远,而第11个特征表示的是第1个像素正下方的像素。其次,前馈神经网络学习的是特征的全局关系而不是局部的模式。更具体地说,这意味着前馈神经网络无法识别一个物体,不管该物体出现在图像的何处。举例来说,假设我们要训练一个神经网络来识别脸,而这些脸可能出现在图像的任意地方,从右上方到中间再到左下方。
卷积神经网络的强大之处在于,它可以解决上面的两个问题(还可以解决其他问题)。本书不会全面解释卷积神经网络,这里仅做简单的说明。一张图像的数据通常包含两个或者三个维度:高度、宽度和深度。
前两个维度非常明显,最后一个需要做一些解释。深度是指一个像素的颜色。在灰度图像中只有一个深度值(像素的强度),因此一张图像可以表示为一个矩阵。但是在彩色图像中,一个像素的颜色是由多个值表示的。比如,在一张RGB图像中,一个像素的颜色是用3个值表示的,分别对应3个颜色分量(红、绿、蓝)。因此,一张图像的数据可以被想象成一个3维张量:宽度 × 高度 × 深度(又被叫作特征图)。在卷积神经网络中,卷积可以被想象成在图像的像素上滑动一个窗口,通过这个窗口查看像素和它周围的邻居们。接着,它把初始图像数据转换为一个新的3维张量,头两个张量是近似的宽度和高度,而第3个维度(包含颜色值)现在表示像素“属于”哪种模式(比如,尖角或者梯度渐变,它也被叫作过滤器)。
第二个重要的概念是池化层。池化层会在我们的数据上移动一个窗口(通常窗口是按每n个像素作为一个步长来移动的,叫作striding),然后对窗口里的数据以某种方式求和,以缩减数据规模。最常用的方法是最大池化(max pooling),它把每个窗口的最大值传递到下一层。使用最大池化的原因之一是它很实用,卷积过程产生了很多要学习的参数,这会让学习过程很快就没有什么收获,所以通过最大池化减少参数的数量是有益的。可以直观地将最大池化想象成“缩小”图像。
这里举一个例子来说明可能会有助于理解。假设我们有一张包含一只狗的脸的图像。第一个卷积层可能找到一些模式,比如形状的边缘。接着,我们使用最大池化层来“缩小”图像,然后用第二个卷积层找到另一些模式,比如狗的耳朵。最后,我们使用第三个最大池化层进一步缩小图像,再使用一个卷积层来找到像狗的脸这样的模式。
全连接层经常被用在网络的最后来做分类。
尽管我们的解决方案看起来有很多行代码,但其实它跟本章前面讲的二元分类器非常类似。在这个解决方案中我们使用了著名的MNIST数据集,它实际上是机器学习领域的一个指标性数据集。MNIST数据集包含70,000张手写的0 ~ 9的数字的小图像(28 × 28像素)。数据集已经做过标记,所以我们知道每一张小图像上的真实数字(也就是其分类)。
标准的训练集和测试集数据的配比是,用60,000张图像做训练,用10,000张图像做测试。
我们把数据重新组织成卷积神经网络期望的格式。具体来讲,就是使用reshape把样本数据转换成Keras期望的形状。接着,我们把数据的值调节到0和1之间,因为如果样本值比网络的参数(通常都初始化成较小的数值)大很多,训练后网络的性能会很差。最后,我们把目标数据用one-hot编码,这样样本的目标就有10个分类,代表从0到9的数字。
像这样处理图像数据之后,我们就可以创建卷积神经网络了。第一步,添加一个卷积层,并指定过滤器的数量和其他特性。窗口的大小是一个超参数,不过3 × 3的窗口对于大部分的图像来说都适用。一般图像越大,使用的窗口就越大。第二步,添加最大池化层,对相邻的像素求和。第三步,添加Dropout层来减小过拟合的概率。第四步,添加一个压平层把卷积输入转换成全连接层可用的格式。最后,添加全连接层和输出层对数据进行分类。注意,因为这是一个多元分类问题,所以我们在输出层使用的是softmax激活函数。
需要指出,这是一个很简单的卷积神经网络,在实际应用中常常能看到有更多卷积层和最大池化层的更深的网络。



本书评论