详述 Deep Learning 中的各种卷积

技术讨论 chengzi ⋅ 于 2周前 ⋅ 138 阅读

作者丨Redflashing@知乎(已授权)
来源丨Deep Learning 深度学习笔记
编辑丨极市平台

本文梳理举例总结深度学习中所遇到的各种卷积,帮助大家更为深刻理解和构建卷积神经网络。

本文将详细介绍以下卷积概念:

  • 2D卷积(2D Convolution)
  • 3D卷积(3D Convolution)
  • $11$卷积($11$ Convolution)
  • 反卷积(转置卷积)(Transposed Convolution)
  • 扩张卷积(Dilated Convolution / Atrous Convolution)
  • 空间可分卷积(Spatially Separable Convolution)
  • 深度可分卷积(Depthwise Separable Convolution)
  • 平展卷积(Flattened Convolution)
  • 分组卷积(Grouped Convolution)
  • 混洗分组卷积(Shuffled Grouped Convolution)
  • 逐点分组卷积(Pointwise Grouped Convolution)

1. 首先,什么是卷积?

​ 在数学(特别是数学分析)中,卷积是一种重要的运算。卷积应用广泛于信号和图像处理以及其他工程科学领域中。深度学习中的卷积神经网络(CNN)就得名于卷积概念。深度学习中卷积的本质是信号和图像处理中的互相关(Cross-correlation)。在信号/图像处理中,卷积定义如下:

连续情况下:

$(f * g)(t) \ \ \stackrel{\mathrm{def}}{=}\ \int_{-\infty}^\infty f(\tau) g(t - \tau) \, d\tau$

离散情况下:

$(f * g)[n]\ \ \stackrel{\mathrm{def}} {=}\ \sum{m=-\infty}^{\infty} {f[m] g[n-m]} = \sum{m=-\infty}^\infty f[n-m]\, g[m]$

1.1. 卷积和互相关(Cross-correlation)的关系

​ 卷积是透过两个函数$f$和$g$生成第三个函数的一种数学算子,表征函数$f$与经过翻转和平移的$g$的乘积函数所围成曲边梯形的面积。

​ 上图(来源:维基百科)为RC电路中的方形脉冲波$g$(过滤器)和指数衰减$f$的脉冲波的卷积 ,同样地重叠部分的面积就相当于$t$处的卷积值。

​ 而互相关是两个函数之间的滑动点积或滑动内积。互相关中的过滤不经过反转,而是直接滑过函数$f$。$f$与$g$之间的交叉区域即是互相关。下图(来源:维基百科)显示了相关性和互相关性的区别。

​ 由此可见,互相关性中的过滤器不会反转。严格意义上来说,深度学习中的“卷积”是互相关(Cross-correlation)运算,本质上执行逐元素乘法和加法。但在之所以习惯性上将其称为卷积,是因为过滤器的权值是在训练过程中学习得到的。如果上面例子中的反转函数$g$是正确的函数,那么经过训练后,学习得到的过滤器看起来就会像是反转后的函数$g$。因此在训练之前,没必要像真正的卷积那样首先反转过滤器。

1.2. 深度学习中的卷积

​ 执行卷积的目的是从输入中提取出有用的特征。在图像处理中,有多种过滤器可供选择。不同的滤波器可以提取中不同的特征。如水平、垂直、对角线边缘特征等。在卷积神经网络(CNN)中,通过卷积提取不同的特征,滤波器的权值在训练期间进行学习。然后将提取到的特征复合得到最后的结果。之所以采用卷积的原因在于卷积运算具有权重共享和平移不变形并且卷积还考虑到了像素空间的联系,卷积的这些特性使得其在计算机视觉任务中具有出色的表现。下图(来源:Towards Data Science)展示了单通道图下卷积(也称为标准卷积)的计算过程。

上图输入为$55$的矩阵,滤波器为$33$的矩阵[[0,1,2],[2,2,0],[0,1,2]],滑动步长Stride=1,填充值Padding=0,输出为$3*3$的矩阵。

​ 在大多数应用中,我们一般需要处理多通道图片。最典型的就是RGB图像。如下图(来源:Andre Mouton)为RGB图像分解的单通道图。

另一个多通道数据的例子是CNN中的层。卷积层通常由多个甚至上百个通道组成。每个通道描述上层的不同特征。如何将通道数不同的层之间进行转换?即如何将通道数为$n$的层转换为通道数为$m$的层?

​ 在描述上述问题我们需要先介绍一些术语:Layers(层)、Channels(通道)、Feature Maps(特征图)、Filters(滤波器)、Kernels(卷积核)。从层次结构的角度来看,层和滤波器的概念处于同一水平,而通道和卷积核在下一级结构中。通道和特征图是同一个概念。一层可以有多个通道(或者说特征图)。如果输入的为一个RGB图像,那么就会有3个通道。通道(Channel)通常被用来描述层(Layer)的结构。相似地,卷积核(Kernel)是被用来描述滤波器(Filter)的结构。下图可直观体现层和通道的关系。

​ 滤波器和卷积核的区别有点难以理解。两者在某些情况下可以互换,故可能造成我们的混淆。那两者之间的不同之处在于那些因素呢?卷积核更倾向于2D的权重矩阵。而滤波器则多指的是多个卷积核堆叠的3D结构。若是一个2D的滤波器,那么两者指的是同一个概念。但对于3D滤波器,在大多数深度学习的卷积中,它是包含卷积核的。每个卷积核都是独一无二的,主要在于强调输入的通道的不同部分。

