第十章 ShuffleNetv2网络详解

系列文章目录


第一章 AlexNet网络详解

第二章 VGG网络详解

第三章 GoogLeNet网络详解 

第四章 ResNet网络详解 

第五章 ResNeXt网络详解 

第六章 MobileNetv1网络详解 

第七章 MobileNetv2网络详解 

第八章 MobileNetv3网络详解 

第九章 ShuffleNetv1网络详解 

第十章 ShuffleNetv2网络详解 

第十一章 EfficientNetv1网络详解 

第十二章 EfficientNetv2网络详解 

第十三章 Transformer注意力机制

第十四章 Vision Transformer网络详解 

第十五章 Swin-Transformer网络详解 

第十六章 ConvNeXt网络详解 

第十七章 RepVGG网络详解 

第十八章 MobileViT网络详解 


文章目录

  •  ShuffleNetv2网络详解
  • 0. 前言
  • 1. 摘要
  • 2.   ShuffleNetv2网络详解网络架构
    • 1.  ShuffleNetv2_Model.py(pytorch实现)
    • 2.
  • 总结


0、前言

1.这篇论文提出了一种基于直接度量的神经网络架构设计方法,并展示了其实验结果和指导性指南。

2.本文的研究背景是当前神经网络架构设计大多是以FLOPs复杂度为导向,而缺乏对速度等直接指标的综合考虑。

3.本文的主要论点是应该通过在目标平台上对直接指标进行全面综合评估,并在此基础上制定优化网络架构的指导性方法。

4.以往的研究大多使用FLOPs作为神经网络架构设计的优化目标,而这种方法忽略了其他因素对实际速度的影响,导致了速度与精度无法同时提高的问题。

5.本文提出了一种基于直接度量的神经网络架构设计方法,通过在目标平台上综合评估速度等直接指标来引导架构的设计,从而实现更高的速度与精度综合表现。

6.实验结果表明,作者提出的网络模型(ShuffleNet V2)在速度和精度平衡方面都达到了最先进的表现,本研究的贡献是提供了一种更全面的指导优化网络架构的方法。但本文的主要局限在于实验数据集的规模较小,未来仍需要更多的实验和验证来证明这种方法的适用性。

深度卷积神经网络(CNN)的架构已经演变了多年,变得更加精确和更快速。自AlexNet里程碑式的工作以来[1],通过新颖的结构,包括VGG [2],GoogLeNet [3],ResNet [4,5],DenseNet [6],ResNeXt [7],SE-Net [8]和自动神经架构搜索 [9,10,11],ImageNet分类准确性已显着提高。除了准确性,计算复杂度是另一个重要的考虑因素。现实任务通常旨在在给定目标平台(例如硬件)和应用场景(例如自动驾驶需要低延迟)的限制的计算预算下获得最佳准确性。这激发了一系列工作,以轻量级架构设计和更好的速度-准确度权衡为目标,包括Xception [12],MobileNet [13],MobileNet V2 [14],ShuffleNet [15]和CondenseNet [16],等等。这些工作中的分组卷积和深度卷积至关重要。为了衡量计算复杂度,广泛使用的度量标准是浮点运算数或FLOPs [1]。然而,FLOPs是一种间接度量标准。它是我们真正关心的直接度量标准(如速度或延迟)的近似,但通常不等价于它。这种差异已经得到注意。

