第十一章 EfficientNetv1网络详解

news2024/11/16 13:33:38

系列文章目录


第一章 AlexNet网络详解

第二章 VGG网络详解

第三章 GoogLeNet网络详解 

第四章 ResNet网络详解 

第五章 ResNeXt网络详解 

第六章 MobileNetv1网络详解 

第七章 MobileNetv2网络详解 

第八章 MobileNetv3网络详解 

第九章 ShuffleNetv1网络详解 

第十章 ShuffleNetv2网络详解 

第十一章 EfficientNetv1网络详解 

第十二章 EfficientNetv2网络详解 

第十三章 Transformer注意力机制

第十四章 Vision Transformer网络详解 

第十五章 Swin-Transformer网络详解 

第十六章 ConvNeXt网络详解 

第十七章 RepVGG网络详解 

第十八章 MobileViT网络详解 

文章目录

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


0、摘要

  1. 根据以往的经验,增加网络的深度depth能够得到更加丰富、复杂的特征并且能够很好的应用到其他任务中。但是网络的深度过深会面临梯度消失,训练困难问题。
  2. 增加网络的width能够获得更高细粒度的特征并且也更容易训练,但对于width很大而且深度较浅的网络往往很难学习到更深层次的特征。
  3. 增加输入网络的图像分辨率能够潜在获得更高细粒度的特征模板,但对于非常高的输入分辨率,准确率的增益也会减少。并且大分辨率图像会增加计算量。

  1. 第一个升维的1x1卷积层,它的卷积核个数是输出特征矩阵channel的n倍
  2. 当n=1时,不要第一个升维的1x1卷积层,即Stage2中的MBConv结构都没有第一个升维的1x1卷积层(这和MobileNetV3网络类似)
  3. 关于shortcut连接,仅当输入MBConv结构的特征矩阵与输出的特征矩阵shape相同时才存在。

SE模块如图所示,由一个全局平均池化,两个全连接层组成。第一个全连接层的节点个数是输入该MBConv特征矩阵channels的1/4,且使用Swish激活函数。第二个全连接层的节点个数等于Depthwise Conv层输出的特征矩阵channels,且使用Sigmoid函数

---------------------------------------------------------------------------------------------------------------------------------

Width_coefficient代表channel维度上的倍率因子,比如在EfficientNetB0中Stage1的3x3卷积层所使用的卷积核个数是32,那么在B6中就是32x1.8=57.6接着取整到离它最近的8的倍数即56,其他Stage同理

Depth_coefficient代表depth维度上的倍率因子(仅针对Stage2到Stage8),比如EfficientNetB0中Stage7的L4,那么在B6中就是4x2.6=10.4,接着向上取整即11.

---------------------------------------------------------------------------------------------------------------------------------

卷积神经网络(ConvNets)通常在固定的资源预算下开发,如果有更多的资源可用,再进行扩展以获得更好的准确性。在本文中,我们系统地研究了模型扩展,并确定了仔细平衡网络深度、宽度和分辨率可以带来更好的性能。基于这一观察结果,我们提出了一种新的缩放方法,使用一个简单但高效的复合系数均匀缩放深度/宽度/分辨率的所有维度。我们展示了这种方法在扩展MobileNets和ResNet方面的有效性。为了更进一步,我们使用神经架构搜索设计了一个新的基线网络,并将其扩展为一系列模型,称为EfficientNets,这些模型比以前的ConvNets具有更好的准确性和效率。特别是,我们的EfficientNet-B7在ImageNet上实现了最先进的84.3% top-1准确率,而在推断时比最好的现有ConvNet小8.4倍,快6.1倍。我们的EfficientNets也具有良好的转移性,在CIFAR-100 (91.7%)、Flowers (98.8%)和其他3个转移学习数据集上实现了最先进的准确性,并且参数数量更少一个数量级。

1、前言

