c4w1_卷积神经网络

发布时间 2023-11-18 10:57:10作者: newbe3three

卷积神经网络

计算机视觉问题

计算机视觉(computer vision)是因深度学习而快速发展的领域之一,它存进了如自动驾驶、人脸识别等应用的发展,同时计算机视觉领域的发展还可以给其他领域提供思路。

计算机视觉应用的实例:图片分类(识别是不是一只猫)、目标检测(检测途中汽车行人等)、图片风格转移等等。

image

同时,计算机视觉领域也面临着一个挑战:图片数据转换为特征向量太大了。比如一张像素为1000*1000的图,转换成向量后有3百万的输入的特征,这就导致了

  • 神经网络的结构非常复杂,参数非常多。在参数如此多的情况下,没有办法获得足够的数据来防止过度拟合。
  • 庞大的计算量,没有足够的性能来计算这么多的参数。

因此为了处理这样大的数据量,需要进行卷积运算。卷积运算是卷积神经网络(convolutional neural network, CNN)中非常重要的一块。

卷积运算

边缘检测 Edge detection example

卷积运算是卷积神经网络的重要基石之一。

当给到你一个图片,希望让电脑搞清楚这张图片里有什么物体,可能首先需要做的是对图片进行边缘检测(Edge detection)。

边缘检测分为:垂直边缘(vertical edges)、水平边缘(horizontal edges)

image

实现垂直边缘检测,需要通过卷积运算来实现。比如检测一张6x6像素的灰度图片的垂直边缘,需要通过一个3x3的矩阵称之为过滤器(filter)或卷积核(kernel)。将原始图片与过滤器(filter)矩阵做卷积运算(convolution),得到一个4x4的图图片。具体的做法是,将filter矩阵贴在原始图片上移动(从左到右,从上到下),每次贴好后逐元素相乘之后求和,得到的结果为4x4矩阵对应的元素。

image

下面是一个gif展示了卷积运算的操作

image

下图是一个比较好理解的例子,通过卷积运算,原始图片中左右两侧为不同颜色的垂直边缘线,变成了4x4图像中间的空白,代表边缘所在的位置。(在比较大的图片中,边缘会比较明显而不是这种小图中空白柱子)

image

比较简单的理解,卷积核(filter)矩阵的两边的左右数字是相反的,如果图片中存在像素值相差比较大的两边(垂直边缘),那么原始图片上这两部分和卷积核的内积,差值就会比较大,那么在得到的新图片上颜色差距就会很明显,从而检验出来边缘。比较简单的理解,卷积核(filter)矩阵的两边的左右数字是相反的,如果图片中存在像素值相差比较大的两边(垂直边缘),那么原始图片上这两部分和卷积核的内积,差值就会比较大,那么在得到的新图片上颜色差距就会很明显,从而检验出来边缘。

更多边缘检测的例子

正边和负边检测(positive and negative edges),也就是从亮到暗和暗到亮的区别。

image

从亮到暗,检测后中间就是亮的;从暗到亮,检测后中间就是暗的。如果不在明暗变化的区别,可以输出矩阵的绝对值。

垂直边缘检测,就是用左右两边互为相反数。水平边缘检测就是上下互为相反数(矩阵转置了一下)

image

当然,filter的选择并不是固定的,还有Sobel滤波器、Scharr滤波器,其值在下面的途中。他们加强了中心点的权重,使算法更健壮(robust)。

滤波器中的值还可以设置为参数,通过模型训练来得到。这样,神经网络使用反向传播算法可以学习到一些低级特征,从而实现对图片所有边缘特征的检测,而不仅限于垂直边缘和水平边缘。

image

填充 Padding

为了构建深度神经网络,需要通过Padding对基本的卷积运算进行改进。那么为什么要填充呢?

  1. 原图片在于卷积filter进行卷积运算的时候变小了,比如上面例子中6x6的图片经过卷积运算后变成了4x4的图片。那么每经过一次卷积运算,图片就会缩小一次,最后可能缩小到1x1。
  2. 图片中边界像素的运算次数要小于中心像素,比如左上角的像素只参加了一次卷积运算,那么在一次又一次的卷积运算中,会丢图片边缘的信息。

为了解决上面的两个问题,就需要进行图像的填充(Padding)操作。具体的做法就是在图像周围填充一圈为0的像素。填充后的图片再进行卷积运算后其维度就会保持原始图片的大小。如下图所示,此时padding,p=1。

image

上述的填充操作一方面在卷积运算后保持了图像的大小,另一方面也使得边界像素参加了更多次运算,缓解了边缘信息丢失的影响。

考虑到是否填充,卷积运算分为两种

  • Valid convolutions:就是不填充
  • Same convolutions:填充之后,保持输入输出图像大小不变

需要注意的是通常在计算机视觉领域,卷积filter的维度大小都是取奇数。一来不会导致填充不对称,二来奇数维度的过滤器会有一个中心点,在计算机视觉领域会方便点。

填充像素的层数可以不是1,要实现Same convolutions,那么填充应该为\(p=\frac{f-1}{2}\)。其中\(f\)代表卷积filter的维度(步长=1)。

