zhaoyin 2018-06-01
本文主要介绍了机器学习概念,讨论了典型卷积神经网络中的主要部分,如卷积层、合并层和完全连接层。
介绍
卷积神经网络(CNN)是一组深层网络,它可以利用数据(如图像)的空间结构来了解数据,从而使算法可以输出一些有用的信息。考虑一个问题,如何确定某个图像中是否有人?例如,如果给CNN一个人的图像,这个深度神经网络首先需要学习一些局部特征(例如眼睛、鼻子、嘴巴等)。这些局部特征就是在卷积层中习得的。
然后,CNN将查看给定图像中存在的局部特征,然后生成特定的激活模式(或激活矢量),该激活模式将完全的表示这些局部特征映射的存在。这些激活模式由CNN中完全连接的层产生。例如,如果图像为非人物,则激活模式将与针对人物图像的激活模式不同。
CNN在模块化层面
现在介绍CNN中的子模块。一个典型的CNN有三种不同的部分。它们是卷积层、合并层和完全连接层。下文将重点介绍合并层的概念。
首先我们讨论卷积层在深度上起到的作用。卷积层由许多内核组成,存在于卷积层中的这些内核(有时称为卷积滤波器)学习图像中存在的局部特征。卷积层学习的这种局部特征称为特征映射。然后将这些特征在图像上进行卷积。这种卷积操作将产生一个矩阵(有时称为激活图)。如果在卷积滤波器中表示的特征出现在输入的该位置处,则激活映射在给定位置处产生高值。
合并层使这些特征通过CNN平移而不会改变(例如,无论人的眼睛是在[x = 10,y = 10]还是[x = 12,y = 11]位置,合并层输出都相同)。聚合几个这样的层,会使我们具有更高的平移不变性。
最后是完全连接层。完全连接层负责根据激活的特征图集和图像中的位置生成不同的激活图案,并激活特征图。这就是CNN在视觉上的样子。
在了解CNN的整体结构的基础上,让我们继续理解构成CNN的每个子组件。
卷积层
卷积运算具体做些什么? 如果该位置存在卷积特征,则卷积运算为给定位置输出高值,否则输出低值。更具体地说,在卷积核的给定位置,我们取每个核心单元值和与核心单元重叠的对应图像像素值的元素相乘,然后取它们的和。精确值的确定根据以下公式(m - 核宽和高,h - 卷积输出,x - 输入,w - 卷积核)。
图像上的卷积过程,如下图所示:
仅仅知道卷积运算的作用还不够,我们还需要了解卷积输出代表什么。设想卷积输出中的值的颜色(0 - 黑色,100 - 白色)。如果你将这幅图可视化像,它将代表一个在眼睛所在位置发光的二元图像。
卷积运算也可以被认为是对给定图像进行某种变换。该变换可能导致各种效果(例如,提取边缘,模糊等)。
合并层
现在让我们来了解合并层的功能。合并(或有时称为二次采样)层使得CNN在卷积输出方面具有平移不变性。实践中使用两种不同的池化机制(最大池化和平均池化)。 我们将max-pooling称为pooling,因为max-pooling与平均池化相比被广泛使用。更准确地说,在给定位置的合并操作输出落入内核的输入的最大值。 在数学上,
让我们通过在前面看到的卷积输出上应用合并层操作来理解其的工作原理。
如您所见,我们使用同一图像的两个变体。一个原始图像和另一个图像在x轴上稍微平移。 但是,合并操作会使两个图像输出完全相同的特征图(黑色 - 0,白色 - 100)。 所以我们说合并操作使得CNN翻译不变量的知识成为可能。需要注意的一点是,我们每次移动的像素不是1个像素,而是2个像素。这就是所谓的跨越式合并,这意味着我们正在以2的步幅进行合并。
完全连接层
完全连接层将结合由不同卷积核所学习的特征,以便网络可以建立关于整体图像的全局表示。 我们可以理解完全连接层,如下所示。
完全连接层中的神经元将根据输入中是否存在由卷积特征表示的各种实体而被激活。当完全连接的神经元为此被激活时,它会根据输入图像中存在的特征产生不同的激活模式。这为图像中存在的输出层提供了一种紧凑的表示形式,即输出层可以轻松用于正确分类图像。
一起编织它们
现在我们所要做的就是将所有这些组合起来,形成一个从原始图像到决策的模型。总而言之,卷积层将学习数据中的各种局部特征,那么合并层将使得CNN对于这些特征的平移不变。最后,我们有完全连接层,说:"我们发现了两只眼睛、一只鼻子和一只嘴巴,所以这一定是一个人,并激活正确的输出。
添加越来越多的层有什么作用?
增加更多的层显然可以提高深度神经网络的性能。事实上,深度学习中最引人注目的突破性研究大多与解决如何添加更多层同时不影响模型的训练的问题有关。因为模型越深入,训练越困难。
但拥有更多的层可以帮助CNN以分层方式学习功能。例如,第一层学习图像中的各种边缘方向,第二层学习基本形状(圆形、三角形等),第三层学习更高级的形状(例如,眼睛的形状、鼻子的形状)等等上。与使用单层学习的CNN相比,这将会有更好的性能。
训练CNN(又名反向传播)
现在需要记住的一点是,当你实现CNN时,这些卷积特征(眼睛、鼻子、嘴巴)不会自己出现。CNN的目标是学习给定数据的这些特征。为此,我们定义一个成本函数,奖励正确识别的数据并惩罚错误分类的数据。示例成本函数是均方根误差或二元交叉熵损失。
在定义了损失之后,我们可以优化特征的权重(即特征的每个单元格值),以反映引导CNN正确识别某个人的有用特征。更具体地说,我们通过在每个参数的梯度相对于损失显示的相反方向上迈出一小步来优化每个卷积核和完全连接的神经元。但是,要实现CNN,您需要知道如何实现梯度传播的确切细节。这是因为,大多数深度学习库(例如TensorFlow、PyTorch)会在您自定义正向计算时在内部实施这些差异化操作。
用Keras实现和运行CNN
这里我们将简要讨论如何实现CNN。仅仅了解基础知识还不够,我们也应该了解如何使用像Keras这样的标准深度学习库来实现模型。
首先我们定义我们想要使用的Keras API。 我们将使用顺序API。
然后我们定义一个卷积层,如下所示:
在这里,32是该层中的内核数量,(3,3)是卷积层的内核大小(高度和宽度)。我们使用非线性激活Relu和[图像高度、图像宽度、颜色通道]的输入形状[28,28,1]。 请注意,输入形状应该是前一层产生的输出的形状 因此,对于第一个卷积层,我们有实际的数据输入。 对于层的其余部分,它将是前一层产生的输出。接下来我们讨论如何实现最大池化:
这里我们不提供任何参数,因为我们将使用Keras中提供的默认值。如果你没有指定参数,Keras将使用(2,2)的内核大小和(2,2)的步幅。接下来我们定义完全连接层。但在此之前,我们需要将输出平坦化,因为完全连接层要处理1D数据:
在这里我们定义了两个完全连接或密集的层。 第一个完全连接的层有256个神经元,并使用Relu激活。 最后,我们定义一个具有10个输出节点并具有softmax激活的密集层。 这充当输出层,它将激活具有相同对象的图像的特定神经元。 最后我们编译我们的模型,
在这里,我们说使用 Adam optimiser(训练模型),使用交叉熵损失并用模型的准确性来评估模型。最后我们可以使用数据来训练和测试我们的模型。我们将使用MNIST数据集,使用在练习中定义的maybe_download和read_mnist函数下载并读入内存。MNIST数据集包含手写数字(0-9)的图像,目标是通过分配图像表示的数字来正确分类图像。
接下来我们通过调用以下函数来训练我们的模型:
我们可以用一些测试数据来测试我们的模型,如下所示:
我们将在几个不同的时期运行它,这将帮助您提高您的模型性能。
结论
我们首先站在有利位置讨论了在CNN内部发生的事情。然后我们讨论了典型CNN中的主要部分,如卷积层、合并层和完全连接层。之后我们更详细地介绍了每个部分。接下来,我们非常简短地讨论了如何在CNN中训练。最后我们讨论了我们可以用Keras实现一个标准的CNN:一个高级的TensorFlow库。