通过扩展 ConvNets 的规模,通常可以实现更高的准确度。例如,ResNet (He et al.,2016)可以通过添加更多层次来从 ResNet-18 扩展到 ResNet-200;最近,GPipe (Huang et al.,2018)通过将基线模型扩大四倍来实现 84.3% 的 ImageNet top-1 准确度。然而,扩展 ConvNets 的过程从未被很好地理解,目前有许多可行的方式。最常见的方式是通过网络深度 (He et al.,2016) 或宽度 (Zagoruyko和Komodakis,2016) 扩展 ConvNets。另一种不太常见但日益流行的方法是通过图像分辨率 (Huang et al.,2018) 扩展模型。在以前的工作中,通常只扩展三种尺寸中的一种 - 深度、宽度和图像大小。虽然可以任意扩展两个或三个尺寸,但任意扩展需要繁琐的手动调整,而且通常仍会导致次优的准确度和效率。在本文中,我们想研究和重新思考扩展 ConvNets 的过程。特别是,我们研究了一个核心问题:是否存在一种基本方法来扩展 ConvNets,以实现更好的准确度和效率?我们的实证研究表明,平衡网络宽度/深度/分辨率的所有维度至关重要,令人惊讶的是,可以通过简单地将它们各自扩大一定比例来实现这种平衡。基于这一观察结果,我们提出了一种简单而有效的复合缩放方法。与任意缩放这些因素的传统做法不同,我们的方法统一缩放网络宽度、深度和分辨率,将它们与常数比例相结合。并采用一组固定的缩放系数进行分辨率调整。例如,如果我们想要使用2N倍的计算资源,那么我们可以简单地通过将网络深度增加αN倍、宽度增加βN倍、图像大小增加γN倍来实现,其中α,β,γ是由原始小模型进行小格子搜索确定的常数系数。图2说明了我们的缩放方法与传统方法之间的差异。从直觉上讲,复合缩放方法是有意义的,因为如果输入图像更大,则网络需要更多的层数来增加感受野,并需要更多的通道来捕捉更细粒度的图案。事实上,以前的理论(Raghu等人,2017; Lu等人,2018)和经验结果(Zagoruyko & Komodakis,2016)都表明网络宽度和深度之间存在某种关系,但据我们所知,我们是第一个在所有三个维度(网络宽度、深度和分辨率)之间经验性地量化这种关系。我们展示了我们的缩放方法在现有的MobileNets (Howard等人,2017; Sandler等人,2018)和ResNet (He等人,2016)上的良好效果。值得注意的是,模型缩放的有效性严重依赖于基础网络。为了更进一步,我们使用神经体系结构搜索(Zoph & Le,2017; Tan等人,2019)来开发一个新的基础网络,并将其扩展以获得一组模型,称为EfficientNets。图1总结了ImageNet的表现,其中我们的EfficientNets明显优于其他ConvNets。特别地,我们的EfficientNet-B7超过了现有的最佳GPipe准确性(Huang等人,2018),但使用的参数数量少8.4倍,推理速度快6.1倍。与广泛使用的ResNet-50(He等人,2016)相比,我们的EfficientNet-B4将top-1准确度从76.3%提高到83.0%(+6.7%),具有类似的FLOPS。除了ImageNet之外,EfficientNets也很好地转化,并在8个广泛使用的数据集中的5个上实现了最新的准确性,在减少达到21倍的参数的同时,就已经超过了现有的ConvNets。

 (图1.模型大小与ImageNet准确性。所有数字都是基于单张图片、单个模型的结果。我们的EfficientNets明显优于其他ConvNets。特别是,EfficientNet-B7在比GPipe小8.4倍、速度快6.1倍的情况下实现了新的84.3%top-1准确率的最佳表现。EfficientNet-B1比ResNet-152小7.6倍、速度快5.7倍。详情请参见表二和表四。)

 (图2.模型缩放。(a)是基准网络示例;(b)-(d)是传统的缩放方法,只增加网络宽度、深度或分辨率中的一个维度。(e)是我们提出的复合缩放方法,它以固定比例均匀缩放所有三个维度)

2、EfficientNetv1网络详解网络架构

EfficientNetv1是由谷歌团队在2019年提出的一种高效的Convolutional Neural Network (CNN)结构,旨在通过同时改变Width(宽度)、Depth(深度)和Resolution(分辨率)三个关键参数以获得最优的模型性能。 EfficientNetv1具有如下的网络架构: 输入图像 (224x224x3) Convolutional layer (3x3) Batch Normalization Swish activation MBConv blocks x n MBConv block的结构为: Depthwise Convolutional layer (3x3) Batch Normalization Swish activation Pointwise Convolutional layer (1x1) Batch Normalization Swish activation 其中MBConv表示Mobile Inverted Residual Bottleneck Block,是由两个分支组成的残差结构,其中一个分支是标准卷积层,另一个分支采用Depthwise Convolutional layer 和Pointwise Convolutional layer组成的轻量化块,以减少处理量和模型参数数量。Swish激活函数是sigmoid函数的近似,可以更好地提高准确度。 在上述MBConv blocks结构中,n代表EfficientNetv1的缩放系数,通过同时缩放Width、Depth和Resolution,可以从EfficientNet-B0到EfficientNet-B7进行选择,以逐步提高模型的深度和复杂性。 最后,EfficientNetv1中还使用了Global Average Pooling和Fully Connected layer产生模型的输出。 总体来说,EfficientNetv1的网络架构旨在通过对三个关键参数进行优化来提高模型的性能和效率,是当前在Imagenet上的性能最好的模型之一。

3.正文分析

