轻量级网络总结

1. SqueezeNet

SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and< 0.5 MB model size

考虑到卷积层的参数量为 C i n ∗ C o u t ∗ K ∗ K C_{in}*C_{out}*K*K CinCoutKK,显然,为了减少参数量,可以从输入输出通道数和卷积核尺寸两个角度出发:

  • 使用更多的1×1卷积
  • 减小3×3卷积的输入核输出通道数

根据以上两个基本原则,SqueezeNet中设计了一个Fire module,squeeze中只使用了1×1卷积,以较少的参数量为代价降低通道数,然后在expand中使用1×1和3×3扩展通道数。

在这里插入图片描述

class Fire(nn.Module):

    def __init__(self, inplanes, squeeze_planes,
                 expand1x1_planes, expand3x3_planes):
        super(Fire, self).__init__()
        self.inplanes = inplanes
        self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1)
        self.squeeze_activation = nn.ReLU(inplace=True)
        self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes,
                                   kernel_size=1)
        self.expand1x1_activation = nn.ReLU(inplace=True)
        self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes,
                                   kernel_size=3, padding=1)
        self.expand3x3_activation = nn.ReLU(inplace=True)

    def forward(self, x):
        x = self.squeeze_activation(self.squeeze(x))
        return torch.cat([
            self.expand1x1_activation(self.expand1x1(x)),
            self.expand3x3_activation(self.expand3x3(x))
        ], 1)

2. ShuffleNet

2.1 v1

ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices

提出问题:对于深度可分离卷积,1×1占用的计算量太大
解决方案:既然3×3卷积可以通过分组减小计算量,那么1×1也可以设置为分组卷积
引出新问题:如果多个组卷积堆叠在一起,就有一个副作用----来自某个通道的输出只来自输入通道的一小部分,如下图(a)所示,导致不同组之间无信息交流。
在这里插入图片描述
进一步的解决方案:将每个组中的通道划分为几个子组,然后向下一层中的每个组提供不同的子组,如上图(b)所示,此时不同组之间进行了信息的交流。

究极解决方案:使用channel shuffle操作,即reshape->transpose->flatten,简单的操作就能均匀打乱通道。
在这里插入图片描述

def channel_shuffle(x, groups):
	b, n, h, w = x.size()
	channels_per_group = n // groups
	# reshape
	x = x.view(b, groups, channels_per_group, h, w)
	# transpose
	# transpose导致tensor不连续,而view方法需要连续的tensor,所以transpose后需要使用.contiguous()
	x = torch.transpose(x, 1, 2).contiguous()
	# flatten
	x = x.view(b, -1, h, w)
	return x

基于以上改进,设计了新的残差单元----ShuffleNet Units,(a)为使用了标准的深度可分离卷积的残差单元,(b)为使用了1×1组卷积和channel shuffle的新残差单元,(c)为stride=2时的新残差单元,在shotcut分支采用了stride=2的AVG Pool而不是1×1卷积,并且使用concat代替add操作,能够以较低的成本扩充通道数。
在这里插入图片描述

2.2 v2

ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design
提出问题:神经网络架构的设计是由间接度量(如FLOPs)来指导的,但是实验表明,具有相似FLOPs的网络具有不同的速度(如下图所示),因此,使用FLOPs作为计算复杂度的唯一度量是不够的,可能会导致次优设计。
在这里插入图片描述
间接(FLOPs)和直接(速度)指标之间的差异可以归结于两个主要原因

  • 内存访问成本(MAC)和并行度:组卷积等高MAC操作(分组会导致读写操作成倍增加)可能会成为GPU的瓶颈;并行度高的模型比其他并行度低的模型快得多。
  • 根据平台的不同,具有相同流程的操作可能有不同的运行时间,如GPU和ARM

解决方案:对于有效的网络架构设计,应该考虑两个原则。首先,应该使用直接度量(例如,速度),而不是间接度量(例如,FLOPs)。其次,这些指标应该在目标平台上进行评估。

