目 录
【1】简介与基本概念
卷积神经网络CNN,是近些年在CV领域取得进展的基石,甚至“任何令人欣喜的深度神经网络领域的成就都和CNN有关”。CNN现在不仅仅是在计算机视觉上大放异彩,在自然语言处理(比如text-CNN)、推荐系统以及语言识别领域具有很多应用。本文将对CNN网络的基本知识进行介绍,这对于初学者是必要的;而后对图像处理的常用CNN网络进行解析。包括LeNet、AlexNet、VGG等
首先,本小节将回顾CNN网络的基本概念和一些关键的操作。
(1)二维卷积层
在卷积神经网络中最为常见的就是二维卷积层,包含宽和高两个属性。在二维卷积层中进行的运算是二维互相关运算,参与运算的两方分别是输入数组和二维核数组(也称为卷积和或者过滤器)。
卷积层不进行卷积计算?事实上,真正的卷积运算是比较复杂的一种运算(左右翻转、上下翻转等),这里使用互相关运算一者是计算更加简单,二者是确实得到的结果和真实的卷积运算的结果一致,本质是一种包含了翻转矩阵和参数矩阵的乘积,学习参数的过程中神经网络并不在意这些。
(2)参数的学习
在一般的CNN网络中,需要学习的参数主要是两个部分,包括卷积核和标量偏差。在初始化网络的时候,需要同时随机初始化这些参数。简化这个过程,针对核数组,如何通过数据进行学习呢?
核心在于构建输入数据与输出数据,并选取合适的误差函数。一般神经网络的训练过程都是需要提供Label的,这标示了每一个输入对应的期望输出结果。
举个例子:在一般的医学影像分割问题中,我们提供了一种称为掩膜(mask)的东西。这个东西就是期望的输出。在神经网络中,我们一开始就应该指明期望输出和实际输出之间的差距,也就是误差(这是一种数学建模,任何优化问题都应当具有明确的优化目标并可以用数学的语言描述)。关于误差的函数有很多,合适的函数具有很好的导向,这是梯度下降的基础。
要体会CNN中卷积核作用,你可以试试CNN领域的 “ helloworld ” ——物体边缘检测。
(3)特征图和感受野
这里有两个简单的概念:特征图和感受野。
- 特征图:二维卷积层输出的二维数组,它可以看作是输入在空间维度上的某一级表征(feature map);
- 影响元素X的所有可能输入区域(可能大于输入的实际尺寸)称为特征图上的元素X的感受野。
多层卷积层可以使得后面的每一个元素获得更大的感受野,从而捕捉输入上更大尺寸的特征。
总的来说,卷积层可以通过重复使用卷积核有效的表征局部空间。
(4)填充和步幅
在了解了卷积层中卷积核的工作方式之后,可以很简单的总结出的规律是卷积层的输出形状和输入形状和卷积核形状决定。假设输入形状是nh X nw,卷积核窗口形状是kh X kw,那么输出形状则是:
(nh-kh+1) x (nw-kw+1)
填充(padding)是指在输入高和宽的两侧填充元素(通常填充0)。一般来说,如果在高的两侧一共填充ph行,在宽的两侧一共填充pw列,那么输出的形状将会是:
(nh-kh+ph+1) x (nw-kw+pw+1)
也就是说,输出的高和宽会分别增加ph和pw。一般的,可以通过合理的填充使得卷积层的输入和输出图像的大小一致,这对于网络各层结果的估计具有很强的意义。一般来说,卷积核的大小一般是奇数高和宽。
卷积窗口(核数组)从输入数组最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。将每次滑动的行数和列数称为步幅。一般情况下,在高和宽两个方向上步幅均为1,也可以使用更大的步幅。
更大的步幅,带来的好处就是可以进一步减少输出的宽和高。(下图步幅=2,填充=1)
(5)多输入通道和多输出通道
前面我们的举例都是基于一个二维矩阵,然而现实中的图像一般都是彩色图像,也就是说不光光包括2个维度还有RGB三个颜色通道(绝大多数)。解决办法是构建和通道数一致的卷积核个数,分别作用在输入二维矩阵上,得到的特征图直接相加即可。
上面这种解决方法不管多少个通道的输入只可以得到一个通道的输出。如果要得到多个通道的输出,其实只需要重复上面的操作若干次即可。
对于多通道输入的情况,如果使用1*1的卷积核,那将失去在宽度和高度两个维度上识别模式的功能,但是多层的结构却能对通道间的关系进行识别。这个卷积层类似与一种全连接网络,可以用来控制网络层之间的通道数来控制模型的复杂度。
(6)池化
池化(Pooling)是卷积神经网络中另一个重要的概念,它实际上是一种形式的降采样,有多种不同形式的非线性池化函数,比如最大池化、最小池化、平均池化等。而其中“最大池化(Max pooling)”是最为常见的,它是将输入的图像划分为若干个矩形区域,对每个子区域输出最大值。
直觉上,这种机制能够有效地原因在于,在发现一个特征之后,它的精确位置远不及它和其他特征的相对位置的关系重要,换言之,池化层的作用就是缓解卷积层对位置的过度敏感性。当然,池化层会不断地减小数据的空间大小,因此参数的数量和计算量也会下降,这在一定程度上也控制了过拟合。
通常来说,CNN的卷积层之间都会周期性地插入池化层。
以上对CNN的基本概念进行了介绍,读者只需要大概掌握即可,接下来我们将进入典型CNN网络设计架构的学习中去。
【2】典型的CNN网络(LeNet、AlexNet)
CNN早在上个世纪70年代就有了萌芽迹象,到现在已经有了丰富的实践成果,如下图所示:
本小节将介绍LeNet网络和AlexNet网络:
(1)经典模型:LeNet
我们考虑这样一个问题,在手写数字识别(MNIST数据集,28*28大小)的问题中,我们如何使用神经网络完成分类工作呢?具体的过程是这样的:
- 每个图片展开为一维度向量(784个元素)
- 输入到全连接层中进行网络的训练
这种分类方法可行吗?确实可行,但是呢,存在很大的局限性
- 图像在同一列的像素点在向量空间可能相距过远,模式基本上不可能被传统的多层感知机识别到;
- 全链接的结构会带来过于复杂的模型和过高的存储开销;
LeNet网络的提出完美解决了上述2个局限,网络结构如下:
LeNet网络由2部分构成,卷积层块和全连接层块。卷积层块的基本单位是卷积层后接最大池化层,以完成空间模式的识别和降低对空间绝对位置的敏感性。全链接层就是将每一个小的样本展平(flatten),而后就是分类的过程。采用Sigmoid激活函数。
这是一种典型的CNN结构,明确卷积层块完成了特征提取的操作,全链接层完成了分类识别的功能(softmax)。参数共享(卷积核)大大减少了参数的规模,这是一个创举。
(2)历史突破:AlexNet
在LeNet之后的近20年里,深度学习、神经网络一度被其他的传统的机器学习算法取代,原因在于计算复杂,稍微大些的数据集合在计算资源上就不可以满足了。传统的图像分类研究的主要流程是:
- 获取图像数据集;
- 使用已有的特征提取函数生成图像的特征;
- 使用机器学习模型对图像的特征分类;
关键在于有标签的图像数据和 “好用” 的图像特征。姑且不说前者,后者就是一个很困难的事情,详情可见我的上一篇博客【Link】。
AlexNet网络的出现使得人们相信学习到的特征可以超过手工设计的特征,即便特征看起来无法解释。接下来我们比较这种网络与LeNet的区别:
- 网络结构的差距:
- 将Sigmoid激活函数修改为ReLu函数,Relu函数相对更加简单且它克服了Sigmoid函数在趋于极限时候的梯度消失问题;
- AlexNet采用了丢弃法(Dropout),控制了全链接层的复杂度;
- AlexNet引入了图像增强操作,比如引入了大量的图像增广,如翻转、裁剪和颜色的变化等;
AlexNet网络有8层网络结构,如上图所示,在卷积层和池化层的搭配上也与LeNet不同,建议读者仔细研究上面这幅图。值得一提的是,最开始的一层卷积核的大小是11 * 11LeNet要大,主要是LeNet针对的是固定输入大小的(28 * 28),而现在的图片很少有这么小的了,所以这是一个改进,再到后面的卷积核就为5 * 5、3 * 3的了,还记得我们之前说过卷积核的大小最好都是奇数吗?现实就是如此。这还说明的是AlexNet已经具有十多倍于LeNet网络的参数规模,好在经过很多年的发展,显卡等硬件的发展已经有了质的飞跃。
前面还提到了激活函数使用的是ReLu函数而非Sigmoid等函数(值域有界),Relu函数的值是没有一个范围的,所以需要对ReLu函数得到的结果进行归一化(Local Response Normalization):
另外值得一提的就是这里的池化操作是有覆盖的池化操作(Overlapping Pooling),很容易理解,就是步长小于池化层的大小,论文中说,这种池化操作更加不容易产生拟合的问题。
【3】使用重复元素的网络(VGG)
AlexNet的出色表现重新激发了学界对于神经网络的研究,“AlexNet是浅层神经网络和深层神经网络的分界线”。深即代表着对更复杂模式提取的能力,这是NN发展历史上大家的最初的认识,虽然并不总是那么准确,但是如何走向更“深”,还是大家追逐的目标。AlexNet并没有提供简单的规则以指导设计新的高效的网络,而本节要继续介绍的VGG却是其中一种!
VGG名字来源于发表这个论文的实验室Visual Geometry Group,它提出了可以通过构建重复使用简单的基础块来构建深度模型的思路。
(1)VGG块
VGG块的构成规律是:连续使用数个相同的填充为1、窗口的形状为3*3的卷积层后面接上一个步幅为2、窗口形状为2 *2的最大池化层。卷积层保持输入和输出的大小保存不变,而池化层则对其减半。
VGG网络在AlexNet的基础上演变而来,主要有以下几个改变:
- 去掉了LRN层,作者发现深度网络中LRN的作用并不明显,就删除了这一层;
- 采用更小的卷积核-3x3,Alexnet中使用了更大的卷积核,比如有7x7的,因此VGG相对于Alexnet而言,参数量更少;
- 池化核变小,VGG中的池化核是2x2,stride为2,Alexnet池化核是3x3,步长为2;
- 网络训练的方式也不同,VGG采用的是分段训练的方法。
以下是原作者提供的多个使用VGG块构成的网络版本,根据权值层的多少,分为VGG-11、VGG-13、VGG-16、VGG-19。
(2)VGG-19网络
模型其实不必做过多的介绍,下面给出一个可用的代码【Link】