最近阿里达摩院出了一篇文章,"TResNet: High Performance GPU-Dedicated Architecture",主要用作分类,是对基础网络Backbone的一些改进。通篇看下来,结果非常SOTA和solid,虽然不算特别惊艳,但也是一篇非常棒的工作了,被称为2020版的"bag of tricks", 而且还非常良心地给出了代码:https://github.com/mrT23/TResNet。
下面我们就来看看这篇文章到底都讲了啥。
摘要
一代经典ResNet50,被很多新近设计的深度学习模型所超越,他们往往有着更高的精度,但却更少(或相当)的FLOPS数量。但实际上是,在GPU的训练速度和推理速度上,最普通的ResNet50网络要远远超过这些网络,体现了非常好的速度-精度折中。
在这篇工作中,我们引入了一系列的架构修改,旨在不失训练和推理速度的前提下,提升网络的精度。我们首先说明了面向FLOPS优化所遇到的瓶颈,并针对此提出了可以更好利用GPU资源的替代方案,最后,我们引入了一个专门针对GPU设计的模型系列——TResNet,它在速度和精度上,都要优于之前的卷积神经网络。
TResNet表现:
(1)和ResNet差不多的速度时,可以在ImageNet数据集上达到80.8%的top-1精度;
(2)在多个单标签分类数据集上达到SOTA精度:Stanford(96.0%),CIFAR-10(99.0%), CIFAR-100(91.5%), Oxford-Flowers(99.1%);
(3)在一个多标签分类任务中取得SOTA结果;
(4)在物体检测任务上也表现出色。
2. TResNet的设计
TResNet的设计基于ResNet50架构,并进行专门的修改和优化,包含3个变种,TResNet-M、TResNet-L和TResNet-XL。不同变种之间只是模型深度和通道数不一样。相比传统ResNet50,我们从以下5个策略,对模型进行精化和改变:
- SpaceToDepth stem
- 抗锯齿降采样
- 原地激活批归一化(In-Place ABN)
- Block类型选择方法
- 优化的SE层
在这些策略中,有些会提升模型的速度,有些则会降低。总而言之,基于TResNet-M,我们使用了多种改进方案,在保证和ResNet50一样速度的基础上,公平地对比模型的精度。
表1是TResNet和ResNet的一个对比。

2.1 算法优化
SpaceToDepth Stem
神经网络通常是从一个主干单元开始的,这个单元的目的是迅速降低输入图像分辨率。例如ResNet50的主干单元由一个步长为2大小为7x7的卷积层和一个maxpooling层组成,它将输入图像的分辨率从224迅速降低到了56.
我们希望用一个快速无缝(步长为1)的层来替代传统基于卷积的降尺寸单元,同时尽可能减少信息损失,并用设计良好的残差块完成所有实际的运算工作。所以新的主干层就一个工作,降低输入图像的分辨率,也就是将输入图像分辨率降低4倍。
我们使用了一个SpaceToDepth转换层(文章在这里)实现这个目的,和原作者(只在等距(单分辨率)网络下使用SpaceToDepth)不同的是,我们直接将SpaceToDepth应用在了主干单元。在SpaceToDepth层后我们接一个简单的卷积层,生成需要的通道数。如图1所示。

抗锯齿降采样(AA)
[46]提出了一个AA组件来替代所有的降采样层,以改善深度网络的平移等距性,并提供更好的准确率和鲁棒性。我们实现了一个类似于[20]的AA的变体,该变体将步长为2的卷积替换为步长为1的卷积加上一个步长为2的3x3模糊核滤波器,如图2所示。

原地激活批归一化(Inplace-ABN)
我们使用 Inplace-ABN + Leaky-ReLU替换 BN+ReLU,有以下几个优势:
- 相比BN,Inplace-ABN极大减少GPU memory的使用,只增加了一点点计算量因此允许更大batch size;
- 相比ReLU, Leaky-ReLU提升了精度,并保持计算量不变,虽然Swish和Mish也可以提高精度,但是计算量和内存消耗都增加了;
- batch size增加以后,别的算法的计算效率也提升了,比方说triplet loss, momentum-contrastive learning.
Block类型选择
ResNet34和ResNet50有着相同的网络架构,唯一的区别是,ResNet34使用的是BasicBlock层(由2个3x3卷积层组成),而ResNet50使用的是Bottleneck层(由2个1x1卷积和1个3x3卷积组成)。两相比较,Bottleneck层使用更多的GPU资源,有更高的准确率;而BasicBlock层有更大的感受野,更适合应用在神经网络较早的stages中。


我们发现在神经网络中单一使用BasicBlock层或Bottleneck层都不是最好的选择,所以我们两个都用了——在神经网络的前两个stages使用BasicBlock层以获取更大的感受野,在神经网络的最后两个stages使用Bottleneck层,以获取更高的精度。
和ResNet50相比,我们在TResNet模型中还修改了stage 3残差块的通道数,表2中列出了TResNet网络的完整规范,包括每个阶段中Block的类型,以及残差块的宽度和个数。

优化的SE层
我们在TResNet架构中添加了专用的SE层。为了减少SE的计算成本并且取得最佳的速度-精度收益,只在网络的前3个stage使用SE。在最后一个stage中,由于特征图的分辨率已经非常低,所以相比global average pooling,使用SE并不会带来明显的精度提升。
与标准SE相比,TResNet对SE的使用位置和超参数都进行了优化:
对于Bottleneck单元,我们在3x3卷积之后使用SE模块,减少因子为8;
对于BasicBlock单元,我们在残差求和之前使用SE模块,减少因子为4。这么做的目的是减少SE层的参数个数和计算量:
由于BasicBlock单元位于网络的前两个阶段,因此它们包含的输入通道数量相对较少,因此只需要一个小的折减系数4。 Bottleneck单元放置在网络的后期,具有更多的输入通道,因此需要更高的降低系数8。 在Bottleneck层的缩小阶段之后放置SE层可以进一步降低计算成本。 带有SE层和Inplace-ABN的完整模块设计如图3所示。
图3. TResNet的BasicBlock和Bottleneck设计
2.2 代码优化
2.2.1 JIT汇编

2.2.2 原地操作
2.2.3 快速全局平均池化
2.2.4 部署优化
3. ImageNet结果
3.1 基本训练

3.2 消融实验
3.2.1 网络优化

3.2.2 代码优化

3.3 高分辨率Fine-Tuning

3.4 和Efficient模型比较


4. 迁移学习结果
4.1 单标签分类

4.2 多标签分类

4.3 物体检测

5. 结论
在本文中,我们指出了神经网络设计模式最新发展的一个可能盲点。 他们倾向于不将实际GPU利用率视为网络质量的衡量标准之一。 尽管有时会测量GPU推理速度,但人们普遍忽略了GPU训练速度和最大可能的批处理大小。 对于许多现实世界的深度学习应用程序而言,训练速度,推理速度和最大批处理大小都是至关重要的因素。
为解决此问题,我们提出了一组精心选择的设计改进方案,这些方案在利用典型GPU资源方面非常有效:SpaceToDepth主干,经济的AA降采样,Inplace-ABN操作,Block类型选择、重新设计和优化的SE层。我们将这些改进与一系列代码优化和增强相结合,以提出一系列专门用于GPU高性能的新模型,我们称之为TResNet。
我们证明,在ImageNet上,相比其他top-1的模型,TResNet有着更好的GPU吞吐量。 此外,在三个常用的单标签分类数据集上,它达到了最新SOTA准确性。 我们还表明,TResNet可以很好地推广到其他计算机视觉任务,在在多标签分类和对象检测数据集上也达到最高分。
网友评论