01 卷积
卷积是指在滑动中提取特征的过程,可以形象地理解为用放大镜把每步都放大并且拍下来,再把拍下来的图片拼接成一个新的大图片的过程。
2D卷积是一个相当简单的操作:
我们先从一个小小的权重矩阵,也就是 卷积核(kernel) 开始,让它逐步在二维输入数据上“扫描”。卷积核“滑动”的同时,计算权重矩阵和扫描所得的数据矩阵的乘积,然后把结果汇总成一个输出像素。
也就是说,【卷积操作后得到的矩阵中的每个元素】都是由两个矩阵乘积得来的
——这两个矩阵分别是【原矩阵在滑动过中分割出来的“大小等同于卷积核”的矩阵】和【卷积核(卷积核一般是一个3×3或者5×5的矩阵)】
卷积核会在其经过的所有位置上都重复以上操作,直到把输入特征矩阵转换为另一个二维的特征矩阵。
简而言之,输出的特征基本上就是原输入特征的加权和(权重是卷积核自带的值),而从像素位置上看,它们所处的地方大致相同。
那么为什么输出特征的会落入这个“大致区域”呢?这取决于卷积核的大小。卷积核的大小直接决定了在生成输出特征时,它合并了多少输入特征,也就是说:卷积核越小,输入输出的位置越接近;卷积核越大,距离就越远。
卷积的计算过程可以参考下面这张图:
02 填充Padding
边缘上的像素永远不会位于卷积核中心,而卷积核也没法扩展到边缘区域以外,所以输入图像的边缘被“修剪”掉了。
这是不理想的,通常我们都希望输入和输出的大小应该保持一致。
Padding就是针对这个问题提出的一个解决方案:它会用额外的“假”像素填充边缘(值一般为0),这样,当卷积核扫描输入数据时,它能延伸到边缘以外的伪像素,从而使输出和输入大小相同。
如下图为一个卷积核为3×3、有padding、Stride为1时的卷积过程:
03 步幅Stride
如果说Padding的作用是使输出与输入同高宽,那么在卷积层中,有时我们会需要一个尺寸小于输入的输出。那这该怎么办呢?这其实是卷积神经网络中的一种常见应用,当通道数量增加时,我们需要降低特征空间维度。实现这一目标有两种方法,一是使用池化层,二是使用Stride(步幅)
如下图为一个卷积核为3×3、有padding、Stride为2时的卷积过程:
Stride为2的卷积计算过程可以参考下面这张图:
滑动卷积核时,我们会先从输入的左上角开始,每次往左滑动一列或者往下滑动一行逐一计算输出,我们将每次滑动的行数和列数称为Stride。
Stride的作用是成倍缩小尺寸,而这个参数的值就是缩小的具体倍数,比如步幅为2,输出就是输入的1/2;步幅为3,输出就是输入的1/3。以此类推。
在一些目前比较先进的网络架构中,如ResNet,它们都选择使用较少的池化层,在有缩小输出需要时选择步幅卷积。
04 卷积核的选择
卷积是为了提取特征,选择不同的卷积核将会提取到不同的特征。
举几个例子(参考链接):
卷积核名称 | 卷积核形式 | 效果 |
---|---|---|
原图 | – | |
– | 0,1,2 2,2,0 0,1,2 | |
垂直边缘检测 | 1,0,-1 1,0,-1 1,0,-1 | |
水平边缘检测 | 1,1,1 0,0,0 -1,-1,-1 |
05 多通道卷积
上述例子都只包含一个输入通道。实际上,大多数输入图像都有3个RGB通道,而通道数的增加意味着网络深度的增加。
这里就要涉及到“卷积核”和“filter”这两个术语的区别。在只有一个通道的情况下,“卷积核”就相当于“filter”,这两个概念是可以互换的;但在一般情况下,它们是两个完全不同的概念。每个“filter”实际上恰好是“卷积核”的一个集合,在当前层,每个通道都对应一个卷积核,且这个卷积核是独一无二的。
参考
-
绝妙可视化:什么是深度学习的卷积?https://zhuanlan.zhihu.com/p/42090228
-
手写代码实现卷积操作(Python):https://blog.csdn.net/qq_41398808/article/details/97925070