机器学习面试题汇总与解析——卷积与池化

本章讲解知识点

    1. 什么是卷积
    1. 深度学习中的卷积层
    1. 池化的概念
    1. 详细讲解池化
    1. 反卷积与反池化
    1. 卷积神经网络反向传播推导


  • 本专栏适合于Python已经入门的学生或人士,有一定的编程基础。
  • 本专栏适合于算法工程师、机器学习、图像处理求职的学生或人士。
  • 本专栏针对面试题答案进行了优化,尽量做到好记、言简意赅。这才是一份面试题总结的正确打开方式。这样才方便背诵
  • 如专栏内容有错漏,欢迎在评论区指出或私聊我更改,一起学习,共同进步。
  • 相信大家都有着高尚的灵魂,请尊重我的知识产权,未经允许严禁各类机构和个人转载、传阅本专栏的内容。

  • 关于机器学习算法书籍,我强烈推荐一本《百面机器学习算法工程师带你面试》,这个就很类似面经,还有讲解,写得比较好。

  • 关于深度学习算法书籍,我强烈推荐一本《解析神经网络——深度学习实践手册》,简称 CNN book,通俗易懂。



1. 什么是卷积

1.1 卷积定义

什么是卷积

卷积是很重要的概念,这里我们一定要讲讲。在数学中,称 (fg)(n)(f*g)(n)f,gf,g 的卷积,

其连续的定义为:

(fg)(n)=f(τ)g(nτ)dτ(.)(f*g)(n) = \int_{-\infty}^\infty f(\tau)g(n-\tau)d\tau \\ \tag{.}

其离散的定义为:

(fg)(n)=τ=f(τ)g(nτ)(.)(f*g)(n) = \sum_{\tau=-\infty}^\infty f(\tau)g(n-\tau) \\ \tag{.}

在后面的图像处理中,都是离散处理,所以我们举个例子来理解一下卷积。比如我有两枚骰子,都投出去,问投掷出来的点数和为 4 的概率是多少?

这里问题的关键是,两个骰子加起来要等于 4,这正是卷积的应用场景。

我们把骰子各个点数出现的概率表示出来:

img

那么,两枚骰子点数加起来为 4 的情况有:

img
img
img

因此,两枚骰子点数加起来为 4 的概率为:

f(1)g(3)+f(2)g(2)+f(3)g(1)(.)f(1)g(3)+ f(2)g(2)+ f(3)g(1) \\ \tag{.}

符合卷积的定义,把它写成标准的形式就是:

(fg)(4)=m=13f(4m)g(m)(.)(f*g)(4) = \sum_{m=1}^3 f(4-m)g(m) \\ \tag{.}

可以看出,卷积其实就是规定了一个运算的规则


图像中的卷积运算

有了上面的基础后,我们再来讲讲图像中的卷积运算,例子一个有噪点的原图,可以把它转为一个矩阵:

img

因为图像有噪点,我想平滑一下图像,图像中的噪点属于高频信号,高频信号,就好像平地耸立的山峰,看起来很显眼。平滑这座山峰的办法之一就是,把山峰刨掉一些土,填到山峰周围去。用数学的话来说,就是把山峰周围的高度平均一下

然后用下面这个平均矩阵来平滑图像。

img

记得刚才说过的算法,把高频信号与周围的数值平均一下就可以平滑山峰。比如我要对点 a1,1a_{1,1} 进行卷积,那么我们从矩阵中取出 a1,1a_{1,1} 附近的点组成矩阵 ff,和 gg 进行卷积运算后,再填回去。

img

要注意一点,ff,虽然和 gg 同维度,但下标有点不一样:

img

用一个动图来说明下计算过程:

img

写成卷积公式就是:

(fg)(1,1)=k=02h=02f(h,k)g(1h,1k)(.)(f*g)(1,1) = \sum_{k=0}^2 \sum_{h=0}^2 f(h,k)g(1-h,1-k) \\ \tag{.}

从这个例子可以很好的看出来,卷积就是一个运算规则

这样相当于实现了 gg 这个矩阵在原图上的滑动(准确来说,下面这幅图把 gg 这个矩阵旋转了 180°)