​ 有了以上概念,下面我们继续讲解多通道卷积。每个卷积核都应用于上一层的输入通道,以生成一个输出通道。所有输出通道组合在一起组成输出层。如下图所示:

输入层为$553$的矩阵(即为三通道)。滤波器为$333$的矩阵(即含有3个卷积核)。首先滤波器中的每个卷积核分别应用于输入层的三个通道。执行上次卷积计算,输出3个$3*3$的通道。

然后对这三通道相加即进行矩阵加法,得到一个$331$的单通道。这个通道就是在输入层($553$)应用单个滤波器($333$)的结果。

​ 同样地,以上过程可以更为统一地看成一个3D的滤波器对输入层进行处理。其中输入层和滤波器有着相同的深度,即输入层的通道数量与滤波器中卷积核数量相同。3D滤波器即只需要在输入层(如图像)的2个维度高和宽滑动(这也是为什么3D滤波器用于处理3D矩阵时,该运算过程称为2D卷积的原因)。在每个滑动位置,执行乘法和加法运算得到一个运算结果(单个数字)。在下面的例子中,滑动在$55x$的输入层($x$为任意值),最后得到的输出层仅含一个输出通道。

​ 进一步地,我们就能非常轻易地理解如何在不同深度的层(Layer)进行转换。假设输入层有$X{in}$个通道,而输出层需要得到$D{out}$个通道。只需要将$D{out}$个过滤器对输入层进行处理,而每一个过滤器有$D{in}$个卷积核。每个过滤器提供一个输出通道。完成该过程,将得到$D_{out}$个通道组成输出层。

1.3. 2D卷积的计算

输入层:$W{in}*H{in}*D_{in}$

超参数:

  • 过滤器个数:$k$
  • 过滤器中卷积核维度:$w*h$
  • 滑动步长(Stride):$s$
  • 填充值(Padding):$p$

输出层:$W{out}*H{out}*D_{out}$

其中输出层和输入层之间的参数关系为,

$$
\begin{cases} W{out} = (W{in} +2p - w)/s + 1 ,\ H{out} = (H{in} +2p - h)/s + 1, \ D_{out} = k \end{cases}
$$

参数量为:$(whD_{in} + 1)*k$

2. 3D卷积

​ 在上一个插图中,可以看出,这实际上是在完成3D卷积。但通常意义上,仍然称之为深度学习的2D卷积。因为将滤波器深度和输入层深度相同,3D滤波器仅在2个维度上移动(例如图像的高度和宽度),得到的结果为单通道。

​ 通过将2D卷积的推广,在3D卷积定义为滤波器的深度小于输入层的深度(即卷积核的个数小于输入层通道数),故3D滤波器需要在三个维度上滑动(输入层的长、宽、高)。在滤波器滑动的每个位置执行一次卷积操作,得到一个数值。当滤波器滑过整个3D空间,输出的结构也是3D的。

​ 2D卷积和3D卷积的主要区别为滤波器滑动的空间维度。3D卷积的优势在于描述3D空间中的对象关系。3D关系在某一些应用中十分重要,如3D对象的分割以及医学图像的重构等。

2.1. 3D卷积的计算

输入层:$W{in}*H{in}D_{in}C_{in}$

超参数:

  • 过滤器个数:$k$
  • 过滤器中卷积核维度:$whd$
  • 滑动步长(Stride):$s$
  • 填充值(Padding):$p$

输出层:$W{out}*H{out}D_{out}C_{out}$

其中输出层和输入层之间的参数关系为,

$$
\begin{cases} W{out} = (W{in} +2p - w)/s + 1 ,\ H{out} = (H{in} +2p - h)/s + 1, \ D{out} = (D{in} +2p - d)/s + 1, \ C_{out} = k \end{cases}
$$

参数量为:$(whd + 1)*k$

*3. $11$卷积**

​ $11$卷积十分有趣。咋一看$11$卷积对于单通道而言仅仅是每个元素乘以一个数字,但如果输入层为多通道,情况就变为有趣了。

上图解释了$11$卷积如何适用于尺寸为$HWD$的输入层,滤波器大小为$11D$,输出通道的尺寸为$HW1$。如果应用$n$个这样的滤波器,然后组合在一起,得到的输出层大小为$HW*n$。

*3.1. $11$卷积的作用**

  • 调节通道数
    由于 $1×1$ 卷积并不会改变 height 和 width,改变通道的第一个最直观的结果,就是可以将原本的数据量进行增加或者减少。这里看其他文章或者博客中都称之为升维、降维。但实际情况维度并没有改变,改变的只是 $height × width × channels$ 中的$channels$这一个维度的大小而已。
  • 增加非线性
    $1*1$卷积核,可以在保持特征图尺度不变的(即不改变)的前提下大幅增加非线性特性(利用后接的非线性激活函数如ReLU)。非线性允许网络学习更复杂的功能,并且使得整个网络能够进一步加深。
  • 跨通道信息
    使用$11$卷积核,实现降维和升维的操作其实就是间通道信息的线性组合变化。例如:在卷积核大小为$33$,卷积核个数为64的滤波器与卷积核大小为$11$,卷积核个数为28的滤波器组合,其输出层大小等于通过卷积核大小为$33$,卷积核个数为28的滤波器所得到的输出层的大小,原来的64个通道就可以理解为跨通道线性组合变成了28通道,这就是通道间的信息交互。
  • 减少参数
    前面所说的降维,其实也是减少了参数,因为特征图少了,参数也自然跟着就减少,相当于在特征图的通道数上进行卷积,压缩特征图,二次提取特征,使得新特征图的特征表达更佳。