在之前的研究中,例如MobileNet v2 [14]比NASNET-A [9]快得多,但它们具有可比较的FLOPs。图1(c)(d)进一步证明了此现象,表明具有类似FLOPs的网络速度不同。因此,仅使用FLOPs作为计算复杂度指标是不够的,可能会导致次优设计。间接指标(FLOPs)与直接指标(速度)之间的差异可以归因于两个主要原因。首先,FLOPs未考虑影响速度的几个重要因素之一。其中一个因素是内存访问成本(MAC)。这种成本在某些操作,如组卷积中占据了很大一部分运行时间。在具有强大计算能力的设备上,如GPU,这可能成为瓶颈。在网络架构设计过程中,不应简单忽略此成本。另一个因素是并行度。具有高并行度的模型可以比具有低并行度的模型更快,前提是它们具有相同的FLOPs。其次,对于具有相同FLOPs的操作,在不同平台上的运行时间可能不同。例如,张量分解广泛用于早期的一些研究中,以加速矩阵乘法。然而,最近的一份研究[19]发现,在GPU上,[22]中的分解甚至比不做分解的1 × 1卷积还要慢,尽管它将FLOPs降低了75%。我们对这个问题进行了调查,并发现这是因为最新的CUDNN [23]库是专门针对3×3的卷积进行优化的。我们不能确定3×3卷积比1×1卷积慢9倍。

通过这些观察,我们提出在进行有效的网络架构设计时应考虑两个原则。首先,应使用直接指标(例如速度)而不是间接指标(例如FLOPs)。其次,这种指标应在目标平台上进行评估。在本文中,我们遵循这两个原则,并提出了一个更有效的网络架构。在第2节中,我们首先分析了两个代表性的最新网络(15,14)的运行时性能。然后,我们推导出了四条有效网络设计准则,超越了仅考虑FLOPs的范畴。虽然这些准则与平台无关,但我们进行了一系列受控实验,在GPU和ARM两个不同的平台上进行了验证,通过专门的代码优化,确保我们的结论在最新技术上。根据这些准则,在第3节中,我们设计了一个新的网络结构。由于它受ShuffleNet(15)的启发,因此被称为ShuffleNet V2。通过第4节中的综合验证实验,它在两个平台上都比以前的网络更快,更准确。图1(a)(b)提供了比较的概述。例如,给定40M FLOPs的计算复杂度预算,ShuffleNet V2比ShuffleNet V1和MobileNet V2分别更准确3.5%和3.7%。

第十章 ShuffleNetv2网络详解_第1张图片

(图1:在四个网络架构和两个硬件平台上,使用四个不同计算复杂度级别来衡量准确度(ImageNet验证集分类)、速度和FLOPs(参见正文)。(a、c)GPU结果,batchsize = 8。(b、d)ARM结果,batchsize = 1。最佳表现算法,即我们提出的ShuffleNet v2,在所有情况下都处于右上角区域)

1、摘要

目前,神经网络架构设计主要由计算复杂度间接指导,即FLOPs。然而,直接指标,例如速度,还依赖其他因素,如存储器访问成本和平台特性。因此,本文提出在目标平台上评估直接指标,而不仅考虑FLOPs。根据一系列控制实验,本文得出了几个有效网络设计的实用指南。因此,我们提出了一种新的架构,称为ShuffleNet V2。综合消融实验证明我们的模型在速度和准确度的权衡方面是最先进的。关键词:CNN架构设计,效率,实用性

2、ShuffleNetv2网络详解网络架构

