参考:https://www.yanxishe.com/TextTranslation/1639
可分离卷积的基本介绍
任何看过MobileNet架构的人都会遇到可分离卷积(separable convolutions)这个概念。但什么是“可分离卷积”,它与标准的卷积又有什么区别?
可分离卷积主要有两种类型:空间可分离卷积(spatial separable convolutions)和深度可分离卷积(depthwise separable convolutions)。
空间可分离卷积
从概念上讲,这是两者中较容易的一个,并说明了讲一个卷积分成两部分(两个卷积核)的想法。空间可分离卷积具有一些显著的局限性,这意味着他在深度学习中没有被大量使用。
空间可分卷积之所以如此命名,是因为它主要处理图像和卷积核(kernel)的空间维度:宽度和高度。(另一个维度,“深度”维度,是每个图像的通道数)。
空间可分离卷积简单地将卷积核划分为两个较小的卷积核。最常见的情况是将3X3的卷积核划分为3X1和1X3的卷积核,如下:
图1: 在空间上分离3X3内核
现在,不是用9次乘法进行一次卷积,而是进行两次卷积,每次3次乘法(总共6次),已达到相同的效果。乘法较少,计算复杂性下降,网络运行速度更快。
图2:简单且空间可分离的卷积
最著名的可在空间上分离的卷积是用于边缘检测的sobel卷积核:
图3:分离的Sobel卷积核
空间可分卷积的主要问题是并非所有卷积核都可以“分离”成两个较小的卷积核。这在训练期间变得特别麻烦,因为网络可能采用所有可能的卷积核,他最终只能使用可以分成两个较小卷积核的一小部分。
深度可分离卷积基
与空间可分离卷积不同,深度可分离卷积使用的内核无法“分解”成两个较小的内核。因此,它更常用。在keras.layers.SeparableConv2D或tf.layers.separable_conv2d中看到的可分离卷积的类型。
深度可分离卷积之所以如此命名,是因为他不仅涉及空间维度,还涉及深度维度(通道数量)。输入图像可疑具有3个通道:R、G、B。在几次卷积之后,图像可以具有多个通道。你可以将每个通道想象成对图像特定的解释说明(interpret);例如,“红色”通道解释每个像素的“红色”,“蓝色”通道解释每个像素的“蓝色”,“绿色”通道解释每个像素的“绿色”。具有64个通道的图像具有对该图像的64种不同的解释。
类似于空间可分离卷积,深度可分离卷积将卷积核分成两个单独的卷积核,这两个卷积进行两个卷积:深度卷积核逐点卷积。
标准的卷积
假设有一个12X12X3像素的输入图像,即一个大小为12X12的RGB图像。对此图像进行5X5卷积,没有填充(padding)且步长为1.如果我们只考虑图像的宽度和高度,卷积过程就像这样:12X12 - (5X5) -> 8X8。5X5卷积核每25个像素进行标量乘法,每次输出1个数。最终得到一个8X8像素的图像,因为没有填充(12-5+1)= 8。
然而,由于图像有3个通道,我们的卷积核也需要有3个通道。这就意味着,每次卷积核移动时,我们实际上执行5X5X3=75次乘法,而不是进行5X5=25次乘法。和二维中的情况一样,我们每25个像素进行一次标量矩阵乘法,输出1个数字。经过5X5X3的卷积核后,12X12X3的图像将成为8X8X1的图像。
图4 具有8X8X1输出的标准卷积
如果我们想增加输出图像中的信道数量呢?如果我们想要8X8X256的输出呢?
我们可以创建256个卷积核来创建256个8X8X1图像,然后将他们堆叠在一起便可创建8X8X256的图像输出。
图5 拥有8X8X256输出的标准卷积
这就是标准卷积的工作原理。把它想象成一个函数:12X12X3 - (5X5X3X256)-> 12X12X256(其中5X5X3X256表示内核的高度、宽度、输入信道数和输出信道数)。并不是这不是矩阵乘法;我们不是将整个图像乘以卷积核,而是将卷积核移动到图像的每个部分,并分别乘以图像的一小部分。
深度可分离卷积的过程可以分为两部分:深度卷积(depthwise convolution)和逐点卷积(pointwise convolution)。
第一部分——深度卷积
深度卷积中,我们在不改变深度的情况下对输入图像进行卷积。使用3个5X5X1的内核。
图6 深度卷积,使用3个内核将12X12X3图像转换为8X8X3图像
每个5X5X1内核迭代图像的一个通道(注意:一个通道,不是所有通道),得到每25各像素组的标量积,得到一个8X8X1图像。将这些图像叠加在一起可以创建一个8X8X3的图像。
第二部分——逐点卷积
原始卷积将12X12X3图像转换为8X8X256图像。目前,深度卷积已经将12X12X3图像转换为8X8X3图像。现在,需要增加每个图像的通道数。
逐点卷积之所以如此命名是因为它使用了1X1核函数,或者说是一个便利每个点的核函数。该内核的深度为输入图像有多少通道,在此例中,是3.因此,通过8X8X3图像迭代1X1X3内核,得到8X8X1图像。
图7 逐点卷积,将一个3通道的图像转换为一个1通道的图像
我们可以创建256个1X1X3内核,每个内核输出一个8X8X1图像,已得到形状为8X8X256的最终图像。
图8 256个核的逐点卷积,输出256个通道的图像
就是这样,我们把卷积分解为两部分:深度卷积核逐点卷积。更抽象地说,如果原始卷积函数是12X12X3 - 5X5X3X256)-> (1X1X3X256)-> (12X12X256)。
深度可分离卷积的意义
计算机在原始卷积中要做乘法的个数:有256个5X5X3内核可以移动8X8次。这是256X3X5X5X8X8 = 1228800次乘法。
可分离卷积要做乘法的个数:有3个5X5X1的核他们移动了8X8次。就是3X5X5X8X8 = 4800次乘法。在点态卷积中,有256个1X1X3的核他们移动了8X8次。这是256X1X1X3X8X8 = 49152次乘法。把它们加起来,就是53952次乘法。
可见53952次乘法要比1228800小很多,计算量越少,网络就能在更短的时间内处理更多的数据。
这是如何实现的呢?我第一次遇到这种解释时,我的直觉并没有真正理解他。这两个卷积不是做同样的事情吗?在这两种情况下,我们都通过一个5X5的内核传递图像,将其缩小到一个通道,然后将其扩展到256个通道。为什么一个的速度是另一个的两倍多?
经过一段时间思考,我意识到主要的区别是:在普通卷积中,我们对图像进行了256次变换。每个变换都要用到5X5X8X8 = 4800次乘法。在可分离卷积中,我们只对图像做一次变换——深度卷积中。然后将转换后的图像简单延长到256通道。不需要一遍又一遍地变换图像,我们可以节省计算能力。
值得注意的是,在Keras和Tensorflow中,都有一个称为“深度乘法器”的参数。默认设置为1。通过改变这个参数,我们可以改变深度卷积中输出通道的数量。例如,如果我们将深度乘法器设置为2,每个5X5X1内核将输出8X8X2的图像,是深度卷积的总输出(堆叠)为8X8X6,而不是8X8x3。有些人可能会选择手动设置深度乘法器来增加神经网络中的参数数量,以便更好滴学习更多的特征。
深度可分离卷积的缺点
因为他减少了卷积中参数的数量,如果网络已经很小,可能会得到太少的参数,网络可能无法再训练中正确学习。然后,如果使用得当,他可以在不显著降低效力的情况下提高效率,这使得他成为一个非常受欢迎的选择。
1X1内核的用法
一个1X1内核或者更确切地说,n个1X1Xm内核,其中n是输出通道的数量,m是输入通道的数量可以在可分离卷积之外使用。1X1内核的一个明显目的是增加或减少图像的深度。如果你发现卷积有太多或太少的通道,1X1卷积核可以帮助平衡他。
然而,对我来说,1X1核的主要目的是应用非线性。在神经网络的每一层之后,我们都可以应用一个激活层。无论是ReLU、PReLU、Softmax还是其他,与卷积层不同,激活层是非线性的。直线的线性组合仍然是直线。非线性层扩展了模型的可能性,这也是通常使“深度”网络优于“宽”网络的原因。为了在不显著增加参数和计算量的情况下增加非线性层的数量,我们可以应用一个1X1内核并在它之后添加一个激活层。这有助于给网络增加一层深度。