img

1.2 卷积的作用

卷积层通过应用一组可学习的卷积核(也称为滤波器)对输入进行卷积操作,以提取输入数据的局部特征。这些卷积核在整个输入上滑动,每次进行局部感知和特征提取。卷积操作的输出称为特征图(Feature Map)

以下是卷积层的一些关键概念和操作:

  • 卷积核(滤波器):卷积层使用一组卷积核来提取输入数据的特征。每个卷积核是一个小的可学习的权重矩阵,它通过卷积操作与输入数据进行相乘和求和,生成特征图。

  • 卷积操作:卷积操作是将卷积核与输入数据进行逐元素乘积,并对结果进行求和。这个操作可以捕捉输入数据的局部空间结构,提取局部特征。

  • 步幅(Stride):卷积操作中的步幅定义了卷积核在输入数据上滑动的距离。较大的步幅会减小输出特征图的尺寸,而较小的步幅会保持更多的空间信息。

  • 零填充(Zero Padding):零填充是在输入数据的周围添加零值元素,以扩展输入数据的尺寸。它可以帮助保持输出特征图的大小,并减小边缘像素的影响。

  • 激活函数:卷积层通常在卷积操作后应用非线性激活函数,如ReLU(Rectified Linear Unit),以引入非线性变换,并增加网络的表达能力。


什么是卷积核(kernel)

卷积使用“kernel”从输入图像中提取某些“特征”。kernel 是一个矩阵,可在图像上滑动并与输入相乘,从而以某种我们期望的方式增强输出。看下面的 GIF。

img

上面的 kernel 可用于锐化图像。但是这个 kernel 有什么特别之处呢?考虑下图所示的两个输入图像。第一个图像,中心值为 3 * 5 + 2 * -1 + 2 * -1 + 2 * -1 + 2 * -1 =7,值 3 增加到 7。第二个图像,输出是 1 * 5 + 2 * -1 + 2 * -1 + 2 * -1 + 2 * -1 = -3,值 1 减少到 -3。显然,3 和 1 之间的对比度增加到了 7 和 -3,图像将更清晰锐利这就相当于提取了物体边界特征

img
img

常用卷积核:Canny 算子、拉普拉斯算子、高斯算子。


为什么卷积核(kernel)可以提取物体特征

我们举例个图片:

img

对于图像处理,我们一般是选择局部的,比如处理尾部上面的一块曲线

img

我们用红色框标注,其对应的矩阵假设为:

img

卷积核,卷积层主要是提取特征的关键,因为它是你需要的特征的过滤器;

上图中,老鼠尾巴,就是我们要提取的特征,那么我们的卷积核应该设为:

img

我们将卷积核作用于图片,直接进行卷积运算,我们发现对于识别的特征计算出来的值非常大;

img

对于上面的卷积:

(50*30)+(50*30)+(50*30)+(20*30)+(50*30)=6600;

对于不能识别的特征,计算的值非常小,如下:

img

对于不能识别的特征,曲线的卷积核与其卷积后的到的值为0。

这样我们就通过卷积核提取到物体的特征了


2. 深度学习中的卷积层

2.1 深度学习中的卷积层

上面我们讲的卷积核都是手动设计的,手工设计特征面对复杂物体的时候就力不从心了。传统的机器学习都是手工设计特征,甚至发展为特征工程。而深度学习则不一样,卷积核不需要手工设计,而是在网络训练过程中自动更新参数,自动提取特征,这就是深度学习大大超越传统机器学习的重要原因。

卷积层(convolution layer)是卷积神经网络中的基础操作,作用是提取图像中的目标的特征。卷积时,卷积核滑动步长为 1,从上图可以看出,一个 5x5 的矩阵经过 3x3 的卷积核后,生成的特征图为 3x3。不过多数情况,为了保证特征图不变,我们会进行 padding 操作,padding 操作是对目标矩阵的最外面一圈填充 0,这样就保证生成的特征图大小和原矩阵一样大了

img