3.正文分析

 网络设计高效实践指南。我们的研究是在两个广泛采用的硬件上进行的,该硬件具有行业级别的CNN库优化。我们注意到我们的CNN库比大多数开源库更有效率。因此,我们确保我们的观察和结论在工业实践中具有可靠性和重要性。{GPU.使用单个NVIDIA GeForce GTX 1080Ti。卷积库为CUDNN 7.0 [23]。我们还激活了CUDNN的基准测试功能,分别选择不同的卷积最快算法。{ARM.使用高度优化的基于Neon的实现的Qualcomm Snapdragon 810。评估仅使用一个线程。

其他设置包括: 打开完整的优化选项(例如,使用张量融合来减少小操作的开销).输入图像大小为224 ×224。每个网络都是随机初始化并评估100次。平均运行时间被使用。为了开始我们的研究,我们分析了两个最先进的网络,ShuffleNet V1 [15]和MobileNet V2 [14]的运行时间性能。它们都非常高效和准确地完成ImageNet分类任务,并且广泛用于低端设备,如手机。尽管我们只分析了这两个网络,但我们注意到它们代表了当前的趋势。它们的核心都是分组卷积和深度卷积,这也是其他最先进网络的关键组成部分,比如ResNeXt [7]、Xception [12]、MobileNet [13]和CondenseNet [16]。总体运行时间被分解为不同的操作,如图2所示。我们注意到FLOPs指标只考虑了卷积部分。尽管这部分消耗了大部分时间,但数据I/O、数据洗牌和元素操作(AddTensor、ReLU等)等其他操作也占据了相当数量的时间。因此,FLOPs不是一个足够准确的实际运行时间估计。基于这一观察,我们从几个不同方面对运行时(或速度)进行了详细分析,并得出了几个对于有效的网络架构设计的实用指南:G1)等通道宽度最小化存储器访问成本(MAC)。现代网络通常采用深度可分离卷积[12,13,15,14],其中逐点卷积(即1×1卷积)占据了大部分的复杂度[15]。我们研究了1×1卷积的卷积核形状。形状由两个参数指定:输入通道数c1和输出通道数c2。设h和w为特征图的空间大小,1×1卷积的FLOPs为B=hwc1c2。为了简化起见,我们假定运算设备中的缓存足够大,可以存储整个特征图。

第十章 ShuffleNetv2网络详解_第2张图片

(图2:ShuffleNet v1 [15](1×,g = 3)和MobileNet v2 [14](1×)两个代表性先进网络架构的运行时间分解。) 

因此,MAC具有由FLOPs给出的下限。当输入和输出通道数量相同时,它达到下限。这个结论是理论上的。在实践中,许多设备上的缓存通常不够大。另外,现代计算库通常采用复杂的阻塞策略来充分利用缓存机制[24]。因此,真正的MAC可能会偏离理论值。为了验证上述结论,进行如下实验。通过重复堆叠10个构建块来构建基准网络。每个块都包含两个卷积层。第一个包含c1个输入通道和c2个输出通道,第二个则相反。表1报告了固定总FLOPs时,通过改变c1:c2比例而获得的运行速度。很明显,当c1:c2接近1:1时,MAC变小,网络评估速度更快。G2)过多的分组卷积会增加MAC。分组卷积是现代网络架构的核心[7,15,25,26,27,28]。通过将所有通道之间的密集卷积变成稀疏卷积(仅在通道组内),可以减少计算复杂性(FLOPs)。一方面,它允许在固定FLOPs下使用更多通道,并增加网络容量(从而获得更好的准确性)。另一方面,增加通道数会导致MAC增加。形式上,按照G1和Eq.1中的符号,1×1分组卷积的MAC和FLOPs之间的关系为MAC = hw(c1 + c2) + c1c2 g = hwc1 + Bgc1 + Bhw; (2)其中g是组数,B = hwc1c2 / g是FLOPs。很容易看出,在给定固定输入形状c1×h×w和计算成本B的情况下,MAC随着g的增长而增加。为了研究实践中的影响,通过堆叠10个点卷积分组卷积层来构建基准网络。表2报告了使用分组卷积的运行速度。

在固定总算力的情况下,使用不同的组数是有差异的。很明显,使用一个大的组数会显著降低运行速度。例如,在GPU上使用8个组比使用1个组(标准密集卷积)慢了两倍以上,在ARM上慢了多达30%。这主要是由于增加了乘加运算。我们指出,我们的实现经过了特殊优化,比逐个组计算卷积要快得多。因此,我们建议应根据目标平台和任务精心选择组数。仅仅因为这可能使得可以使用更多的通道而使用大的组数是不明智的,因为准确性增加的好处很容易被迅速增加的计算成本所抵消。G3)网络分段降低了并行度。在GoogLeNet系列[29,30,3,31]和自动生成的体系结构[9,11,10]中,在每个网络块中广泛采用了“多路径”结构。使用许多小的运算符(这里称为“分段运算符”)而不是少量的大运算符。例如,在NASNET-A[9]中,分段运算符的数量(即一个构建块中的单个卷积或池操作的数量)为13。相比之下,在像ResNet [4]这样的常规结构中,这个数字是2或3。

