神经网络学习笔记13——高效卷积神经网络架构ShuffleNet
系列文章目录
文章目录
- 系列文章目录
- 前言
- 模型的发展
- 更大更强
- 更小更快
- 高效卷积神经网络架构
- 模型名称
- 参数量
- 乘加运算量
- 评价指标
- 高效卷积神经网络的比较
- 一、ShuffleNet
- 1、ShuffleNet V1
- 1.分组卷积Group Convolution
- 2.通道混洗操作channel shuffle
- 3.层结构与模型结构
- 2、ShuffleNet V2
- 1.MAC、MACs、FLOPs与FLOPS
- 2.高效网络设计指南
- 3.高效网络设计指南
- 4.层结构与模型结构
- 总结
前言
模型的发展
从2012年发展至今,神经网络模型经历了从卷积神经网络CNN到注意力机制Transformer等范式性的演进。然而,贯穿始终的核心研究驱动力始终围绕着两个相辅相成又看似矛盾的方向:
更大更强
追求模型的极致能力和认知边界突破。
能够学习更多的信息,捕捉更细的特征,提升泛化能力,解决开放域问题等。
目的是为了能处理更复杂的任务,比如通用人工智能、自然语言理解与生成、科学计算模拟等。主要通过增大模型参数规模、增加训练数据量、构建复杂的架构以及优化训练技术来实现这一目标。
更小更快
追求模型的实用效率和普适部署。
能够为了在能维持一定精度的前提下减少参数量和运算量。
目的是满足边缘/终端设备的低功耗、实时性、低成本、隐私保护要求,降低云端推理成本、提高响应速度,主要通过设计更高效的模型架构,进行裁剪、量化、蒸馏对模型进行压缩,优化特定算子和结合AI硬件加速来实现这一目标。
高效卷积神经网络架构
模型名称
表示轻量化神经网络模型的名称,名称中包含着几个重要信息:
1、不同的架构家族 (如 squeezenet, Mobilenet, ShuffleNet, EfficientNet, GhostNet, DeiT, ConvVT)。
2、不同的版本/变体标识 (如V1, V2, V3)。
3、不同的规模/宽度乘子 (如 0.5, 0.75, 1.0, 1.5x, 2x, -Small, -Large)。
4、其他配置参数 (如 160, 224 通常指输入图像的尺寸, g=3/8 对 ShuffleNet 指分组卷积的分组数,还有像b0/b1/b2/b3、S/M/L、A1/A2/A3、lite0/lite1/lite2/lite3/lite4等模型设置,特指不同尺寸或者不同复杂度)。
参数量
参数量是指模型中需要学习的参数总数。
1、参数量决定模型的内存占用(如显存和内存)和数据加载和传输时间,参数需从内存频繁读取到计算单元,高参数量可能导致内存带宽瓶颈,拖慢推理速度(尤其在移动设备)。
2、参数量与模型的复杂度、学习能力和表达能力有紧密关系(通常参数越多,模型越复杂,理论上拟合能力越强)。
3、参数量也是衡量模型“轻量化”程度的最关键指标之一,轻量化模型的核心目标就是在保持一定性能的前提下,尽可能减少参数量。
乘加运算量
乘加运算量是指模型进行一次前向推理(处理一张图片)所需完成的 乘法累加操作的总次数。一次乘加运算通常指 a * b + c 这样的计算。
1、乘加运算量是衡量模型计算复杂度和推断速度(尤其是在硬件上)的最常用指标之一,与模型的耗电量(对移动设备尤为重要)强相关。
2、乘加运算量是衡量模型“轻量化”程度的核心指标,直接决定计算时间(如GPU/CPU的浮点运算耗时),需要在满足性能要求下降低此值。
3、神经网络中的主要计算(如卷积、全连接层)绝大部分都是由大量的乘加操作构成的,统计乘加次数能有效反映整体的计算负担。
评价指标
ImageNet fp32 top1 accuracy评价指标是衡量不同轻量化模型分类准确性的核心依据。它直观地告诉我们在识别 1000 类物体时,模型猜中“第一名”的概率是多少。用户可以通过这个值直接比较不同模型在相同的权威数据集和评估标准下的表现优劣。数值越高越好。
1、fp32是模型在运行/评估时使用的数值精度,代表 单精度浮点数(Single-precision floating-point format),是一种在计算机中表示实数的格式,使用 32 位(4 字节)存储一个数字。有些轻量化模型在部署时可能会使用更丰富的精度选择,比如fp16、int8、int4、int2以及混合精度,通过对模型量化以加速和减小模型体积,但在学术论文和基准对比中,通常报告 fp32 精度以保证公平比较。
2、ImageNet数据集是一个巨大的、公开的图像数据集,具体是指 ILSVRC 2012 数据集(ImageNet Large Scale Visual Recognition Challenge 2012)。它包含超过 140万 张训练图像,5万 张验证图像,10万 张测试图像,涵盖了 1000 个不同的物体类别(如“猫”、“狗”、“汽车”、“杯子”等)。
3、top1 accuracy是评估图像分类任务最直接、最重要的性能指标。在推理过程中对验证/测试集中的每一张图片都会输出一个包含 1000 个类别的概率分布也就是置信度。而top1 accuracy指的是模型预测的概率最高的那个类别恰好等于图片真实标签的比例。有时还会使用top5 accuracy,它指的是图片的真实标签出现在模型预测的前5个最高概率类别之中的比例。
高效卷积神经网络的比较
一、ShuffleNet
1、ShuffleNet V1
ShuffleNet V1论文地址
1.分组卷积Group Convolution
在分组卷积中,g = 1,Cin=CoutC_{in} = C_{out}Cin=Cout时:
相当于不分群组,所有输入通道都在一个组里,该组卷积核需要与所有输入通道进行卷积操作,来生成所有输出通道。这是分组卷积的一个极端且非常重要的特例,称为标准卷积。
虽然这样学习到的特征会充分混合,但是计算量和参数量却是最大的。
在分组卷积中,1 < g < CinC_{in}Cin,Cin=CoutC_{in} = C_{out}Cin=Cout时:
将输入通道平均分成g组,每组有Cing\frac {C_{in}}{g}gCin个通道。
第一组包含 [通道1, 通道2,…, 通道Cing\frac {C_{in}}{g}gCin]
第二组包含 [通道(Cing+1)(\frac {C_{in}}{g}+1)(gCin+1), 通道(Cing+2)(\frac {C_{in}}{g}+2)(gCin+2),…, 通道(Cing+Cing)(\frac {C_{in}}{g} + \frac {C_{in}}{g})(gCin+gCin)]
…
第g组包含 [通道(Cin−Cing+1)(C_{in}-\frac {C_{in}}{g}+1)(Cin−gCin+1), 通道(Cin−Cing+2)(C_{in}-\frac {C_{in}}{g}+2)(Cin−gCin+2),…, 通道CinC_{in}Cin]
第g组卷积核只与第g组进行卷积,生成第g组输出通道。最后将将不同组得到输出按顺序在通道维度上进行拼接,得到最终的输出特征图。
这样学习到的特征参数量和计算量减少,是标准卷积的1g\frac{1}{g}g1。
在分组卷积中,g = CinC_{in}Cin,Cin=CoutC_{in} = C_{out}Cin=Cout时:
相当于每个输入通道都作为独立的一个组,一个卷积核只与一个输入通道进行卷积操作,来生成所有输出通道。将所有单通道的输出拼接起来,得到最终的输出特征图。这是分组卷积的一个极端且非常重要的特例,称为DW深度卷积。
这样学习到的特征参数量和计算量降到极低,是标准卷积的1Cin\frac{1}{C_{in}}Cin1
ConvolutionKernel=Cin×CoutgConvolution \ Kernel = \frac{C_{in}×C_{out}}{g}Convolution Kernel=gCin×Cout
g:分组数。
CinC_{in}Cin:输入特征图深度,也就是通道数。
CoutC_{out}Cout:输出特征图深度,也就是通道数。
在分组卷积中,每个分组只在组内执行一个小的标准卷积,这使得模型的参数数量会减少。
如果一个卷积层有4个输入通道和4个输出通道,且不使用分组,那么将有4个输入通道× 4个输出通道=16个权重参数。
如果使用g=2进行分组卷积,每个分组将只有2个输入通道和2个输出通道,因此每组只有4个权重参数,两个分组总共8个参数,减少了一半的权重参数。
由于参数数量的减少,分组卷积在前向传播和反向传播过程中的计算量也会减少。这可以加快训练和推理的速度,尤其是在资源受限的情况下。
分组卷积可以提高计算的并行度,因为每个分组可以独立地进行计算。这使得分组卷积在多核处理器和GPU上更加高效。
减少参数和计算量也意味着节省了内存使用,这对于部署在内存受限的设备上的模型尤其重要。
2.通道混洗操作channel shuffle
a)标准分组卷积
将输入的特征图按通道顺序划分为红、绿、蓝三组,每组特征图使用GConv1分组卷积在组内进行独立计算,GConv1输出的Feature特征图同样按通道顺序保持着组间的隔离。下一层的GConv2分组卷积同样在组内进行独立计算,最后输出最终的output特征图。
虽然标准分组卷积极大减少了计算量和参数,但是特征信息流被限制在每个通道组内部,只能接收到来自自己组内的信息,组内特征之间只能进行有限学习,组外特征无法交流,容易导致模型学习到的特征非常局限,模型的性能和表达能力大打折扣。
b)交叉分组思路
将输入的特征图按通道顺序划分为红、绿、蓝三组,每组特征图使用GConv1分组卷积在组内进行独立计算,GConv1输出的Feature特征图同样按通道顺序保持着组间的隔离。下一层的GConv2分组卷积从Feature特征图的各个通道中交叉提取拼出新的特征分组,并进行独立计算,最后输出最终的output特征图。
实现了跨组的信息流动,让后续的卷积操作能够融合来自不同组的信息,大大提升了模型的表现力。
c)通道混洗分组卷积
将输入的特征图按通道顺序划分为红、绿、蓝三组,每组特征图使用GConv1分组卷积在组内进行独立计算,GConv1输出的Feature特征图同样按通道顺序保持着组间的隔离。使用Channel Shuffle操作将Feature特征图每个分组内部按组数均匀划分为三份子块,将原本属于不同组的通道混合起来并交错排列。下一层的GConv2分组卷积在新构建的分组内进行独立计算,最后输出最终的output特征图。
实现了与(b))交叉分组相同的思路,促进了通道组间的信息交流,让后续的卷积操作能够融合来自不同组的信息,大大提升了模型的表现力。
通道混洗”只是一个简单的张量变形重塑和索引排序操作,不涉及任何计算或需要学习的参数,因此计算成本几乎可以忽略不计。
3.层结构与模型结构
a)带深度可分离卷积的残差模块
1×1 Conv+BN ReLU:使用1×1普通卷积对输入的特征图进行通道升维,然后使用批归一化和ReLU激活函数。
3×3 DWConv+BN ReLU:使用3×3深度可分离卷积对输入的特征图进行空间特征学习,然后使用批归一化和ReLU激活函数。
1×1 Conv+BN:使用1x1普通卷积对输入的特征图进行通道降维,然后使用批归一化。
Add+ReLU:通过残差连接将旁路和主路的特征图相加,然后使用ReLU激活函数。
b)带有通道混洗分组卷积的残差模块
1×1 GConv+BN ReLU:使用1×1分组卷积对输入的特征图进行通道升维,然后使用批归一化和ReLU激活函数。
Channel Shuffle:通道混洗操作,通过重新排列通道的顺序,让后续的卷积操作能够接收到来自不同组的特征,促进了组间信息交换。
3×3 DWConv+BN:使用3×3深度可分离卷积对输入的特征图进行空间特征学习,然后使用批归一化和ReLU激活函数。
1×1 GConv+BN:使用1x1分组卷积对输入的特征图进行通道降维,然后使用批归一化。
Add+ReLU:通过残差连接将旁路和主路的特征图相加,然后使用ReLU激活函数。
c)带有通道混洗分组卷积的残差下采样模块
1×1 GConv+BN ReLU:使用1×1分组卷积对输入的特征图进行通道升维,然后使用批归一化和ReLU激活函数。
Channel Shuffle:通道混洗操作,通过重新排列通道的顺序,让后续的卷积操作能够接收到来自不同组的特征,促进了组间信息交换。
3×3 DWConv(stride=2)+BN:使用3×3深度可分离卷积对输入的特征图进行步长为2的空间特征学习,对特征图进行下采样操作,然后使用批归一化和ReLU激活函数。
1×1 GConv+BN:使用1x1分组卷积对输入的特征图进行通道降维,然后使用批归一化。
3×3 AVGPool(stride=2):使用平均池化对特征图进行下采样,平均池化更关注区域的全局统计特征,适用于需要保留背景或平缓变化的场景。
Concat+ReLU:旁路和主路的特征图高度和宽度相同,但通道数不同,使用Concat操作将它们沿着通道维度直接拼接起来,最终输出特征图的通道数等于旁路和主路的通道数之和,然后使用ReLU激活函数。
Resnet:hw(1×1×c×m)+hw(3×3×m×m)+hw(1×1×m×c)=hw(2cm+9m2)Resnet: hw(1×1×c×m)+hw(3×3×m×m)+hw(1×1×m×c)=hw(2cm+9m^2)Resnet:hw(1×1×c×m)+hw(3×3×m×m)+hw(1×1×m×c)=hw(2cm+9m2)
ShuffleNet:hw(1×1×c×m)/g+hw(3×3×m)+hw(1×1×m×c)/g=hw(2cm/g+9m)ShuffleNet: hw(1×1×c×m)/g+hw(3×3×m)+hw(1×1×m×c)/g=hw(2cm/g+9m)ShuffleNet:hw(1×1×c×m)/g+hw(3×3×m)+hw(1×1×m×c)/g=hw(2cm/g+9m)
对于Resnet结构,第一个是1×1标准卷积的计算量为1×1×w×h×c×1×m1×1×w×h×c×1×m1×1×w×h×c×1×m,第二个是3×3标准卷积的计算量为3×3×w×h×c×m×m3×3×w×h×c×m×m3×3×w×h×c×m×m,第三个是1×1标准卷积的计算量为1×1×w×h×c×1×m1×1×w×h×c×1×m1×1×w×h×c×1×m。
对于ShuffleNet结构,第一个是1×1分组卷积的计算量为(1×1×w×h×c×1×m)/g(1×1×w×h×c×1×m)/g(1×1×w×h×c×1×m)/g,第二个是3×3DW卷积的计算量为3×3×w×h×c×m3×3×w×h×c×m3×3×w×h×c×m,第三个是1×1分组卷积的计算量为(1×1×w×h×c×1×m)/g(1×1×w×h×c×1×m)/g(1×1×w×h×c×1×m)/g。
Output size:输入特征图的W×H。
KSize:卷积核大小。
Stride:步长。
Repeat:每个Stage的重复次数。
Output channels(g groups):在不同分组情况下的特征图通道数。
Image:图像输入大小为224×224。
Conv1:标准卷积,有效提取初始特征和通道升维。
MaxPool:最大池化下采样,进一步下采样,快速减少计算量较大的空间尺寸。
Stage2:核心构建模块,首先使用一个步长为2的带有通道混洗分组卷积的残差下采样模块对特征图进行下采样,然后使用三个步长为1的带有通道混洗分组卷积的残差模块对特征图进行学习。
Stage3:核心构建模块,首先使用一个步长为2的带有通道混洗分组卷积的残差下采样模块对特征图进行下采样,然后使用七个步长为1的带有通道混洗分组卷积的残差模块对特征图进行学习。
Stage4:核心构建模块,首先使用一个步长为2的带有通道混洗分组卷积的残差下采样模块对特征图进行下采样,然后使用三个步长为1的带有通道混洗分组卷积的残差模块对特征图进行学习。
GlobalPool: 7×7的全局平均池化,将最后一个Stage输出的7x7的特征图直接降维成1×1。
FC:全连接层,将GlobalPool后的向量映射到1000个类别上。
Complexity:模型复杂度分析。
当 g=1:所有通道都参与计算,即标准卷积。
当 g=2:输入和输出通道被分成2个独立的组,卷积操作在这两个组内分别进行,然后再将结果拼接起来。
…
当 g=8:输入和输出通道被分成8个独立的组,卷积操作在这八个组内分别进行,然后再将结果拼接起来。
ShuffleNet通过引入分组卷积来大幅降低计算量,分组数g越多,计算量就越小。
如果一味地增加分组,即使有Channel Shuffle机制促进组间信息交换,但是还是不可避免的导致学习能力下降。
增加分组能够节省计算量,使用省下来的计算量去增加通道数,从而使总计算量保持稳定。
同时为了公平地比较不同分组的模型性能,尽量使得不同分组的模型在相近的计算复杂度下进行对比。
因此,当增加分组g时,Stage2会选择增加通道数,Stage3和Stage4则通道翻倍,一方面通过增加深度加强学习能力,另一方面平衡不同分组模型的计算量。
2、ShuffleNet V2
ShuffleNet V2论文地址
1.MAC、MACs、FLOPs与FLOPS
a=a+(b×c)a = a + (b × c)a=a+(b×c)
MAC:乘加运算Multiply-Accumulate Operation,主要包含一个乘法和一个加法,是神经网络中最常见、最基础的操作单元。
MACs=H×W×Cin×K×K×CoutMACs = H×W×C_{in}×K×K×C_{out}MACs=H×W×Cin×K×K×Cout
MACs:乘加运算次数Multiply–Accumulate Operations,是一个数量单位,用来衡量模型的计算复杂度或计算量。
FLOPs=2×H×W×Cin×K×K×CoutFLOPs = 2×H×W×C_{in}×K×K×C_{out}FLOPs=2×H×W×Cin×K×K×Cout
FLOPs: 浮点运算次数Floating Point Operations,这是一个数量单位,用来衡量一个模型、一个算法或一次计算总共需要多少次浮点运算。1次MAC = 2次FLOPs(因为一次乘法算一次FLOP,一次加法也算一次FLOP)。
FLOPS=(总的浮点运算次数(FLOPs))/(计算所花费的时间(s))FLOPS = (总的浮点运算次数(FLOPs)) / (计算所花费的时间(s))FLOPS=(总的浮点运算次数(FLOPs))/(计算所花费的时间(s))
FLOPS: 每秒浮点运算次数Floating Point Operations Per Second,这是一个速率单位,用来衡量计算硬件CPU或GPU每秒钟能执行多少次浮点运算,是衡量计算性能的指标。
2.高效网络设计指南
在GPU计算平台和ARM计算平台上,对比了ShuffleNet V1与MobileNet V2两种模型在推理运行时中不同操作的时间消耗占比:
Conv:卷积操作,是卷积神经网络中最核心也是最耗时的操作之一。
Data:数据IO,主要包括内存的读取、写入等操作,在计算能力强的硬件上,这部分开销会相对明显。
Elem-wise:逐元素操作,例如激活函数、张量乘加等操作,虽然计算量小但是次数频繁。
Shuffle:通道混洗操作,ShuffleNet模型特有的操作。
Other:其他操作。
在GPU中ShuffleNet V1的卷积占了一半的推理时间,其次是数据IO和逐元素操作也占据了较大的比例,剩下的就是其他操作与通道混洗操作。
在ARM中ShuffleNet V1的卷积占了绝大部分的推理时间,其次是其他操作和逐元素操作占据了小部分的比例,剩下的数据IO与通道混洗操作几乎可以忽略不计。
在GPU中MobileNet V2的卷积占了一半的推理时间,其次是数据IO和逐元素操作也占据了较大的比例,剩下的就是其他操作。
在ARM中MobileNet V2的卷积占了绝大部分的推理时间,其次是逐元素操作占据了小部分的比例,剩下的数据IO与其他操作几乎可以忽略不计。
不同模型在不同计算平台上的表现,体现了不同操作的在推理运行中的时间占比。
GPU具有强大的并行计算能力,而ARM的并行计算能力远弱于GPU,所以卷积操作的计算耗时占比相对会更多。
ARM属于一种CPU芯片,对于复杂串行的数据读取或写入操作会比GPU更加灵活与快捷,所以ARM的数据IO操作耗时会比GPU更少。
ShuffleNet对比MobileNet模型使用了分组卷积和通道混洗操作,导致在GPU和ARM上的Shuffle和Other的计算耗时占比相对更多。
所以一个模型在GPU上高效,并不意味着在ARM上也同样高效。不同的硬件架构对不同计算操作的优化程度不同,因此设计移动端模型时必须考虑目标平台的特性。
3.高效网络设计指南
G1)Equal channel width minimizes memory access cost (MAC)
相等的通道宽度最大限度地降低了内存访问成本(MAC)。
核心思想: 在卷积运算中,当输入通道数CinC_{in}Cin和输出通道数CoutC_{out}Cout相等时,内存访问成本最小,从而能实现更高的计算效率。这里的MAC指的是内存访问成本而不是上面的乘加运算单元。
在硬件计算中,对内存进行增删读写等访问操作所消耗的时间和能量往往比执行计算操作本身还要多,使用降低内存访问成本是优化速度的关键。
B=H×W×Cin×K×K×Cout=HWCinCoutB = H×W×C_{in}×K×K×C_{out} = HWC_{in}C_{out}B=H×W×Cin×K×K×Cout=HWCinCout
MAC=H×W×Cin+Cin×Cout+H×W×Cout=HW(Cin+Cout)+CinCoutMAC = H×W×C_{in}+C_{in}×C_{out}+H×W×C_{out} = HW(C_{in}+C_{out})+C_{in}C_{out}MAC=H×W×Cin+Cin×Cout+H×W×Cout=HW(Cin+Cout)+CinCout
a+b2≥a×b(当a=b时,均值不等式的两边相等)\frac{a+b}{2} \geq \sqrt{a×b}(当a=b时,均值不等式的两边相等)2a+b≥a×b(当a=b时,均值不等式的两边相等)
MAC=HW(Cin+Cout)+CinCout≥H×W×2Cin×Cout+Cin×Cout≥2HWB+BHWMAC = HW(C_{in}+C_{out})+C_{in}C_{out} \geq H×W×2\sqrt{C_{in}×C_{out}}+C_{in}×C_{out} \geq 2\sqrt{HWB}+\frac{B}{HW}MAC=HW(Cin+Cout)+CinCout≥H×W×2Cin×Cout+Cin×Cout≥2HWB+HWB
一个1×1卷积层的理论计算量B是通过FLOPs(看起来像是MACs)计算得到的,一个1×1卷积层的内存访问量MAC为输入张量的读取+卷积核权重的读取+输出张量的写入。
当固定计算预算B的前提下,根据均值不等式,当输入通道数CinC_{in}Cin和输出通道数CoutC_{out}Cout相等时,内存访问量MAC取得最小值。如果输入通道数CinC_{in}Cin和输出通道数CoutC_{out}Cout相差很大,内存访问量MAC就会显著增加。
所以在设计Bottleneck网络块时,要尽量让中间层的通道数与输入输出通道数保持相等或接近,而不是为了降低FLOPs而过度压缩中间通道数。看似FLOPs降低,但是内存访问量MAC可能很高,导致实际速度变慢。
G2)Excessive group convolution increases MAC
过多的分组卷积会增加MAC。
核心思想: 分组卷积虽然能减少计算量FLOPs,但过度使用或分组数g过大会导致内存访问成本MAC急剧增加。
B=HWCinCoutgB = \frac{HWC_{in}C_{out}}{g}B=gHWCinCout
MAC=HWCin+HWCout+CinCout=Bgcout+Bgcin+BHWMAC = HWC_{in}+HWC_{out}+C_{in}C_{out} = \frac{Bg}{c_{out}}+\frac{Bg}{c_{in}}+\frac{B}{HW}MAC=HWCin+HWCout+CinCout=coutBg+cinBg+HWB
一个1×1分组卷积层的理论计算量B是通过FLOPs(看起来像是MACs)计算得到的,当分组越多g值越大,B值会越小。
一个1×1分组卷积层的内存访问量MAC为输入张量的读取+卷积核权重的读取+输出张量的写入,当分组越多g值越大,卷积核权重的读取会越快。
ShuffleNet V1中当分组越多g值越大,通常需要增加通道数来保持模型学习量,这也导致HW(Cin+Cout)HW(C_{in}+C_{out})HW(Cin+Cout)实际上在g增加时通道数也会增加,导致内存访问成本MAC增加。
当B固定不变时,分组越多g值越大,会导致Bgcout\frac{Bg}{c_{out}}coutBg和Bgcin\frac{Bg}{c_{in}}cinBg增加。
虽然分组卷积在实际推理中非常节省计算,但是当使用的分组数越多g值越大反而可能会因为MAC的大幅增加而抵消掉FLOPs减少带来的好处,甚至让速度变慢。
G3)Network fragmentation reduces degree of parallelism
网络碎片降低了并行度。
核心思想: 如果一个Bottleneck网络块中包含太多的小型操作或分支,显得网络结构过于“碎片化”,会导致硬件并行计算能力降低,即使它可能让理论FLOPs更低。
一个模块由多条不同路径分支组成,每个分支又可能包含一些1x1卷积、3x3卷积、池化等小操作,这些小操作的特点就是计算强度低、数据量小、操作简单。
在计算平台中这些操作都需要GPU内核来启动和执行,频繁启动多个小内核会产生额外开销。而分支结构需要在最终合并点进行同步,等待所有分支计算完成,这可能会造成等待和延迟。
尽管这种碎片化的结构已被证明对准确性有益,但它可能会降低效率,因为它对具有强大并行计算能力的GPU设备不友好。
一个纯粹的的卷积操作更容易被硬件优化和并行化,使得计算效率更高,所以在网络架构设计时,应倾向于更简单、更纯粹、更“稠密”的模块结构,减少分支数量,尤其是在需要高速度的轻量级网络中。
G4)Element-wise operations are non-negligible
元素操作是不可忽略的。
核心思想:逐元素操作虽然理论FLOPs很低,但其内存访问成本很高,在轻量级网络中会占用相当比例的运行时间。
元素级操作是指那些输入和输出张量在对应位置上的元素独立进行计算的操作。例如激活函数、逐元素加法、逐元素乘法等,它们的计算量小浮点运算数小,但它们需要读取和写入整个张量导致内存访问成本MAC相对较高。
在大型网络中,卷积等计算密集型操作占绝对主导,元素级操作的耗时占比不明显。但在轻量级网络中,FLOPs总量本来就少,这些操作的相对开销就变得非常突出。所以优化网络时,不能只盯着卷积的FLOPs,还需要尽量减少元素级操作的数量。可以移除一些不必要的激活函数,或者将连续的逐元素操作合并在一起执行,以减少内存读写次数。
总结:
- 使用平衡的通道宽度相等的卷积操作。
- 注意使用分组卷积的成本。
- 降低模型碎片化操作的开销。
- 减少不必要的元素级操作。
4.层结构与模型结构
a)带有通道混洗分组卷积的残差模块
1×1 GConv+BN ReLU:使用1×1分组卷积对输入的特征图进行通道升维,然后使用批归一化和ReLU激活函数。
Channel Shuffle:通道混洗操作,通过重新排列通道的顺序,让后续的卷积操作能够接收到来自不同组的特征,促进了组间信息交换。
3×3 DWConv+BN:使用3×3深度可分离卷积对输入的特征图进行空间特征学习,然后使用批归一化和ReLU激活函数。
1×1 GConv+BN:使用1x1分组卷积对输入的特征图进行通道降维,然后使用批归一化。
Add+ReLU:通过残差连接将旁路和主路的特征图相加,然后使用ReLU激活函数。
b)带有通道混洗分组卷积的残差下采样模块
1×1 GConv+BN ReLU:使用1×1分组卷积对输入的特征图进行通道升维,然后使用批归一化和ReLU激活函数。
Channel Shuffle:通道混洗操作,通过重新排列通道的顺序,让后续的卷积操作能够接收到来自不同组的特征,促进了组间信息交换。
3×3 DWConv(stride=2)+BN:使用3×3深度可分离卷积对输入的特征图进行步长为2的空间特征学习,对特征图进行下采样操作,然后使用批归一化和ReLU激活函数。
1×1 GConv+BN:使用1x1分组卷积对输入的特征图进行通道降维,然后使用批归一化。
3×3 AVGPool(stride=2):使用平均池化对特征图进行下采样,平均池化更关注区域的全局统计特征,适用于需要保留背景或平缓变化的场景。
Concat+ReLU:旁路和主路的特征图高度和宽度相同,但通道数不同,使用Concat操作将它们沿着通道维度直接拼接起来,最终输出特征图的通道数等于旁路和主路的通道数之和,然后使用ReLU激活函数。
c)带有通道分割的深度可分离卷积残差模块
Channel Split:使用通道分割操作将输入在通道维度上被直接、无计算地切分成两部分。
1×1 Conv+BN ReLU:使用1×1卷积对输入的特征图进行通道升维,然后使用批归一化和ReLU激活函数。
3×3 DWConv+BN:使用3×3深度可分离卷积对输入的特征图进行空间特征学习,然后使用批归一化和ReLU激活函数。
1×1 Conv+BN ReLU:使用1x1分组卷积对输入的特征图进行通道降维,然后使用批归一化。
Concat:使用Concat操作将它们沿着通道维度直接拼接起来,最终输出特征图的通道数等于旁路和主路的通道数之和,使得输出通道数等于输入通道数。
Channel Shuffle:通道混洗操作,通过重新排列通道的顺序,对拼接后的结果进行通道混洗,促进左右分支的信息交流,为下一个单元做准备。
d)深度可分离卷积的残差下采样模块
左分支:
3×3 DWConv(stride=2)+BN:使用3×3深度可分离卷积对输入的特征图进行步长为2的空间特征学习,对特征图进行下采样操作,然后使用批归一化和ReLU激活函数。
1×1 Conv+BN ReLU:使用1x1分组卷积对输入的特征图进行通道降维,然后使用批归一化。
右分支:
1×1 Conv+BN ReLU:使用1×1卷积对输入的特征图进行通道升维,然后使用批归一化和ReLU激活函数。
3×3 DWConv(stride=2)+BN:使用3×3深度可分离卷积对输入的特征图进行步长为2的空间特征学习,对特征图进行下采样操作,然后使用批归一化和ReLU激活函数。
1×1 Conv+BN ReLU:使用1x1分组卷积对输入的特征图进行通道降维,然后使用批归一化。
合并:
Concat:使用Concat操作将它们沿着通道维度直接拼接起来,两个分支下采样输出的特征图尺寸相同,在通道维度上拼接起来,因此通道数翻倍。
Channel Shuffle:通道混洗操作,通过重新排列通道的顺序,对拼接后的结果进行通道混洗,促进左右分支的信息交流,为下一个单元做准备。
在c模型结构中:
通道分割操作将输入通道分成两个分支,一半原始特征数据用作残差保留,一半原始特征数据进行轻量计算,避免了碎片化操作。
左分支执行恒等映射,保持输入和输出通道数不变,降低模型碎片化操作的开销。
右分支执行多层卷积,将分组卷积替换为普通卷积,虽然没有降低FLOPs,但是避免了内存访问成本的增加。
使用Concat合并,相比Add加法具有更低的计算复杂度,如果使用Add加法操作融合特征在一定程度上会稀释原始的恒等信息,而Concat合并则完美保留了一半的原始输入信息。
最后输入和输出的通道数相等,实现通道宽度相等的卷积操作,能够最小化内存访问成本。
在d模型结构中:
左分支执行多层卷积,使用DW卷积和普通卷积进行下采样操作,虽然没有降低FLOPs,但是避免了内存访问成本的增加。
右分支执行多层卷积,使用深度可分离卷积进行下采样操作,虽然没有降低FLOPs,但是避免了内存访问成本的增加。
两个分支的结构相似对称,都包含了实际计算的操作,有利于提高并行度。
Output size:输入特征图的W×H。
KSize:卷积核大小。
Stride:步长。
Repeat:每个Stage的重复次数。
Output channels:在不同复杂度系数下的特征图通道数。
Image:图像输入大小为224×224。
Conv1:标准卷积,有效提取初始特征和通道升维。
MaxPool:最大池化下采样,进一步下采样,快速减少计算量较大的空间尺寸。
Stage2:核心构建模块,首先使用一个步长为2的带有通道混洗分组卷积的残差下采样模块对特征图进行下采样,然后使用三个步长为1的带有通道混洗分组卷积的残差模块对特征图进行学习。
Stage3:核心构建模块,首先使用一个步长为2的带有通道混洗分组卷积的残差下采样模块对特征图进行下采样,然后使用七个步长为1的带有通道混洗分组卷积的残差模块对特征图进行学习。
Stage4:核心构建模块,首先使用一个步长为2的带有通道混洗分组卷积的残差下采样模块对特征图进行下采样,然后使用三个步长为1的带有通道混洗分组卷积的残差模块对特征图进行学习。
Conv5:标准1×1卷积,用于整合和提升特征维度。
GlobalPool: 7×7的全局平均池化,将最后一个Stage输出的7x7的特征图直接降维成1×1。
FC:全连接层,将GlobalPool后的向量映射到1000个类别上。
FLOPs:浮点运算次数,一次计算总共需要多少次浮点运算。
of Weights:模型参数量。
通过一个复杂度系数Output channels来调控整个网络中大多数层的通道数,从而得到不同计算量和精度水平的模型,以适应不同的硬件需求。
总结
ShuffleNetV1 核心创新是通道重排 操作。它通过分组点卷积 和通道混洗 来解决标准1x1卷积计算量大的问题,在保持精度的同时显著提升了速度。
ShuffleNetV2 则更进一步,侧重于提升实际硬件运行速度。它提出了四条高效网络设计的实用准则,并据此重新设计了模块,通过通道分割 来避免频繁的组操作,并采用更简单的算子组合,最终在速度和精度上均超越了V1。