贡献
(1)推导了四种高效网络设计的指导方针

  • G1: 输入输出通道数相等可尽量降低内存访问成本(MAC):轻量级网络中常使用深度可分离卷积,其中点卷积计算复杂度最大,因此以点卷积为例进行分析。假设输入输出通道数分别为 C i n C_{in} Cin C o u t C_{out} Cout,特征图尺寸为 H × W H×W H×W,在bias=False的情况下,浮点运算次数 B = H × W × C o u t × C i n B=H×W×C_{out}×C_{in} B=H×W×Cout×Cin;假设计算设备中的缓存大到足以存储features和weight, M A C = H × W × ( C o u t + C i n ) + C o u t × C i n MAC=H×W×(C_{out}+C_{in})+C_{out}×C_{in} MAC=H×W×(Cout+Cin)+Cout×Cin。在固定FLOPs的情况下,根据均值不等式有:
    在这里插入图片描述 因此,MAC有一个由FLOPs给出的下界。当输入通道和输出通道的数量相等时,MAC达到下界。

  • G2: 过度的组卷积会增加MAC:对于分组卷积,浮点运算次数 B = ( H × W × C o u t × C i n ) / g B=(H×W×C_{out}×C_{in}) / g B=(H×W×Cout×Cin)/g,MAC与FLOPs的关系如下:
    在这里插入图片描述 显然,固定FLOPs时,MAC随着分组数g的增大而增大。

  • G3: 网络碎片化降低并行度:虽然多分支这种碎片化的结构已被证明有利于提升网络性能,但它可能会降低效率,因为它对像GPU这样具有强大并行计算能力的设备不友好。还引入了额外的开销,如内核启动和同步。

  • G4: 元素级操作是不可忽略的:在如shufflenet-v1和mobilenet-v2这样的轻量级模型中,元素级操作占用了相当多的时间,特别是在GPU上。元素级操作包括ReLU、Add等,虽然FLOPs很小,但是MAC较高。
    在这里插入图片描述

(2)基于推导的四种高效网络设计的指导方针,设计了新的轻量级残差模块(如下图,a、b是v1中的单元结构,c、d是v2中的单元结构):通过channel split保证输入输出通道数相等,符合G1; 将1×1分组卷积替换为标准的1×1卷积,符合G2和G3(因为分组卷积是碎片化结构);将Add替换为Concat,并去掉了最后的ReLU,替换为channel shuffle,符合G4。

在这里插入图片描述

3. MobileNet

3.1 v1

MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications
提出了深度可分离卷积,能够大幅减少参数量和计算量:
在这里插入图片描述
假设输入通道和输出通道数分别为 N N N M M M,卷积核尺寸为 D K × D K D_K×D_K DK×DK,输出特征图尺寸为 D F × D F D_F×D_F DF×DF,那么标准卷积的计算量为:
在这里插入图片描述
深度可分离卷积的计算量为:
在这里插入图片描述
计算量降低了:
在这里插入图片描述
有一点需要注意,由于Depthwise卷积使用了分组卷积,因此适用于移动端等流水线型平台,对GPU不友好。

3.2 v2

MobileNetV2: Inverted Residuals and Linear Bottlenecks

3.3 v3

Searching for MobileNetV3

4. GhostNet

4.1 v1

GhostNet: More Features from Cheap Operations
提出了轻量级模块Ghost module,简单来说,其实就是将深度可分离卷积倒过来,先PW卷积再DW卷积,只是减少了PW卷积数量,然后通过identity补上通道数,从而既能扩展输出通道数又能减少参数量和计算量。
在这里插入图片描述

4.2 v2

GhostNetV2: Enhance Cheap Operation with Long-Range Attention
self-attention能捕获全局信息,但是计算复杂度高,大幅增加推理耗时,对于轻量级模型来说无法接受。针对该问题,GhostNetV2为轻量化小模型专门设计硬件友好的注意力机制----基于解耦全连接层的注意力模块。

一个适用于端侧小模型的注意力模块应当满足3个条件:

  1. 对长距离空间信息的建模能力强。相比CNN,Transformer性能强大的一个重要原因是它能够建模全局空间信息,因此新的注意力模块也应当能捕捉空间长距离信息。
  2. 部署高效。注意力模块应该硬件友好,计算高效,以免拖慢推理速度,特别是不应包含硬件不友好的操作。
  3. 概念简单。为了保证注意力模块的泛化能力,这个模块的设计应当越简单越好。

自注意力模块能够很好地建模长期依赖关系,但是reshape和transpose操作会产生较高的时延。那么有什么操作可以替代注意力模块呢?分析一下自注意力模块中的操作,其实就是建立特征图中任意两个像素之间的关系,考虑到全连接层的输出与输入的每个元素都相关,因此也可以用来建模长期依赖,并且实现起来更方便。给定一个特征图 Z ∈ R H × W × C Z\in\mathbb{R}^{H\times W \times C} ZRH×W×C,可以视为 H × W H\times W H×W个tokens,然后直接通过全连接层生成注意力图,如下式:
在这里插入图片描述
按照上式计算注意力图仍然具有较高的计算复杂度,有研究表明,CNN中的特征图通常是低秩的,没有必要将不同空间位置的所有输入和输出tokens密集连接。考虑到特征图是二维,自然可以将全连接层分解为两个连续的FC层,沿着水平方向和垂直方向聚合特征(有点CCNet中交叉注意力的味道)。为了进一步减小计算量,在送入FC层前,对特征图进行下采样,在FC层后再上采样回到原来的尺寸。
在这里插入图片描述
在GhostNetV1 bottleneck的基础上插入DFC attention模块,就形成了GhostNetV2 bottleneck
在这里插入图片描述

  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值