尽管这种分段结构已被证明对准确性有益,但它可能会降低效率,因为它对于GPU等具有强大并行计算能力的设备来说是不友好的。它还引入了额外的开销,例如内核启动和同步。

表1: Guideline 1的验证实验。测试了四种不同的输入/输出通道比率(c1和c2),在这四种比率下,通过改变通道数量固定了总FLOPs。输入图像大小为56×56。

Table 1:Validation experiment for Guideline 1.Four different ratios of number of input/output channels (c1 and c2)are tested,while the total FLOPs under the four ratios is fixed by varying the number of channels.Input image size is 56 ×56

GPU(Batches/.sec)

ARM(Images/sec.)

c1:c2

(c1,c2) for ×1

×1

×2

×4

(c1,c2) for ×1

×1

×2

×4

1:1

(128,128)

1480

723

232

(32,32)

76.2

21.7

5.3

1:2

(90,180)

1296

586

206

(22,44)

72.9

20.5

5.1

1:6

(52,312)

876

489

189

(13,78)

69.1

17.9

4.6

1:12

(36,432)

748

392

163

(9,108)

57.6

15.1

4.4

该表格展示了针对Guideline 1进行的验证实验结果,其中测试了四种不同的输入/输出通道比率(c1和c2),并在保持总FLOPs不变的情况下通过调整通道数量来实现。具体参数解释如下:

GPU (Batches/sec.):使用GPU进行计算时,每秒钟可以处理的batch数。

ARM (Images/sec.):使用ARM处理器进行计算时,每秒钟可以处理的图像数。

c1:c2 (c1,c2) for ×1 ×1 ×2 ×4:输入/输出通道比率,其中c1表示输入通道数,c2表示输出通道数,后面的×1 ×1 ×2 ×4表示四种不同的通道倍增方式。

(c1,c2) for ×1 ×1 ×2 ×4:在不同的通道倍增方式下,通过调整通道数量得到的总FLOPs,其中输入图像大小为56x56。

从表格中可以提取以下信息:

随着输入/输出通道比率的变化,GPU和ARM的处理速度都会发生变化。

在相同的输入/输出通道比率下,GPU的处理速度明显高于ARM,这可能是由于GPU在并行计算方面的优势。

随着通道数量的增加,GPU和ARM的处理速度都会降低,这是由于计算复杂度的增加。

在不同的通道倍增方式下,总FLOPs保持不变,但GPU和ARM的处理速度会发生变化,这是由于不同的通道倍增方式会影响计算的瓶颈。

总的来说,该表格展示了在Guideline 1下进行的验证实验,突出了输入/输出通道比率、通道数量和通道倍增方式对计算速度的影响。

表2:指南2的验证实验。测试了4个不同的组数g,而总FLOPs在这四个值下是通过改变总通道数c来保持固定的。输入图像尺寸为56 ×56。

Table 2:Validation experiment for Guideline 2.Four values of group number g are tested,while the total FLOPs under the four values is fixed by varying the total channel number c.Input image size is 56 ×56.

GPU(Batches/.sec)

ARM(Images/sec.)

g

c for ×1

×1

×2

×4

c for ×1

×1

×2

×4

1

128

2451

1289

437

64

40.0

10.2

2.3

2

180

1725

873

341

90

35.0

9.5

2.2

4

256

1026

644

338

128

32.9

8.7

2.1

8

360

634

455

230

180

27.8

7.5

1.8

该表格展示了针对Guideline 2进行的验证实验结果,其中测试了四种不同的分组数量g,并在保持总FLOPs不变的情况下通过调整通道数量来实现。具体参数解释如下:

