参考资料:
https://www.cnblogs.com/shine-lee/p/10243114.html
https://blog.yani.ai/filter-group-tutorial/
https://blog.csdn.net/zhangjunhit/article/details/90762578
Group Convolution分组卷积,最早见于AlexNet——2012年Imagenet的冠军方法,Group Convolution被用来切分网络,使其在2个GPU上并行运行,AlexNet网络结构如下:
动机:用分组卷积的操作,来缓解对单个处理器的压力。例如,当前一些轻量级的SOTA(State Of The Art)网络。
如果输入feature map尺寸为C∗H∗W,卷积核有N个,输出feature map与卷积核的数量相同也是N,每个卷积核的尺寸为C∗K∗K,N个卷积核的总参数量为N∗C∗K∗K,输入map与输出map的连接方式如下图左所示:
对输入feature map进行分组,然后每组分别卷积。假设输入feature map的尺寸仍为C∗H∗W,输出feature map的数量为N个,如果设定要分成G个groups,则每组的输入feature map数量为 C G \frac{C}{G} GC,每组的输出feature map数量为 N G \frac{N}{G} GN,每个卷积核的尺寸为 C G ∗ K ∗ K \frac{C}{G}∗K∗K GC∗K∗K,卷积核的总数仍为N个,每组的卷积核数量为 N G \frac{N}{G} GN,卷积核只与其同组的输入map进行卷积,卷积核的总参数量为 N ∗ C G ∗ K ∗ K N*\frac{C}{G}∗K∗K N∗GC∗K∗K,可见,总参数量减少为原来的 1 G \frac{1}{G} G1,其连接方式如上图右所示,group1输出map数为2,有2个卷积核,每个卷积核的channel数为4,与group1的输入map的channel数相同,卷积核只与同组的输入map卷积,而不与其他组的输入map卷积。
减少参数量,分成G组,则该层的参数量减少为原来的 1 G \frac{1}{G} G1
Group Convolution可以看成是structured sparse,每个卷积核的尺寸由C∗K∗K变为 C G ∗ K ∗ K \frac{C}{G}∗K∗K GC∗K∗K,可以将其余 ( C − C G ) ∗ K ∗ K (C-\frac{C}{G})∗K∗K (C−GC)∗K∗K的参数视为0,有时甚至可以在减少参数量的同时获得更好的效果(相当于正则)。
当分组数量等于输入map数量,输出map数量也等于输入map数量,即G=N=C、N个卷积核每个尺寸为1∗K∗K时,Group Convolution就成了Depthwise Convolution,参见MobileNet和Xception等,参数量进一步缩减,如下图所示:
global average pooling(全局平均池化,GAP):当G=C=N且K=H=W.
在NIN(Network In Network)论文中提出的全局平均池化,主要是为了区别全连接层。CNN分类的全连接层的作用:将最后一层卷积得到的feature map stretch成向量,对这个向量做乘法,最终降低其维度,然后输入到softmax层中得到对应的每个类别的得分。
全连接存在的问题:参数量过大,降低了训练的速度,且很容易过拟合。全连接层将卷积层展开成向量之后不还是要针对每个feature map进行分类,而GAP的思路就是将上述两个过程合二为一,一起做了。如图所示:
论文:Network In Network
论文下载:https://arxiv.org/abs/1312.4400
论文解读:https://www.cnblogs.com/makefile/p/nin.html
此时,卷积层共4个Filter,每个Filter包含了3个Kernel,每个Kernel的大小为3×3。因此卷积层的参数数量可以用如下公式来计算:N_std = 4 × 3 × 3 × 3 = 108
其中一个Filter只包含一个大小为3×3的Kernel,卷积部分的参数个数计算如下:
N_depthwise = 3 × 3 × 3 = 27
Depthwise Convolution完成后的Feature map数量与输入层的depth相同,但是这种运算对输入层的每个channel独立进行卷积运算后就结束了,没有有效的利用不同map在相同空间位置上的信息。因此需要增加另外一步操作来将这些map进行组合生成新的Feature map,即接下来的Pointwise Convolution。
由于采用的是1×1卷积的方式,此步中卷积涉及到的参数个数可以计算为:
N_pointwise = 1 × 1 × 3 × 4 = 12
经过Pointwise Convolution之后,同样输出了4张Feature map,与常规卷积的输出维度相同。
Depthwise Separable Convolution:核心思想是将一个完整的卷积运算分解为两步进行,分别为Depthwise Convolution与Pointwise Convolution。参数个数可以计算为:
N_separable = N_depthwise + N_pointwise = 39
相同的输入,同样是得到4张Feature map,Separable Convolution的参数个数是常规卷积的约1/3。因此,在参数量相同的前提下,采用Separable Convolution的神经网络层数可以做的更深。
Group conv是一种channel分组的方式,Depthwise +Pointwise是卷积的方式,只是ShuffleNet里面把两者应用起来了。因此Group conv和Depthwise +Pointwise并不能划等号。
Depthwise +Pointwise卷积是提供一种把feature map的空间信息(height&width)和通道信息(channel)拆分分别处理的方法,而group卷积只是单纯的通道分组处理,降低复杂度。
原始的conv操作可以看做一个2D版本的无隐层神经网络。
代表模型:
LeNet:最早使用stack单卷积+单池化结构的方式,卷积层来做特征提取,池化来做空间下采样
AlexNet:后来发现单卷积提取到的特征不是很丰富,于是开始stack多卷积+单池化的结构
VGG([1409.1556] Very Deep Convolutional Networks for Large-Scale Image Recognition):结构没怎么变,只是更深了
每层卷积只能用一种尺寸的卷积核?-- Inception结构
融合了Network In Network的增加隐层提升非线性表达的思想,于是有了这种先用1*1的卷积映射到隐空间,再在隐空间做卷积的结构。同时考虑了多尺度,在单层卷积层中用多个不同大小的卷积核来卷积,再把结果concat起来。
这一结构,被称之为“Inception”。
代表模型:
Inception-v1([1409.4842] Going Deeper with Convolutions):stack以上这种Inception结构
Inception-v2(Accelerating Deep Network Training by Reducing Internal Covariate Shift):加了BatchNormalization正则,去除55卷积,用两个33代替
Inception-v3([1512.00567] Rethinking the Inception Architecture for Computer Vision):77卷积又拆成71+1*7
Inception-v4([1602.07261] Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning):加入了残差结构
Depthwise Separable Convolution,可以说是Inception的延续。顾名思义,将depthwise convolution和pointwise convolution两个过程合起来。这个pointwise convolution就是1*1的卷积,可以看做是对那么多分离的通道做了个融合。
从Inception结构来看深度可分离卷积。
Inception结构(简化版本):
上面的简化版本,我们又可以看做,把一整个输入做 1 ∗ 1 1*1 1∗1卷积,然后切成三段,分别 3 ∗ 3 3*3 3∗3卷积后相连,如下图,这两个形式是等价的,即Inception的简化版本又可以用如下形式表达:
如果不是分成三段,而是分成5段或者更多,那模型的表达能力是不是更强呢?于是我们就切更多段,切到不能再切了,正好是Output channels的数量(极限版本):
于是,就有了深度卷积(depthwise convolution),深度卷积是对输入的每一个channel独立的用对应channel的所有卷积核去卷积,假设卷积核的shape是[filter_height, filter_width, in_channels, channel_multiplier],那么每个in_channel会输出channel_multiplier那么多个通道,最后的feature map就会有in_channels * channel_multiplier个通道了。反观普通的卷积,输出的feature map一般就只有channel_multiplier那么多个通道。
参考资料:
【Tensorflow】tf.nn.depthwise_conv2d如何实现深度卷积? - CSDN博客
【Tensorflow】tf.nn.separable_conv2d如何实现深度可分卷积? - CSDN博客
**代表模型:**Xception(Xception: Deep Learning with Depthwise Separable Convolutions)
在图像分割领域,图像输入到CNN(典型的网络比如FCN)中,图像分割FCN中有两个关键,一个是pooling减小图像尺寸增大感受野,另一个是upsampling扩大图像尺寸。在先减小再增大尺寸的过程中,肯定有一些信息损失掉了,那么能不能设计一种新的操作,不通过pooling也能有较大的感受野看到更多的信息呢?
Dilation卷积,空洞卷积,是解决pixel-wise输出模型的一种常用的卷积方式。一种普遍的认识是,pooling下采样操作导致的信息丢失是不可逆的,通常的分类识别模型,只需要预测每一类的概率,所以我们不需要考虑pooling会导致损失图像细节信息的问题,但是做像素级的预测时(譬如语义分割),就要考虑到这个问题了。所以就要有一种卷积代替pooling的作用(成倍的增加感受野),而空洞卷积就是为了做这个的。通过卷积核插“0”的方式,它可以比普通的卷积获得更大的感受野,这个idea的motivation就介绍到这里。
参考资料:
如何理解空洞卷积(dilated convolution)?
膨胀卷积–Multi-scale context aggregation by dilated convolutions
【Tensorflow】tf.nn.atrous_conv2d如何实现空洞卷积? - CSDN博客
标准的3×3卷积核只能看到对应区域3×3的大小,但是为了能让卷积核看到更大的范围,dilated conv使其成为了可能。dilated conv原论文中的结构如图所示:
上图b可以理解为卷积核大小依然是3×3,但是每个卷积点之间有1个空洞,也就是在绿色7×7区域里面,只有9个红色点位置作了卷积处理,其余点权重为0。这样即使卷积核大小不变,但它看到的区域变得更大了。
dilated convolution的好处是不做pooling损失信息的情况下,加大了感受野,让每个卷积输出都包含较大范围的信息,在图像需要全局信息或者语音文本需要较长的sequence信息依赖的问题中,都能很好的应用dilated conv。
代表模型:
FCN([1411.4038] Fully Convolutional Networks for Semantic Segmentation):Fully convolutional networks,顾名思义,整个网络就只有卷积组成,在语义分割的任务中,因为卷积输出的feature map是有spatial信息的,所以最后的全连接层全部替换成了卷积层。
Wavenet(WaveNet: A Generative Model for Raw Audio):用于语音合成。
这是ImageNet 2017 竞赛 Image Classification 任务的冠军模型SENet的核心模块,原文叫做”Squeeze-and-Excitation“,暂且把这个卷积称作”特征重标定卷积“。
和前面不同的是,这个卷积是对特征维度作改进的。一个卷积层中往往有数以千计的卷积核,而且我们知道卷积核对应了特征,于是乎那么多特征要怎么区分?这个方法就是通过学习的方式来自动获取到每个特征通道的重要程度,然后依照计算出来的重要程度去提升有用的特征并抑制对当前任务用处不大的特征。
首先做普通的卷积,得到了一个的output feature map,它的shape为[C,H,W],根据paper的观点,这个feature map的特征很混乱。然后为了获得重要性的评价指标,直接对这个feature map做一个Global Average Pooling,然后我们就得到了长度为C的向量。(这里还涉及到一个额外的东西,如果你了解卷积,你就会发现一旦某一特征经常被激活,那么Global Average Pooling计算出来的值会比较大,说明它对结果的影响也比较大,反之越小的值,对结果的影响就越小)
然后我们对这个向量加两个FC层,做非线性映射,这俩FC层的参数,也就是网络需要额外学习的参数。
最后输出的向量,我们可以看做特征的重要性程度,然后与feature map对应channel相乘就得到特征有序的feature map了。
另外它还可以和几个主流网络结构结合起来一起用,比如Inception和Res:
**代表模型:**Squeeze-and-Excitation Networks(Squeeze-and-Excitation Networks)
卷积核形状一定是矩形吗?-- Deformable convolution
传统的卷积核一般都是长方形或正方形,但MSRA提出了一个相当反直觉的见解,认为卷积核的形状可以是变化的,变形的卷积核能让它只看感兴趣的图像区域 ,这样识别出来的特征更佳。
要做到这个操作,可以直接在原来的过滤器前面再加一层过滤器,这层过滤器学习的是下一层卷积核的位置偏移量(offset),这样只是增加了一层过滤器,或者直接把原网络中的某一层过滤器当成学习offset的过滤器,这样实际增加的计算量是相当少的,但能实现可变形卷积核,识别特征的效果更好。
详细MSRA的解读可以看这个链接:可变形卷积网络:计算机新“视”界。
上图中包含两处卷积,第一处是获取offsets的卷积,即我们对input feature map做卷积,得到一个输出(offset field),然后再在这个输出上取对应位置的一组值作为offsets。假设input feature map的shape为[batch,height,width,channels],我们指定输出通道变成两倍,卷积得到的offset field就是[batch,height,width,2×channels],为什么指定通道变成两倍呢?因为我们需要在这个offset field里面取一组卷积核的offsets,而一个offset肯定不能一个值就表示的,最少也要用两个值(x方向上的偏移和y方向上的偏移)所以,如果我们的卷积核是33,那意味着我们需要33个offsets,一共需要233个值,取完了这些值,就可以顺利使卷积核形变了。第二处就是使用变形的卷积核来卷积,这个比较常规。(这里还有一个用双线性插值的方法获取某一卷积形变后位置的输入的过程)
这里有一个介绍性的Slide:http://prlab.tudelft.nl/sites/default/files/Deformable_CNN.pdf
**代表模型:**Deformable Convolutional Networks(Deformable Convolutional Networks):暂时还没有其他模型使用这种卷积,期待后续会有更多的工作把这个idea和其他视觉任务比如检测,跟踪相结合。
卷积类型 | 输出大小 | 参数数量 | 层数 | 切入点 | 代表模型 |
---|---|---|---|---|---|
普通卷积 | 1 | LeNet, AleNet, VGG | |||
多尺寸卷积 | 变大 | 增加很多 | >=2 | 多尺度(空间维度) | Inception V1, Inception V2, Inception V3, Inception V4 |
空洞卷积(Dialated Conv) | 与普通卷积保持一致 | 与普通卷积保持一致 | 1 | 感受野(空间维度) | FCN, Wavenet |
深度可分离卷积(Depthwise Separate Conv) | 变大 | 略微增加 | >=2 | 空间维度/特征维度 | Xception |
可变形卷积(Deformable Conv) | 增加 | >=2 | 空间维度 | Deformable Convolutional Networks | |
特征重标定卷积 | 增加 | >=2 | 特征维度 | SENet | |
参考资料:
https://www.cnblogs.com/shixiangwan/p/7536369.html
https://zhuanlan.zhihu.com/p/29367273
卷积核一定越大越好吗?-- 小卷积核
分组卷积首先在在AlexNet中出现,还用到一些非常大的卷积核,比如11×11、5×5卷积核,先前的观念是:卷积核越大,receptive field(感受野)越大,获取到的图片信息越多,因此获得的特征越好。但是大的卷积核会导致计算量的暴增,不利于模型深度的增加,计算性能也会降低。
卷积核一定越大越好?-- 3×3卷积核
VGG用小卷积核替代大卷积核,利用2个3×3卷积核的组合比1个5×5卷积核的效果更佳,同时参数(3×3×2 VS 5×5×1)被降低,因此后来3×3卷积核被广泛应用在各种模型中。
每层卷积只能用一种尺寸的卷积核?-- 多尺寸卷积
传统的层叠式网络,基本上都是一个个卷积层的堆叠,每层只用一个尺寸的卷积核,例如VGG结构中使用了大量的3×3卷积层。事实上,同一层feature map可以分别使用多个不同尺寸的卷积核,以获得不同尺度的特征,再把这些特征结合起来,得到的特征往往比使用单一卷积核的要好,谷歌的GoogleNet,或者说Inception系列的网络,就使用了多个卷积核的结构:
GoogleNet优点:一个输入的feature map分别同时经过1×1、3×3、5×5的卷积核的处理,得出的特征再组合起来,获得更佳的特征。
GoogleNet缺点:这个结构会存在一个严重的问题:参数量比单种卷积核要多很多,如此庞大的计算量会使得模型效率低下。
怎样减少卷积层参数量?-- Bottleneck
发明GoogleNet的团队发现,如果仅仅引入多个尺寸的卷积核,会带来大量的额外的参数,受到Network In Network中1×1卷积核的启发,为了解决这个问题,他们往Inception结构中加入了一些1×1的卷积核,如图所示:
即引入了bottleneck结构,在每个卷积核前加上1x1卷积核来降低参数量。
根据上图,我们来做个对比计算,假设输入feature map的维度为256维,要求输出维度也是256维。有以下两种操作:
1×1卷积核也被认为是影响深远的操作,往后大型的网络为了降低参数量都会应用上1×1卷积核。
越深的网络就越难训练吗?– ResNet残差网络
传统的卷积层层叠网络会遇到一个问题,当层数加深时,网络的表现越来越差,很大程度上的原因是因为当层数加深时,梯度消散得越来越严重,以至于反向传播很难训练到浅层的网络。
为了解决这个问题,何凯明大神想出了一个“残差网络”,使得梯度更容易地流动到浅层的网络当中去,而且这种“skip connection”能带来更多的好处。
残差网络ResNet设计的残差模块,如下图所示,可以训练更深的网络。
参考:
极深网络(ResNet/DenseNet): Skip Connection为何有效及其它
为什么ResNet和DenseNet可以这么深?一文详解残差块为何能解决梯度弥散问题
卷积操作时必须同时考虑通道和区域吗?-- DepthWise操作
标准的卷积过程可以看上图,一个2×2的卷积核在卷积时,对应图像区域中的所有通道均被同时考虑,问题在于,为什么一定要同时考虑图像区域和通道?我们为什么不能把通道和空间区域分开考虑?
Xception网络就是基于以上的问题发明而来。我们首先对每一个通道进行各自的卷积操作,有多少个通道就有多少个过滤器。得到新的通道feature maps之后,这时再对这批新的通道feature maps进行标准的1×1跨通道卷积操作。这种操作被称为 “DepthWise convolution” ,缩写“DW”。
这种操作是相当有效的,在imagenet 1000类分类任务中已经超过了InceptionV3的表现,而且也同时减少了大量的参数,我们来算一算,假设输入通道数为3,要求输出通道数为256,两种做法:
直接接一个3×3×256的卷积核,参数量为:3×3×3×256 = 6,912
DW操作,分两步完成,参数量为:3×3×3 + 3×1×1×256 = 795,又把参数量降低到九分之一!
因此,一个depthwise操作比标准的卷积操作降低不少的参数量,同时论文中指出这个模型得到了更好的分类效果。
分组卷积能否对通道进行随机分组?-- ShuffleNet
在AlexNet的Group Convolution当中,特征的通道被平均分到不同组里面,最后再通过两个全连接层来融合特征,这样一来,就只能在最后时刻才融合不同组之间的特征,对模型的泛化性是相当不利的。为了解决这个问题,ShuffleNet在每一次层叠这种Group conv层前,都进行一次channel shuffle,shuffle过的通道被分配到不同组当中。进行完一次group conv之后,再一次channel shuffle,然后分到下一层组卷积当中,以此循环。
ShuffleNet引入逐点分组卷积(pointwise group convolution)和通道混洗(channel shuffle),改进AlexNet中的Group Convolution。
经过channel shuffle之后,Group conv输出的特征能考虑到更多通道,输出的特征自然代表性就更高。另外,AlexNet的分组卷积,实际上是标准卷积操作,而在ShuffleNet里面的分组卷积操作是depthwise卷积,因此结合了通道洗牌和分组depthwise卷积的ShuffleNet,能得到超少量的参数以及超越mobilenet、媲美AlexNet的准确率!
通道间的特征都是平等的吗? – SEnet
无论是在Inception、DenseNet或者ShuffleNet里面,我们对所有通道产生的特征都是不分权重直接结合的,那为什么要认为所有通道的特征对模型的作用就是相等的呢?
SENet对特征权重重分配,使得特征显著性增强。
一组特征在上一层被输出,这时候分两条路线,第一条直接通过,第二条首先进行Squeeze操作(Global Average Pooling),把每个通道3维的特征压缩成一个1维,从而得到一个特征通道向量(每个数字代表对应通道的特征)。然后进行Excitation操作,把这一列特征通道向量输入两个全连接层和sigmoid,建模出特征通道间的相关性,得到的输出其实就是每个通道对应的权重,把这些权重通过Scale乘法通道加权到原来的特征上(第一条路),这样就完成了特征通道的权重分配。
论文:Squeeze-and-Excitation Networks
论文链接:https://arxiv.org/abs/1709.01507
代码地址:https://github.com/hujie-frank/SENet
PyTorch代码地址:https://github.com/miraclewkf/SENet-PyTorch
论文解读:https://www.jianshu.com/p/59fdc448a33f
参考资料:专栏 | Momenta详解ImageNet 2017夺冠架构SENet
参考资料:https://blog.csdn.net/liqiming100/article/details/82111115
CNN模型的发展趋势:从巨型网络到轻量化网络。现在工业界追求的重点已经不是准确率的提升(因为都已经很高了),都聚焦于速度与准确率的trade off,都希望模型又快又准。因此从原来AlexNet、VGGnet,到体积小一点的Inception、Resnet系列,到目前能移植到移动端的MobileNet、ShuffleNet(体积能降低到0.5mb!)。
卷积核:
卷积层连接:
卷积层通道:
启发
类比到通道加权操作,卷积层跨层连接能否也进行加权处理?bottleneck + Group conv + channel shuffle + depthwise的结合会不会成为以后降低参数量的标准配置?
欢迎各位关注我的个人公众号:HsuDan,我将分享更多自己的学习心得、避坑总结、面试经验、AI最新技术资讯。