[深度学习] 深度可分离卷积

一 深度可分离卷积

深度可分离卷积之所以如此命名,是因为它不仅处理空间维度,还处理深度维度-通道的数量。通常输入图像可以有3个通道:RGB。经过几次卷积后,一个图像可能有多个通道。你可以把每个频道想象成那个图像的一个特殊解释;例如,“红色”通道解释每个像素的“红色”,“蓝色”通道解释每个像素的“蓝色”,“绿色”通道解释每个像素的“绿色”。一个有64个频道的图像有64种不同的解释。

深度可分离卷积将一个核分裂成两个独立的核,分别做两个卷积:深度卷积和点向卷积。

标准的卷积过程可以看上图,一个5×5的卷积核在卷积时,对应图像区域中的所有通道均被同时考虑,问题在于,为什么一定要同时考虑图像区域和通道?我们为什么不能把通道和空间区域分开考虑?

深度可分离卷积提出了一种新的思路:对于不同的输入channel采取不同的卷积核进行卷积,它将普通的卷积操作分解为两个过程。

《[深度学习] 深度可分离卷积》

 卷积过程

假设有 《[深度学习] 深度可分离卷积》的输入,同时有 k个 3×3的卷积。如果设置 padding=1且 stride=1,那么普通卷积输出为 《[深度学习] 深度可分离卷积》 。

《[深度学习] 深度可分离卷积》

Depthwise 过程

Depthwise是指将 《[深度学习] 深度可分离卷积》的输入分为 C 组,然后每一组做 3×3卷积。这样相当于收集了每个Channel的空间特征,即Depthwise特征。   输出《[深度学习] 深度可分离卷积》

《[深度学习] 深度可分离卷积》

Pointwise 过程

Pointwise是指对 的输入《[深度学习] 深度可分离卷积》(上面的输出)做 k个普通的1×1卷积。这样相当于收集了每个点的特征,即Pointwise特征。Depthwise+Pointwise最终输出也是 《[深度学习] 深度可分离卷积》.

《[深度学习] 深度可分离卷积》

 

二 实际例子

例子1

常规卷积操作