GPU (Batches/sec.):使用GPU进行计算时,每秒钟可以处理的batch数。

CPU (Images/sec.):使用CPU进行计算时,每秒钟可以处理的图像数。

g:分组数量。

c for ×1 ×1 ×2 ×4:在不同的通道倍增方式下,通过调整通道数量得到的总FLOPs,其中输入图像大小为56x56。

从表格中可以提取以下信息:

随着分组数量g的增加,GPU和CPU的处理速度都会发生变化。

在相同的分组数量下,GPU的处理速度明显高于CPU,这可能是由于GPU在并行计算方面的优势。

随着通道数量的增加,GPU和CPU的处理速度都会降低,这是由于计算复杂度的增加。

在不同的通道倍增方式下,总FLOPs保持不变,但GPU和CPU的处理速度会发生变化,这是由于不同的通道倍增方式会影响计算的瓶颈。

总的来说,该表格展示了在Guideline 2下进行的验证实验,突出了分组数量、通道数量和通道倍增方式对计算速度的影响。

表3:指南3.c的验证实验表示单个片段的通道数。其他分段结构的通道数将根据FLOPs进行调整,以保持与单个片段相同。输入图像尺寸为56×56

Table 3:Validation experiment for Guideline 3.c denotes the number of channels for 1-fragment.The channel number in other fragmented structures is adjusted so that the FLOPs is the same as 1-fragment.Input image size is 56 ×56

GPU(Batches/.sec)

ARM(Images/sec.)

c=128

c=256

c=512

c=64

c=128

c=256

1-fragment

2446

1274

434

40.2

10.1

2.3

2-fragment-series

1790

909

336

38.6

10.1

2.2

4-fragment-series

752

745

349

38.4

10.1

2.3

2-fragment-parallel

1537

803

320

33.4

9.1

2.2

4-fragment- parallel

691

572

292

35.0

8.4

2.1

该表格展示了针对Guideline 3进行的验证实验结果,其中测试了不同的分片结构和通道数量,并通过调整通道数量使得总FLOPs相同。具体参数解释如下:

GPU(Batches/sec.):使用GPU进行计算时,每秒钟可以处理的batch数。

CPU (Images/sec.):使用CPU进行计算时,每秒钟可以处理的图像数。

c=128 c=256 c=512:不同的通道数量。

1-fragment:单片结构。

2-fragment-series:双片结构,串行连接。

4-fragment-series:四片结构,串行连接。

2-fragment-parallel:双片结构,并行连接。

4-fragment-parallel:四片结构,并行连接。

从表格中可以提取以下信息:

不同的分片结构和通道数量会对GPU和CPU的处理速度产生影响。

在相同的通道数量下,GPU的处理速度明显高于CPU,这可能是由于GPU在并行计算方面的优势。

不同的分片结构会影响计算的瓶颈,从而影响GPU和CPU的处理速度。

并行连接的分片结构相对于串行连接的分片结构具有更好的计算性能。

总的来说,该表格展示了在Guideline 3下进行的验证实验,突出了分片结构和通道数量对计算速度的影响。

表格4: Guideline 4 的验证实验。ReLU和Shortcut操作分别从“瓶颈”单元[4]中移除。c是单元中的通道数。该单元被重复堆叠了10次以基准测试速度。

Table 4:Validation experiment for Guideline 4.The ReLU and shortcut operations are removed from the \bottleneck"unit [4],separately.c is the number of channels in unit.The unit is stacked repeatedly for 10 times to benchmark the speed.

GPU(Batches/.sec)

ARM(Images/sec.)

RELU

short-cut

c=32

c=64

c=128

c=32

c=64

c=128

yes

yes

2427

2066

1436

56.7

16.9

5.0

yes

no

2647

2256

1735

61.9

18.8

5.2

no

yes

2672

2121

1458

57.3

18.2