​ 关于 $1 1$卷积的一个有趣的观点来自 Yann LeCun, “在卷积神经网络中, 没有‘全连接层(fully-connected layers)’的概念。只有卷积层具有$11$卷积核和全连接表。”

*3.2. $11$卷积的应用**

$11$卷积在多个经典网络中发挥了重要作用,以下简要介绍几个$11$卷积重要的应用。

  • Network in Network(NIN)
    NIN提出了MLP卷积层,MLP卷积层通过叠加"Micro Network"网络,提高非线性表达,而其中的"Micro Network"基本组成单元是$11$卷积网路,说到这,就要解释一下$11$卷积了,该篇论文是首次提出$11$卷积,具有划时代的意义,之后的GoogleNet借鉴了$11$卷积,还专门致谢过这篇论文。
  • Inception
    ​ GoogleNet首次提出Inception模块,Inception一共有V1、V2、V3、V4四个版本(这里就不详述了)。下图为Inception V1的结构如下图两个图所示。

在充分引入$11$卷积进行降维后如图(b)所示,总体而言相比于图(a)其卷积参数量已经减少了近4倍。
​ 在inception结构中,大量采用了$1
1$卷积,主要是两点作用:a.对数据进行降维;b.引入更多的非线性,提高泛化能力,因为卷积后要经过ReLU激活函数;

  • ResNet

ResNet同样也利用了$11$卷积,并且是在$33$卷积层的前后都使用了,不仅进行了降维,还进行了升维,参数数量进一步减少。其中右图又称为Bottleneck Design,目的一目了然,就是为了降低参数的数目,第一个$11$的卷积把通道量从256降到64,然后在最后通过$11$卷积恢复,整体上用的参数数目差了近16.94倍。
​ 对于常规ResNet,可以用于34层或者更少的网络中,对于Bottleneck Design的ResNet通常用于更深的如101这样的网络中,目的是减少计算和参数量。

*3.3. $11$卷积的计算**

​ $1*1$卷积实际上看做2D卷积的特殊情况,计算的过程可参考2D卷积的计算过程。

4. Convolution Arithmetic

现在我们知道了Depth维度的卷积。我们继续学习另外两个方向(Height\&Width),同样重要的卷积算法。一些术语:

  • Kernel size(卷积核尺寸):卷积核在上面的部分已有提到,卷积核大小定义了卷积的视图。
  • Stride(步长):定义了卷积核在图像中移动的每一步的大小。比如Stride=1,那么卷积核就是按一个像素大小移动。Stride=2,那么卷积核在图像中就是按2个像素移动(即,会跳过一个像素)。我们可以用stride>=2,来对图像进行下采样。
  • Padding:可以将Padding理解为在图像外围补充一些像素点。padding可以保持空间输出维度等于输入图像,必要的话,可以在输入外围填充0。另一方面,unpadded卷积只对输入图像的像素执行卷积,没有填充0。输出的尺寸将小于输入。

5. 反卷积(转置卷积)

​ 对于很多生成模型(如GAN中的生成器、自动编码器(Autoencoder)、语义分割等模型)。我们通常希望进行与正常卷积相反的装换,即我们希望执行上采样,比如自动编码器或者语义分割。(对于语义分割,首先用编码器提取特征图,然后用解码器回复原始图像大小,这样来分类原始图像的每个像素。)

​ 实现上采样的传统方法是应用插值方案或人工创建规则。而神经网络等现代架构则倾向于让网络自己自动学习合适的变换,无需人类干预。为了做到这一点,我们可以使用转置卷积。

​ 转置卷积在文献中也被称为去卷积(Deconvolution)或微步幅卷积(Fractionally strided convolution)。但是,需要指出去卷积这个名称并不是很合适,因为转置卷积并非信号/图像处理领域定义的那种真正的去卷积。从技术上讲,信号处理中的去卷积是卷积运算的逆运算。但这里却不是这种运算。后面我们会介绍为什么将这种运算称为转置卷积更自然且更合适。

​ 我们可以使用常见卷积实现转置卷积。这里我们用一个简单的例子来说明,输入层为$22$,先进行填充值Padding为$22$单位步长的零填充,再使用步长Stride为1的$33$卷积核进行卷积操作则实现了上采样,上采样输出的大小为$44$。

​ 值得一提的是,可以通过各种填充和步长,我们可以将同样的$22$输入映射到不同的图像尺寸。下图,转置卷积被应用在同一张$22$的输入上(输入之间插入了一个零,并且周围加了$22$的单位步长的零填充)上应用$33$的卷积核,得到的结果(即上采样结果)大小为$5*5$。

​ 通过观察上述例子中的转置卷积能够帮助我们构建起一些直观的认识。但为了进一步应用转置卷积,我们还需要了解计算机的矩阵乘法是如何实现的。从实现过程的角度我们可以理解为何转置卷积才是最合适的名称。