对于一张5×5像素、三通道(shape为5×5×3),经过3×3卷积核的卷积层(假设输出通道数为4,则卷积核shape为3×3×3×4,最终输出4个Feature Map,如果有same padding则尺寸与输入层相同(5×5),如果没有则为尺寸变为3×3

《[深度学习] 深度可分离卷积》

卷积层共4个Filter,每个Filter包含了3个Kernel,每个Kernel的大小为3×3。因此卷积层的参数数量可以用如下公式来计算:

N_std = 4 × 3 × 3 × 3 = 108

 

第1部分-深度卷积

Depthwise Convolution的一个卷积核负责一个通道,一个通道只被一个卷积核卷积

一张5×5像素、三通道彩色输入图片(shape为5×5×3),Depthwise Convolution首先经过第一次卷积运算,DW完全是在二维平面内进行。卷积核的数量与上一层的通道数相同(通道和卷积核一一对应)。所以一个三通道的图像经过运算后生成了3个Feature map(如果有same padding则尺寸与输入层相同为5×5),如下图所示。

《[深度学习] 深度可分离卷积》

其中一个Filter只包含一个大小为3×3的Kernel,卷积部分的参数个数计算如下:

N_depthwise = 3 × 3 × 3 = 27

Depthwise Convolution完成后的Feature map数量与输入层的通道数相同,无法扩展Feature map。而且这种运算对输入层的每个通道独立进行卷积运算,没有有效的利用不同通道在相同空间位置上的feature信息。因此需要Pointwise Convolution来将这些Feature map进行组合生成新的Feature map

第2部分-逐点卷积

Pointwise Convolution的运算与常规卷积运算非常相似,它的卷积核的尺寸为 1×1×M,M为上一层的通道数。所以这里的卷积运算会将上一步的map在深度方向上进行加权组合,生成新的Feature map。有几个卷积核就有几个输出Feature map

《[深度学习] 深度可分离卷积》

由于采用的是1×1卷积的方式,此步中卷积涉及到的参数个数可以计算为:

N_pointwise = 1 × 1 × 3 × 4 = 12

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

参数对比

回顾一下,常规卷积的参数个数为:
N_std = 4 × 3 × 3 × 3 = 108

Separable Convolution的参数由两部分相加得到:
N_depthwise = 3 × 3 × 3 = 27
N_pointwise = 1 × 1 × 3 × 4 = 12
N_separable = N_depthwise + N_pointwise = 39

相同的输入,同样是得到4张Feature map,Separable Convolution的参数个数是常规卷积的约1/3。因此,在参数量相同的前提下,采用Separable Convolution的神经网络层数可以做的更深。

 

 

例子2

常规普通卷积

一个典型的图像不是二维的;它也有深度,宽度和高度。假设我们有一个12x12x3像素的输入图像,大小为12×12的RGB图像。

我们对图像做一个5×5的卷积,不加填充,步幅为1。如果我们只考虑图像的宽度和高度,卷积过程是这样的:12×12 – (5×5) – >8×8。5×5内核每25个像素进行标量乘法,每次输出一个数字。由于没有填充(12-5 +1 = 8),我们最终得到一个8×8像素的图像。

然而,由于图像有3个通道,卷积核也需要有3个通道。这意味着,不是做5×5=25次乘法,而是每次内核移动时做5x5x3=75次乘法。

就像二维解释一样,我们对每25个像素做标量矩阵乘法,输出一个数字。在经过5x5x3内核之后,12x12x3图像将变成8x8x1图像。

《[深度学习] 深度可分离卷积》

如果我们想增加输出图像中的通道数量呢?如果我们想要大小为8x8x256的输出呢?

我们可以创建256个内核来创建256个8x8x1图像,然后将它们堆叠在一起,创建出8x8x256图像输出。

《[深度学习] 深度可分离卷积》

这就是正常卷积的工作原理。

我喜欢把它看做一个函数:12x12x3-(5x5x3x256)->8x8x256(其中5x5x3x256表示内核的高度、宽度、输入通道数和输出通道数)。并不是说这不是矩阵乘法;我们不是将整个图像乘以内核,而是将内核移动到图像的每个部分,并分别乘以图像的小部分。

深度可分离卷积将这个过程分为两部分:深度卷积和点向卷积。

 

第1部分-深度卷积:

不使用padding, 并使用same

在第一部分深度卷积中,我们在不改变深度的情况下,对输入图像进行了反方向卷积。我们使用3个5x5x1形状的内核。

可以参考一下视频:https://youtu.be/D_VJoaSew7Q

《[深度学习] 深度可分离卷积》

每个5x5x1内核迭代图像的1个通道(注意:1个通道,而不是所有通道),得到每25个像素组的标量积,得到一个8x8x1图像。将这些图像叠加在一起可创建8x8x3图像。

 

第2部分-点向卷积:

记住,原始卷积将12x12x3图像转换为8x8x256图像。目前,深度卷积已经将12x12x3图像转换为8x8x3图像。现在,我们需要增加每个图像的通道数。

点向卷积之所以如此命名是因为它使用了一个1×1内核,或者说是一个遍历每个点的内核。该内核有一个深度,不管输入图像有多少通道;在我们的例子中,它是3。因此,我们通过8x8x3图像迭代1x1x3内核,得到8x8x1图像。

《[深度学习] 深度可分离卷积》

我们可以创建256个1x1x3内核,每个内核输出一个8x8x1图像,以得到形状为8x8x256的最终图像。

《[深度学习] 深度可分离卷积》

就这样!我们把卷积分解成2:深度卷积和点向卷积。

更抽象地说,如果原始卷积函数是12x12x3 – (5x5x3x256)→8x8x256,

我们可以将这个新的卷积表示为12x12x3 – (5x5x1x3) →8x8x3 – > (1x1x3x256) – >8x8x256。

 

三 深度可分离卷积优势与创新

我们来计算一下计算机在原始卷积中要做的乘法的个数。有256个5x5x3内核可以移动8×8次。这是256x5x5x3x8x8 = 1228800 次乘法。

可分离卷积呢? 在深度卷积中,我们有3个5x5x1的内核它们移动了8×8次。也就是3x5x5x1x8x8 = 4800。在点向卷积中,我们有256个1x1x3的内核它们移动了8×8次。这是256x1x1x3x8x8 = 49152。把它们加起来,就是53952次乘法。

52,952比1,228,800小很多。计算量越少,网络就能在更短的时间内处理更多的数据。

然而,这是如何实现的呢? 我第一次遇到这种解释时,我的直觉并没有真正理解它。这两个卷积不是做同样的事情吗?在这两种情况下,我们都通过一个5×5内核传递图像,将其缩小到一个通道,然后将其扩展到256个通道。为什么一个的速度是另一个的两倍多?

经过一段时间的思考,我意识到主要的区别是:在普通卷积中,我们对图像进行了256次变换。每个变换都要用到5x5x3x8x8=4800次乘法。在可分离卷积中,我们只对图像做一次变换——在深度卷积中。然后,我们将转换后的图像简单地延长到256通道。不需要一遍又一遍地变换图像,我们可以节省计算能力。

值得注意的是,在Keras和Tensorflow中,都有一个称为“深度乘数”的参数。默认设置为1。通过改变这个参数,我们可以改变深度卷积中输出通道的数量。例如,如果我们将深度乘法器设置为2,每个5x5x1内核将输出8x8x2的图像,使深度卷积的总输出(堆叠)为8x8x6,而不是8x8x3。有些人可能会选择手动设置深度乘法器来增加神经网络中的参数数量,以便更好地学习更多的特征。

深度可分离卷积是不是很棒?当然!因为它减少了卷积中参数的数量,如果你的网络已经很小,你可能会得到很少的参数,你的网络可能无法在训练中正确运作。然而,如果使用得当,它可以在适当的情况下提高效率,这使得它成为一个非常受欢迎的选择。

 

1×1 Kernels:

最后,由于点向卷积使用了这个概念,我想讨论一下1×1内核的用法。

一个1×1内核——或者更确切地说,n个1x1xm内核,其中n是输出通道的数量,m是输入通道的数量——可以在可分离卷积之外使用。1×1内核的一个明显目的是增加或减少图像的深度。如果你发现卷积有太多或太少的通道,1×1核可以帮助平衡它。

然而,对我来说,1×1核的主要目的是应用非线性。在神经网络的每一层之后,我们都可以应用一个激活层。无论是ReLU、PReLU、Softmax还是其他,与卷积层不同,激活层是非线性的。直线的线性组合仍然是直线。非线性层扩展了模型的可能性,这也是通常使“深度”网络优于“宽”网络的原因。为了在不显著增加参数和计算量的情况下增加非线性层的数量,我们可以应用一个1×1内核并在它之后添加一个激活层。这有助于给网络增加一层深度。

 

 

 

参考:

http://www.atyun.com/39076.html

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

『高性能模型』深度可分离卷积和MobileNet_v1

 

 

    原文作者:Vinkin~Fight
    原文地址: https://blog.csdn.net/zwqjoy/article/details/103384367
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