卷积神经网络准确性:自2012年AlexNet(Krizhevsky等人)获得ImageNet比赛冠军以来,通过变得更大,卷积神经网络的准确性越来越高:虽然2014年ImageNet冠军GoogleNet(Szegedy等人,2015)使用约6.8M参数实现了74.8%的top-1准确率,但2017年ImageNet冠军SENet(Hu等人,2018)使用145M参数实现了82.7%的top-1准确率。最近,GPipe(Huang等人,2018)将ImageNet top-1验证准确性的最新水平进一步推至84.3%,使用了557M个参数:它非常大,只能通过分割网络并将每个部分分配到不同的加速器来使用专用的管道并行库进行训练。虽然这些模型主要设计用于ImageNet,但最近的研究表明,更好的ImageNet模型在各种迁移学习数据集(Kornblith等人,2019)以及其他计算机视觉任务如目标检测(He等人,2016; Tan等人,2019)中表现更好。尽管更高的准确性对许多应用至关重要,但我们已经达到了硬件内存限制,因此进一步提高准确性需要更好的效率。

 卷积神经网络的效率:深度卷积神经网络通常会超过参数化。模型压缩(韩等,2016年;何等,2018年;杨等,2018年)是一种通过牺牲准确性换取效率来减少模型大小的常见方式。随着移动手机的普及,人们也经常手工制作高效的移动大小卷积神经网络,如SqueezeNets(Iandola等,2016年;Gholami等,2018年),MobileNets(Howard等,2017年;Sandler等,2018年)和ShuffleNets(张等,2018年;马等,2018年)。最近,神经架构搜索在设计高效的移动大小卷积神经网络(谭等,2019年;蔡等,2019年)中越来越受欢迎,并通过广泛调整网络宽度、深度、卷积核类型和大小实现了比手工制作的移动卷积神经网络更好的效率。然而,如何将这些技术应用于设计空间更大、调整成本更高的大型模型仍不清楚。为了实现这一目标,本文采用模型缩放技术研究超大型卷积神经网络的效率,超过现有最先进的准确性水平。

