为什么要用卷积神经网络
图像对于计算机来说就是像素点的集合。如果是灰度图像,就是一个二维矩阵,矩阵里面的值表示的是这个像素的灰度值。如果是彩色图片,如RGB,则是一个x*y*3的三维矩阵,每一个颜色channel都是一个二维矩阵,3个颜色构成一个三维矩阵。
为什么不用普通的fully connected network去处理图片呢?原因有两个,如果把一个三维矩阵变成一个一维数组作为输入,一方面会使图像的空间信息丢失。另一方面会需要很多很多参数。
卷积神经网络的结构
在普通神经网络中,每一层都是由一竖排的神经元构成,这些神经元与输入数据进行全连接,即能获取全部的输入数据。但是卷积神经网络(CNN)有不同的层。
下图是CNN的一个网络结构。
输入图像是一个32*32*3的矩阵,先进入第一个卷积层,经过32个5*5*3的 filter进行卷积计算后得到一个18*18*32的feature map。
然后进入第一个池化层,用一个2*2 的filter进行最大池化操作,得到一个10*10*32的feature map。
然后再进入第二个卷积层,经过48个5*5*32的filter后得到6*6*48的feature map。
然后进入第二个池化层,经过一个2*2的filter做最大池化操作,得到4*4*48的feature map。
再将得到的feature map 拍平成一个768*1的隐藏层,即常见的普通神经网络中的层。
在这之后会再经过一个普通隐藏层,两个隐藏层之间进行全连接。
最后输出层有2个元素,进行预测。输出层和隐藏层之间进行全连接。
从上面可以看到,CNN中常见的层主要有卷积层(convolutional layer),池化层(pooling layer),全连接层(fully connected layer)。
卷积层:
卷积层是用filter在输入图像上滑动,每次取一小块和filter长宽相同的局部区域和filter做卷积计算。如果图像的深度d大于1层的话,则分别在在每一层用filter和一块局部区域做卷积,然后将d个结果相加。得到的结果作为下一层的一个神经元。
我们知道,对计算机而言,图片是由一个一个像素(pixel)组成,另外,图像还有通道(channel),如彩色图像有R,G,B三个channel,灰度图像有一个channel。channel就是输入图像的深度,一个channel上的像素信息的尺寸就是输入图像的长和宽。所以输入图像是一个三维矩阵,包含长,宽和深度信息。
卷积核,也叫过滤器(filter)也是一个三维矩阵。在计算机视觉中,过滤器用来对图像进行过滤,可以获取图像的特征或者对图像进行去除噪声等操作。filter的长宽是自己设定的一个超参数,如可以设为5*5,filter的深度和输入图像的深度一致。
如下图,输入图像的长,宽,深度为32*32*3, filter的长,宽,深度为5*5*3,这里只有一个filter,经过卷积操作后,得到一个长,宽,深度为28*28*1的 activation map。
卷积操作是什么呢?卷积的公式是。关于卷积的详细介绍请自行搜索。
在CNN中,卷积的计算就是将filter中每一个元素与输入图像选中的局部区域中的每一个元素进行相乘再相加。
下面用一个例子说明一下卷积是怎么算的。
在下图中,filter只有1层,长宽为2*2,输入图像a深度也只有1层,大小为3*3. 将filter在a上滑动,获取和filter一样大小的局部区域,如a中红框区域。然后对w中的每一个元素和红框区域对应的每一个元素相乘再相加。如
计算的结果6作为下一层其中一个神经元的值。然后filter向右滑动,到达蓝色框处,进行卷积计算,得到1.
这时图片的一排像素已经扫描完毕,filter到第二行开头处,接着进行卷积计算,直到整个图片滑动完成。然后可以得到一个尺寸为2*2的输出。
在一个卷积层中,也可以有多个filter,每个filter可以提取图像的一类特征,多个filter就可以提取多种特征。以下是用了6个5*5的filter的卷积层,由于一个filter可以得到一个activation map,6个filter就可以得到6个activation maps。这些activation maps组成下一层的输入,即下一层的输入的长宽深为28*28*6.
进行卷积计算后,一般都会用一个激活函数加入非线性,激活函数一般选用ReLU函数,可以防止网络层次较深带来的梯度消失。
CNN中可能会有多个卷积+ReLU层,每层之间图像的尺寸和filter的尺寸,个数之间的关系如下图所示:
filter的深度和输入图像的深度一致,如下图中红框中的3.
第一层filter的个数是第二层图像的深度,同时第二层图像的深度又会是第二层filter的深度,如黄框中的6。
由上面的第一个例子我们可以看到一个3*3的原图进过2*2的filter后变成了一个2*2的图像。图像的大小减少了。如果CNN网络层次较多的话,图像就会减小得很快。但是这样可能会丢失掉很多有用的信息,如一些边和角的信息。为了让图片能保持原来大小,可以适用全零填充(zero-padding)
全零填充是指在原图像的周围填充一圈0,然后再进行卷积运算,如下图所示:
这样经过卷积运算后输出的图像大小为3*3.
当然也不一定要以全0填充,也可以用mirror或者extend方式填充,只是在实践中,以0填充存在一定的合理性。
当filter在输入图像上滑动时,可以选择以一定的步长(stride)进行滑动,比如下图中以步长为2滑动,得到的输出图像大小为2*2.
当向右滑动和向下滑动时,不一定要选择一样的步长,只是实践中大家一般都会选择一样的。
filter以不同的步长滑动的结果对比如下图所示:
通过上面的介绍我们知道输出图像的长宽由原始图像大小,filter大小,是否padding,滑动步长有关,他们之间的关系是:
输出图像的尺寸=[(原始图像尺寸+2*padding尺寸-filter尺寸)/ 步长] + 1
如果向右和向下的步长不一样,则长和宽分开计算。
下面举个例子看看:
我们从上文可知,输出图像的深度由filter的个数决定,为10.
长宽由计算公式求出,为32*32,所以输出图像的尺寸为32*32*10
我们知道下一层的一个神经元通过filter只能与输入图像的一个局部的区域进行连接。而不是像普通神经网络一样和全部的输入数据进行连接,所以它是局部连接的。
一个filter会在输入图像上滑动,会和多个局部区域进行计算,所以这多个局部区域是共享一个filter的参数的。这也是CNN的一个特点:参数共享,参数共享可以大大减少参数的个数。
下一层的神经元通过一个5*5的filter只能看到前一层5*5大小的局部区域。这个5*5的区域大小叫做感受野(receptive field)。
那么一个卷积层中有多少个参数呢,下面看一个例子:
输入图像尺寸为32*32*3,用10个5*5的filter进行卷积操作。参数的个数一共是760个。因为filter是三维的,要把长,宽和深度都算进去,另外每一个filter都有一个bias,也得加进去。
有的时候还会有尺寸为1*1的filter,那这样的filter的作用是什么呢,如下图所示
卷积计算完整例子
下面我们以一个例子来看看一个完整的卷积层的运算是怎么样的。在这个例子中,输入图像有3个通道,每个通道的大小为5*5,周围进行了全零填充。 对应于输入数据的3个通道,每个filter的深度也为3。这里一共有两个filter,filter w0 和w1,每个filter的尺寸为3*3*3。filter滑动的步长为2。根据计算公式,我们会得到输出图像的长宽为 [(5 + 2 * 1 - 3)/ 2] + 1 = 3,深度为filter的个数2,所以输出图像的尺寸为3*3*2。
filter 1的第一层和输入图像的第一层进行卷积计算,设得到的值为f1_1, filter1 的第二层与输入图像的第二层进行卷积计算,得到f1_2,同样可以得到f1_3, 再把这3层的结果相加并加上filter 1的bias的值,得到的结果作为输出图像的第一层中的神经元的值。
如f1_1 = 0 *(-1)+ 0 *(1)+ 0 * 0 + 0 * 0 + 0 * 1 + 1 * 0 + 0 * 0 + 2 * 1 + 2 * 1 = 4
f1_2 = 0 *(-1)+ 0 *(-1)+ 0 *(0)+ 0 *(0)+ 1 *(0)+ 0 * 0 + 0 * 0 + 0 * (-1) + 0 * 0 = 0
f1_3 = 0 * 0 + 0 * 0 + 0 * (-1)+ 0 * 0 + 2 * 1 + 1 * 0 + 0 * 1 + 1 * (-1) + 0 * (-1) = 1
f1_bias = 1
所以 output[0,0,0] = 4 +1 + 0 + 1 = 6
不同的卷积层获取的特征
在有多个卷积层的CNN网络中个,一般靠前的卷积层包含的filter个数较少,靠后的卷积层包含的filter个数较多,因为靠前的卷积层提取出来的是一些low-level 的features,如横线,竖线,斜线等,中间的卷积层会提取一些mid-level features,如corner,edge等,靠后的卷积层会提取一些high-level 的features, 如比较具象一点的特征。最后再由全连接层进行线性分类。
一般filter都会设计得小而深。
下面是从一个数据集提取出来的特征的可视化图:
卷积层总结:
池化层
卷积层后面有时会接一个池化层,池化层的作用是对图像进行向下采样,缩小图片的尺寸,可以减少参数个数,减少计算量。
常用的池化一般有最大池化和均值池化。 池化层也有filter,filter有尺寸,也会以一定步长移动。
下图是2*2的filter以步长2移动,进行最大池化。最大池化是指对于输入图像中和filter一样尺寸的局部区域,选择所有元素的最大值作为下一层神经元的值。
均值池化则是指取这个区域内的平均值作为下一层神经元的值。
池化只会改变图片的长和宽,不会改变图像的深度。
池化层总结:
全连接层
当所有的 conv + ReLU + pooling做完之后,会把输出的神经元拍平,然后用全连接层和后面的层相连,然后再与输出层相连,得到预测的分类或者数值。
下一节讲CNN的反向传播及代码实现
参考:
1. 斯坦福cs231n 课程:https://www.youtube.com/watch?v=bNb2fEVKeEo&list=PL3FW7Lu3i5JvHM8ljYj-zLfQRF3EO8sYv&index=5
2. CNN介绍:https://pqpo.me/2019/05/29/learn-vgg-cnn/
3. CNN介绍:https://www.zybuluo.com/hanbingtao/note/485480
4. CNN 可视化:http://shixialiu.com/publications/cnnvis/demo/
5. CNN BP: https://www.jefkine.com/general/2016/09/05/backpropagation-in-convolutional-neural-networks/
6. http://andrew.gibiansky.com/blog/machine-learning/convolutional-neural-networks/