Depthwise(DW)卷积与Pointwise(PW)卷积,合起来被称作Depthwise Separable Convolution(参见Google的Xception),该结构和常规卷积操作类似,可用来提取特征,但相比于常规卷积操作,其参数量和运算成本较低。所以在一些轻量级网络中会碰到这种结构,如MobileNet。
MobileNet原论文:https://arxiv.org/pdf/1704.04861.pdfhttps://arxiv.org/pdf/1704.04861.pdf
1、常规卷积操作
对于一张5×5像素、三通道彩色输入图片(shape为5×5×3)。经过3×3卷积核的卷积层(假设输出通道数为4,则卷积核shape为3×3×3×4),最终输出4个Feature Map,如果有same padding则尺寸与输入层相同(5×5),如果没有则为尺寸变为3×3。
2、Depthwise Separable Convolution
为了降低卷积中的参数,谷歌研究人员提出将常规卷积拆分为 Depthwise 和 Pointwise 两部分。即Depthwise Separable Convolution是将一个完整的卷积运算分解为两步进行,即Depthwise Convolution与Pointwise Convolution。
a) Depthwise Convolution
不同于常规卷积操作,Depthwise Convolution的一个卷积核负责一个通道,一个通道只被一个卷积核卷积。上面所提到的常规卷积每个卷积核是同时操作输入图片的每个通道。
同样是对于一张5×5像素、三通道彩色输入图片(shape为5×5×3),Depthwise Convolution首先经过第一次卷积运算,不同于上面的常规卷积,DW完全是在二维平面内进行。卷积核的数量与上一层的通道数相同(通道和卷积核一一对应)。所以一个三通道的图像经过运算后生成了3个Feature map(如果有same padding则尺寸与输入层相同为5×5),如下图所示。
Depthwise Convolution完成后的Feature map数量与输入层的通道数相同,无法扩展Feature map。而且这种运算对输入层的每个通道独立进行卷积运算,没有有效的利用不同通道在相同空间位置上的feature信息。因此需要Pointwise Convolution来将这些Feature map进行组合生成新的Feature map。
b) Pointwise Convolution
Pointwise Convolution的运算与常规卷积运算非常相似,它的卷积核的尺寸为 1×1×M,M为上一层的通道数。所以这里的卷积运算会将上一步的map在深度方向上进行加权组合,生成新的Feature map。有几个卷积核就有几个输出Feature map。如下图所示。
也就是说,depthwise层,只改变feature map的大小,不改变通道数。。而Pointwise 层则相反,只改变通道数,不改变大小。这样将常规卷积的做法(改变大小和通道数)拆分成两步走。
3、参数量的变化
常规卷积:一般来说,输入卷积的通道数如果是Ci,输出的通道数如果是Co,卷积核大小为 kxk,那么卷积的参数量就是 Ci x Co x k x k。 如“常规卷积操作”中,卷积核大小为3x3,参数量为:3x4x3x3=108。
Depthwise: 处理上述图像,分为三组处理,卷积核的数量与输入的通道数相同(即组数),所以经过运算生成三个 feature map,卷积的参数为:3x1x3x3=27。 Depthwise没有充分利用不同通道上相同位置的信息,因此需要 Pointwise 来将这些特征重新整合。
Pointwise: 卷积核尺寸为 1x1x3通道数。其实是将 Depthwise 的结果逐像素加权融合。但是,这里有几个 filter 输出就有几个通道。如下图所示,参数量为:1x1x3x4=12。
综上,通过 Depthwise 和 Pointwise 操作,卷积参数量为:27+12 = 39,显著小于常规卷积操作的 108。
4、Caffe 中的代码实现
海思 NNIE 中的 DepthwiseConv
层便是经过卷积优化后的。
5、其它问题
虽然使用深度可分离卷积可以让参数量变小,但是实际上用GPU训练的时候深度可分离卷积会非常的占用内存,并且比普通的3*3卷积要慢很多(实测)
//这一点本人在训练时也遇过,但是暂不清楚原因。