卷积神经网络CNN(Convolution Neural Networks)在1998年由YannLecun提出,并迅速成为应用最广泛的神经网络结构。CNN对图像分割处理有着杰出的表现,在图像特征提取、图像分类等图像处理领域拥有巨大的潜能。
在前一篇文章中,详细介绍了BP神经网络的结构,其针对一维数据能够进行很好的训练与测试。
但是,在BP神经网络中,针对二维及以上的数据的处理存在着很严重的问题:
BP中使用了全连接层(Affine层)。全连接输入时,需要将数据拉平为一维数据,从而丢失了重要的空间信息——
以三维图像(长、宽、RGB通道)为例,空间上邻近的像素为相似的值,RGB的各个通道有着密切的关联性,相距较远的像素之间没有什么关联等空间信息。
CNN的出现很好的解决了这个问题:
CNN中将BP神经网络的“Affine层”替换为“卷积层-池化层”的结构形式,通过构建多层的卷积层自动提取图像上的特征。
卷积层可以保持数据形状不变,当输入数据为RGB图像时,卷积层会以三维形式接受数据,并同样以三维数据的形式将数据输出至下一层。
上图是一个BP网络结构,下图是一个CNN网络结构。可以看到部分Affine层被替换,从而避免了数据维数的减少。
排在前面的较浅的卷积层采用较小的感知域,可以学习到图像的一些局部特征(如纹理特征);
排在后面的较深的卷积层采用较大的感知域,可以学习到更加抽象的特征(如物体的大小,位置和方向等)。
一个完整的卷积神经网络的层级结构包括:
接下来,我们分别介绍各层的功能。
该层要做的处理主要是:对原始数据进行预处理。
其中包括:
去均值:把输入数据的各个维度都中心化为0,如下图所示,其目的就是把样本的中心拉回到坐标原点上。
归一化:幅度归一到同样的范围,同样如上图所示,即减少各维度数据取值范围的差异带来的干扰,比如,我们有两个维度的特征A和B,A的范围是0到10,而B的范围是0到1000,如果直接使用这两个特征是有问题的,因此要做归一化,即A和B的数据都变为0到1的范围。
PCA/白化:用PCA降维;白化是对数据各个特征轴上的幅度归一化。
CNN的核心是卷积层,而卷积层的主要功能就是进行卷积计算。接下来我们先了解一下什么是卷积运算。
因为我也没有认真学过卷积的数学原理(其实是本科没有认真听课QAQ),所以这里引用《Convolutional Neural Networks》这篇文章中的介绍,对深度学习中的卷积运算进行一个形象化的描述。
在上图中,移动的部分称为卷积核(kernel)——对应之前介绍过的权重。
将一个二维数据——比如一张黑白图像作为输入,每一个格子表示为一个像素,其中的数值代表这个像素的灰度,或称像素值。这样一个输入称为一个特征图。
kernel从左上角开始,将kernel在特征图上覆盖的像素值与kernel相应的的内核值相乘,然后将乘积相加。将结果放置在输出特征图中与kernel中心相对应的点。下图显示了第一步的示例。
kernel移动一个步幅(此处为一个像素),然后重复此过程,直到特征图中所有可能的位置都按如图所示进行过滤为止。
其计算公式如下,其本质是kernel所有权重与其在输入图像上对应元素之和。
但是,在上图中我们看到,新生成的特征图的行数和列数都缩小了。在有很多层的CNN网络中,这种情况会导致数据维数缩减。针对这个问题,我们可以对数据进行“填充”。
.
还是上面这个例子,我们可以对这个特征图进行填充——在矩阵周围填充0,随后kernel仍然从左上角开始进行卷积计算,这样即可保证输出数据与输入数据保持一致。其过程如下图所示:
上例中kernel是以步幅为1的方式进行移动,在很多情况中,步幅可以是更大的数值,如2,3等。
但是在改变步幅的同时,也要注意填充的大小,以保证输入输出形状一致。
在以上例子中,我们的数据是一张黑白图像——含有长、高、灰度数据,其形式为一个二维数据。
而一个普通的彩色图像除了包含长、高以外,还需要处理通道方向(RGB),因此是一个三维矩阵。当通道上有多个特征图时,会按照通道进行输入数据和kernel的卷积运算,并将三个通道对应元素的结果相加,得到输出。其过程如下图所示:
随后,我们用一个方块来代替矩阵,从而将图像扩展到广义的三维数据。
设一个数据通道数为C,高度为H,长度为W。
其Kernel的通道数为C,高度为FH,长度为FW。
但是我们看到,在经过一层卷积层之后,通道数变成了1,输出数据变为了2维数据,无法继续传递到下一层卷积层。为了能够继续传递至下一层卷积层,要使输出在通道方向上也拥有维度。为了达到这一目的,我们可以增加kernel的数量。
这样一来,输出数据同样保持了三维的形状,可以继续进行卷积计算。
在卷积神经网络的处理中,一般会将多个输入数据进行批处理——将N个输入数据同时进行计算,将N次的处理汇总成了1次进行。在各层之间传递的数据是4维数据,即 ( batch_num , channel , heigh t, weight )。
FN个kernel (FN,C,FH,FW)对数据(N,C,H,W)进行卷积计算,得到数据(N,FN,OH,OW),随后加上FN个偏置,即可得到N个输出数据,并将输出数据传递给下一层,这就是CNN的处理流。
得益于python对于矩阵的扩展性,不同大小的矩阵仍可以相加,因此偏置可以加到卷积运算的结果之中。
我们可以看到,输入数据为4维矩阵,输出数据也为4维矩阵,因此保留了空间上的特征,并按照Kernel的权值进行过滤噪声和提取特征。
以上就是卷积层完成的功能。
提取不同的特征,主要依靠kernel的权值大小及分布。
以下图为例,两个不同的Kernel,根据权值分布的不同,可以分别对图像的水平特征和垂直特征进行提取。
功能:把卷积层输出结果做非线性映射。
ReLU函数在上一篇文章中已经做过介绍,其具有收敛快,求梯度简单,因此应用于CNN之中。
池化是缩小高、长方向上的空间的运算。其主要目标是针对输入数据参数太多,而图像细节不利于高层特征的提取,而降低输入数据的特征空间,或者可以认为是降低输入数据分辨率。
池化层有MAX池化和Average池化等。
下面是MAX池化的一个例子:
在每个区域中提取最大值,并舍弃其余值,从而达到缩小特征空间的作用。
池化层有以下特征:
在卷积神经网络的最后,仍然需要全连接层进行分类。目前CNNs会采用多层全连接层,其连接方式与传统的BP神经网络的连接方式是一样的。
优点:
缺点:
3. 需要调参,需要大样本量。
4. 物理意义不明确(我们仍不知道那天我们所学习的卷积层到底提取的是什么特征。而且神经网络本身就是一种难以解释的“黑箱模型”)