5.1

no

no

2842

2376

1782

66.3

20.2

5.4

该表格展示了针对Guideline 4进行的验证实验结果,其中测试了不同的“bottleneck”单元中是否存在ReLU和shortcut操作,并且使用不同的通道数量进行堆叠。具体参数解释如下:

GPU (Batches/sec.):使用GPU进行计算时,每秒钟可以处理的batch数。

CPU (Images/sec.):使用CPU进行计算时,每秒钟可以处理的图像数。

ReLU:是否在“bottleneck”单元中加入ReLU操作。

shortcut:是否在“bottleneck”单元中加入shortcut操作。

c=32 c=64 c=128:不同的通道数量。

从表格中可以提取以下信息:

在不同的通道数量下,加入ReLU和shortcut操作会对GPU和CPU的处理速度产生影响。

在相同的ReLU和shortcut设置下,GPU的处理速度明显高于CPU,这可能是由于GPU在并行计算方面的优势。

在相同的通道数量下,加入ReLU和shortcut操作会提高计算的瓶颈,从而影响GPU和CPU的处理速度。

不加入ReLU和shortcut操作的“bottleneck”单元具有更快的计算速度。

总的来说,该表格展示了在Guideline 4下进行的验证实验,突出了ReLU和shortcut操作以及通道数量对计算速度的影响。

第十章 ShuffleNetv2网络详解_第3张图片

(图3:ShuffleNet v1 [15]和本文的构建块。(a)基本ShuffleNet单元;(b)用于空间下采样(2×)的ShuffleNet单元;(c)我们的基本单元;(d)我们的用于空间下采样(2×)的单元。DWConv:深度可分离卷积。GConv:组卷积。)


 为了量化网络碎片化如何影响效率,我们评估了一系列具有不同碎片化程度的网络块。具体来说,每个构建块由1到4个1×1卷积组成,这些卷积按顺序或并行排列。附录中说明了这些块的结构。每个块重复堆叠10次。表3中的结果显示,碎片化显著降低了GPU的速度,例如4个碎片的结构比1个碎片慢3倍。在ARM上,速度降低相对较小。G4)成分操作是不可忽略的。如图2所示,在轻量级模型(如[15,14])中,成分操作占用了相当数量的时间,特别是在GPU上。在这里,成分运算符包括ReLU、AddTensor、AddBias等。它们的FLOP很小,但相对较重的MAC。特别地,我们还将深度卷积[12,13,14,15]视为成分运算符,因为它也具有高的MAC/FLOPs比值。为了验证,我们在ResNet [4]的"瓶颈"单元中进行了实验(1×1卷积,然后是3×3卷积,然后是1×1卷积,带ReLU和快捷连接)。分别去除了ReLU和快捷操作,不同变体的运行时间在表4中报告。我们观察到,在ReLU和快捷操作被移除后,GPU和ARM都获得了约20%的加速。结论和讨论基于上述指南和经验研究,我们得出结论,高效的网络架构应该1)使用"平衡化"卷积(相等的通道宽度);2)意识到使用组卷积的成本;3)降低碎片化程度;以及4)减少成分运算。这些理想的属性取决于平台特征(如内存处理和代码优化),这些特征超出了理论FLOPs。它们应该纳入实际网络设计的考虑。

轻量级神经网络结构的最新进展[15,13,14,9,11,10,12]主要基于FLOPs指标,而不考虑上述特性。例如,ShuffleNet v1 [15]严重依赖于组卷积(针对G2)和类似瓶颈的构建块(针对G1)。MobileNet v2 [14]使用反转瓶颈结构,违反了G1。它使用深度卷积和ReLUs在“厚”特征图上,违反了G4。自动生成的结构[9,11,10]高度分散,违反了G3。

1.ShuffleNetv2.py(pytorch实现)

from torch import nn
import torch

