卷积神经网络入门篇
1 引言¶
卷积神经网络(Convolutional Neural Networks),通常我们将之简称为ConvNets或者CNN,它是一种在图像识别和分类领域十分流行且行之有效的神经网络。目前,CNN网络已经作为一种非常重要且实用的工具成功应用于人脸识别、机器人和自动驾驶中的目标识别、信号灯识别等应用中。因此,学习卷积神经网络是以前十分有必要的事情。
然而,理解CNNs网络并且学会怎么使用CNN网络却不是一件容易的事情。本篇博客正是作为入门篇,对CNN网络如何针对图片进行工作展开介绍。不过,如果你刚开始接触神经网络算法,那我建议你还是先理解一下多层感知机是如何工作的,你可以参考这篇博客。
本文写作的初衷是看了一篇关于CNN网络的外文博客,感觉写的真的很不错,但毕竟是外文,感觉思维方式,行文习惯看着别扭,于是就打算翻译出来,在翻译过程中添加了很多自己的理解,如有误解,还请指出。
2 关于图像¶
从本质上说,每一张图片都可以表示为像素值构成的矩阵:
通道是一个常规术语,用于指代图像的特定组成部分。一张标准的图像一般具有三个通道:红色,绿色和蓝色。所以,对于图像,我们可以将它们想象成三个彼此堆叠的2d矩阵(每种颜色一个),每个像素值的范围为0到255。当然,如果是灰度图像,那么就只会有一个通道,也就只有一个2d矩阵,矩阵中每一个值元素值都在0到255之间,0代表黑色,255代表白色。
3 LeNet网络——最早的CNN网络¶
3.1 从LeNet开始¶
LeNet是最早提出的一类CNN网络,它的提出极大推进了深度学习的发展。1988年,经过多次迭代更新之后,LeNet的开拓者将他研究的这种神经网络结构命名为LeNet5。在那段时间,LeNet架构主要是被用来做字符识别,例如识别邮编和数字。
接下来,我们结合图3来对LeNet网络结构如何进行图像识别进行分析。近几年,有很多在LeNet结构基础上优化改进而来的网络结构被相继提出,这些网络的主要概念源自于LeNet,所以,理解LeNet网络是很有必要的,这将会使我们理解其他网络更加轻松。
图1所展示的卷积神经网络结构与最初的LeNet网络结构非常相似,它可以将输入的图像划分为四类:狗、猫、船、鸟(最初的LeNet网络主要是用来完成字符识别)。从图2可以明显看出,当输入一张包含船的图像时,网络可以正确得进行分类(判断为船的概率高达94%,其他3类概率就要低得多,概率总和为1)。
图1所示的CNN网络主要完成了4种操作:
(1)卷积
(2)非线性变化(relu))
(3)池化(或者说下采样)
(4)分类
这四种操作是每一个CNN网络的基础结构,所以,理解这四种操作对于整体理解CNN网络非常有必要。
3.2 卷积层¶
卷积层通过输入的方块数据对图像进行“扫描”,能够在保留像素空间关系的同时对输入图像展开学习,从而达到提取特征的目的。在上文中我们讨论过,每一张图像都可以看做是像素值组成的矩阵,我们通常用$w \times h \times c$的方式来描述输入矩阵size,其中$w$和$h$表示图像的长和宽,$c$表示通道数,有时候为了描述方便,当通道数为1时可以省略描述通道数。现在,假设有一张$5 \times 5 \times 1$的输入图像,为方便介绍,我们姑且假设该图像像素值只取0或1,如图3所示。
进行卷积运算时,需要初始化一个$n \times n \times c$的矩阵,这个矩阵称为滤波器或者卷积核(本文以滤波器称呼),如图4所示为一个$3 \times 3 \times 1$的滤波器。在大多数情况下,滤波器的长和宽是相等的,这么设置的原因是为了描述方面,实现起来也更加简单。另外,滤波器的通道数$c$必须与输入图像的通道数对应,卷积过程中,输入层有多少个通道,滤波器就要有多少个通道,但是滤波器的数量是任意的,滤波器的数量决定了卷积后特征图的通道数。滤波器中的各参数值会在网络训练过程中通过反向传播算法自行优化。
图2中$5 \times 5 \times 1$的输入图像与图3所示的$3 \times 3 \times 1$滤波器进行卷积运算过程如下图5动画所示。我们在绿色图像中滑动滤波器,每次滑动1像素的距离,这个距离我们称之为步长(stride),每一次滑动后,都计算滤波器每个元素与对应所覆盖位置像素值的乘积,然后将获得的9个乘积相加求和就是这一次滑动覆盖区域卷积运算的输出,当滤波器滑动到最右侧后,往下滑动一个步长,并回到最左侧继续从左往右滑动依次进行卷积运算,直到绿色图像中所有像素都被覆盖参与了卷积运算,最终,每一步的输出共同组成了右侧粉红色的矩阵。这个粉色矩阵就是完成的卷积操作后提取到的特征,通常,我们称之为特征图。
如果图像存在多个通道,例如最常见的的3通道图像(RGB通道),滤波器也必须有3个通道与图像的3个通道对应地进行卷积运算,每个通道都将产生一个矩阵,将三个矩阵相加输出才是最终的特征图。
在整个卷积运算过程中,有必要注意一下卷积操作的两大特征:局部连接和权值共享。
局部连接是指每一次卷积操作都只会对图片的一小部分局部区域进行卷积运算,这部分区域的大小称为感受野,感受野与滤波器大小是相对应的。例如用一个$3 \times 3 \times 1$的滤波器对一张$100 \times 100 \times 1$的图片进行卷积,那么感受野就是$3 \times 3$,每次只会对图片中的一个$3 \times 3$的区域进行卷积运算。
权值共享是指整张图片的所有区域都使用同一个滤波器进行卷积运算去生成一个新的特征,例如用一个$3 \times 3 \times 1$的滤波器对一张$100 \times 100 \times 1$的图片进行卷积,在图片内任意一个3*3的区域内都使用既定的9个卷积权值,不会去改变,这就是权值共享。如果要生成不同的特征,则使用不同的滤波器即可。
局部连接和权值共享操作生成新的特征时很好的利用了图片的局部相关性,同时也大大减少了参数量,降低过拟合风险,同时也提高了训练速度——这也是为什么在图像识别、目标识别等应用中卷积神经网络会这么盛行的原因。
另外,需要注意的是,对同一张图像,经过使用不同的滤波器进行卷积运算后输出的特征图也是有差别的。例如如图6所示的一张图像经过不同的滤波器进行卷积运算后的输出大相径庭:
下图7动画更加生动地展示了CNN网络是如何工作的:一个滤波器在一张图片上滑动进行卷积操作,结束所有滑动之后将会产生一个特征图;当用另一个滤波器进行滑动后,将会产生一个不一样的特征图,在我理解看来,这相当于用不同的角度对图像进行观察,产生不同视角下的特征图,获得的信息更加丰富(记得小学的时候学过一篇课文叫《画核桃》,说的是全班同学在不同的角度观察讲台上的核桃然后画出来,最终大家针对同一个核桃却画出来不一样的样子,我想CNN网络就是这个思想,从不同的角度观察输入图像,然后综合多个角度观察结果获得更加丰富的特征,所以性能更好),而且卷及操作也保留了原始图像像素在空间上的局部依存关系,在肉眼直观感受上我们可能觉得产生的特征图相比原图像更加模糊,但事实上,这种运算对于计算机来说可能确实十分有意义的。而且,一般来说,卷积层越多,网络提取复杂特征的能力就越强,例如在图像分类任务重,CNN网络可以通过第一次卷积进行边缘检测,然后在边缘检测基础上第二次卷积可以进行简单的形状检测,更进一步的,后续的卷积可以形状检测基础上进行一些更高层次的特征提取,例如人脸识别。
卷积层输出的特征图的大小由卷积深度、步长和padding三个参数决定,这三个参数都需要我们在构建网络之前确定好。
深度(Depth):深度是指在在一个卷积层中滤波器的数量。如图8所示,我们使用了3个不同的过滤器,因此卷积操作后将产生3个不同的特征图。我们可以将3个特征图看做是多个2d矩阵的堆叠,所以在这个卷积网络中,特征图的深度是3。
步长(Stride):步长是过滤器每一次在图像中滑动时跨过的像素数量,当步长为1时,每一每次只向右滑动一个像素,当一行卷积运算结束时,也只向下滑动一个像素。注意,步长越大,最终产生的特征图就越小。
Padding:当没有进行padding操作时,我们是不能以图像边缘像素为中心进行卷积运算的,为了解决这一问题,如图9所示,我们可以在图像的外围填充0,这相当于扩充了图像的size,这个填充0的操作就叫做padding。padding操作还有一个好处就是允许我们对特征图的大小进行控制。在实际应用中,也可以填充0以外的其它值,只不过应用的不多。
在滤波器size设置上,size也就越大,意味着一次卷积运算能够感知到的信息就越多,但参数量越大,模型越复杂。对于这个问题,我们可以用小滤波器做多次卷积运算来替代一次大滤波器的卷积运算。例如两次$3 \times 3$大小的卷积运算对用$3 \times 3$的滤波器产生一个特征图在进行一次卷积运算等价于一次$5 \times 5$的卷积运算但是参数量从25个降低到18个,3次$3 \times 3$的卷积运算等价于一次$7 \times 7$的卷积运算参数量从49个降低到27个。
多卷积运算多次卷积操作是通过连续多层卷积来完成的,而且在卷积层之间可以添加非线性操作层,增强模型的非线性表达能力,所以,通过多次小卷积运算来代替一次大卷积运算的方法是非常推荐的,也是目前的常用操作。
3.3 非线性变换¶
必须承认,在现实世界中绝大部分需要使用卷积神经网络去解决的问题都是非线性的,但是,我们在上文中介绍的所有有关的卷积操作无非都是矩阵的相加或相乘运算,都是线性运算,所以为进一步增强卷积网络拟合能力,需要在上文介绍的卷积操作的基础上添加非线性变化。在卷积神经网络中,进行非线性变换大多是通过引入relu函数实现的。relu函数会对卷积后输出的特征图中每一个元素进行非线性变换:对所有大于等于0的元素保持原样输出,对所有小于零的元素转换为0输出。relu函数图像如下图10所示。下图9所示是对上文图6中一特征图使用relu函数进行非线性变换。除了relu函数外,也可以通过tanh或sigmod等函数来进行非线性变换,但是却用得不多,且被证实,relu函数的性能是最好的。图11所示为上图3中输出的特征图使用relu函数进行非线性变换效果。
对于非线性变换操作,通常不会当做单独一层来处理,而是作为层与层(卷积层与卷积层、卷积层与池化层)之间的连接关节,在很多网络结构可视化图片中,并不会直接画出非线性变化,但是我们要明白,层与层都有必要存在非线性变化。
3.4 池化层¶
池化层又叫做下采样层,作用是可以在保留大部分重要信息的同时缩小卷积后输出的特征的的size。池化操作包括最大池化(max pooling)、平均池化(average pooling)和求和池化(sum pooling)等。以最大池化为例,假设窗口大小为2 x 2,那么每一次池化操作都是对特征图中2 x 2窗口中取最大的一个值作为当前输出,如果是平均池化,就是取当前2 x 2窗口中的4个元素的平均值作为输出。在是应用中,最大池化应用最大,也是表现最佳的,因为通常人们感兴趣的都是最明显的,也就是值最大的。图12展示了一个用2 x 2窗口对一个卷积以及relu非线性变换之后的特征图进行池化的例子。
与卷积操作一样,池化操作也有步长的概念,通过设置1以上的步长可以实现跳跃式的滑动,更大幅度地缩小输出特征图的sizze。另外,对于多通道的输入,在池化是需要分别进行池化操作,所以也会产生多数量的多个特征图输出,如下图13所示。
下图14展示了对图7所示的relu之后的特征图进行最大值池化和求和池化后的输出效果图。
最后,总结一下池化层的作用:
- 进一步缩小特征图的size,方便管理
- 减少参数数量和网络运算量,降低过拟合风险
- 对图像中细微的异常有更强的鲁棒性。由于采用最大池化和平均池化,图像中一些细微畸变不会对最终的输出产生太大影响
- 可以以相同的视角对图像所有位置进行探测,不会对信息有所遗漏
3.5 层的组合¶
到目前为止,我们已经介绍了卷积层、relu函数和池化层是如何工作的,这三中这个组件在任何CNN网络中都是最基础的组成部分。如图16所示的网络中有两组卷积-relu-池化的组合,在第二个组合中,我们使用了六个滤波器并由此产生了六个特征图,然后使用relu函数对6个特征图相继进行非线性变换和最大池化。
这些层最终的输出将作为输入传递到全连接层中。全连接层是一个使用softmax函数进行激活的多层感知机,从“全连接”这个名称中就可以看出,全连接层中相邻两层的神经元节点是两两之间完全连接的。经过卷积和池化之后的输出可以看做是输入图像的高层次特征,全连接层的作用就是在训练数据集的基础上利用这些特征对输入图像进行分类。关于全连接层,其结构和原理与传统全连接神经网络是一样的,这里不再过多叙述。
在整个卷积神经网络(卷积层+池化层+全连接层)中,卷积层和池化层起到从初始输入图像中提取特征的作用,而全连接层则是起到分类器的作用,应用提取到的特征完成对图像的分类等任务。
至于如何对分类进行判断,则是有全连接层的最后一个softmax层完成。softmax函数将会输出一个向量,向量中各元素为属于各类别的概率。如下图14所示,是一个4分类网络模型,输入的是一张类别标签为船的图像,经过卷积、池化和全连接层之后最终对应输出了一个包含4个元素的向量,即[0, 0, 1, 0],其中船所对应的值为1,代表该模型判断输入图像认定其类别标签为船的概率为1。在概率论上,1代表着百分百的肯定,如果分类正确,那就是是最完美的分类。
最后,完整总结一下卷积神经网络构建和训练步骤:
Step 1 :随机初始化所有滤波器参数和权重,设定网络中超参数,例如过滤器的个数、长宽、网络结构等等。
Step 2 :将一张张训练图像“喂”给网络,图像在网络中将依次完成前向传播的过程(卷积层->池化层->全连接层),最终输出一个概率向量。由于初始时所有参数、权重均为随机设置,所以,刚开始时网络判别后输出的准确率也很低(基本随机),例如上图14中输出为小船的概率为[0.2, 0.4, 0.1, 0.3]。
Step 3 :计算输出层输出概率向量与真实分类的总误差,计算公式如下: $$Total{\text{ }}Error = \frac{1}{2}\sum {{{(target{\text{ }}probalility - output{\text{ }}probability)}^2}} $$
Step 4 :使用反向传播算法来计算误差相对于网络中所有权重的梯度,并使用梯度下降法来更新所有卷积层参数和网络中各权重参数值,以最小化输出误差。在这个更新过程中,权重是根据该参数对误差的影响力来寄信调整的,当一次反向传播更新完成后,再一次输入同一图像时,输出概率现在可能是[0.1, 0.1, 0.7, 0.1],更接近目标向量[0, 0, 1, 0],这意味着网络已学会通过调整其滤波器参数和网络权重参数来正确分类该特定图像,从而减少输出误差。注意,诸如滤波器数量、大小,网络体系结构等参数在步骤1之前都已固定,在训练过程中不会更改,这一步骤仅更新滤波器矩阵中的值和网络连接权重。
Step 5 : 重复2-4步骤,指导网络满足指定终止训练条件,例如迭代次数达到指定数量或准确率达标。
经过上述步骤训练完成的CNNs网络中所有权重参数以及卷积层的参数都已经得到优化,能够对训练集中的图像数据进行很好的分类。然而,当一张新的图像(在训练集中没有出现过的)输入到训练好的CNNs网络中时,它将再次从输入层开始经历卷积-池化-全连接层等一系列前向传播的过程,最终输出一个属于各个类别的概率向量。当然,对于新图像在网络中的前向传播过程使用的将是训练完成后的权重以及卷积参数,如果在训练网络时使用的图像数据集足够大、数据足够漂亮,那么训练出来的权重和卷积参数在新图像上将会有更加完美的表现,最终输出的分类概率误差更小。
作者:奥辰
微信号:chb1137796095
Github:https://github.com/ChenHuabin321
欢迎加V交流,共同学习,共同进步!
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。