模型缩放:对于不同的资源限制,有许多方式可以对ConvNet进行缩放:例如,ResNet(He et al。,2016)可以通过调整网络深度(#layers)进行缩小(例如,ResNet-18)或扩展(例如,ResNet-200),而WideResNet(Zagoruyko&Komodakis,2016)和MobileNets(Howard et al。,2017)可以通过网络宽度(#channels)进行缩放。同时,更大的输入图像尺寸也被公认能提高准确性,但会增加更多的FLOPS开销。虽然之前的研究已经证明(Raghu et al。,2017;Lin&Jegelka,2018;Sharir&Shashua,2018;Lu et al。,2018),对于ConvNets 的表达能力,网络深度和宽度两者都很重要,但如何有效地缩放ConvNet以实现更好的效率和准确性仍然是一个开放性问题。我们的工作系统地和经验性地研究了ConvNet缩放的三个维度:网络宽度、深度和分辨率。

在这一部分中,我们将制定缩放问题,研究不同的方法,并提出我们的新的缩放方法。3.1问题阐述ConvNet层i可以被定义为函数:Yi=Fi(Xi),其中Fi是算子,Yi是输出张量,Xi是输入张量,张量形状为hHi;Wi;Cii1,其中Hi和Wi是空间维度,Ci是通道维度。ConvNet N可以通过组成层的列表来表示:N=Fk... F2 F1(X1)=Jj=1... k Fj(X1)。在实践中,ConvNet层通常被分成多个阶段,每个阶段的所有层分享相同的架构:例如,ResNet(He等,2016)有五个阶段,每个阶段的所有层都具有相同的卷积类型,除了第一层执行下采样。因此,我们可以将ConvNet定义为:N=Ki=1...s FLi ^i FLi ^i XhHi;Wi;Cii(1)其中FLi ^i FLi ^i表示第i层Fi在阶段i中重复Li次,hHi;Wi;Cii表示层i输入张量X的形状。图2(a)说明了一个典型的ConvNet,其中空间维度逐渐缩小,但通道维度在层中扩展,例如,从初始输入形状h224; 224; 3i到最终输出形状h7; 7; 512i。与大多数专注于找到最佳层架构Fi的常规ConvNet设计不同,模型缩放尝试扩展网络长度(Li)、宽度(Ci)和/或分辨率(Hi;Wi),而不改变Fi在基线网络中预定义的架构。通过固定Fi,模型缩放简化了新资源约束的设计问题,但它仍然是一个探索每个层的不同Li;Ci;Hi;Wi的大型设计空间。为了进一步减少设计空间,我们限制所有层必须以恒定比例均匀缩放。我们的目标是最大化任何给定资源约束的模型准确性,这可以被制定为一个优化问题:max d;w;r Accuracy N(d;w;r)s:t:N(d;w;r)=Ki=1...s F^d·L^i ^i Xhr·H^i;r·W^i;w·C^ii(2)记忆(N)≤目标内存FLOPS(N)≤目标flops其中w;d;'

3.2. 缩放维度 问题2的主要困难在于最佳的d;w;r互相依赖,并且在不同的资源约束下值会发生变化。由于这个困难,传统方法大多在以下几个维度缩放ConvNets:深度(d):扩展网络深度是许多ConvNets(He等人,2016;Huang等人,2017;Szegedy等人,2015;2016)采用的最常见方法。直觉是深度的ConvNet可以捕获更加丰富和复杂的特征,并在新任务上很好地推广。然而,由于消失的梯度问题(Zagoruyko&Komodakis,2016),更深的网络也更难以训练。尽管有一些技术,例如跳跃连接(He等人,2016)和批量归一化(Ioffe&Szegedy,2015),可以缓解训练问题,但非常深的网络的精度增益会降低:例如,ResNet-1000的精度与ResNet-101相似,即使它有更多的层。图3(中间)显示了我们关于使用不同深度系数d缩放基线模型的经验研究,进一步表明非常深的ConvNets的精度返回有限。

宽度(w):对于小型模型,缩放网络宽度通常被广泛使用(Howard et al., 2017; Sandler et al., 2018; Tan et al., 2019)。正如Zagoruyko和Komodakis(2016)所讨论的,更宽的网络往往能够捕捉更精细的特征并更容易训练。然而,极宽但浅的网络往往难以捕捉更高级的特征。我们在图3(左)中的实证结果表明,当网络变得更宽(即宽度w变大)时,准确度很快饱和。 分辨率(r):对于更高分辨率的输入图像,ConvNets可以潜在地捕捉更精细的模式。从早期ConvNets的224x224开始,现代ConvNets倾向于使用299x299(Szegedy et al., 2016)或331x331(Zoph et al., 2018)以获得更好的准确性。最近,GPipe(Huang et al., 2018)使用480x480的分辨率实现了ImageNet最先进的准确性。更高的分辨率,例如600x600,在物体检测ConvNets(He等人,2017; Lin等人,2017)中也被广泛使用。图3(右)展示了缩放网络分辨率的结果,确实更高的分辨率提高了准确度,但对于非常高的分辨率(r = 1:0表示分辨率224x224,r = 2:5表示分辨率560x560),准确度的增益减小。 以上分析带给我们第一个观察结果:观察结果1-放大网络宽度、深度或分辨率中的任何一个维度都能提高准确度,但对于更大的模型,准确度的增益逐渐降低。

分辨率(r):随着更高分辨率的输入图像,ConvNets可以潜在地捕捉到更精细的模式。从早期ConvNets的224x224开始,现代ConvNets倾向于使用299x299(Szegedy等人,2016)或331x331(Zoph等人,2018)以获得更好的准确性。最近,GPipe(Huang等人,2018)通过480x480分辨率实现了最先进的ImageNet准确性。更高的分辨率,例如600x600,在对象检测ConvNets(He等人,2017; Lin等人,2017)中也被广泛使用。图3(右)显示了网络分辨率的缩放结果,高分辨率确实提高了准确性,但对于非常高的分辨率(r = 1:0表示分辨率224x224,r = 2:5表示分辨率560x560)的准确性增益逐渐减少。以上分析带领我们到第一个观察:观察1-扩大网络宽度、深度或分辨率的任何维度都可以提高准确性,但准确性的提高对于更大的模型而言有所减弱。

 (图3.使用不同的网络宽度(w)、深度(d)和分辨率(r)系数来扩展基线模型。具有更大宽度、深度或分辨率的大型网络倾向于实现更高的准确性,但在达到80%后,准确性增益很快饱和,显示了单一维度扩展的限制。基线网络在表1中描述)

3.3. 复合比例尺 我们从经验上观察到不同的缩放维度并不是独立的。直观地说,对于更高分辨率的图像,我们应该增加网络的深度,从而更大的感受野可以捕捉到包含更多像素的类似特征。相应地,当分辨率更高时,我们也应该增加网络的宽度,以便在高分辨率图像中捕捉到更细粒度的模式和更多的像素。这些直觉表明,我们需要协调和平衡不同的比例尺维度,而不是传统的单一维度比例尺。为了验证我们的直觉,我们比较了在不同的网络深度和分辨率下的宽度比例尺,如图4所示。如果我们只缩放网络宽度w而不改变深度(d=1.0)和分辨率(r=1.0),精度会很快饱和。在更深的(d=2.0)和更高分辨率(r=2.0)下,宽度比例尺在相同的FLOPS成本下实现了更好的精度。这些结果引导我们得出第二个观察结果:观察2 - 为了追求更好的精度和效率,在ConvNet比例尺达到平衡时,平衡所有的网络宽度、深度和分辨率是至关重要的。事实上,一些先前的工作(Zoph等,2018年;Real等,2019年)已经尝试过任意平衡网络的宽度和深度,但它们都需要繁琐的手动调整。在本文中,我们提出了一种新的复合缩放方法,它使用复合系数φ以原则性地统一缩放网络的宽度、深度和分辨率:深度:d =αφ,宽度:w =βφ,分辨率:r =γφ,使得α·β2·γ2≈2,α≥1;β≥1;γ≥1(3)。其中α、β、γ是可以通过小网格搜索确定的常数。直观地,φ是一个用户指定的系数,用于控制模型缩放所需的更多资源的数量,而α、β、γ则指定如何将这些额外资源分配到网络宽度、深度和分辨率上。值得注意的是,常规卷积运算的FLOPS与d、w2、r2成比例,即倍增网络的深度将使FLOPS倍增,但倍增网络的宽度或分辨率将使FLOPS增加四倍。由于卷积运算通常在ConvNets中占主导地位,使用方程3进行ConvNet的缩放将增加总FLOPS约为α·β2·γ2φ。在本文中,我们限制α·β2·γ2≈2,以使对于任何新的φ,总FLOPS将近似增加2φ。

(图4.不同基线网络的缩放网络宽度。线上的每个点表示具有不同宽度系数(w)的模型。所有基线网络均来自表1。第一个基线网络(d = 1.0,r = 1.0)具有18个卷积层,分辨率为224x224,而最后一个基线(d = 2.0,r = 1.3)具有36层,分辨率为299x299。)

<ol start="4"> <li>EfficientNet架构 由于模型缩放不会改变基线网络中的层操作F^i,因此拥有一个好的基线网络也是至关重要的。我们将使用现有的ConvNets来评估我们的缩放方法,但为了更好地展示我们的缩放方法的有效性,我们还开发了一个名为EfficientNet的新的移动大小基线。受(Tan et al.,2019)的启发,我们通过利用多目标神经架构搜索来优化精度和FLOPS,开发了我们的基线网络。具体而言,我们使用与(Tan et al.,2019)相同的搜索空间,并使用ACC(m)× [FLOPS(m)= T]w作为优化目标,其中ACC(m)和FLOPS(m)表示模型m的精度和FLOPS,T是目标FLOPS,w = -0.07是控制精度和FLOPS之间平衡的超参数。与(Tan et al.,2019; Cai et al.,2019)不同,我们在这里优化FLOPS而不是延迟,因为我们没有针对任何特定的硬件设备。我们的搜索产生了一个有效的网络,我们将其命名为EfficientNet-B0。由于我们使用与(Tan et al.,2019)相同的搜索空间,因此该架构类似于Mnas-Net,但由于较大的FLOPS目标(我们的FLOPS目标为400M),我们的EfficientNet-B0略微更大。表1显示了EfficientNet-B0的架构。其主要构建块是移动反向瓶颈MBConv(Sandler et al.,2018; Tan et al.,2019),我们还添加了收缩和激发优化(Hu et al.,2018)。从基线EfficientNet-B0开始,我们应用我们的复合缩放方法来进行两步缩放:•第1步:我们首先固定φ = 1,假设有两倍的资源可用,并基于公式2和3进行小型网格搜索。特别是,我们发现EfficientNet-B0的最佳值为α = 1:2;β = 1:1;γ = 1:15,在α·β2·γ2 ≈ 2的约束下。•第2步:然后固定α;β;γ为常数,并使用公式3对基线网络进行不同的φ缩放,以获得EfficientNet-B1到B7(详见表2)。值得注意的是,可以实现更好的性能。

(图5. FLOPS与ImageNet精度-类似于图1,但它比较的是FLOPS,而不是模型大小) 

 (图6. 模型参数与迁移学习准确性- 所有模型都是在ImageNet上预训练,并在新数据集上进行微调。)

实验 在这一部分,我们将首先评估我们的缩放方法对现有ConvNets和新提出的EfficientNets的影响。 5.1. 将MobileNets和ResNets放大 作为概念验证,我们首先将我们的缩放方法应用于广泛使用的MobileNets(Howard等人,2017; Sandler等人,2018)和ResNet(He等人,2016)。表3显示了按不同方式缩放它们的ImageNet结果。与其他单一维度缩放方法相比,我们的复合缩放方法提高了所有这些模型的准确性,表明我们所提出的通用现有ConvNets缩放方法的有效性。

le 3.5.2 EfficientNet在ImageNet上的结果 我们在ImageNet上训练了EfficientNet模型,使用了与(Tan et al.,2019)类似的设置:RMSProp优化器,衰减率为0.9和动量为0.9; 批归一化动量为0.99; 权重衰减为1e-5; 初始学习率为0.256,每2.4个周期衰减0.97。我们还使用了SiLU(Swish-1)激活(Ramachandran等人,2018; Elfwing等人,2018; Hendrycks&Gimpel,2016)、AutoAugment(Cubuk等人,2019)和随机深度(Huang等人,2016),生存概率为0.8。众所周知,更大的模型需要更多的正则化,我们从EfficientNet-B0的0.2线性增加了Dropout(Srivastava等人,2014)比率到B7的0.5。我们从训练集中随机选择了25K张图像作为minival集合,并对此minival进行提前停止;然后我们在原始验证集上评估提前停止的检查点以报告最终的验证精度。表2显示了所有从相同基准EfficientNet-B0缩放的EfficientNet模型的性能。我们的EfficientNet模型通常使用比其他类似精度的ConvNet少一个数量级的参数和FLOPS。特别是,我们的EfficientNet-B7通过使用66M的参数和37B FLOPS实现了84.3%top1的准确率,比之前最佳的GPipe(Huang等人,2018)更准确但更小8.4倍。这些增益来自更好的架构、更好的缩放和更好的训练设置,这些设置都是针对EfficientNet定制的。图1和图5说明了代表性ConvNets的参数-精度和FLOPS-精度曲线,其中我们缩放的EfficientNet模型使用比其他ConvNets更少的参数和FLOPS实现更高的准确性。值得注意的是,我们的EfficientNet模型不仅小,而且计算更便宜。例如,我们的EfficientNet-B3使用18倍的FLOPS比ResNeXt-101(Xie等人,2017)实现了更高的准确率。为了验证延迟,我们还在真实CPU上测量了一些代表性CovNets的推理延迟,如表3所示。

 (图7.不同缩放方法模型的类激活图(CAM)(Zhou等人,2016)-我们的复合缩放方法使得缩放模型(最后一列)能够聚焦于更具有物体细节的更相关区域。模型细节在表7中)

 (图8.使用不同方法扩展EfficientNet-B0的规模)

5.3. EfficientNet的迁移学习结果 我们还在一系列常用的迁移学习数据集上评估了我们的EfficientNet,如表6所示。我们借鉴了(Kornblith等人,2019)和(Huang等人,2018)的相同训练设置,即采用ImageNet预训练检查点并微调新的数据集。表5显示了迁移学习的性能:(1)与NASNet-A(Zoph等人,2018)和Inception-v4(Szegedy等人,2017)等公开可用的模型相比,我们的EfficientNet模型在平均参数减少4.7倍(高达21倍)的情况下实现了更高的准确性。 (2)与动态合成训练数据的DAT(Ngiam等人,2018)和使用专门的管道并行训练的GPipe(Huang等人,2018)等最先进的模型相比,在8个数据集中,我们的EfficientNet模型仍然在5个数据集中超越它们的准确性,但使用了少9.6倍的参数。图6比较了各种模型的准确性-参数曲线。总的来说,我们的EfficientNets在拥有一个数量级更少的参数的情况下,始终可以达到比现有模型包括ResNet(He等人,2016),DenseNet(Huang等人,2017),Inception(Szegedy等人,2017)和NASNet(Zoph等人,2018)更好的准确性。

6.讨论为了分离我们所提出的缩放方法与EfficientNet架构的贡献,图8比较了相同EfficientNet-B0基准网络的不同缩放方法的ImageNet性能。总的来说,所有的缩放方法都能够提高准确率,但代价是更高的FLOPS,但我们的复合缩放方法可以进一步提高准确率,最高可比其他单一维度的缩放方法提高2.5%,表明我们所提出的复合缩放方法的重要性。为了进一步了解为什么我们的复合缩放方法比其他方法更好,图7比较了几个具有不同缩放方法的代表模型的类激活图(Zhou等人,2016)。所有这些模型都是从同一个基线模型进行缩放的,它们的统计数据显示在表7中。图像是从ImageNet验证集中随机选取的。如图所示,使用复合缩放方法的模型倾向于关注更多相关区域的对象细节,而其他模型要么缺乏对象细节,要么无法捕捉图像中的所有对象。

1.EfficientNetv1.py(pytorch实现)

from typing import List, Callable
import torch
from torch import Tensor
import torch.nn as nn

def channel_shuffle(x:Tensor, groups:int) -> Tensor:
    batch_size, num_channels, height, width = x.size()
    channel_per_group = num_channels // groups
    x = x.view(batch_size, groups, channel_per_group, height, width)
    x = torch.transpose(x, 1, 2).contiguous()
    x = x.view(batch_size, -1, height, width)
    return x

class InvertedResidual(nn.Module):
    def __init__(self, input_c: int, output_c:int, stride:int):
        super(InvertedResidual, self).__init__()
        if stride not in [1, 2]:
            raise ValueError("illegal stride value.")
        self.stride = stride
        assert output_c % 2 == 0
        branch_features = output_c // 2
        assert (self.stride != 1) or (input_c == branch_features << 1)
        if self.stride == 2:
            self.branch1 = nn.Sequential(
                self.depthwise_conv(input_c, input_c, kernel_s=3, stride=self.stride, padding=1),
                nn.BatchNorm2d(input_c),
                nn.Conv2d(input_c, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
                nn.BatchNorm2d(branch_features),
                nn.ReLU(inplace=True)
            )
        else:
            self.branch1 = nn.Sequential()
        self.branch2 = nn.Sequential(
            nn.Conv2d(input_c if self.stride > 1 else branch_features, branch_features, kernel_size=1,
                      stride=1, padding=0, bias=False),
            nn.BatchNorm2d(branch_features),
            nn.ReLU(inplace=True),
            self.depthwise_conv(branch_features, branch_features, kernel_s=3, stride=self.stride, padding=1),
            nn.BatchNorm2d(branch_features),
            nn.Conv2d(branch_features, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(branch_features),
            nn.ReLU(inplace=True)
        )

    @staticmethod
    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)

    def forward(self, x: Tensor) -> Tensor:
        if self.stride == 1:
            x1, x2 = x.chunk(2, dim=1)
            out = torch.cat((x1, self.branch1(x), self.branch2(x)), dim=1)
        else:
            out = torch.cat((self.branch1(x), self.branch2(x)), dim=1)
        out = channel_shuffle(out, 2)
        return out

class ShuffleNetV2(nn.Module):
    def __int__(self,
                stages_repeats: List[int],
                stages_out_channels: List[int],
                num_classes:int=1000,
                inverted_residual: Callable[..., nn.Module] = InvertedResidual):
        super(ShuffleNetV2, self).__init__()
        if len(stages_repeats) != 3:
            raise ValueError("expected stages_repeats as list of 3 positive ints")
        if len(stages_out_channels) != 5:
            raise ValueError("expected stage_out_channels as list of 5 positive ints")
        self._stage_out_channels = stages_out_channels
        input_channels=3,
        output_channels = self._stage_out_channels[0]
        self.conv1 = nn.Sequential(
            nn.Conv2d(input_channels, output_channels, kernel_size=3, stride=2, padding=1, bias=False),
            nn.BatchNorm2d(output_channels),
            nn.ReLU(inplace=True)
        )
        input_channels = output_channels
        self.maxpoool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        self.stage2:nn.Sequential
        self.stage3:nn.Sequential
        self.stage4:nn.Sequential
        stages_names = ["stage{}".format(i) for i in [2, 3, 4]]
        for name, repeats, output_channels in zip(stages_names, stages_repeats, stages_out_channels[1:]):
            seq = [inverted_residual(input_channels, output_channels, 2)]
            for i in range(repeats - 1):
                seq.append(inverted_residual(output_channels, output_channels, 1))
            setattr(self, name, nn.Sequential(*seq))
            input_channels = output_channels
        output_channels = self._stage_out_channels[-1]
        self.conv5 = nn.Sequential(
            nn.Conv2d(input_channels, output_channels, kernel_size=1, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(output_channels),
            nn.ReLU(inplace=True)
        )
        self.fc = nn.Linear(output_channels, num_classes)

    def _forward_impl(self, x:Tensor) -> Tensor:
        x = self.conv1(x)
        x = self.maxpoool(x)
        x = self.stage2(x)
        x = self.stage3(x)
        x = self.stage4(x)
        x = self.conv5(x)
        x = x.mean([2, 3])
        x = self.fc(x)
        return x
    def forward(self, x:Tensor) -> Tensor:
        return self._forward_impl(x)

def shufflenet_v2_x0_5(num_classes=1000):
    model = ShuffleNetV2(stages_repeats=[4, 8, 4],
                         stages_out_channels=[24, 48, 96, 192, 1024],
                         num_classes=num_classes)
    return model

def shufflenet_v2_x1_0(num_classes=1000):
    model = ShuffleNetV2(stages_repeats=[4, 8, 4],
                         stages_out_channels=[24, 116, 232, 464, 1024],
                         num_classes=num_classes)
    return model

def shufflenet_v2_x1_5(num_classes=1000):
    model = ShuffleNetV2(stages_repeats=[4, 8, 4],
                         stages_out_channels=[24, 176, 352, 704, 1024],
                         num_classes=num_classes)
    return model

def shufflenet_v2_x2_0(num_classes=1000):
    model = ShuffleNetV2(stages_repeats=[4, 8, 4],
                         stages_out_channels=[24, 244, 488, 976, 2048],
                         num_classes=num_classes)
    return model

总结

结论 在本文中,我们系统地研究了ConvNet的规模问题,并发现仔细平衡网络的宽度、深度和分辨率是一个重要但缺失的部分,使我们无法获得更好的准确性和效率。为了解决这个问题,我们提出了一种简单而高效的复合缩放方法,它使我们能够更有原则地将基准ConvNet扩展到任何目标资源限制,同时保持模型的效率。通过这种复合缩放方法的支持,我们展示了一个移动大小的EfficientNet模型可以非常有效地扩展,比ImageNet和五个常用的迁移学习数据集上的最新准确性提高了一个数量级,同时参数和FLOPS少得多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/676932.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ffmpeg 音视频处理神器

1 FFmpeg是什么 ffmpeg是一套用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它包含了非常先进的音频/视频编解码库libavcodec&#xff0c;提供了录制、转换以及流化音视频的完整解决方案。 许多FFmpeg的开发人员都来自MPla…

AWS Lambda 介绍

计算服务的演进 EC2------Container-------Lambda 虚拟机---容器--------------serverless无服务器架构 什么是AWS Lambda&#xff1f; AWS lambda的核心是事件驱动&#xff0c;驱动可能来自&#xff0c;Alexa,SNS&#xff0c;DynamoDB&#xff0c;S3&#xff0c;Kinesis等&…

什么是队列?Python中如何使用队列(62)

小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 和猫妹学Python&#xff0c;一起趣味学编程。 今日主题 什么是队列&#xff1f; 队列有哪些接口(api)&#xff1f; 在Python中如何表示队列&#xff1f; 什么是队列 队…

HDFS的工作原理是怎么样的?是如何实现HA模式?

原文链接&#xff1a;http://www.ibearzmblog.com/#/technology/info?id714dcb3957e29185493239b269a9ef65 前言 HDFS是能够提供一个分布式文件存储的系统&#xff0c;在大型数据文件的存储中&#xff0c;能够提供高吞吐量的数据访问&#xff0c;那么它是如何实现数据文件的…

电机调速执行

一、建立思维导图&#xff0c;将功能分析近而转换成技术要点&#xff0c;逐步实现。 二、编码器 1、机械编码器 &#xff08;1&#xff09;机械编码器是什么&#xff0c;张啥样&#xff1f; 如下图&#xff0c;这个就是我们生活应用中常见的机械编码器&#xff0c;我们又叫旋…

【C++】模板初阶——函数模板和类模板

&#x1f680; 作者简介&#xff1a;一名在后端领域学习&#xff0c;并渴望能够学有所成的追梦人。 &#x1f681; 个人主页&#xff1a;不 良 &#x1f525; 系列专栏&#xff1a;&#x1f6f8;C &#x1f6f9;Linux &#x1f4d5; 学习格言&#xff1a;博观而约取&#xff0…

鲍威尔一句话,BTC冲破30000!币圈涨跌不再依赖美联储降息?

仅仅一夜&#xff0c;全球最大的加密货币比特币价格突破30000美元关键阻力位&#xff0c;最高突破至30800美元&#xff0c;创2023年4月以来的最高价。而美联储主席鲍威尔的证词&#xff0c;竟是这波行情的最大催化剂。 鲍威尔周三出席众议院金融服务委员会接受质询&#xff0c;…

为什么独立站做不好?80%的人都走过这5个弯路

最近接触了不少卖家&#xff0c;发现不少独立站因为犯下一些常见的错误&#xff0c;导致最终失败&#xff0c;但是这些都是完全可以避免的。 那些新手卖家常见的问题就是许多人对独立站运营没有基本概念&#xff0c;同时并没有把脑袋中的零散的技巧串起来。要知道独立站运营是…

青大数据结构【2018】【单选、简答】

关键字: 计算机数据结构、存储方式、递归设计、矩阵压缩存储、二叉树形态、哈希冲突、希尔排序 一、单选 二、简答 对于线性表的存储,当采用顺序存储时,插入和删除元素平均需要移动半个表长,而链式存储结构只需要修改相应的指针就可以了。 递归设计要注意递归函数式的内…

【Java系列】深入解析Stream API

序言 你只管努力&#xff0c;其他交给时间&#xff0c;时间会证明一切。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记论点蓝色&#xff1a;用来标记论点 希望这篇文章能让你不仅有一定的收获&#xff0c;而且…

看完这篇 教你玩转渗透测试靶机vulnhub—Emplre: Lupinone

Vulnhub靶机Emplre: Lupinone渗透测试详解 Vulnhub靶机介绍&#xff1a;Vulnhub靶机下载&#xff1a;Vulnhub靶机安装&#xff1a;Vulnhub靶机漏洞详解&#xff1a;①&#xff1a;信息收集&#xff1a;②&#xff1a;SSH私钥爆破登入&#xff1a;③&#xff1a;pip提权&#xf…

[晕事]今天做了件晕事14,查单词charp

从内核模块的代码里看到一个单词charp&#xff0c;去尝试查单词&#xff0c;发现了一个 Charp impact value 【机】 夏比冲击值 这个直接是音译&#xff0c;肯定不是想要的&#xff0c; 后来使用bing搜索引擎&#xff0c;里面有一个链接&#xff1a; 这个网页真是很有迷惑性&am…

GEE:实现 Lee 杂波滤波器(Lee speckle filter)降低或去除SAR图像中的杂波(speckle noise)

作者:CSDN @ _养乐多_ 这段代码实现了一种叫做Refined Lee滤波器的雷达图像处理算法。Lee speckle filter(Lee杂波滤波器)是一种常用的合成孔径雷达(SAR)图像处理算法,用于降低或去除SAR图像中的杂波(speckle noise)。SAR图像中的杂波是由于SAR工作原理导致的干涉和散…

图形编辑器开发:缩放至适应画布

大家好&#xff0c;我是前端西瓜哥。 之前我们实现了画布缩放的功能&#xff0c;本文来讲讲如何让内容缩放至适应画布大小&#xff08;Zoom to fit&#xff09;。 我们看看效果。 文中的动图演示来自我正在开发的图形设计工具&#xff1a; https://github.com/F-star/suika 线…

SpringBoot 统⼀功能处理

目录 SpringBoot 统一功能处理概念 统一用户登录权限验证 登录功能代码 Spring拦截器实现步骤&#xff1a; 统一项目访问前缀 第一种方法&#xff1a;重写configurePathMatch方法进行配置 第二种方法&#xff1a;在系统的配置文件.properties中进行配置 统一异常处理返回…

香橙派4 2. 驱动usb2.0芯片cy7c68013

0. 环境 - 香橙派4&#xff08;Orangepi4_2.1.2_ubuntu_bionic_desktop_linux4.4.179.img&#xff09; - EZ-USB FX2LP CY7C68013A USB 核心板 1. 下载FX3_SDK_1.3.4_linux EZ-USB™ FX3 Software Development Kit https://www.infineon.com/cms/en/design-support/tools/sdk…

Autosar模式管理实战系列08-BswM与EcuM模块交互详解

本文框架 前言EcuM及BswM交互EcuM及BswM交互总览启动时BswM与EcuM的状态管理交接下电时BswM与EcuM的状态管理交接前言 在Autosar模式管理系列介绍01-BswM文章中,我们对BswM基本内容进行了介绍,我们知道了BswM是根据既定的仲裁规则对来自应用层SWCs或其他底层BSW模块,同时也…

InnoDB 和 MyISAM 的区别

1、InnoDB支持事务&#xff0c;MyISAM不支持&#xff1b; 2、InnoDB支持外键&#xff0c;MyISAM不支持&#xff1b; 3、InnoDB是簇索引&#xff0c;MyISAM是非簇索引&#xff1b; 4、Innodb不支持fulltext全文索引&#xff0c;MyISAM支持&#xff1b; 5、InnoDB支持到行级锁&am…

JavaSE基础语法--数组的拷贝

数组的拷贝方法有好几种&#xff0c;第一种是简单的for循环。通过遍历原数组来给新数组赋值完成数组的拷贝代码如下&#xff1a; import java.util.Arrays;public class TestDemo {public static void main(String[] args) {int[] arr1{1,2,3,4,5,6};int[] arr2new int[arr1.l…