卷积的步长

在前面的例子中,每次filter都是移动一个格,也就是步长(stride)为1。在卷积运算中,允许移动的举例大于1。

对于一个nxn的图像,fxf的filter,填充p层,和步长为s,进行卷积计算后,其维度应该是\((\biggl\lfloor \frac{n+2p-f}{s}+1 \biggr\rfloor \times \biggl\lfloor \frac{n+2p-f}{s}+1 \biggr\rfloor)\),计算结果不为整数的,向下取整就好了,因为我们不计算filter没有完全落在图像上的情况。就下图这种情形。

image

关于卷积和和互相关(cross-correlation)的说明:严格来说,前面介绍的卷积操作和数学上定义的卷积有所差别。数学上的卷积,在卷积进行前要线对fiter进行旋转操作,然后在进行互相关操作(就上面说的逐元素乘积求和)。旋转操作后,满足结合律。

image

但是在深度学中,对卷积的定义就是上面提到的filter贴合好后,逐元素乘积求和(尽管在数学上这成为互相关)。但这并不会影响在编程中要实现的东西。因为毕竟filter中的数据都是后面要在网络中进行加权求和中学习的参数,所以不旋转影响不大,而且简化代码。

三维卷积

上面介绍的卷积都是应用在二维的灰度图片上,现在将卷积应用于三维上(比如RGB图片上)

RBG图片卷积运算的例子

image

RGB图片是通过三个颜色通道叠加在一起,也就是三个矩阵叠加,所以原始图片的大小就是6x6x3。对应的,用来做卷积运算的filter也要扩充到三维。要注意的是,在进行卷积运算时,原始图片的通道数(channel)要和filter的通道数一致。

这种情况下,运算的规则是,将这个三维的filter的三个channel对应贴合到原始图片的三个channel上,在每个通道上对应做卷积运算,再把三个通道运算的和作为整体的运算结果,写入到结果矩阵对应位置。

image

如果仅关注一种颜色的边界,如红色,则可以考虑把filter上对应绿色和蓝色的通道上矩阵全部设为0矩阵。如果RGB三种颜色的边界都考虑,那就这是filter三个通道的矩阵都正常设置。

如果想有多个过滤器怎么办?(就是同时检测垂直、水平或其他方向的边界)。可以应用多个filter(Multi filters是构建CNN的重要思想。)

image

总结一下维度,原始图片维度是\(n * n *n\),过滤器维度是\(f*f*n_c\),那么得到的结果维度应该是$(n-f+1) (n-f+1)n'_c \(,\)n'_c$是使用filter的个数。

最后要简要说明\(n_c\)这个参数可以称为channel(通道)或者是深度(depth)。

单层卷积网络

一个单层卷积神经网络例子如下

image

把我们前面学到的神经网络和多过滤器结合起来。这里一个filter就像是一层神经网络中的一个神经单元,每一个filter是对一个特征的检测,进行卷积操作就像是加上权重参数W。进行卷积运算之后加上偏置b,并应用非线性函数RelU,就得到了这一神经单元的输出,把这一层每个filter(神经单元)的输出结合起来就得到了该层网络(卷积层)的输出。

在上图的例子中,使用了两个filter也就是检测了两个特征,最终得到了4x4x2的输出。如果使用10个过滤器,堆叠在一起就会得到4x4x10的输出。

image

如上图的例子,每个filter都是3x3x3,那么通过卷积计算检测一个特征就需要\(3*3*3+1\)个参数(1个bais);那么相应的,10个filter就有280个参数。

对于卷积计算参数的个数是固定不变的,也就是无论输入的图片是多大,参数都是固定的是比较少的。这是也是卷积神经网络的一个特性可以避免过拟合。

总结卷积神经网络的符号(第l层为卷积层):

  • $f^{[l]} $:filter 的大小,就是矩阵的列数或行数,一般是行列式。

  • \(p^{[l]}\):填充的层数

  • \(s^{[l]}\):卷积计算的步长

  • \(n_C^{[l]}\):filter的数量

  • \(n_H^{[l]}*n_W^{[l]}*n_C^{[l-1]}\):输入图形的维度,其通道数与上一层filter数相等

  • \(n_H^{[l]}*n_W^{[l]}*n_C^{[l]}\):输出图形的维度,通道数与本层filter相等

  • 每层的filter的维度:\(f^{[l]}*f^{[l]}*n_C^{[l-1]}\),本层filter通道数应该与本层输入图片通道数一致

  • Activation:\(a^{[l]}\rightarrow n_H^{[l]}*n_W^{[l]}*n_c^{[l]}\),与本层输出图片维度一致,\(A^{[l]}\)的维度是\(m \times n_H^{[l]} \times n_W^{[l]} \times n_C^{[l]}\)

  • 权重参数W个数:\(f^{[l]}*f^{[l]}*n_c^{[l-1]}*n_C^{[l]}\),本层filter个数再乘以每个filter中元素个数

  • 偏置b个数:\(n_C^{[l]}-(1,1,1,n_C^{[l]})\)

  • 其中$n_H^{[l]}=\biggl\lfloor \frac{n_H{[l-1]}+2p-f{[l]}}{s{[l]}}+1 \biggr\rfloor $ \(n_W^{[l]}=\biggl\lfloor \frac{n_W^{[l-1]}+2p^{[l]}-f^{[l]}}{s^{[l]}}+1 \biggr\rfloor\)