与之类似,若三维情形下的卷积层 ll 的输入张量为 xlRHl×Wl×Dl\mathbf{x}^l\in \mathbb {R}^{H^l \times W^l \times D^l},该层卷积核为 flRH×W×Dl\mathbf{f}^l\in \mathbb {R}^{H \times W \times D^l}三维输入时卷积操作实际只是将二维卷积扩展到了对应位置的所有通道上(即 DlD^l),最终将一次卷积处理的所有 H×W×DlH \times W \times D^l 个元素求和作为该位置卷积的结果,如图,图左卷积核大小为 3x4x3,图右为在该位置卷积操作后得到的 1x1x1 的输出结果。

img

进一步地,若类似 fl\mathbf{f}^l 这样的卷积核有 DD 个,则在同一个位置可得到 1×1×1×D1 \times 1 \times1 \times D 维度的卷积输出,而 DD 即为第 l+1l+1 层特征 xl+1\mathbf {x}^{l+1} 的通道数 Dl+1D^{l+1}

img

权重共享

在卷积神经网络中,权重共享简单来理解就是,输入一张图片,这张图片用一个卷积核进行卷积操作的时候,图片中的每一个位置都被同一个卷积核进行卷积,所以权重是一样的,也就是共享。

img

2.2 深度学习中的卷积计算

卷积的计算是 CNN 中最基本的算术单元,卷积的计算过程中出现的:Input Feature Map(FP), Output Feature Map(FP), 以及与 Kernel(size, strides, padding, dilation rate 等) 之间的关系和计算方式是我们应该掌握的基本知识。

1.卷积 Input FP size 与 Output FP size 之间的计算公式

如图 1 所示, 其展示了从 Input FP 经过卷积计算得到 Output FP的过程,每个通道相互之间独立

img

假设 Input FP 的尺寸方形为 W×WW \times W, Output FP 的尺寸为 N×NN \times N 为例,kernel 为方形,大小为 k×kk \times k, Input FP 的 Padding 为 pp, 卷积计算的步长(stride) 为 ss, 卷积计算:

N=[W+2pks]+1(.)N = [\frac {W +2p-k} {s}]+1 \\ \tag{.}

假设 Input FP 的尺寸矩形为 W×HW \times H, Output FP 的尺寸为 W×HW^{'} \times H^{'} 为例,kernel 为方形,大小为 k×kk \times k, Input FP 的 Padding 为 pp, 卷积计算的步长(stride) 为 ss, 图像通道数为 CC,卷积计算:

