作者: 丁伟瀚
本文转载自知悉,经作者授权转载。
相关链接: https://zhuanlan.zhihu.com/p/344324470
2020年B站的年度弹劾幕是"敖青回来"。一定有很多时刻,让你感觉到"先生的青春又回来了"。在一个卷积网络是各种超吸附精确到小数后位的时代,你还记得五六年前的田园日子吗,当时堆叠几个卷积层会提出这一点?
我们最近的工作RepVGG实现了VGG风格的单向极简主义架构,具有结构重新参数化,一直滚动到最后,在速度和性能方面达到SOTA水平,在ImageNet上的准确率超过80%。
没有NAS,没有关注,没有新颖的激活功能,甚至没有分支结构,只有3x3卷积和ReLU,你能实现SOTA性能吗?
开源预训练模型和代码(PyTorch版本)已经发布了两天,并且已经下载了数百次,根据实际业务中的同行反馈。
< h1级"pgc-h-center-line">太长而无法读取</h1>版本
方法有多简单?在5 p.m.阅读完文章后,您可以在晚餐前完成编写代码并开始训练,第二天您将看到结果。如果您没有时间完成本文,只需点击下面的代码并阅读前100行即可正确完成。
下面我们来仔细看看。
<h1类"pgc-h-center-line"的>模型定义。</h1>
我们所说的"VGG"的意思是:
1.没有分支结构。这通常被称为铂金或前馈架构。
2. 仅使用 3x3 卷积。
3. 仅使用 ReLU 作为激活函数。
以下是对 RepVGG 模型基本架构的一句话介绍:将 20 层 3x3 卷积堆叠成 5 个阶段,每个阶段的第一层是 stride-2 的分步示例,每个卷积层以 ReLU 作为激活函数。
在一句话中,用一句话描述了RepVGG模型的详细结构:RepVGG-A的五个阶段是RepVGG-B的五个阶段宽度的几倍,RepVGG-B的五个阶段是1,2,4,14,1,1和RepVGG-B的五个阶段的宽度的几倍。这里的倍数是随机指定的"工作"数量,例如1.5,2.5,而无需微调。
对训练设置还有一句话:ImageNet上的120个epoch,没有技巧,甚至直接使用官方PyTorch示例的训练代码!
为什么要设计这种极简主义的模型,这么简单的手动设计模型如何在ImageNet上达到SOTA级别?
<为什么VGG模型应该>h1类"pgc-h-center-line"中使用</h1>
除了我们相信简单就是美之外,VGG极简主义模型至少具有五个实际优势(见论文)。
1.3x3卷积非常快。在 GPU 上,3x3 卷积的计算密度(理论计算除以所花费的时间)可能是 1x1 和 5x5 卷积的四倍。
2.由于并行度高,单向架构非常快。同样数量的计算,"大而全"的计算效率远远超过"小而破"的操作。
3. 单向架构节省内存。例如,ResNet 的快捷方式将其内存占用量加倍,尽管它不考虑计算。
4.单向架构灵活性较好,易于改变每层宽度(如修剪)。
5. RepVGG 主体只有一个运算符:3x3 卷积 ReLU。在设计专用芯片时,考虑到芯片的尺寸或成本,我们可以集成大量3x3卷积ReLU单元以实现高效率。不要忘记,单个架构的内存节省功能也可以帮助我们减少存储单元。
<h1级"pgc-h-center-line"的>被大量参数化,以使VGG再次伟大</h1>
VGG模型近年来很少受到关注,主要是由于与各种多分支架构(如ResNet,Inception,DenseNet和各种NAS架构)相比,性能较差。
例如,对ResNet良好性能的一种解释是,ResNet的分支结构(快捷方式)产生了一个具有大量子模型的隐式融合(因为每次遇到分支时总路径都会加倍),这是单向架构显然不具备的功能。
由于多分支架构有利于训练,而我们要部署的模型是单向架构,因此提出一种解耦训练与推理架构。我们通常以相同的方式使用模型:
1. 训练模型
2. 部署此模型
但在这里,我们提出了一种新的方法:
1. 训练多分支模型
2. 将等效于单个模型的多分支模型转换为
3. 部署单向模型
这使您可以利用多分支模型训练(高性能)和单向模型推理(快速、节省内存)的优势。这里的关键显然是构建的形式和多分支模型的转换方式。
我们的实现是在训练期间将并行 1x1 体积积分和常量映射分支添加到每个 3x3 卷积层,以形成 RepVGG 块。此设计基于 ResNet 的方法,不同之处在于 ResNet 每两层或三层添加一次,而我们每层添加一次。
训练完成后,我们对模型进行等效的转换以获取部署模型。这种转换也非常简单,因为1x1卷积是3x3卷积的特殊(卷积核心中有许多0),而常数映射是1x1卷积的特殊(单位矩阵作为卷积核心)!根据卷积的线性度(特别是可加性),每个 RepVGG 块的三个分支可以组合成一个 3x3 卷积。
下图描述了转换过程。在此示例中,输入和输出通道均为 2,因此 3x3 卷积的参数为 4 个 3x3 矩阵,而 1x1 卷积的参数为 2x2 矩阵。请注意,所有三个分支都有一个 BN(批量归一化)层,其参数包括累积的均值和标准差以及学习的比例因子和偏差。
这并不妨碍转换的可行性,因为推理时的卷积层和随后的BN层可以等价地转换为具有偏差的卷积层(通常称为"吸吮BN")。
在三个分支中的每一个"吸吮BN"之后(请注意,常量映射可以看作是一个参数为2x2单位矩阵的"卷积层"!),将获得 1x1 卷积核心,其中 0 填充到 3x3 中。最后,三个分支获得的卷积核心和偏差相加。
通过这种方式,每个 RepVGG 块转换前后的输出完全相同,因此训练的模型可以等效地转换为只有 3x3 卷积的单个模型。
从这个转换过程中,我们看到了"结构再参数化"的本质:训练的结构对应一组参数,我们在推理中想要的结构对应另一组参数,只要前者参数可以等价于后者,前者的结构就可以转换为后者。
实验结果<>h1级"pgc-h-中心线"。</h1>
在1080Ti上进行测试,RepVGG型号的速度精度非常出色。通过公平的训练设置,具有相同精度的 repVGG 速度为 ResNet-50 的 183%、ResNet-101 的 201%、EfficientNet 的 259% 和 RegNet 的 131%。
请注意,RepVGG 比 EvericientNet 和 RegNet 实现了更高的性能,而无需使用任何 NAS 或繁重的手动迭代设计。
这也表明,测量不同架构中 FLOP 的真实速度是不合适的。例如,RepVGG-B2的FLOP比EfficiftNet-B3快10倍,但1080Ti的速度是后者的两倍,这表明前者的计算密度是后者的20倍以上。
在Cityscapes上的语义分割实验表明,在更快的条件下,RepVGG模型比ResNet系列快约1%至1.7%,或者在mIoU高出0.37%时快62%。
另一系列烧蚀研究和对比实验表明,结构再参数化是RepVGG模型优异性能的关键(见论文)。
最后,需要注意的是,RepVGG是专为GPU和专用硬件设计的高效模型,追求高速、省内存、少关注参数数量和理论计算。在低计算设备上,它可能不如MobileNet和ShuffleNet系列合适。
论文地址:
https://arxiv.org/abs/2101.03697
开源预训练模型和代码(PyTorch 版本):
https://github.com/DingXiaoH/RepVGG
(MegEngine版本):
https://github.com/megvii-model/RepVGG
引用:
[1] 安德烈亚斯·法伊特、迈克尔·J·威尔伯和塞尔日·贝里蒂。残差网络的行为类似于相对浅层网络的集合。在神经信息处理系统的进步中,第550-558页,2016年。2, 4, 8