简单卷积网络示例

下图为一个简单的CNN

image

  • 输入图片的维度是39x39x3

  • 最后输出的图片,可以将其展开(flatten or unroll)成一个向量,再交给logistic单元或softmax单元处理,实现分类

  • 像上图示例,图片的高度\(n_H^{[l]}\)和图片宽度\(n_W^{[l]}\)随着层数的增加逐渐减低,但是通道数\(n_C^{[l]}\)不断增加。许多卷积网络也都可以看到这种趋势(为什么这样处理,看到弹幕这么说)

典型的卷积网络构成

通常由三层

  • 卷积层,Convolution (CONV)

  • 池化层,Pooling (POOL)

  • 全连接层,Fully connected (FC)

    全连接层,指的是每一个结点都与上一层的所有结点相连,用来把前面几层提取到的特征综合起来。由于其全连接的特性,一般全连接层的参数也是最多的。https://zhuanlan.zhihu.com/p/552186222

池化层 Pooling Layers

https://zhuanlan.zhihu.com/p/545293528

除了卷积层以外,卷积网络还经常用到池化层(Pooling layer)。池化,也叫Pooling,其本质其实就是采样,池化对于输入的图片,选择某种方式对其进行压缩,以加快神经网络的运算速度。这里说的某种方式,其实就是池化的算法,比如最大池化或平均池化。

池化层的示意图(Max pooling):

image

池化的过程类似于卷积。

上图表示的就是对一个图片领域内的值,采用2x2的池化核,步长为2进行扫描,选择最大值输出,称为最大池化(Max pooling)。

最大池化Max pool,常用的参数为filter=2,stride=2,这样的参数处理的效果就是输出图片的高度、宽度减半,通道数不变。因为我们会对每层通道都进行池化操作。池化操作一般padding=0,池化的目的就是缩小图片提取特征,这和填充的目的相悖。

还有一种平均池化,和最大池化类似,就是求区域内的平均值作为输出结果。一般来将,最大池化用得比较多。

因为在池化操作中,池化filter只负责划分出某次池化操作需要的图片上的范围,filter没有数据计算,在训练过程中也就没有权重参数需要学习。

在通道这个维度上,每次池化操作都是独立的。

池化层的优点是:

  • 缩小了图片,但保留了图像的特征,加快计算的速度。
  • 池化层没有要学习的参数,因此在训练的过程中,可以在一定程度上防止过拟合的发生。

卷积神经网络示例

下面是一个用来识别手写数字的卷积神经网络架构(LeNet-5):

image

  • 一般把Conv Layer 和 Pooling Layer合在一起算一层,因为池化层没有参数训练。但是也有人分成两层
  • 常见的网络结构Conv ==> Pool ==> Conv ==> Pool ==> FC ==> FC ==> softmax
  • 在上图的例子中,把layer2得到的volume展开后,输入给全连接层。在FC3中,就像NN一样,有400个输入,120个神经单元。
  • 卷积神经网络中,图片的高度和宽度是在不断递减的,通道数是在不断增加的
  • 关于超参数的选择,尽量参考论文的经验。

整个例子的参数个数如下:

Activation shape Activation Size #parameters
Input: (32, 32, 3) 3072 0
CONV1(f=5, s=1) (28, 28, 6) 4704 156 (=5x5x6+6)
POOL1 (14, 14, 6) 1176 0
CONV2(f=5, s=1) (10, 10, 16) 1600 416 (=5x5x16+16)
POOL2 (5, 5, 16) 400 0
FC3 (120, 1) 120 48120 (=120*400+120)
FC4 (84, 1) 84 10164 (=84*120+84)
Softmax (10, 1) 10 850 (=10*84+10)
  • 池化层没有要学习的参数,全连接层要学习的参数最多。
  • 激活函数输出的值整体在下降

为什么要用卷积?

CONV Layer相比一般神经网络的全连接层的优势:

  • 参数共享(parameter sharing) 以上一节的例子为例,如果在第一层就用FC的话,参数可达4704x3070 + 4704个,这个数字已经膨胀到了1400万,而这还仅是训练一个只有32x32像素的小图片。 而CONV Layer只有156个参数。 参数共享为什么可行呢?一个feature检测器,即filter(比如垂直边界检测)在图片的一个地方适用,也很可能在图片的其他地方适用(在这一点上很像transfering learning或multi-task learning)。这种共享不仅在底层feature有用,也在高层feature有用(比如检测眼睛)。
  • 稀疏连接(sparsity of connections) 稀疏连接是指,输出中的每个单元仅和输入的一个小分区相关,比如输出的左上角的像素仅仅由输入左上角的9个像素决定(假设filter大小是3*3),而其他输入都不会影响。

卷积神经网络可以通过这两种机制减少参数,以便我们用更小的训练集来训练它,从而预防过度拟合。