W=[W+2pks]+1H=[H+2pks]+1C=C(.)W^{'} = [\frac {W +2p-k} {s}]+1 \\ H^{'} = [\frac {H +2p-k} {s}]+1 \\ C^{'} = C \\ \tag{.}

比如,输入特征图为 5x5,卷积核为 3x3,外加 padding 为 1,则其输出尺寸为 53+2×11+1=5\frac {5-3+2 \times 1} {1} + 1 = 5。(记住:卷积向下取整,如 3.2,向下取整结果为 3

2.池化操作输出特征图大小计算

设输入图像尺寸为 W×HW \times H,其中 WW 为图像宽,HH 为图像高,CC 为图像深度(通道数),卷积核的尺寸为 k×kk \times kss 为步长

池化后输出图像大小:

W=[Wks]+1H=[Hks]+1C=C(.)W^{'} = [\frac {W -k} {s}]+1 \\ H^{'} = [\frac {H -k} {s}]+1 \\ C^{'} = C \\ \tag{.}

当进行池化操作时,步长 ss 就等于池化核的尺寸,如输入为 24x24,池化核为 4x4,则输出为 2444+1=6\frac {24-4} {4} + 1 = 6。(记住: 池化向上取整,如 3.6,向上取整结果为 4

3.空洞卷积输出特征图大小计算

设输入图像尺寸为 W×HW \times H,其中 WW 为图像宽,HH 为图像高,CC 为图像深度(通道数),卷积核的尺寸为 k×kk \times kss 为步长,Padding 为 pp, 空洞卷积的空洞率为 dd(正常卷积空洞率为 1)

W=[Wd(k1)1+2ps]+1H=[Hd(k1)1+2ps]+1C=C(.)W^{'} = [\frac {W -d(k-1)-1+2p} {s}]+1 \\ H^{'} = [\frac {H -d(k-1)-1+2p} {s}]+1 \\ C^{'} = C \\ \tag{.}

空洞卷积核是 d=2,k=2 的空洞卷积卷积核。输入为 5x5,则输出为 52(21)1+2×11+1=5\frac {5-2(2-1)-1+2 \times 1} {1} + 1 = 5。这样我们也保证了输出的特征图尺寸不变。

2.3 空洞卷积

空洞卷积

Dilated/Atrous Convolution (中文叫做空洞卷积或者膨胀卷积) 或者是 Convolution with holes 从字面上就很好理解,是在标准的卷积核里注入空洞,以此来增加 感受野。相比原来的正常convolution,dilated convolution 多了一个超参数称之为 dilation rate(空洞率) 指的是 kernel 的间隔数量(e.g. 标准卷积的空洞率是 1)。

img

标准卷积 Standard Convolution with a 3 x 3 kernel (and padding)

img

空洞卷积 Dilated Convolution with a 3 x 3 kernel and dilation rate 2

空洞卷积的优缺点:优点是与标准卷积相比,在保持同等计算量的情况下,可以扩大感受野。对于检测与分割任务,扩大感受野可以提升精度; 缺点是会出现网格效应(gridding effect),丢失局部像素信息

2.4 Depthwise 卷积与 Pointwise 卷积

Depthwise 卷积与 Pointwise 卷积

Depthwise 卷积与 Pointwise 卷积,合起来被称作 Depthwise Separable Convolution(深度可分离卷积), 该结构和常规的卷积操作类似,可以用来提取特征,但相比于常规的卷积操作,其参数量和运算成本比较低,所以在一些轻量级网络中会碰到如此结构。

1.常规卷积操作

对于一张 5x5 像素,三通道彩色输入图片,经过 3x3x4 卷积核的卷积层,最终会输出 4 个 feature map。

img

此时,卷积层共 4 个 Filter,每个 Filter 包含了 3 个 Kernel,每个 Kernel 的大小为 3×3。

2.Depthwise Separable Convolution(深度可分离卷积)

Depthwise Separable Convolution(深度可分离卷积)是将一个完整的卷积运算分解为两步运行,即 Depthwise 卷积Pointwise 卷积

Depthwise 卷积不同于常规的操作,Depthwise convolution 的一个卷积核只负责一个通道,即一个通道只被一个卷积核卷积。

同样是对一张 5x5 像素,3 通道彩色输入图片,Depthwise 卷积的一个卷积核只负责一个通道,即一个通道只被一个卷积核卷积,卷积核的数量与上一层的通道数相同。所以一个三通道的图像经过运算后生成了 3 个 Feature map。这里其实最终的维数应该是 3x3,因为每一个卷积都会作用一次,所以最终是 3x3 维度。

img

Depthwise Convolution 完成后的 Feature map 数量与输入层的 depth 相同,但是这种运算对输入层的每个 channel 独立进行卷积运算后就结束了,没有有效的利用不同 map 在相同空间位置上的信息。因此需要增加另外一步操作来将这些 map 进行组合生成新的 Feature map,即接下来的 Pointwise Convolution

Pointwise 卷积运算则是常规的运算,它的卷积核的尺寸为 1x1xM,M 为需要得到的最终 feature map 数量,所以这里的卷积运算会将上一步的 map 在深度方向上进行加权组合,生成新的 feature map,总共为 M 维度,操作方法就是 concate,然后再用 1x1 的卷积形成 1 维的(也可以用 1x1 先卷积,然后将不同 feature map 进行 add)。

Pointwise convolution过程如图:

img

经过 Pointwise Convolution 之后,同样输出了 4 张 Feature map,与常规卷积的输出维度相同。

3.参数量计算

普通卷积:3x3x3x4=108

3x3 是卷积核尺寸,3 是输入图片通道数目,4 是输出卷积核的个数。

深度可分离卷积:

DW:3x3x3x1=27

这里卷积核个数其实只设置为 1。会形成 3 张 feature map

PW:1x1x3x4=12

1x1 为卷积核的尺寸,3 为上一层 feature map 的数量,4 为最终需要的维度。其实这里我们也得到了 4 维的 feature map。

total:27+12=39

明显可以看到,深度可分离卷积计算量比普通卷积小很多,只有其近三分之一的计算量。

2.5 分组卷积

分组卷积

Group convolution 分组卷积,最早在 AlexNet 中出现,由于当时的硬件资源有限,训练 AlexNet 时卷积操作不能全部放在同一个 GPU 处理,因此作者把 feature maps 分给多个 GPU 分别进行处理,最后把多个 GPU 的结果进行融合。下图就是将特征图分成两半,卷积后再组合。

img

2.6 shuffleNet

shuffleNet

pointwise 卷积加强通道间的联系,还有另外的方式,那就是shuffleNetshuffleNet 通过将所有特征图通道“混洗”实现联系,思想比较简单,不再赘述。图 C 就体现了通道混洗的概念。

img

2.7 可变形(Deformable) 卷积

就特征提取的形状而言,卷积非常严格。也就是说,kernel 形状仅为正方形/矩形(或其他一些需要手动确定的形状),因此它们只能在这种模式下使用。如果卷积的形状本身是可学习的呢?这是引入可变形卷积背后的核心思想。

img

可变形卷积引入了一组可学习的参数,用于调整卷积核在输入特征图上的位置。这些可变形参数可以根据输入特征的上下文和形变信息来自适应地调整卷积采样位置,以适应不同的图像结构和形变情况。

实际上,可变形卷积的实现非常简单。每个kernel都用两个不同的矩阵表示。第一分支学习从原点预测“偏移”。此偏移量表示要处理原点周围的哪些输入。由于每个偏移量都是独立预测的,它们之间无需形成任何刚性形状,因此具有可变形的特性。第二个分支只是卷积分支,其输入是这些偏移量处的值。

img

3. 池化的概念

3.1 定义与作用

在深度学习中,池化(Pooling)是一种常用的操作,用于减少卷积神经网络(CNN)中特征图的尺寸,并提取出主要的特征信息。池化操作通过对输入特征图的局部区域进行聚合,将多个特征值合并为一个代表性的值。

池化操作通常有两种形式:最大池化(Max Pooling)和平均池化(Average Pooling)。

  • 最大池化(Max Pooling):最大池化将输入特征图划分为不重叠的矩形区域,然后在每个区域内选择最大的特征值作为池化结果。最大池化能够保留图像中的主要特征,对于不同尺度、旋转或平移的物体具有一定的不变性。
img
  • 平均池化(Average Pooling):平均池化将输入特征图划分为不重叠的矩形区域,然后计算每个区域内特征值的平均值作为池化结果。平均池化能够降低特征图的尺寸并保留一定的特征信息,对于减少过拟合有一定的作用。
img

池化操作的主要作用如下:

  • 特征降维:通过减小特征图的尺寸,降低了后续层的计算复杂度,减少了模型的参数量和计算量。

  • 平移不变性:池化操作在局部区域内进行聚合,对输入特征的平移具有一定的不变性,使得模型对于平移变换具有一定的鲁棒性。

  • 提取主要特征:池化操作能够从局部区域中提取出最显著的特征值,从而强化图像的主要特征,减少冗余信息。

  • 控制过拟合:池化操作能够在一定程度上减少特征图的尺寸和参数量,减轻模型的过拟合现象。

3.2 为什么使用池化

假如没有池化,在深度学习中,一张高清图像 4k X 4k 大小,在整个训练和预测过程中,都要一直用卷积核计算整张图像,为了获取更大视野的特征,还得用更大的卷积核,那 GPU 就顶不住了。所以为了获取更大的感受野同时降低计算复杂度,我们可以在训练过程中,将特征图尺寸减半送入后面的神经元,这就是池化出现的背景了

池化的作用体现在降采样:保留显著特征、降低特征维度与计算复杂度、提升网络不变性、控制模型过拟合。通过池化整合特征,网络提取的特征图越来越接近我们的目标。

img
img
img

从CNN的特征提取可视化来看,一开始网络提取的是边缘特征,然后到局部特征,最后整合成了完整的目标特征。池化从中发挥了重要作用,描述了图像的高层抽象


4. 详细讲解池化

3.1 平均池化

计算图像区域的平均值作为该区域池化后的值。

img

3.2 最大池化

选图像区域的最大值作为该区域池化后的值。

img

3.3 Stochastic pooling(随机池化)

Stochastic pooling 是一种简单有效的正则化 CNN 的方法,能够降低 max pooling 的过拟合现象,提高泛化能力。对于 pooling 层的输入,根据输入的多项式分布随机选择一个值作为输出。训练阶段和测试阶段的操作略有不同。

训练阶段:

前向传播:先将池化窗口中的元素全部除以它们的和,得到概率矩阵;再按照概率随机选中的方格的值,作为该区域池化后的值。(stochastic pooling 方法非常简单,只需对 feature map 中的元素按照其概率值大小随机选择,即元素值大的被选中的概率也大。而不像 max-pooling 那样,永远只取那个最大值元素。)

img

反向传播:求导时,只需保留前向传播中已经被选中节点的位置的值,其它值都为 0,类似 max-pooling 的反向传播。

测试阶段:在测试时也使用 Stochastic Pooling 会对预测值引入噪音,降低性能。取而代之的是使用概率矩阵加权平均。比使用 Average Pooling 表现要好一些。

3.4 重叠池化

重叠池化就是,相邻池化窗口之间有重叠区域,此时一般 sizeX > stride。

3.5 步长为 2 的卷积

步长为 2 的卷积相当于卷积同时池化。

3.6 空间金字塔池化SPP(Spatial Pyramid Pooling)

空间金字塔池化(Spatial Pyramid Pooling,SPP)是一种用于处理输入图像尺寸不固定的卷积神经网络(CNN)的技术。它的主要目的是允许网络对不同大小的输入图像进行处理,并生成固定长度的特征向量。

在之前的 CNN 中,对于结构已经确定的网络,需要输入一张固定大小的图片,比如 224x224、32x32、96x96 等。这样对于我们希望检测各种大小的图片的时候,需要经过裁剪,或者缩放等一系列操作,从而导致信息的损失或形变,这样往往会降低识别检测的精度。空间金字塔池化 SPP 使得我们构建的网络,可以输入任意大小的图片,不需要经过裁剪缩放等操作,只要你喜欢,任意大小的图片都可以。不仅如此,这个算法用了以后,精度也会有所提高。

img

空间金字塔池化 SPP 原理: 如上图所示,从下往上看,这是一个传统的网络架构模型,5 层卷积层,这里的卷积层叫做 convolution 和 pooling 层的联合体,统一叫做卷积层,后面跟随全连接层。我们这里需要处理的就是在网络的全连接层前面加一层金字塔 pooling 层解决输入图片大小不一的情况。注意我们上面曾提到使用多个窗口(不同尺寸的 pooling 窗口,如上图中蓝色,青绿,银灰的窗口, 然后对 feature maps 进行 pooling,将分别得到的结果进行合并就会得到固定长度的输出), 这就是得到固定输出的原因。这就解决了特征图大小不一的状况了。文章中用的是 AlexNet,conv5 得到的 feature map 大小为 13x13x256。SPP 其实就是做了多尺度的提取特征。

我们来看看具体操作:

假设输入 SSP 层的 feature map of conv5 的 shape 是 (h,w,c)

首先 SSP 层把 feature map of conv5 划分成 4x4 的小方块(对应图中蓝色矩形),每个小方块的宽高分别为 w/4,h/4,通道数为c,不能整除时需要取整。针对 feature map 的每个通道,分别在这 16 个小方块进行最大池化(MaxPooling),也就是取出小方块里的最大值。每一个通道都能取出 16 个最大值,所以所有通道共有 16c 个值;然后 SSP 层把 feature map of conv5 划分成 2x2 的小方块(对应图中绿色矩形),使用同样的方法得到 4c 个值;接着 SSP 层把 feature map of conv5 划分成 1x1 的小方块(对应图中灰色矩形),得到 c 个值,最后将上面三个值串联起来得到长度为 16c+4c+c=21c 的特征表示

显而易见,通过 SSP