def _make_divisible(ch, divisor=8, min_ch=None):
    if min_ch is None:
        min_ch = divisor
    new_ch = max(min_ch, int(ch + divisor / 2) // divisor * divisor)
    if new_ch < 0.9 * ch:
        new_ch += divisor
    return new_ch

class ConvBNReLU(nn.Sequential):
    def __init__(self, in_channel, out_channel, kernel_size=3, stride=1, groups=1):
        padding = (kernel_size - 1) // 2
        super(ConvBNReLU, self).__init__(
            nn.Conv2d(in_channel, out_channel, kernel_size, stride, padding, groups=groups, bias=False),
            nn.BatchNorm2d(out_channel),
            nn.ReLU6(inplace=True)
        )

class InvertedResidual(nn.Module):
    def __init__(self, in_channel, out_channel, stride, expand_ratio):
        super(InvertedResidual, self).__init__()
        hidden_channel = in_channel * expand_ratio
        self.use_shortcut = stride == 1 and in_channel == out_channel
        layers = []
        if expand_ratio != 1:
            layers.append(ConvBNReLU(in_channel, hidden_channel, kernel_size=1))
        layers.extend([
            ConvBNReLU(hidden_channel, hidden_channel, stride=stride, groups=hidden_channel),
            nn.Conv2d(hidden_channel, out_channel, kernel_size=1, bias=False),
            nn.BatchNorm2d(out_channel)
        ])
        self.conv = nn.Sequential(*layers)
    def forward(self, x):
        if self.use_shortcut:
            return x + self.conv(x)
        else:
            return self.conv(x)

class MobileNetV2(nn.Module):
    def __init__(self, num_classes=1000, alpha=1.0, round_nearest=8):
        super(MobileNetV2, self).__init__()
        block = InvertedResidual
        input_channel = _make_divisible(32*alpha, round_nearest)
        last_channel = _make_divisible(1280*alpha, round_nearest)

        Inverted_residul_setting = [
            [1, 16, 1, 1],
            [6, 24, 2, 2],
            [6, 32, 3, 2],
            [6, 64, 4, 2],
            [6, 96, 3, 1],
            [6, 160, 3, 2],
            [6, 320, 1, 1]
        ]
        features = []
        features.append(ConvBNReLU(3, input_channel, stride=2))
        for t, c, n, s in Inverted_residul_setting:
            output_channel = _make_divisible(c * alpha, round_nearest)
            for i in range(n):
                stride = s if i == 0 else 1
                features.append(block(input_channel, output_channel, stride, expand_ratio=t))
                input_channel = output_channel
        features.append(ConvBNReLU(input_channel, last_channel, 1))
        self.features = nn.Sequential(*features)
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.classifier = nn.Sequential(
            nn.Dropout(0.2),
            nn.Linear(last_channel, num_classes)
        )
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out')
                if m.bias is not None:
                    nn.init.zeros_(m.bias)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.ones_(m.weight)
                nn.init.zeros_(m.bias)
            elif isinstance(m, nn.Linear):
                nn.init.normal_(m.weight, 0.01)
                nn.init.zeros_(m.bias)
    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

总结

最后,我们评估了在ARM平台上移动设备上ShuffleNet模型的实际推理速度。虽然具有更大的组数(例如g = 4或g =8)的ShuffleNets通常具有更好的性能,但我们发现在我们当前的实现中效率较低。从经验上来看,g = 3通常在精确度和实际推理时间之间有适当的权衡。如表8所示,采用了三个输入分辨率进行测试。由于内存访问和其他开销,我们发现每4个理论复杂度的降低通常会在我们的实现中导致约2.6倍的实际加速。尽管如此,与AlexNet[21]相比,我们的ShuffleNet 0.5×模型在可比的分类准确性下仍然实现了约13倍的实际加速(理论加速为18倍),比以前的AlexNet级别模型或速度提升方法如[14,16,22,42,43,38]要快得多。

你可能感兴趣的:(transformer,深度学习,人工智能)