第一章 手把手教你深度学习和实战-----线性回归+梯度下降法
第二章 手把手教你深度学习和实战-----逻辑回归算法
第三章 手把手教你深度学习和实战-----全连接神经网络
第四章 手把手教你深度学习和实战-----卷积神经网络
第五章 手把手教你深度学习和实战-----循环神经网络
卷积神经网络是深度学习中一个比较重要的知识点,目前深度学习分为三大块:大数据与数据挖掘、计算机视觉、自然语言处理。计算机视觉中深度学习算法几乎都用到了卷积神经网络来作为图像的特征提取,因此卷积神经网络在深度学习中的地位是不可撼动的。
但是卷积神经网络在1998年就被提出了,一直没有被广泛利用的原因是那时候计算机的性能比较低,卷积神经网络的性能很难被发挥。直到2012年AlexNet取得ImageNet比赛的分类任务的冠军,并且分类准确率远远超过利用传统方法实现的分类结果,从此深度学习的发展一发不可收拾。
既然卷积神经网络多用于图像的特征提取,在进行卷积神经网络模型的学习之前要搞清图像在计算机中的本质是什么,这样才有利于去学习卷积神经网络。目前比较流行的图片格式有灰度和RGB格式。
灰度图就是我们常见的黑白图像,如下图是一个黑白图像,这是一个数字8,仔细观察图片可以发现,这个图片的边缘貌似是由一个又一个小方格所组成的,事实上这个图片整体就是用一个又一个小方格所组成的。由于这个图像的高度为24,宽度为16,因此这个图片是由24*16一共384个小方格所组成的。
但是从图中可以看到有黑色、白色、灰色的地方,同时灰色的程度还不尽相同。图像中的每一个小块都代表一个像素,每一个小块都有一个像素值,这些像素值表示像素的强度,像素值的大小范围为0到255,其中0为黑色,255为白色,图像越深的地方说明像素值越接近0,图像越浅的地方说明像素值越接近255。因此在计算机中图像保存为一个数字矩阵。具体就如下图所示:
灰度图是由一个数字矩阵表示的,但是我们生活中更加常见的彩色图是由3个数字矩阵表示的。
不知道大家在生活中观察到这样的情况,就是有时候不小心把水溅到了手机屏幕或者电视屏幕上,通过水珠可以观察到一个又一个很小的小方格,这些方格有不同的颜色,但是只有红色、绿色和蓝色。初中的时候学习物理的时候知道,这3个颜色称为3原色,可以按不同的比例生成各种颜色。如下图所示:
因此,计算机表示彩色图的时候是用3个数字矩阵表示的。具体形式如下图所示:
1个用于显示红色的矩阵,矩阵的中的数值大小范围也是在0到255,当数值越接近0的时候红色的表示就越深,当数值越接近0的时候,红色的表示就越浅。
1个用于显示绿色的矩阵,矩阵的中的数值大小范围也是在0到255,当数值越接近0的时候绿色的表示就越深,当数值越接近0的时候,绿色的表示就越浅。
1个用于显示蓝色的矩阵,矩阵的中的数值大小范围也是在0到255,当数值越接近0的时候蓝色的表示就越深,当数值越接近0的时候,蓝色的表示就越浅。
这些像素数值在0到255之间,其中每个数字代表像素的强度,所有这些通道矩阵叠加在一起就变成了三通道图像,当图像的形状加载到计算机中时,像素矩阵为H×W×3。其中H是整个高度上的像素数量,W是整个宽度上的像素数,3表示通道数。
首先,来看一下卷积神经网络的整体结构,如下图所示,相对于全连接神经网络,卷积神经网络中出现了卷积层和池化层,输入卷积神经网络中的数据特征图通过卷积运算和池化运算,将其中的有效特征提取出来输入到全连接层,并对数据进行分类或者预测。
卷积神经网络出现了一些特有的术语,比如填充和步幅等。之前对图片在计算中本质进行了讲解,图片在计算机中就是一个数字矩阵,而卷积神经网络的输入就是这样的一个数字矩阵,输入的数据的格式应该是CHW,这里的C就是数据的通道数,以之前灰度图和彩色图为例灰度图的C就是1,彩色图就是3(需要注意的是:这里的C不一定是1或者3,通过卷积计算后特征图的通道会变化,同时输入数据不一定是图片数据,那么构造的数据特征图的通道也不一定是1或者3);同时这里的H就是数据矩阵的高,W就是数据矩阵的宽。
在全连接神经网络中,相邻的神经元全部连接在一起,因此一个神经网络层呈现长条状,但是输入的数据是图像这样具有3维形状的数据的时候,全连接神经网络的处理是将数据拉平为一维的状态。如下图所示: 像图像这样的3维形状的数据中应该含有重要的空间信息。比如,空间上相邻的地方像素值应该是相似的值、RGB通道之间分别有着密切的关联性,但是相距比较远的像素之间的关联性比较低。但是全连接层会忽视形状,将全部的信息作为相同的神经元处理,因此无法利用与形状相关的信息。
但是卷积神经网络中的卷积层可以保持形状不变,当输入的数据是图像的时候,卷积层会以3维的数据形式接受数据,同样以3维的形式输出到下一层,因此相对于全连接神经网络,卷积神经网络可以比较好的理解空间形状的数据。
卷积神经网络的核心就是存在卷积运算的卷积层,卷积运算相当于图像处理中的滤波运算,因此卷积核又被称之为滤波器。下面通过一个具体的例子来理解卷积运算。 如上图所示,输入的数据是一个具有空间形状的数据,卷积核也是一个具有长高方向的维度,假设用(height,width)表示数据和卷积核的形状,在本例中数据和卷积核的形状分别为(3,3)和(2,2),输出数据的大小为(2,2)。但是要注意的是,卷积核的长和高一般是一样大小的(当然也是可以用不一样大小的)。
现在来具体解释一下卷积运算的运算过程。对于输入数据,卷积运算以一定间隔来滑动和卷积核大小一样的窗口的数据和卷积核进行对于位置相乘并求和。如图所示,卷积核的窗口大小为22,那么从数据的左上角取一块和卷积核一样大小的数据块和卷积核对应的位置相乘,最后将数据求和。这里的具体计算如下式所示: 0 ∗ 0 + 1 ∗ 1 + 3 ∗ 2 + 3 ∗ 4 = 19 0 * 0+1 * 1+3 * 2+3 * 4=19 0∗0+1∗1+3∗2+3∗4=19 此时再将这个窗口向右滑动一步,如图所示,取该窗口中的数据和卷积核进行卷积运算,并得出对应值。此时窗口已经不能再向右边滑动了,那么窗口向下滑动一步,继续重复上述窗口从左到右滑动取数据和卷积核进行对应数据相乘最后求和的步骤。具体如图所示: 在全连接神经网络中,神经网络有两种参数,一种是权重参数、一种是偏置参数。在卷积神经网络中,卷积核就是卷积神经网络网络的权重参数,当然卷积神经网络中也是存在偏置参数的。如图所示,偏置参数的形状通常是一个11,这个偏置的参数值会被加到通过卷积运算的所有元素上。具体如图所示:
填充是卷积运算中经常会用到的处理,其操作步骤就是对输入数据周围填入固定的数据(通常这个数据为0)。如图所示: 如上图例子中,在一个输入为(3,3)大小的周围填充一圈为0的数据,这时输入的数据大小转变为(5,5),因此填充的幅度为1。利用填充好的数据和大小为(2,2)的卷积核进行卷积运算,得到一个大小为(4,4)的输出数据。当然这个填充的幅度也可以设置为比1大的任意整数。
使用填充的主要目的是调整输出数据的大小。比如,输入的数据大小为(3,3),卷积核的大小为(2,2),进行卷积运算得出的输出数据大小为(2,2);当对输入数据进行幅度为1的填充,此时输入的数据的大小为(5,5),经过卷积运算输出的数据大小就为(4,4)。如果不填充数据的话,输入数据大小为(3,3),输出数据大小为(2,2),相当于输出数据比输入数据大小缩小了1个元素,如果在一个卷积神经网络中有多个卷积层,需要进行多次的卷积运算,如果每次进行卷积运算都会缩小空间,那么在某个时刻可能输出的大小为(1,1),这时候就无法进行卷积运算了。因此为了避免这样的情况,利用填充操作可以解决上述出现的问题,保持输出数据的空间大小不变或者变大。
利用卷积核在输入数据上进行滑动的间隔称为步幅。上述的所有例子中的步幅都是1,这里的步幅是可以设置的,和填充的幅度一样,可以设置为大于1的整数。如下图,当步幅为2的时候进行的卷积运算的运算结果如图所示:
如上图所示,输入数据大小为(4,4),卷积核的大小为(2,2),数据填充为0,步幅的大小为2;步幅为2的计算过程为,卷积核在数据左上找到一块和自己大小一样的数据块进行卷积运算,然后再向右滑动两个像素大小进行卷积运算,直到卷积核不能向右滑动为止,然后再在数据的最左边向下滑动2个步幅重复上述的卷积运算操作,直到数据进行完卷积操作为止。具体上图相对来说比较直观的展示出步幅为2的卷积运算的过程。
从图中可以很轻易的得到通过卷积运算最终的输出的大小为(2,2),因此很显然增大步幅后,输出的大小会变小。而增大填充后,输出的大小会变大。那么有没有一套来计算输入数据和输出数据中的关系呢?答案是显然有的。
假设输入大小为(H,W),卷积核大小为(FH,FW),输出数据的大小为(OH,OW),填充为P,步幅S。
计算的公式如下: O H = H + 2 P − F H S + 1 O W = W + 2 P − F W S + 1 \begin{gathered} O H=\frac{H+2 P-F H}{S}+1 \\ O W=\frac{W+2 P-F W}{S}+1 \end{gathered} OH=SH+2P−FH+1OW=SW+2P−FW+1 现在利用公式来计算上述的关于填充的案例和步幅的案例。
关于填充案例的计算如下: O H = 3 + 2 ∗ 1 − 2 1 + 1 = 4 O W = 3 + 2 ∗ 1 − 2 1 + 1 = 4 \begin{aligned} &O H=\frac{3+2 * 1-2}{1}+1=4 \\ &O W=\frac{3+2 * 1-2}{1}+1=4 \end{aligned} OH=13+2∗1−2+1=4OW=13+2∗1−2+1=4 很显然和最终得出的结果是吻合的。
步幅案例的计算如下: O H = 4 + 2 ∗ 0 − 2 2 + 1 = 2 O W = 4 + 2 ∗ 0 − 2 2 + 1 = 2 \begin{aligned} &O H=\frac{4+2 * 0-2}{2}+1=2 \\ &O W=\frac{4+2 * 0-2}{2}+1=2 \end{aligned} OH=24+2∗0−2+1=2OW=24+2∗0−2+1=2 很显然这里的计算也是和最终图中的结果是吻合的。
这里需要注意的是,步幅和填充是可以自己设定的,但是可能会出现最终的计算结果不是整数的情况,会导致最后的程序的运行出现报错,这样的情况要尽量的避免,当然有的深度学习框架会进行四舍五入,不进行报错进行继续运算。
上述的例子中的数据都是以通道数为1来进行讲解的,但是图像除了通道数为1的灰度图还有通道数为3的彩色图,同时卷积运算也可以改变输入特征的通道数,使输出特征变成多通道的特征图;因此多通道的数据不仅仅要考虑高和长方向之外,还需要处理通道方向。因此通道方向有多个特征图时,按通道进行输入数据和卷积核进行卷积运算,并将结果相加,从而得到输出特征图。这里,我们用一个3通道的数据来演示多通道数据的卷积运算的过程。
如上图所示,输入数据是一个通道数为3,形状大小为(4,4)的特征图。由于输入通道为3,卷积核的通道必须要和输入数据的通道一样,同时每个通道的卷积核的形状大小也必须一样,因此这里设置的卷积核的通道数为3,形状大小为(3,3)。将不同通道的特征图和对应通道的卷积核进行卷积运算,并将最终的计算结果相加;相比较于单通道卷积运算,这里多了一步将不同通道的卷积运算结果相加。因此如图所示,最终的输出的特征图的通道大小为1,形状为(2,2)。
上述的过程可以用长方体来进行思考,可能会更加的生动形象,如图可以很形象的将上述的多通道数据的卷积过程描述出来。
其中,数据的可以表示为(通道,高,宽)。因此图中输入数据的形状为(C,H,W),卷积核的形状为(C,FH,FW),输出数据的形状为(OH,OW)。
当然,当卷积核只有一个的时候,输出的特征图的通道数就为1。当时在卷积运算的时候希望输出的特征图为多通道,这时候就需要多设置几个卷积核(就是多设置几组权重)。
如图所示,当输入的数据大小为(C,H,W)的时候,卷积核一共有FN个且大小为(C,FH,FW)。因此输出的特征图的大小为(FN,OH,OW)。 当然卷积神经网络中不仅仅有权重参数(卷积核),还有偏置参数,当通道数为C的时候,具体的计算过程如下图所示:
当输入的数据大小为(C,H,W)的时候,卷积核一共有FN个且大小为(C,FH,FW)。经过卷积运算后输出的特征图的大小为(FN,OH,OW),因此偏置的通道数需要和输出特征图的通道数一样,因此偏置的大小为(FN,1,1)。将偏置和输出特征图进行像素相加,最后得到的输出特征图的大小为(FN,OH,OW),因此加上偏置是不改变输出特征的形状的,只改变输出特征数值的大小。
池化层是缩小特征图空间的运算,池化层和卷积层的不同是,特征图是需要和卷积核进行卷积运算,因此卷积层是有需要进行参数的学习的,通过前向传播确定误差,再通过反向传播进行参数的更新。但是池化层只是从目标区域中提取最大值或者平均值,所以是没有需要学习的参数的。
池化层所要做的事情是在目标区域中提取像素的最大值,或者计算平均值。因此池化层的操作就有了两类操作,分别叫最大池化和平均池化,现在来具体看看池化操作是怎么进行了。
如下图所示,是最大池化的计算过程:
如上图所示,输入数据是一个(4,4)大小的特征图,利用目标区域为(2,2)大小在特征图上进行从左到右,从上到下在目标区域内取最大值。同时池化层的步幅大小一般和池化的窗口大小一样,比如该样例中的池化窗口大小为(2,2),那么此时的步幅就设定为2,通过不断的计算一个(4,4)大小的特征图最终转变成(2,2)的计算图。当然池化层的输入特征图和输出特征图之间的关系也可以利用上述的卷积层的输入输出计算公式来计算,只不过卷积核大小变成池化窗口大小而已。
例如该案例的计算如下: O H = 4 + 2 ∗ 0 − 2 2 + 1 = 2 O W = 4 + 2 ∗ 0 − 2 2 + 1 = 2 \begin{aligned} &O H=\frac{4+2 * 0-2}{2}+1=2 \\ &O W=\frac{4+2 * 0-2}{2}+1=2 \end{aligned} OH=24+2∗0−2+1=2OW=24+2∗0−2+1=2 最终的计算结果和图中最终得出的结果是吻合的。
除了最大池化还有平均池化操作,顾名思义,平均池化就是将目标区域中的值进行平均求和。
如下图所示,是平均池化的计算过程: 平均池化的具体过程就不再赘述,上图很清晰的展现了计算的过程。但是在图像识别领域,主要使用的还是最大池化比较多。
池化还有一些需要注意的地方:
输入的数据不仅有长和高,还有通道这一概念。但是池化层的运算不会对输入特征图的通道进行改变,池化操作是按通道独立进行计算的。
池化层对对微小的位置变化具有鲁棒性,使模型更加的健壮。当输入特征数据发现微小的变化的时候,输出的特征图的结果仍然是一样的,具体如下图所示:
红框中的数据的位置发生了变化,但是返回的结果是一样的,很显然池化操作是只关注局部特征,对整体的细微变化并不敏感,这在图像识别领域是一个很好的操作,因为一个图像我们只关注其中对我们判断有用的点,而不需要对全局每个特征都进行判断。
卷积神经网络是深度学习中极其重要的神经网络模型,在此基础上发展成计算机视觉领域,目前计算机神经有图像分类、目标检测、图像分割等分支,其落地项目也很多。其中大部分算法都是在卷积神经网络的基础上进行改进而成,而想学习好卷积神经网络需要配合各种网络模型图去理解他,本文也是在大量模型图的基础上对卷积神经网络进行讲解,方便大家进行理解和学习。