【神经网络架构】RepVGG: Making VGG-style ConvNets Great Again
原始题目 | RepVGG: Making VGG-style ConvNets Great Again |
---|---|
中文名称 | RepVGG: 让 VGG-风格的卷积网络们 再次伟大 |
发表时间 | 2021年1月11日 |
平台 | CVPR-2021 |
来源 | MEGVII(旷世) |
文章链接 | https://arxiv.org/pdf/2101.03697v3.pdf |
开源代码 | https://github.com/megvii-model/RepVGG |
这名字 Trump 直呼内行。
摘要
我们提出了一种简单但功能强大的卷积神经网络结构,在推理时间它具有一个类似VGG的结构,除了3 × 3 卷积和ReLU的堆叠,不包含任何东西。在训练时间,模型有多分支拓扑(multi-branch topology)。
通过结构重参数化技术实现了训练时间和推理时间架构的解耦,从而将模型命名为RepVGG。在ImageNet上,RepVGG达到80%以上的top-1精度,据我们所知,这是一个普通(plain)模型第一次达到这种精度。在NVIDIA 1080Ti GPU上,RepVGG模型的运行速度比ResNet-50快83%,比ResNet-101快101%,精度更高,与最先进的模型(如EfficientNet和RegNet)相比,显示了良好的 accuracy-speed 权衡。
5. 结论
我们提出了一种简单的 3 × 3 conv和ReLU 堆叠的RepVGG架构,特别适用于GPU和专门的推理芯片。使用我们的结构重参数化(re-parameterization)方法,它在ImageNet上达到了80%以上的top-1精度,与最先进的模型相比,显示了良好的 speed-accuracy权衡。
1. 引言
一个经典的卷积神经网络(ConvNet),VGG[31]在图像识别方面取得了巨大的成功,其简单的架构由一堆conv、ReLU和 pooling 组成。随着Inception [33, 34, 32, 19], ResNet[12]和DenseNet[17]的出现,很多研究的兴趣转移到精心设计的架构上,使得模型越来越复杂。最近的一些架构是基于自动[44,29,23]或手动[28]架构搜索,或者搜索复合(compound)缩放策略[35]。
虽然许多复杂的ConvNets提供了比简单的网络更高的精度,缺点是显著的。
-
复杂的多分支设计(如ResNet中的残差相加( residual-addition)和Inception中的分支拼接(branch-concatenation)使得模型难以实现和定制,降低了推理速度和内存利用率。
-
一些组件(例如,Xception[3]和MobileNets[16,30]中的 depthwise conv 和ShuffleNets[24, 41]中的 channel shuffle)增加了内存访问成本,并且缺乏各种设备的支持。
由于影响推断速度的因素太多,浮点运算的数量(floating-point operations (FLOPs))不能准确地反映实际速度。虽然一些新型的模型比老式的像VGG和ResNet-18/34/50[12]有更低的FLOPs,但它们可能不会跑得更快(表4)。因此,VGG和ResNets的原始版本仍然大量用于学术界和工业界的实际应用。
在本文中,我们提出了RepVGG,这是一种 VGG 风格的架构,它优于许多复杂的模型(图 1)。RepVGG具有以下优点:
- 该模型具有类似 VGG 的普通(也称为 前馈)拓扑1,没有任何分支,这意味着每一层都将其唯一前一层的输出作为输入,并将输出馈送到其唯一的下一层。
- 该模型的主体仅使用 3 × 3 conv 和 ReLU。
- 具体架构(包括特定的深度和层的宽度)是在没有自动搜索 [44]、手动细化 [28]、复合缩放 [35] 或其他繁重设计的情况下实例化的。
1在本文中,一个网络拓扑只关注组件如何连接到其他组件,一个架构是指拓扑以及组件的明细(specification),比如深度和宽度,一个结构可以指架构的任何组件或部分。
对于一个普通(plain)模型来说,要达到与多分支架构相当的性能水平是很有挑战性的。一种解释是,一个多分支拓扑,如ResNet,使模型成为众多浅层模型[36]的隐式集合,从而训练多分支模型避免了梯度消失问题。
因为多分支架构的好处都是用于训练的,而缺点是不希望用于推理的,我们提出通过结构化 re-parameterization来解耦训练时的多分支和推理时的plain 架构,这意味着通过转换其参数将一个架构转换为另一个架构。具体来说,一个网络结构是与一组参数相耦合的,例如,用一个四阶核张量(a 4th-order kernel tensor)表示 一个 conv层。如果可以将某一结构的参数转换为另一组由另一结构耦合而成的参数,则可以将前者等价地替换为后者,从而改变整个网络架构。
具体来说,我们使用 identity 和 1×1 分支构造了训练时的 RepVGG,这是受 ResNet 的启发,但采用了不同的,可以通过 structural re-parameterization 来删除分支(图 2,4)。在训练后,我们用简单的代数(algebra)进行变换,因为一个 identity 分支可以看作是退化的 1×1 卷积,而后者可以进一步被看作是退化的 3×3 卷积,因此我们可以使用 原始 3 × 3 核,identity 和 1 × 1 分支 和 batch normalization (BN) [19] 层 的训练参数构建单个 3 × 3 核。因此,转换后的模型有一个 3 × 3 的卷积层堆叠,用于测试和部署。
值得注意的是,推理时间 RepVGG 的主体只有一种类型的算子:3 × 3 conv 后跟 ReLU,这使得 RepVGG 在 GPU 等通用计算设备上运行速度更快。 更好的是,RepVGG 允许专用硬件实现更高的速度,因为考虑到芯片尺寸和功耗,我们需要的运算符类型越少,我们可以集合到芯片上的计算单元就越多。 因此,专门用于 RepVGG 的推理芯片可以具有大量的 3×3-ReLU 单元和更少的内存单元(因为普通(plain)拓扑结构是内存经济的( memory-economical),如 图 3 所示)。 我们的贡献总结如下:
- 我们提出了 RepVGG,这是一种简单的架构,与最先进的技术相比,具有良好的 speed-accuracy 权衡。
- 我们提出了使用 structural re-parameterization 将训练时多分支拓扑与推理时的普通架构解耦。
- 我们展示了RepVGG 在图像分类和语义分割中的有效性,以及实现的效率和易用性。
2. 相关工作
2.1 从Single-path 到 Multi-branch
在 VGG [31] 将 ImageNet 分类的 top-1 准确率提高到 70% 以上之后,有许多创新使 ConvNets 变得复杂以获得高性能,例如现代的 GoogLeNet [33] 和后来的 Inception 模型 [34, 32, 19 ]采用精心设计的多分支架构,ResNet [12]提出了一种简化的双分支架构,而DenseNet [17]通过将低层与众多高层连接起来使拓扑结构更加复杂。 神经架构搜索 (NAS) [44, 29, 23, 35] 和手动设计的空间设计(manual designing
space design) [28] 可以生成性能更高的卷积网络,但代价是大量计算资源或人力。 一些大版本的 NAS 生成模型甚至无法在普通 GPU 上训练,因此限制了应用。 除了实施不便外,复杂的模型可能会降低并行度[24],从而减慢推理速度。
2.2. Single-path 模型的有效训练
已经有一些尝试在没有分支的情况下训练 ConvNet。 然而,先前的工作主要是试图使非常深的模型以合理的accuracy 收敛,但没有比复杂模型获得更好的性能。 因此,这些方法和得到的模型既不简单也不实用。 提出了一种初始化方法 [37] 来训练极深的plain ConvNet。 使用基于平均场理论的方案,10,000 层网络在 MNIST 上的训练准确率超过 99%,在 CIFAR-10 上的准确率超过 82%。 尽管这些模型并不实用(即使 LeNet-5 [21] 在 MNIST 上的准确率可以达到 99.3%,而 VGG-16 在 CIFAR10 上的准确率也可以达到 93% 以上),但其理论贡献是有见地的。 最近的一项工作 [25] 结合了几种技术,包括 Leaky ReLU、最大范数和仔细初始化。 在 ImageNet 上,它表明具有 147M 参数的plain ConvNet 可以达到 74.6% 的 top-1 准确率,比其报告的基线(ResNet-101, 76.6%, 45M 参数)低 2%。
值得注意的是,这篇论文不仅仅是一个简单的模型可以很好地收敛的证明,并不打算训练像 ResNets 这样非常深的 ConvNets。 相反,我们的目标是建立一个具有合理深度和合适的 accuracy-speed 权衡的简单模型,可以使用最常见的组件(例如,常规 conv 和 BN)和简单的代数来简单地实现。
2.3. Model Re-parameterization
DiracNet [39] 是一种与我们相关的 Re-parameterization 方法。它通过将卷积层的内核编码为 \(\hat{W} = diag(a)I + diag(b)W_{norm}\) 来构建深层 plain 模型,其中 \(\hat{W}\) 是用于卷积的最终权重(被视为矩阵的 4 阶张量),a 和b 是学习向量,\(W_{norm}\) 是 normalized 的可学习核。与具有相当数量参数的 ResNet 相比,DiracNet 的 top-1 准确率在 CIFAR100 上低 2.29%(78.46% vs. 80.75%),在 ImageNet 上低 0.62%(DiracNet-34 的 72.21% vs. ResNet-34的 72.83%)。 DiracNet 在两个方面与我们的方法不同:
1) RepVGG 的训练时候的行为是由实际数据流通过具体结构实现的,该结构稍后可以转换为另一种结构,而 DiracNet 只是使用了 conv kernels 的另一种数学表达式,以便于优化。换句话说,训练时的 RepVGG 是真正的多分支模型,但 DiracNet 不是。
2) DiracNet 的性能高于 normally 参数化的 plain 模型,但低于可比较的 ResNet,而 RepVGG 模型的性能大大优于 ResNet。 Asym Conv Block (ACB) [10]、DO-Conv [1] 和 ExpandNet [11] 在将 block 转换为 conv 的意义上也可以被视为 structural reparameterization。与我们的方法相比,不同之处在于它们是为组件级改进而设计的,并用作任何架构中卷积层的直接替代品,而我们的structural reparameterization 对于训练plain 卷积网络至关重要,如Sect.4.2.
2.4. Winograd 卷积
RepVGG 仅使用 3 × 3 卷积,因为它在 GPU 和 CPU 上被一些现代计算库(如 NVIDIA cuDNN [2] 和 Intel MKL [18])高度优化。表1 显示了在 1080Ti GPU 上使用 cuDNN 7.5.0 测试的理论 FLOP、实际运行时间和计算密度 (measured in Tera FLoating-point Operations Per Second, TFLOPS)2。 3×3 conv 的理论计算密度大约是其他的 4 倍,这表明表明总的理论 FLOPs 不能代表不同架构之间的实际速度。 Winograd [20] 是加速 3 × 3 卷积的经典算法(仅当步幅为 1 时),已被 cuDNN 和 MKL 等库很好地支持(并默认启用)。例如,使用标准 F(2 × 2, 3 × 3) Winograd,3×3 conv 的乘法量(MULs)减少到原始的\(\frac{4}{9}\)。由于乘法比加法更耗时,我们计算 MULs 以测量带有 Winograd 支持的计算成本(在表 4、5 中由 Wino MULs 表示)。请注意,具体的计算库和硬件 决定是否对每个算子使用 Winograd,因为小规模卷积可能由于内存开销而无法加速3。
表1 使用不同的内核大小进行速度测试,在 NVIDIA 1080Ti 上,batch size = 32、input channels = output channels = 2048, resolution = 56×56, stride = 1。 时间使用结果是硬件 warming up 后运行 10 次的平均值。
Kernel size |
Theoretical FLOPs (B) |
Time usage (ms) |
Theoretical TFLOPS |
---|---|---|---|
1 × 1 | 420.9 | 84.5 | 9.96 |
3 × 3 | 3788.1 | 198.8 | 38.10 |
5 × 5 | 10522.6 | 2092.5 | 10.57 |
7 × 7 | 20624.4 | 4394.3 | 9.38 |
2 作为一种常见的做法,我们在计算理论 FLOPs 时将乘加算作一次操作,但像 NVIDIA 这样的硬件供应商通常在报告 TFLOPS 时将其算作两次操作。
3 我们的结果是使用 cuDNN 7.5.0、1080Ti 逐个操作手动测试的。 对于每个 stride-1 3 × 3 conv,我们将其时间使用情况与相同 FLOPs 的 stride-2 对应一起测试。 如果后者运行速度明显较慢,我们假设前者使用 F(2 × 2, 3 × 3) Winograd。 这种测试方法是近似的,因此结果仅供参考。
3. 通过 Structural Re-param 构建 RepVGG
3.1. Simple is Fast, Memory-economical, Flexible
使用简单的 ConvNets 至少有三个原因:它们快速、节省内存和灵活。
Fast 许多最近的多分支架构具有比 VGG 更低的理论 FLOPs,但可能不会运行得更快。例如,VGG-16 的 FLOPs 是 EfficientNet-B3 [35] 的 8.4 倍,但在 1080Ti 上运行速度快 1.8 倍(表 4),这意味着前者的计算密度是后者的 15 倍。除了 Winograd conv 带来的加速之外,FLOPs 和速度之间的差异可以归因于对速度有相当大影响但 FLOPs 没有考虑到的两个重要因素:内存访问成本(MAC)和并行度 [24 ]。例如,尽管所需的分支 addition 或 concatenation计算可以忽略不计,但 MAC 很重要。此外,MAC 在分组卷积中占时间使用的很大一部分。另一方面,在相同的 FLOP 下,具有高度并行性的模型可能比另一个并行度低的模型快得多。由于多分支拓扑在 Inception 和自动生成的架构中被广泛采用,因此使用多个小型算子而不是几个大型算子。之前的工作 [24] 报告说,NASNET-A [43] 中的碎片化算子数量(即一个构建block中的单个 conv 或pooling操作的数量)为 13,这对 GPU 等具有强大并行计算能力的设备不友好并引入了额外的开销,例如内核启动和同步。相比之下,这个数字在 ResNets 中是 2 或 3,我们将其设为 1:单个 conv。
Memory-economical 多分支拓扑的内存效率低,因为每个分支的结果都需要保存直到addition or concatenation,显着提高了内存占用的峰值。 图 3 显示对于一个残差block的输入需要保存直到addition。 假设 block 保持feature map size,额外内存占用的峰值为输入的2倍。 相反,plain 拓扑允许在操作完成时立即释放特定层的输入所占用的内存。 在设计专用硬件时,一个plain的 ConvNet 允许深度内存优化并降低内存单元的成本,以便我们可以将更多的计算单元集合到芯片上。
Flexible 多分支拓扑对架构规范施加了约束。 例如,ResNet 要求将卷积层组织为残差块,这限制了灵活性,因为每个残差块的最后一个卷积层必须产生相同形状的张量,否则shortcut addition 将没有意义。 更糟糕的是,多分支拓扑限制了channel pruning 的应用[22, 14],这是一种去除一些不重要channel的实用技术,并且一些方法可以通过自动发现每层的适当宽度来优化模型架构[8] . 然而,多分支模型使pruning变得棘手,并导致显着的性能下降或低加速比 [7, 22, 9]。 相比之下,简单的架构允许我们根据我们的要求自由配置每个 conv 层并进行prune以获得更好的性能-效率( performance-efficiency)权衡。
3.2. Training-time Multi-branch Architecture
Plain ConvNets 有很多优点,但有一个致命的弱点:性能不佳。例如,使用像 BN [19] 这样的现代组件,VGG-16 在 ImageNet 上可以达到 72% 以上的 top-1 accuracy,这似乎已经过时了。我们的structural re-parameterization 方法受到 ResNet 的启发,它显式地构造了一个 shortcut 分支来将信息流建模为 y = x + f(x),并使用残差块来学习 f。当 x 和 f(x) 的维度不匹配时,就变成了y = g(x)+f(x),其中g(x)是一个1×1 conv实现的卷积shortcut。 ResNets 成功的一个解释是,这种多分支架构使模型成为许多较浅模型的隐式集合 [36]。 具体来说,对于 n 个块,该模型可以解释为 \(2^{n}\) 个模型的集合,因为每个块将流分支成两条路径。
由于多分支拓扑在推理方面存在缺陷,但分支似乎有利于训练 [36],因此我们使用多个分支来制作多个模型的仅训练时间集合。为了使大多数成员更浅或更简单,我们使用类似 ResNet 的identity(仅当维度匹配时)和 1 × 1 分支,以便构建块的训练时间信息流为 y = x + g(x) + f(x)。 我们简单地堆叠几个这样的块来构建训练时间模型。 从与 [36] 相同的角度来看,该模型变成了 \(3^{n}\) 个成员和 n 个这样的块的集合。
3.3. Re-param for Plain Inference-time Model
在本小节中,我们将描述如何将经过训练的 block 转换为单个 3 × 3 卷积层以进行推理。 请注意,我们在 addition 之前的每个分支中都使用了 BN(图 4)。 形式上,我们使用 \(W^{(3)} \in R^{ C_{2} \times C_{1} \times 3 \times 3 }\) 表示具有 \(C_{1}\) 个输入通道和 \(C_{2}\) 个输出通道的 3×3 卷积层的内核,并且 \(W^{(1)} \in R^{ C_{2} \times C_{1} }\) 表示 1×1分支的内核。 我们使用 \(\mu ^{(3)},\sigma ^{(3)} ,\gamma ^{(3)} , \beta^{(3)}\) 作为在 3 × 3 conv后的 BN 层的 the accumulated
mean, standard deviation and learned scaling factor and bias。\(\mu ^{(1)},\sigma ^{(1)} ,\gamma ^{(1)} , \beta^{(1)}\) 在 1 × 1 conv 后,\(\mu ^{(0)},\sigma ^{(0)} ,\gamma ^{(0)} , \beta^{(0)}\)在恒等(identity)分支后。令 \(M^{(1)} \in R^{ N \times C_{1} \times H_{1} \times W_{1} }\) , \(M^{(2)} \in R^{ N \times C_{2} \times H_{2} \times W_{2} }\) 分别是输入和输出。 ∗ 为卷积算子。如果 \(C_{1} = C_{2},H_{1} = H_{2},W_{1} = W_{2}\),我们有:
否则,我们只是不使用 identity 分支,因此上述等式只有前两项。 这里 bn 是推理时候 BN 函数,形式上,\(∀_{1} ≤ i ≤ C_{2}\),
我们首先将每个 BN 及其前面的 conv 层转换为带有偏置向量的 conv。 令 \(\{{W}', {b}' \}\) 为从 \(\{W, \mu ,\sigma ,\gamma ,\beta\}\) 转换而来的内核和bias,我们有
那么很容易验证 \(∀_{1} ≤ i ≤ C_{2}\),
这种转换也适用于恒等分支,因为恒等可以被视为以恒等矩阵为内核的 1 × 1 卷积。 经过这样的变换,我们将得到一个 3 × 3 的内核、两个 1 × 1 的内核和三个bias vectors。 然后我们通过将三个bias vectors相加得到最终的bias,并通过将 1×1 内核添加到 3×3 内核的中心点来获得最终的 3×3 内核,这可以通过首先对两个1 × 1 内核进行零填充到 3 × 3,并将三个内核相加,如图 4 所示。请注意,这种变换的等效性要求 3 × 3 和 1 × 1 层具有相同的 stride ,并且填充配置为 后者应比前者少一个像素。 例如,对于将输入填充一个像素的 3×3 层(这是最常见的情况),1×1 层应该有 padding = 0。
图 4:一个RepVGG block的 Structural re-parameterization。 为了便于可视化,我们假设 \(C_{2}=C_{1}=2\),因此 3×3 层有四个 3×3 矩阵,1×1 层的内核是一个 2×2 矩阵。
3.4 架构明细
表 2 显示了 RepVGG 的明细,包括深度和宽度。 RepVGG 是 VGG 风格,因为它采用简单的拓扑结构并大量使用 3×3 卷积,但它不像 VGG 那样使用最大池化,因为我们希望 body 只有一种类型的算子。 我们将 3×3 层安排为 5 个阶段,一个阶段的第一层以 stride = 2 进行下采样。对于图像分类,我们使用global average pooling,然后使用全连接层作为head。 对于其他任务,task-specific 的 heads 可以用于任何层产生的特征。
表 2:: RepVGG 的架构规范。 这里 2 × 64a 意味着 stage2 有 2 层,每层都有 64a 通道。
阶段 | 输出大小 | RepVGG-A | RepVGG-B |
---|---|---|---|
1 | 112 × 112 | 1 × min(64, 64a) | 1 × min(64, 64a) |
2 | 56 × 56 | 2 × 64a | 4 × 64a |
3 | 28 × 28 | 4 × 128a | 6 × 128a |
4 | 14 × 14 | 14 × 256a | 16 × 256a |
5 | 7 × 7 | 1 × 512b | 1 × 512b |
我们根据三个简单的准则来决定每个阶段的层数。 1)第一阶段以大分辨率运行,这很耗时,所以我们只使用一层来降低延迟。 2)最后阶段应该有更多的通道,所以我们只使用一层来保存参数。 3)我们将最多层放入倒数第二阶段(ImageNet 上的输出分辨率为 14 × 14),遵循 ResNet 及其最近的变体 [12、28、38](例如,ResNet-101 在其 14 × 14 中使用 69 层 -解决阶段)。 我们让五个阶段分别有 1、2、4、14、1 层来构造一个名为 RepVGG-A 的实例。 我们还构建了一个更深的 RepVGG-B,它在 stage 2、3 和 4 中多了 2 层。我们使用 RepVGG-A 与其他轻量级和中量级模型竞争,包括 ResNet-18/34/50,以及 RepVGG-B 与高-性能的对比。
我们通过统一缩放 [64、128、256、512] 的经典宽度设置(例如,VGG 和 ResNets)来确定层宽度。 我们使用乘数 a 来缩放前四个阶段,b 用于最后阶段,并且通常设置 b > a,因为我们希望最后一层具有更丰富的特征,用于分类或其他下游任务。 由于 RepVGG 在最后阶段只有一层,因此较大的 b 不会显着增加延迟,也不会显着增加参数量。 具体来说,stage 2,3,4,5的宽度分别为[64a,128a,256a,512b]。 为了避免在高分辨率特征图上进行大规模卷积,如果 a < 1,我们缩小 stage1 但不放大,因此 stage1 的宽度为 min(64, 64a)。
为了进一步减少参数和计算,我们可以选择将 groupwise 3 × 3 conv 层与密集(dense)层交错,以牺牲accuracy来提高效率。 具体来说,我们为 RepVGG-A 的第 3 层、第 5 层、第 7 层、...、第 21 层 和 RepVGG-B 的 additional的 第 23、25 和 27 层 设置组数 g 。为简单起见,我们将这些层的 g 全局设置为 1、2 或 4,而无需逐层调整。 我们不使用相邻的分组卷积层,因为这会禁用通道间信息交换并带来副作用 [41]:来自某个通道的输出将仅来自一小部分输入通道。 请注意,1×1 分支应具有与 3×3 conv 相同的 g。
4. 实验
我们将 RepVGG 与 ImageNet 上的基线进行比较,通过一系列消融研究和比较证明 structural re-parameterization的重要性,并验证语义分割的泛化性能 [42]。
4.1. RepVGG 用于 ImageNet Classification
我们将 RepVGG 与 ImageNet-1K [6] 上的经典和最新模型进行比较,包括 VGG-16 [31]、ResNet [12]、ResNeXt [38]、EfficientNet [35] 和 RegNet [28],其中 包含 128 万张用于训练的图像和 5 万张用于验证的图像。 我们分别使用 EfficientNet-B0/B3 和 RegNet3.2GF/12GF 作为中量级和重量级最先进模型的代表。 我们改变乘数 a 和 b 以生成一系列 RepVGG 模型以与基线进行比较(表 3)。
表 3:乘数 a 和 b 定义的 RepVGG 模型。
名字 | 每个阶段的层数 | a | b |
---|---|---|---|
RepVGG-A0 | 1, 2, 4, 14, 1 | 0.75 | 2.5 |
RepVGG-A1 | 1, 2, 4, 14, 1 | 1 | 2.5 |
RepVGG-A2 | 1, 2, 4, 14, 1 | 1.5 | 2.75 |
RepVGG-B0 | 1, 4, 6, 16, 1 | 1 | 2.5 |
RepVGG-B1 | 1, 4, 6, 16, 1 | 2 | 4 |
RepVGG-B2 | 1, 4, 6, 16, 1 | 2.5 | 5 |
RepVGG-B3 | 1, 4, 6, 16, 1 | 3 | 5 |
我们首先将 RepVGG 与 ResNets [12] 进行比较,这是最常见的基准。 我们分别使用 RepVGG-A0/A1/A2 与 ResNet-18/34/50 进行比较。 为了与更大的模型进行比较,我们构建了更深的 RepVGG-B0/B1/B2/B3,宽度增加。 对于那些具有交错分组层的 RepVGG 模型,我们将 g2/g4 后缀到模型名称。
为了训练轻量级和中量级模型,我们仅使用简单的数据增强管道,包括随机裁剪和左右翻转,遵循官方 PyTorch 示例 [27]。我们在 8 个 GPU 上使用 256 的全局 batch size,初始化为 0.1 的学习率和 120 个 epoch 的余弦退火,标准 SGD,动量系数为 0.9,卷积核和全连接层的权重衰减为 \(10^{-4}\)。对于包括 RegNetX-12GF、EfficientNet-B3 和 RepVGG-B3 在内的重量级模型,我们使用 5-epoch warmup、200 epoch 的余弦学习率退火、标签平滑 [34] 和 mixup [40](如 [13]),以及Autoaugment [5] 的数据增强管道,随机裁剪和翻转。 RepVGG-B2 及其 g2/g4 变体在这两种设置中都进行了训练。我们在 1080Ti GPU4 上测试每个batch size 为 128 的模型的速度,首先输入 50 个batches以预热硬件,然后记录 50 个 batches 时间使用情况。为了公平比较,我们在同一个 GPU 上测试了所有模型,并且基线的所有 conv-BN 序列也被转换为带有 bias 的 conv(方程 3)。
4 我们使用这样的 a batch size 是因为它足够大,可以实现每个测试模型的 100% GPU 利用率,以模拟追求最大 QPS(每秒查询数)的实际应用场景,对于 batch size 为 256 的 EfficientNet-B3,我们的 GPU 内存不足。
表4 显示了 RepVGG 有利的 accuracy-speed 折衷:RepVGG-A0 在accuracy 和速度方面分别比 ResNet-18 好 1.25% 和 33%,RepVGGA1 比 ResNet-34 好 0.29%/64%,RepVGG-A2 比 ResNet-50 好 0.17%/83%。 使用交错分组层 (g2/g4),RepVGG 模型得到进一步加速,accuracy 下降合理:RepVGG-B1g4 比 ResNet-101 好 0.37%/101%, 相同的在 accuracy 下,RepVGGB1g2 比 ResNet-152 快 2.66 倍。 尽管参数的数量不是我们主要关心的问题,但上述所有 RepVGG 模型都比 ResNets 的参数效率更高。 与经典的 VGG-16 相比,RepVGG-B2 的参数只有 58%,运行速度提高了 10%,accuracy 提高了 6.57%。 据我们所知,这个最高 accuracy (74.5%)的VGG 与 使用 RePr [26](一种基于剪枝的训练方法)相比,RepVGG-B2 的 accuracy 高出 4.28%。
表 4:在 ImageNet 上经过 120 个 epoch 的简单数据增强训练的结果。 速度在 1080Ti 上测试,批量大小为 128,全精度 (fp32),以 examples/second 为单位进行测量。 我们计算理论上的 FLOPs 和 Wino MULs,如 Sect 2.4.中所述。 基线是我们具有相同训练设置的实现。
与 state-of-the-art 基线相比,RepVGG 也表现出良好的性能,考虑到它的简单性:RepVGG-A2 比 EfficientNetB0 好 1.37%/59%,RepVGG-B1 比 RegNetX3.2GF 好 0.39%,运行速度稍快 . 值得注意的是,RepVGG 模型在 200 个 epoch 时达到了 80% 以上的准确率(表 5),据我们所知,这是plain模型第一次赶上最先进的技术。 与 RegNetX-12GF 相比,RepVGG-B3 的运行速度提高了 31%,考虑到 RepVGG 不像 RegNet [28] 那样需要大量人力来细化设计空间,并且架构超参数设置随意,这令人印象深刻。
表 5:在 ImageNet 上使用 Autoaugment[5]、标签平滑和混合训练了 200 个epochs的结果。
作为计算复杂度的两个proxies,我们计算了理论 FLOPs 和 Wino MULs,如 Sect 2.4 中所述。 例如,我们发现 EfficientNet-B0/B3 中的所有 conv 都没有被 Winograd 算法加速。 表 4 显示 Wino MUL 是 GPU 上更好的proxy,例如,ResNet-152 运行速度比 VGG-16 慢,理论 FLOPs 更低,但 Wino MULs 更高。 当然,实际速度应该始终是黄金标准。
4.2. Structural Re-parameterization is the Key
在本小节中,我们验证了 structural re-parameterization 技术的重要性(表 6)。 所有模型都使用上述相同的简单训练设置从头开始训练 120 个 epoch。 首先,我们通过从 RepVGG-B0 的每个 block 中删除identity and/or 1×1 分支来进行消融研究。 移除两个分支后,训练时模型降级为普通的 plain 模型,accuracy 仅达到 72.39%。 1×1 的accuracy 提高到 73.15%,identity 的 accuracy 提高到 74.79%。 全功能 RepVGGB0 的 accuracy 为 75.14%,比普通 plain 模型高 2.75%。 从训练时(即尚未转换)模型的推理速度来看,通过 structural re-parameterization 去除恒等和 1×1 分支带来了显着的加速。
表 6:在 RepVGG-B0 上进行 120 个 epochs 的消融研究。 使用转换前的模型(批量大小=128)测试了 w/o re-param 的推理速度(examples/s)。 再次注意,所有模型都具有相同的最终结构。
然后我们构建了一系列变体和基线,用于在 RepVGG-B0 上进行比较(表 7)。 同样,所有模型都是在 120 个 epoch 中从头开始训练的。
表 7:与经过 120 个 epochs 训练的 RepVGG-B0 上的变体和基线进行比较。
- Identity w/o BN 删除Identity分支中的 BN。
- Post-addition BN 删除三个分支中的 BN 层,并在 addition 后附加一个 BN 层。 换句话说,BN的位置从pre-addition变为post-addition。
- +ReLU in branches 将 ReLU 插入每个分支(BN 之后和addition 之前)。 由于这样的 block 不能转化为单个conv层,所以没有实际用处,我们只是想看看更多的非线性是否会带来更高的性能。
- DiracNet [39] 采用了精心设计的卷积核 re-parameterization ,如 Sect 2.2 中介绍的那样。我们使用它的官方 PyTorch 代码来构建这个层来替换原来的 3 × 3 conv。
- Trivial Re-param 是通过直接向 3 × 3 内核添加一个identity 核来对 conv 内核进行更简单的 re-parameterization ,可以将其视为 DiracNet 的降级版本(\(\hat{W} = I + W\) [39])。
- Asymmetric(非对称) Conv Block (ACB) [10] 可以被视为另一种形式的structural re-parameterization。 我们与 ACB 进行比较,看看我们的structural re-parameterization 的改进是否是由于组件级的过度参数化(即额外的参数使每 3 × 3 conv 更强)。
- Residual Reorg 通过以类似 ResNet 的方式(每个块 2 层)重新组织每个阶段来构建每个阶段。 具体来说,生成的模型在第一个和最后一个阶段有一个 3×3 层,在第 2、3、4 阶段有 2、3、8 个残差块,并使用类似于 ResNet-18/34 的shortcuts 。
我们认为structural re-param优于DiractNet和Trivial Re-param的优势在于前者依赖于通过具有非线性行为(BN)的具体结构的实际数据流,而后者仅使用conv kernels的另一种数学表达式 . 前者的“re-param”是指“使用一个结构的参数来参数化另一个结构”,而后者的意思是“先用另一组参数计算参数,然后将它们用于其他计算”。 对于像训练时间 BN 这样的非线性组件,前者不能被后者逼近。 作为证据,通过移除 BN 会降低accuracy,而通过添加 ReLU 会提高 accuracy 。 换句话说,虽然 RepVGG 块可以等效地转换为单个 conv 进行推理,但推理时间等价并不意味着训练时间等价,因为我们不能构造一个卷积层以具有与 RepVGG 块相同的训练时间行为 .
与 ACB 的比较表明 RepVGG 的成功不应简单地归因于每个组件的过度参数化的影响,因为 ACB 使用更多的参数但产生的性能较差。 作为双重检查,我们用 RepVGG 块替换 ResNet-50 的每个 3×3 卷积,并从头开始训练 120 个 epoch。 准确度为 76.34%,仅比 ResNet-50 基线高 0.03%,这表明 RepVGG-style structural re-parameterization 不是通用的过参数化技术,而是训练强大的 plain ConvNets 的关键方法。 与 Residual Reorg(具有相同数量的 3 × 3 conv 和额外的训练和推理additional shortcuts 的真实残差网络)相比,RepVGG 的性能提高了 0.58%,这并不奇怪,因为 RepVGG 具有更多的分支。 例如,分支使 RepVGG 的 stage4 成为 \(2 × 3^{15} = 2.8 × 10^7\) 个模型 [36] 的集合,而 Residual Reorg 的数量为 \(2^8 = 256\)。
4.3. 语义分割
我们验证了 ImageNet-pretrained RepVGG 在 Cityscapes [4] 上的语义分割的泛化性能(表 8)。我们使用 PSPNet [42] 框架,一个多元学习率策略,基数为 0.01,power为 0.9,权重衰减为 \(10^{-4}\),全局 batch size 为 16,在 8 个 GPU 上运行 40 个 epoch。为了公平比较,我们仅将 ResNet-50/101 主干更改为 RepVGG-B1g2/B2 并保持其他设置相同。跟随官方 PSPNet-50/101 [42] 在 ResNet-50/101 的最后两个阶段使用 dilated conv 之后,我们将 RepVGG-B1g2/B2 的最后两个阶段中的所有 3×3 卷积层进行了 dilated 。然而,目前 3 × 3 dilated conv 的低效实现(尽管 FLOPs 与 3 × 3 常规 conv 相同)减慢了推理速度。为了便于比较,我们只在最后 5 层(即 stage4 的最后 4 层和 stage5 的唯一层)构建另外两个 PSPNets(用 fast 表示),这样 PSPNets 的运行速度略快于ResNet-50/101-backbone 对应物。 RepVGG backbones 在平均 IoU 方面的性能分别比 ResNet-50 和 ResNet-101 高 1.71% 和 1.01%,速度更快,而 RepVGG-B1g2-fast 在 mIoU 方面的性能比 ResNet-101 backbones 高 0.37,运行速度快 62%。有趣的是,扩张(dilation)似乎对较大的模型更有效,因为与 RepVGG-B1g2-fast 相比,使用更多扩张的卷积层并没有提高性能,但将 RepVGG-B2 的 mIoU 提高了 1.05%,并有合理的减速。
表 8:Cityscapes [4] 上的语义分割在 validation 子集上进行了测试。 速度(examples/second)在同一个 1080Ti GPU 上以 16 的批量大小、全精度 (fp32) 和 713×713 的输入分辨率进行测试。
4.4. 限制
RepVGG 模型是快速、简单且实用的 ConvNets,专为 GPU 和专用硬件上的最大速度而设计,较少考虑参数数量。 它们比 ResNets 参数效率更高,但可能不如用于低功耗设备的 MobileNets [16, 30, 15] 和 ShuffleNets [41, 24] 等移动系统模型受到青睐。