轻量级网络之ShuffleNet v2

轻量级网络之ShuffleNet v2

  • 前言
  • 评价指标
  • 四个原则
  • 优化
  • 网络结构
  • 性能对比
  • channel shuffle的pytorch代码
  • DW卷积的pytorch代码

欢迎交流,禁止转载!!

前言

《ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design》
论文地址:https://arxiv.org/pdf/1807.11164v1.pdf
之前人们提出了很多轻量级的网络MobileNet V1 V2 和ShuffleNet V1等,但是可以发现参数量少≠运算速度快,这跟硬件以及计算方式有很大的关系,因此为了能加快速度,旷世做了认真的分析,并基于ShuffleNet V1加以改进出ShuffleNet V2。2018年被ECCV收录。

评价指标

首先,需要了解一下一些基本概念:

FLOPS:每秒浮点运算次数,这个由硬件决定。
GFLOPS:每秒10亿次的浮点运算数,1GFlops = 1,000MFlops。
FLOPs:指计算量的大小,理解为计算量。可以用来衡量算法/模型的复杂度。具体指的是multiply-add数量,计算模型中乘法和加法的运算次数。对于普通卷积层而言:FLOPs = 2*H*W( CinK2+1)Cout
maccs:是multiply-accumulate operations,指点积运算,一个 macc = 2FLOPs。
MAC:memory access cost 内存访问消耗,这里举个例子更好理解,比如1x1的卷积:MAC=H*W*Cin+H*W*Cout+1*1*Cin*Cout,第一项是输入特征层的内存访问消耗。第二项是输出特征层内存访问消耗,第三项是卷积核的内存访问消耗。
https://www.cnblogs.com/xuanyuyt/p/12653041.html

目前大部分的模型加速和压缩文章在对比加速效果时用的指标都是FLOPs,这个指标主要衡量的就是卷积层的乘法操作。但是文章通过实验发现FLOPs并不能完全衡量模型速度,下图是将模型各个部分运行时间分解后的图,可见在GPU上卷积所占的比重只有一半,数据的I/O、Shuffle、elemwise也占用了相当大的时间。当然,还跟计算操作的并行化有直接的关系,如果过于零散,速度也会下降。
轻量级网络之ShuffleNet v2_第1张图片

因此,作者计算得到了下面四条设计的指南

四个原则

注意:这些结论都是在FLOPs相等的条件下得到的,也就是说通过设计网络来减少上述提到的一些操作。并用一个网络来验证
G1: 输入输出通道数相同时,内存访问成本(MAC)最小化
轻量级网络之ShuffleNet v2_第2张图片
实验证明:
轻量级网络之ShuffleNet v2_第3张图片
G2:过多的分组卷积会加大内存访问成本(MAC)
轻量级网络之ShuffleNet v2_第4张图片
轻量级网络之ShuffleNet v2_第5张图片

G3:网络碎片化的结构会减小并行度
轻量级网络之ShuffleNet v2_第6张图片

轻量级网络之ShuffleNet v2_第7张图片

G4:Element-wise 操作不能被忽视

轻量级网络之ShuffleNet v2_第8张图片
这里把激活函数的运算和short-cut的相加操作考虑进来。

优化

根据上述四项原则,作者对V1进行了改进:

轻量级网络之ShuffleNet v2_第9张图片
轻量级网络之ShuffleNet v2_第10张图片

网络结构

轻量级网络之ShuffleNet v2_第11张图片
ShuffleNet V2不仅高效,而且精度也很高。主要的原因有两点:

  1. 每个块使用了更多的特征通道和更大的网络容量,很高效;
  2. 在每个块中,一半的特征通道直接通过这个块结构进入下一个块结构,这可以被看作一种特征复用,和DenseNet的思想很接近;
    轻量级网络之ShuffleNet v2_第12张图片

性能对比

可以看出ShuffleNet V2在速度和精度上都几乎达到了最优。
图像分类:
轻量级网络之ShuffleNet v2_第13张图片
目标检测 COCO数据集:

轻量级网络之ShuffleNet v2_第14张图片
在这里插入图片描述
作者下分析这里xception在目标检测上性能较好的原因是有更大的感受野,受此启发, 在ShuffleNetd v2每个block的1x1卷积前增加了3 × 3 depthwise convolution得到ShuffleNet v2*。个人觉得是参数量带来的提升。

channel shuffle的pytorch代码

def channel_shuffle(x: Tensor, groups: int) -> Tensor:

    batch_size, num_channels, height, width = x.size()
    channels_per_group = num_channels // groups
    # reshape
    # [batch_size, num_channels, height, width] -> [batch_size, groups, channels_per_group, height, width]
    x = x.view(batch_size, groups, channels_per_group, height, width)
    x = torch.transpose(x, 1, 2).contiguous()
    # flatten
    x = x.view(batch_size, -1, height, width)
    return x

DW卷积的pytorch代码

def depthwise_conv(input_c: int,output_c: int,kernel_s: int,stride: int = 1,padding: int = 0,
                       bias: bool = False) -> nn.Conv2d:
        return nn.Conv2d(in_channels=input_c, out_channels=output_c, kernel_size=kernel_s,
                         stride=stride, padding=padding, bias=bias, groups=input_c)

欢迎交流,禁止转载!!
上一篇:轻量级网络之ShuffleNet v1
下一篇:轻量级网络之MobileNet v3

你可能感兴趣的:(CNN卷积神经网络,深度学习,人工智能,算法,卷积,轻量级网络)