​ 在卷积中,我们这样定义:用$C$代表卷积核,$input$为输入图像,$output$为输出图像。经过卷积(矩阵乘法)后,我们将$input$从大图像下采样为小图像$output$。这种矩阵乘法实现遵循$C*input=output$。

​ 下面的例子展示了这种运算在计算机内的工作方式。它将输入平展($161$)矩阵,并将卷积核转换为一个稀疏矩阵($416$)。然后,在稀疏矩阵和平展的输入之间使用矩阵乘法。之后,再将所得到的矩阵($41$)转为$22$输出。

​ 此时,若用卷积核对应稀疏矩阵的转置$C^T$($164$)乘以输出的平展($41$)所得到的结果($161$)的形状和输入的形状($161$)相同。

但值得注意的是,上述两次操作并不是可逆关系,对于同一个卷积核(因非其稀疏矩阵不是正交矩阵),结果转置操作之后并不能恢复到原始的数值,而仅仅保留原始的形状,所以转置卷积的名字由此而来。并回答了上面提到的疑问,相比于“逆卷积”而言转置卷积更加准确。

​ 转置矩阵的算术解释可参考:https://arxiv.org/abs/1603.07285

5.1. 棋盘效应(Checkboard artifacts)

​ 在使用转置卷积时观察到一个棘手的现象(尤其是深色部分常出现)就是"棋盘格子状伪影",被命名为棋盘效应(Checkboard artifacts)。下图直观地展示了棋盘效应(来源:https://distill.pub/2016/deconv\-checkerboard/

​ 本文仅做简要介绍,详细部分请参考论文:Deconvolution and Checkerboard Artifacts

​ 棋盘效应是由于转置卷积的“不均匀重叠”(Uneven overlap)的结果。使图像中某个部位的颜色比其他部位更深。尤其是当卷积核(Kernel)的大小不能被步长(Stride)整除时,反卷积就会不均匀重叠。虽然原则上网络可以通过训练调整权重来避免这种情况,但在实践中神经网络很难完全避免这种不均匀重叠。

​ 下面通过一个详细的例子,更为直观展示棋盘效应。下图的顶部部分是输入层,底部部分为转置卷积输出结果。结果转置卷积操作,小尺寸的输入映射到较大尺寸的输出(体现在长和宽维度)。

​ 在(a)中,步长为1,卷积核为$2*2$。如红色部分所展示,输入第一个像素映射到输出上第一个和第二个像素。而正如绿色部分,输入的第二个像素映射到输出上的第二个和第三个像素。则输出上的第二个像素从输入上的第一个和第二个像素接收信息。总而言之,输出中间部分的像素从输入中接收的信息存在重叠区域。在示例(b)中的卷积核大小增加到3时,输出所接收到的大多数信息的中心部分将收缩。但这并不是最大的问题,因为重叠仍然是均匀的。

如果将步幅改为2,在卷积核大小为2的示例中,输出上的所有像素从输入中接收相同数量的信息。由下图(a)可见,此时描以转置卷积的重叠。若将卷积核大小改为4(下图(b)),则均匀重叠区域将收缩,与此同时因为重叠是均匀的,故仍然为有效输出。但如果将卷积核大小改为3,步长为2(下图(c)),以及将卷积核大小改为5,步长为2(下图(d)),问题就出现了,对于这两种情况输出上的每个像素接收的信息量与相邻像素不同。在输出上找不到连续且均匀重叠区域。

​ 在二维情况下棋盘效应更为严重,下图直观地展示了在二维空间内的棋盘效应。

5.1.1 如何避免棋盘效应

  • 采取可以被步长整除的卷积核长度
    该方法较好地应对了棋盘效应问题,但仍然不够圆满,因为一旦我们的卷积核学习不均匀,依旧会产生棋盘效应(如下图所示)

  • 插值
    可以直接进行插值Resize操作,然后再进行卷积操作。该方式在超分辨率的相关论文中比较常见。例如我们可以用常见的图形学中常用的双线性插值和近邻插值以及样条插值来进行上采样。

5.2. 转置卷积的计算

输入层:$W{in}*H{in}*D_{in}$

超参数:

  • 过滤器个数:$k$
  • 过滤器中卷积核维度:$w*h$
  • 滑动步长(Stride):$s$
  • 填充值(Padding):$p$

输出层:$W{out}*H{out}*D_{out}$

(为简化计算,设$W{in}=H{in}=in$,则记$W{out}=H{out}=out$)

其中输出层和输入层之间的参数关系分为两种情况:

情况一:$(in-1)*s-2p+k=out$

$$
\begin{cases} out=s*(in-1)-2p+k, \ D_{out} = k \end{cases}
$$

情况二:$(in-1)*s-2p+k\not=out$

$$
\begin{cases} out=s(in-1)-2p+k+(out+2p-k)\%s, \ D_{out} = k \end{cases}
$$

​ 这里以经典图像语义分割模型全卷积网络FCN-32s为例,上采样转置卷积的输入为$77$,我们希望进行一次上采样后恢复成原始图像尺寸$224224$,代入公式$\begin{cases} out=s*(in-1)-2p+k, \ out=224,in=7\end{cases}$得到一个关于$s,k,p$三者之间的关系等式:$6s+k-2p=224$。最后通过实验,得到最合适的一组数据:$s=16,k=64,p=32$。

6. 扩张卷积(空洞卷积)

扩张卷积由这两篇引入:

这是一个标准的离散卷积:

$$
(F*k)(p)=\sum_{s+t=p}F(s)k(t)
$$

扩张卷积如下:

$$
(F*{l}k)(p) = \sum{s+lt=p}F(s)k(t)
$$

当$l=1$时,扩张卷积变为标准卷积。

​ 直观地来说,扩张卷积通过在卷积核元素之间插入空格来使得卷积核膨胀。新增加的参数$l$表示扩张率,表示我们希望将卷积核“膨胀”的程度。具体的实现会不同,通常情况下在卷积核元素之间插入$l-1$个空格。下面分别展示了$l=1,2,4$时的卷积核膨胀后的大小。

图像中,$33$个红点表示卷积核原本大小为$33$。尽管所有这三个扩张卷积的卷积核都是同一尺寸,但模型的感受野却有很大的不同。$l=1$时感受野为$33$,$l=2$时感受野为$77$。$l=3$时感受野为$15*15$。值得注意的是,上述操作的参数量都是相同的。扩张卷积在不增加计算成本的情况下,能让模型有更大的感受野(因为卷积核尺寸不变),这在多个扩张卷积彼此堆叠时尤其有效。

​ 论文《Multi-scale context aggregation by dilated convolutions》的作者用多个扩张卷积层构建了一个网络,其中扩张率 l 每层都按指数增大。由此,**有效的感受野大小随层而指数增长,而参数的数量仅线性增长。**这篇论文中扩张卷积的作用是系统性地聚合多个比例的形境信息,而不丢失分辨率。这篇论文表明其提出的模块能够提升那时候(2016 年)的当前最佳形义分割系统的准确度。请参阅那篇论文了解更多信息。

6.1. 扩张卷积的应用

主要讨论扩张卷积在语义分割(Semantic Segmentation)的应用

​ 一个$77$的卷积层的正则等效于3个$33$的卷积层的叠加。而这样的设计不仅可以大幅度减少参数量,其本身带有正则性质的卷积核能够更容易学一个可生成和表达的特征空间。这些特点也是现在绝大部分基于卷积的深层网络都在使用小卷积核的原因。

​ 但深层的卷积神经网络对于一些任务仍然存在致命的缺陷。较为突出的是(由上采样和池化层引起):

  • 上采样核和池化层是不可逆的
  • 内部数据结构丢失;空间层级化信息丢失
  • 细节丢失(假设有四个池化层,则任何小于$2^4=16$像素的细节将被舍弃,并无法重建。)

在这样的问题存在的情况下,语义分割问题一直处在瓶颈无法再明显提高精度,而扩张卷积的概念就很好避免了上述问题

6.3. 扩张卷积存在的问题

  • **问题一:**网格效应
    假设我们仅仅简单地多次叠加扩张卷积$3*3$卷积核的话,则会出现下图的问题:

我们发现卷积核并不连续,也就是并不是所有的像素用来计算了,由于图像等信息具有连续性质,这对pixel-level dense prediction 的任务来说是致命的。

  • **问题二:****Long-ranged information might be not relevant.
    从扩张卷积的设计背景来看就能推测出这样的设计是用来获取 long-ranged information。然而光采用较大扩张率的信息或许只对一些大物体分割有效果,而对小物体来说可能有消极的作用。如何同时处理不同大小的物体的关系(感受野粒度),则是设计好 扩张卷积网络的关键。

对于扩张卷积问题的处理,这里就不详述了。

6.4. 扩张卷积的计算

以卷积核元素之间插入$l-1$个空格为例子

输入层:$W{in}*H{in}*D_{in}$

超参数:

  • 扩张率:$l$
  • 过滤器个数:$k$
  • 过滤器中卷积核维度:$w*h$
  • 滑动步长(Stride):$s$
  • 填充值(Padding):$p$

输出层:$W{out}*H{out}*D_{out}$

其中输出层和输入层之间的参数关系为,

$$
\begin{cases} w_0 = (w-1)(l-1) + w,\h_0 = (h-1)(l-1) + h,\W{out} = (W{in} +2p - w0)/s + 1 ,\ H{out} = (H_{in} +2p - h0)/s + 1, \ D{out} = k \end{cases}
$$

参数量为:$(whD_{in} + 1)*k$

7. 可分卷积(Separable Convolution)

​ 在一些经典网络架构中可分卷积发挥了重要的作用,比如MobileNets。可分卷积又可分为空间可分卷积核深度可分卷积。

7.1. 空间可分卷积(Spatially Separable Convolution)

​ 空间可分卷积根据图像宽核高的2D空间尺寸进行操作。从概念上来讲,空间可分卷积将卷积分解为两个独立的操作。我们拿数字图像处理中常见的$33$索贝尔算子(Sobel operator,主要用于边缘检测)分解为$31$和$1*3$卷积核。

在卷积中,$33$卷积核直接与图像卷积进行卷积运算(具体过程可参考转置卷积中计算机中如何处理卷积运算)。在空间可分卷积中,$31$卷积核先于图像进行卷积再应用$1*3$卷积核。执行相同的操作时,相比于直接卷积运算需要9个参数这样仅需要6个参数。

​ 此外,在空间可分卷积中相比于正常卷积所进行的矩阵乘法次数也更少。下面给出一个具体的例子,$55$图像经过$33$卷积核(步长为1,填充为0),水平滑动3个位置,垂直滑动3个位置。一共滑动9个位置,在每个位置9个元素进行逐个乘法。所以总共要执行$9*9=81$乘法运算。

​ 另一方面,对于空间可分卷积,我们首先对$55$的图像应用$31$卷积核。在水平滑动5个位置以及垂直滑动3个位置即$53=15$个位置,在每个位置完成3次乘法运算,总共是$153=45$次乘法运算。再将得到的$35$的输出应用$13$卷积核。那么需要水平滑动3个位置和垂直扫描3个位置,总共9个位置,每个位置完成3次乘法运算,那么总共要执行$9*3=27$次乘法运算,所以上述空间可分卷积一共完成$45+27=72$次乘法运算,相比于正常卷积乘法运算减少了。

​ 这里我们来归纳一下上面的例子。现在我们应用卷积在一共$nn$图像上,卷积核为$mm$,步长为1,填充为0。

  • 标准卷积计算成本:
    $(n-2)(n-2)m*m$
  • 空间可分卷积计算成本:
    $n(n-2)m+(n-2)(n-2)m\=(2n-2)(n-2)m$
  • 空间可分卷积与标准卷积的计算成本之比为:
    $\dfrac{2}{m} + \dfrac{2}{m*(n-2)}$

对于图像大小$n$大于卷积核大小的情况($n>>m$),此时比值变为$\frac{2}{m}$。这意味着在这种渐进的情况下,当卷积核为$33$,空间可分卷积的卷积计算成本是标准卷积的$\frac{2}{3}$。如果为$55$卷积其值为$\frac{2}{5}$,如果为$7*7$卷积其值为$\frac{2}{7}$等等。

​ 虽然空间可分卷积可节省成本,但很少用于深度学习。其中一个主要的原因是:并非所有卷积核都可以分成两个较小的卷积核。如果我们用空间可分卷积取代所有传统的卷积,则有可能我们限制自己在训练期间搜索所有可能的内核,导致模型训练结果不尽如人意。

7.2. 深度可分卷积

​ 相比于空间可分卷积,深度可分卷积在深度学习中要常用得多(比如MobileNet和Xception)。深度可分卷积包含两个步骤:深度卷积和$1*1$卷积。

​ 在描述这些步骤前,值得再复习2D卷积和$11$卷积。现在快速回顾一下标准2D卷积。这里举一个具体示例,假设输入为$773$,滤波器为$333$。使用一个滤波器进行2D卷积后,输出层的大小为$55*1$(只有1个通道)。

​ 通常,在两个神经网络层之间应用多个过滤器。假设我们这里有128个过滤器。在应用这128个过滤器后得到输出为128个$551$矩阵。堆叠成$55128$。这样做,我们将输入层($773$)转换为输出层($55128$)。空间尺寸(即高度和宽度)收缩,而深度则扩展。

现在,通过深度可分卷积实现相同的转换。

​ 首先,我们将深度卷积应用于输入层。但不是使用大小$333$的2D卷积单个滤波器,我们将单其中3个卷积核分别单独使用。每个卷积核与对应输入层的单个通道进行卷积操作(即省略单个滤波器将输入处理当中的多通道对应位置相加为单通道的过程),则得到一个$553$的输出。

​ 接下来,使用大小为$113$的卷积核,完成$11$卷积。最后得到$55*1$的输出。

​ 于是我们可以应用128个$11$卷积核,这样我们同样得到一个$55*128$的输出。

深度可分卷积的操作流程可如下图所示:

那么深度可分卷积相比于普通2D卷积的优势是什么?

​ 深度可分卷积和空间可分卷积的优势一样也是减少了计算成本。与2D卷积相比,深度可分卷积所需的操作要少得多。这里我们以上面的例子来计算。有128个$333$卷积核滑动$55$个位置。即$12833355=86400$次乘法运算。而在可分离卷积中,在步骤一中,有3个$331$卷积核滑动$55$个位置一共进行了$333155=675$次乘法运算。在步骤二中,有128个$113$卷积核滑动$55$次一共$12811355=9600$次乘法运算,总体而言深度可分卷积仅需要$675*9600=10275$次乘法运算。其计算成本仅仅是2D卷积的$12\%$左右。

​ 同样,我们对深度可分卷积进行归纳。假设输入为$hwd$,应用$n$个$h_0h_0d$的滤波器(步长为1,填充为0,$h$为偶数),同时输出层为$(h-h_0+1)(w-h_0+1)n$。

  • 2D卷积的计算成本:
    $nh_0h_0d(h-h_0+1)*(w-h_0+1)$
  • 深度可分卷积的计算成本:
    $dh_0h_01(h-h_0+1)(w-h_0+1) +\ n11d(h-h_0+1)(w-h_0+1)\=(h_0h_0+n)d(h-h_0+1)(w-h_0+1)$
  • 深度可分卷积和2D卷积所需的计算成本比值为:
    $\frac{1}{n}+\frac{1}{h_0^2}$

​ 目前大多数网络结构的输出层通常都有很多通道,可达数百个甚至上千个。该情况下($n>>h_0$),则上式可简写为$\frac{1}{h_0^2}$。基于此,如果使用$33$的滤波器,则2D卷积的乘法计算次数比深度可分卷积多9倍。对于$55$的滤波器,2D卷积的乘法次数可能是其25倍。

​ **使用深度可分卷积有什么缺点吗?**当然有。深度可分卷积可大幅度减少卷积的参数。因此对于规模较小的模型,如果将2D卷积替换为深度可分卷积,其模型大小可能会显著降低,模型的能力可能会变得不太理想,因此得到的模型可能是次优的。但如果使用得当,深度可分卷积能在不牺牲模型性能的前提下显著提高效率。

8.平展卷积(Flattened convolutions)

​ 在论文《Flattened convolutional neural networks for feedforward acceleration》中介绍了平展卷积。从直觉上看,平展卷积的理念是滤波器分离。我们不应用一个标准的滤波器将输入映射到输出,而是将此标准的滤波器分解为3个1D滤波器。这种想法与上述空间可分卷积类似,其中的一个空间滤波器近似于两个 rank-1 过滤器(秩1矩阵),而秩1矩阵可表示为一列基乘以一行基的形式$A=UV^T$,最后分解得到3个1D滤波器。

​ 应该注意的是,如果标准滤波器是rank-1滤波器,则此类滤波器就可分为3个1D滤波器的向量积。实际情况中标准滤波器的秩通常大于1。论文中也提到,随着分类问题难度的增加,将平展卷积直接应用于滤波器会导致显著的信息丢失。

​ 为了缓解此类问题,论文对感受野的连接进行限制,以便模型在训练时可以学习分解后的1D滤波器。这篇论文提到,通过使用由连续的 1D 过滤器组成的扁平化网络在 3D 空间的所有方向上训练模型,能够提供的性能与标准卷积网络相当,不过由于学习参数的显著减少,其计算成本要更低得多

9. 分组卷积

​ 首次在大规模图像数据集(ImageNet)实现了深层卷积神经网络结构,引发深度学习热潮的AlexNet 论文(https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf)在 2012 年引入了分组卷积。实现分组卷积的主要原因是让网络训练可在 2 个内存有限(每个 GPU 有 1.5 GB 内存)的 GPU 上进行。下面的 AlexNet 表明在大多数层中都有两个分开的卷积路径。这是在两个 GPU 上执行模型并行化(当然如果可以使用更多 GPU,还能执行多 GPU 并行化)。

​ 这里我们介绍一下分组卷积的工作方式。首先典型的2D卷积步骤如下图所示。在该例子中通过应用128个大小为$333$的滤波器将输入层($773$)变换到输出层($55128$)。推广而言,即通过$D{out}$个大小为$hwD{in}$的滤波器将输入层($H{in}*W{in}D{in}$)变换到输出层($H{out}W{out}*D{out}$)。

​ 而在分组卷积中,滤波器被分成不同的组。每个组负责具有一定深度的2D卷积。下图展示了具有两个滤波器分组的分组卷积。在每个滤波器组中,每个滤波器只有原2D卷积的一半数目。它们的深度是$\frac{D{in}}{2}$个滤波器。第一个滤波器分组(红色)与输入层的前一半(按深度分半,即$[:,:,0:\frac{D{out}}{2}]$)进行卷积操作。因此,每个滤波器分组都会创建$\frac{D{out}}{2}$个通道。整体而言,两个分组会创建$2*\frac{D{out}}{2}=D{out}$个通道。然后我们将这些通道堆叠在一起得到有$D{out}$个通道的输出层。

9.1. 分组卷积与深度可分卷积比较

​ 从上面的例子已经可以发现分组卷积和深度可分卷积之间的联系和差异。如果滤波器组的数量和输入层通道数相同,则每个滤波器的深度都为1,这与深度可分卷积相同。另一方面,每个滤波器组都包含$\frac{D{out}}{D{in}}$个滤波器。整体而言,输出层的深度为$D_{out}$。这不同于深度可分卷积的情况--深度卷积的第一个步骤并不会改变层的深度。深度可分卷积的深度通过$1*1$卷积进行深度的扩展。

9.2. 分组卷积的优点

  • 高效训练
    ​ 由于卷积可分为多个路径,因此每个路径可以由不同的GPU进行处理。此过程允许以并行的方式对多个GPU进行模型训练。这种基于多GPU的模型并行化允许网络在每个步骤处理更多图像。一般认为模型并行化比数据并行化效果更好,后者将数据集分成多个批次(Batch),然后分开训练每一批次。但是当批次大小过小时,本质上执行的是随机梯度下降,而非批梯度下降,这会造成收敛速度缓慢切收敛结果更差。
    在训练非常深的神经网络时,分组卷积会非常重要,正如下图ResNeXt中那样,图片来自论文(https://arxiv.org/abs/1611.05431

  • 高效模型
    ​ 即模型参数随着滤波器组的数量的增加而减少。在前面的示例中,滤波器在标准2D卷积中参数量为:$hwD{in}*D{out}$。而具有2个滤波器组的分组卷积的参数量为:$(hw\frac{D{in}}{2}*\frac{D{out}}{2})*2$。参数量减少了一半。
  • 模型性能更优
    ​ 这有一点让人惊讶,分组卷积在某些情况下能提供比标准2D卷积更好的模型。这在文章(https://blog.yani.io/filter-group-tutorial/)有很好地解释,这里仅做简要的分析。
    ​ 原因主要和稀疏滤波器(稀疏矩阵)有关。下图是相邻层滤波器的相关性,为稀疏关系。图为在 CIFAR10 上训练的一个 Network-in-Network 模型中相邻层的过滤器的相关性矩阵。高度相关的过滤器对更明亮,而相关性更低的过滤器则更暗。图片来自:https://blog.yani.io/filter-group-tutorial

但当我们用分组卷积后,神奇的事情发生了

​ 上图是当用 1、2、4、8、16 个过滤器分组训练模型时,相邻层的滤波器之间的相关性。那篇文章提出了一个可能的解释:滤波器分组的效果是在通道维度上学习块对角结构的稀疏性……在网络中,具有高相关性的过滤器是使用过滤器分组以一种更为结构化的方式学习到。从效果上看,不必学习的过滤器关系就不再参数化。这样显著地减少网络中的参数数量能使其不容易过拟合,因此,一种类似正则化的效果让优化器可以学习得到更准确更高效的深度网络

​ 上图是AlexNet中Conv1滤波器分解:正如作者指出的那样,过滤器分组似乎会将学习到的过滤器结构性地组织成两个不同的分组。图片来自 AlexNet 论文(https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf)。
​ 此外,每个滤波器分组都会学习数据的一个独特表征。正如 AlexNet 的作者指出的那样,滤波器分组似乎会将学习到的过滤器结构性地组织成两个不同的分组——黑白过滤器和彩色过滤器。

9.3. 混洗分组卷积(Shuffled Grouped Convolution)

​ 混洗分组卷积由旷视(Face++)团队在ShuffleNet(https://arxiv.org/abs/1707.01083)首次提出,ShuffleNet是一种计算效率非常高的卷积结构,专门为计算能力非常有限的移动设备(10-150MFLOP)而设计。

​ 混洗分组卷积背后的思想与分组卷积背后的理念(用于 MobileNetResNeXt示例)和深度可分卷积(在Xception 中使用)。总体而言,随机分组卷积涉及分组卷积和通道混洗。

​ 在有关分组卷积的部分中,我们知道滤波器被分成不同的组。每个组负责具有一定深度的传统 2D 卷积。总的计算量显著减少。对于下图中的示例,我们有 3 个滤波器组。第一个滤波器组与输入层中的红色部分进行卷积操作。同样,第二个和第三个滤波器组与输入中的绿色和蓝色部分进行卷积操作。每个滤波器组中的卷积核深度仅占输入层中总通道计数的$\frac{1}{3}$。在此示例中,在第一个分组卷积 GConv1 之后,输入图层映射再通过中间层(下文针对该部分进行讲解)。然后,通过第二个分组卷积 GConv2 映射到输出图层。

​ 分组卷积在计算上是有效的。但问题是,每个滤波器组只处理从输入层中的固定部分传递的信息。对于上图中的示例,第一个滤波器组(红色)仅处理从输入通道前 1/3 传递的信息。蓝色滤波器组(蓝色)仅处理从输入通道的最后 1/3 传递的信息。因此,每个滤波器组都仅限于学习一些特定功能。这一特性阻止通道组之间的信息流,并在训练期间削弱了模型表现力。为了克服此问题,ShuffleNet 中引入了通道混洗(Channel Shuffle), 用来进行不同分组的特征之间的信息流动, 以提高性能.。

​ 通道混洗操作(Channel Shuffle Operation)的想法是,我们希望混合来自不同筛选器组的信息。在下图中,我们使用 3 个滤波器组应用第一个分组卷积 GConv1 后获取特征。在将结果输入到第二个分组卷积之前,我们首先将每个组中的通道划分为多个子组。我们混洗了这些子组。

​ 在进行这样的洗牌之后,我们继续一样执行第二组卷积 GConv2。但现在,由于经过混洗后信息已经混合,因此,通过允许通道之间的信息交换,增强了模型的表现力。

9.4. 逐点分组卷积(Pointwise Grouped Convolution)

​ ShuffleNet 也引入了组点分组卷积.通常对于分组卷积(如 MobileNet或 ResNeXt,组操作在$33$空间卷积上执行,但在$11$卷积上不执行。

​ ShuffleNet论文认为,$11$卷积在计算上也是昂贵的。并建议在$11$卷积上也应用分组卷积。顾名思义,逐点分组卷积执行$1*1$卷积的组操作。该操作与分组卷积相同,只有一个修改在$11$筛选器上执行,而不是$nn$滤波器 ($n>1$)

​ 在ShuffleNet的论文中,作者利用了三种类型的卷积:(1) 混洗分组卷积;(2) 逐点分组卷积;和 (3) 深度可分卷积。这种架构设计在保持精度的同时显著降低了计算成本。例如,ShuffleNet 和 AlexNet 的分类错误在实际移动设备上是可比的。但是,计算成本已大幅降低,从 AlexNet 中的 720 MFLOP 减少到 ShuffleNet 中的 40\~140 MFLOP。由于计算成本相对较低,模型性能好,ShuffleNet在移动设备卷积神经网领域越来越受欢迎。

参考资料

小迷离

成为第一个点赞的人吧 :bowtie:
回复数量: 0
暂无回复~
您需要登陆以后才能留下评论!