date: 2018/05/02

update: 2020/03/27

Don't say "lazy" - 桜高軽音部:频繁被日推


分类任务是计算机视觉(Computer Vision, CV)的基础任务,给网络输入一张图片并输出图片的分类结果,要求被识别对象占图片的主体位置。但在实际应用中经常不能直接采集到这样的图片,所以就出现了目标检测任务、语义分割任务等等,他们除了能识别对象之外还能定位出对象在图片上的位置——这并不意味着分类网络没有用处,因为目标检测、语义分割等更高级的任务都需要依赖分类网络作为前端的特征提取器(称为backbone),所以说分类是CV的基础。


参考:

  1. Hands-On Machine Learning with Scikit-Learn and TensorFlow(2017)》Chap13
  2. 卷积神经网络——深度学习实践手册(2017.05)
  3. GluonCV主页 比较了一些常见网络的性能和推理速度
  4. PaperWithCode 比较了一系列分类网络的性能和参数规模


CNN的典型组合方式是,以 卷积层+激活函数(比如relu)+池化层 作为一组操作;

一张图片经过若干组这样的操作的stack之后,变得越来越小,同时越来越深(feature maps越来越多);

在stack的顶层,经过一个常规的前馈神经网络(由若干个带激活的全连接层组成)后产生预测结果(通常经过一个softmax层)——

12Typical_CNN_Architectures.png


LeNet-5

1998年由Yann LeCun提出,用于实现手写体数字识别(MNIST);

12LeNet-5.png



AlexNet

论文:《Imagenet Classification with Deep Convolutional Neural Networks(2012)


赢得2012年的ImageNet ILSVRC比赛;

与LeNet-5很像,只是更大更深(约60万个参数)

12AlexNet.png



其中,
      分别是LRN的第i个特征图输入、正则化输出;

是超参量, 称为偏置, 称为深度半径;
      是特征图的数量;
      比如,当 时,强烈激活的神经元会抑制他的上一个和下一个特征图中相同位置的神经元;


变种:ZFNet

论文:《Visualizing and Understanding Convolutional Networks(2014)

2013年ILSVRC比赛冠军


VGG-Nets

论文:《VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION(2015)

2014年ILSVRC亚军

image.png


特点:

  1. 只使用带padding的3x3小核卷积
    增加网络深度时确保各层输入大小随深度增加而不减小
  2. “卷积+ReLU”的堆叠,适当位置用最大池化下采样
    网络卷积的通道数逐渐增加(
    从此设计CNN时有了“特征图宽高减小一半,通道数就膨胀一倍;每扩大一倍,通道数就减小一半”的惯例,这样可以大致保持每一个卷积层或每一个block的计算量相近,同时也符合“特征越抽象(特征图尺寸越小),蕴含的信息越丰富(所需的通道数越多)”这样一种认知
  3. 最后使用三个连续的全连接层——VGG模型参数的主要来源
    前两个全连接使用Dropout正则化
  4. VGG系列网络主要包括VGG11、VGG13、VGG16、VGG19(数字表示“全连接层数量 + 卷积层数量”


NIN(Network in Netwrok)

论文:《Network In Network(2014)

这里提出的NIN并不常用,但却启发了后来的Inception和ResNet。


特点:

  1. 在卷积层之后加入多层感知机
    这里的多层感知机指的不是全连接层,而是两层1x1卷积,这增加了通道间的融合且减少了计算量;
  2. 使用全局平均池化(Global Average Pooling)操作替代全连接层
    用GAP替代VGG中的前两层全连接,保留最后一个全连接作为分类器,这减少了参数,避免过拟合;


Inception

参考:《从Inception v1到Inception-ResNet,一文概览Inception家族的「奋斗史」| 机器之心

注意Inception的默认输入尺寸是299而不是224


Inception-v1

论文:《Going Deeper with Convolutions(2015)

2014年ILSVRC冠军,也称为GoogLeNet;

利用子网络inception模块,网络更加高效(大约只有AlexNet的十分之一),使得网络可以更深;


Inception模块:


image.png


Inception-v1(GoogLeNet)框架:

包括9个堆叠Inception模块,每个卷积层都使用ReLU激活函数。

12GoogLeNet.png


辅助损失:

为了缓解深层网络的梯度消失问题,Inception-v1从网络中间抽出两组特征图,分别以此用“k5s3平均池化 + k1s1卷积 + 全连接 + 全连接 + Softmax”的辅助分类器计算得到两个辅助损失aux_loss1和aux_loss2,与主loss加权后作为总loss进行训练。 total_loss = main_loss + 0.3 * aux_loss1 + 0.3 * aux_loss2 


Inception-v2

论文:《Rethinking the Inception Architecture for Computer Vision (CVPR2016)

v2只是个过渡版本,论文里把v3也一并提了出来。


三种改进的Inception模块:

Origin

image.png

A

image.png

B

image.png

C

image.png


Inception-v3

论文:《Rethinking the Inception Architecture for Computer Vision (CVPR2016)》同v2


在Inception-v2的基础上,


完整结构:

image.png

(图中As in figure 5/6/7 分别对应前述的 A/B/C


Inception-v4和Inception-ResNet-v1/v2

论文:《Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning (AAAI2017)

这篇论文同时提出了Inception-v4、Inception-ResNet-v1和Inception-ResNet-v2;

Inception-ResNet-v1计算规模与Inception-v3相当,

Inception-ResNet-v2计算规模与Inception-v4相当


改进stem:

一般会将网络最初的卷积层堆叠(比如这里是指Inception模块之前的所有层)称为stem。

image.png      image.png      image.png

左:Inception-v1/v2/v3;  中:Inception-ResNet-v1;  右:Inception-v4、Inception-ResNet-v2


这里把三个版本的stem都列出来作一比较,


改进Inception模块:

A

B

C

I1

image.png

I2/I3


image.png


image.png


image.png

I4

image.png

image.png

image.png

IR1/IR2

image.png

image.png

image.png


设计专门的下采样块:

v1-v3都是直接用最大池化来实现下采样。

image.png    image.png    image.png

左:I4/IR1/IR2第一次下采样;  中:I4第二次下采样;  右:IR1/IR2第二次下采样


残差激活值缩放:

作者观察到当网络太深时,深层的残差单元可能会使网络崩溃,此时可以尝试在残差上设置一个缩放因子(如0.1-0.3)来增加训练的稳定性。

image.png


ResNet

ResNet-v1

论文:《Deep Residual Learning for Image Recognition(2015)

参考:

  1. 机器之心 - 一文简述ResNet及其多种变体(2018) 》【原文
  2. Training Very Deep Networks(2015)
    受LSTM中门机制的启发,提出高速公路网络,对前馈神经网络进行修正,使信息能够在多个神经网络层之间高效流动;这一思想也影响了ResNet网络


2015年ILSVRC冠军;网络更深(152层),如此深的网络能够被训练主要得益于Skip Connections(或Shortcut Connections)技术;


残差学习(Residual Learning)

在常规网络的基础上,网络输出前增加一个与输入加和的操作;

这时网络不再直接训练目标函数 ,而是训练

12Residual_Learning.png


对于常规网络,权重通常被初始化为一个比较小的数值(回顾《梯度消失与梯度爆炸 - 随机初始化 | Hey~YaHei!》),网络一开始只能输出一个非常小的结果;

但是残差网络输出的却是一个接近输入的结果,而往往我们所要训练的目标函数跟这个输入还是比较接近的,这将大大加速我们的训练过程;


而且,如果加入了很多skip connections,网络可以在很早的时候就开始取得进步(有效地学习),即使中间有部分层还没开始进步也不影响,因为信号的传递很容易穿过整个网络(随后ResNet-v2部分就残差单元如何有效缓解梯度消失做详细论述);

深层残差网络可以看作是很多残差单元(Residual Unit, RU)的堆叠,每个残差单元是一个包含一个skip connection的小网络(Network In Network的思想)——

12Deep_Residual_Network.png


整体框架:

常见的有ResNet18, ResNet34, ResNet50, ResNet101, ResNet152,数字表示的是“卷积层数量+全连接层数量”(但不包括下采样时shortcut通路上的下采样卷积)

12ResNet.png

12Double_Units.png

image.png

左:BasicBlock;    右:Bottleneck


ResNet-v1d

论文:《Bag of Tricks for Image Classification with Convolutional Neural Networks(2018)》Model Tweak


改进1:推迟下采样

image.png    image.png

左:原始的Bottleneck下采样;    右:改进的Bottleneck下采样


考虑原始的下采样,其中第一个1x1卷积用来作为下采样,所以步长设为了2。但你仔细想想会发现,核大小1x1、步长2的卷积会造成3/4的信息直接丢失。以6x6的特征图为例,如下图所示,只有红色部分的信息能够传递到下一层去,非红色部分均不参与卷积计算。

conv_k1s2.jpg


由此可见,在1x1的卷积层作下采样是不明智的,更好的做法是把下采样过程挪到3x3的卷积上,如下图所示,由于卷积核宽度大于步长,卷积核在移动过程中能够遍历输入特征图上的所有信息(甚至还能有重叠):

conv_k3s2.jpg


改进2:拆解大核卷积

Inception-v1跟ResNet-v1一样都使用了7x7大核卷积,Inception-v3则将其拆解为三个3x3小核卷积,这一操作同样可以借鉴过来改进ResNet-v1。

image.png      image.png

左:原始的stem;    右:改进的stem


改进3:用平均池化替代1x1卷积做下采样

image.png      image.png      image.png

左:原始的Bottleneck下采样;  中:改进1的Bottleneck下采样;  右:改进1+3的Bottleneck下采样


还是下采样模块,原本shortcut支路也是用步长为2的1x1卷积做下采样,但如果直接把1x1卷积改为3x3卷积,将大大增加计算量(甚至超过残差路径的计算量),因此用更简单的2x2平均池化实现shortcut支路的下采样,既不会引入太多的额外开销,又不会直接丢失过多的信息。


效果:


model_tweak_results.jpg

(B/C/D分别代表改进1/1+2/1+2+3后的ResNet)

ResNet50-D准确率提高了0.95%,FLOPS增加了13%,但实测速度只下降3%。


改进4:零gamma初始化

初始化BN时,通常令,但在残差单元中将最后一个BN初始化为会是更好的选择,具体参见 高效训练 - 零gamma初始化


ResNet-v2

论文:《Identity Mappings in Deep Residual Networks(ECCV2016)

对ResNetv1做了一些有效的改进,使得shortcut的通路更加“干净”,有利于信息的流通,不仅可以训练更深层的网络,而且使得ResNet的表现有了进一步的提升

ResidualBlockv2.png


残差单元如何缓解梯度消失:

先用数学符号定义残差网络

其中,

是第l个残差单元的输入;

是第个残差单元的一系列权重;

表示残差单元的计算过程(不包含最后的ReLU);

表示shortcut的通路;

 表示激活函数


为了方便分析,我们先简化问题,忽略激活函数,即令 ,则有

那么对任意

对应地,反向传播时有

如此一来,残差单元在前向传播时能直接获得浅层信息,而且在反向传播时不容易出现梯度消失,这也是ResNet有效的主要原因。


即使如此,ResNet-v1在超过200层时依旧会出现明显的过拟合现象。

首先要观察到,前述的分析中为简化问题忽略了激活函数的作用,而v2则指出激活函数妨碍了shortcut通路的信息流通,并尝试改变激活的位置来使得通路更加干净。


shortcut路径通畅的重要性:

作者设计了如下实验,分别为shortcut通路引入各种干扰——比如缩放、门控、丢弃等,发现模型的表现明显下降,以此证明shortcut路径通畅的重要性。

ShortcutPathExperiment.png

ShortcutPathResult.png


改进方案:改变非线性激活的位置

作者实验了各种激活的位置,得到了更好的设计方式

ResNetv2Activation.png

  1. b将BN也放到shortcut通路上,使shortcut通路更加复杂化,模型表现变差
  2. c把ReLU提到残差通路上,虽然shortcut通路变得干净,但做addition时残差均非负,特征的数值随着网络加深只会一味地增大,不利于学习特征提取
  3. d把ReLU提到卷积之前,与v1的表现差不多
  4. e把BN和ReLU都提到卷积之前,模型表现明显要比v1更好


ResNeXt

论文:《Aggregated Residual Transformations for Deep Neural Networks (CVPR2017)

利用分组卷积替换3x3标准卷积,某种程度上可以看做是一种集成技术,使得相同计算量下有更丰富的特征提取能力。

image.png

左:ResNet BottleNeck;    右:ResNeXt BottleNeck


假设BottleNeck的输入通道数为,实际提取特征(3x3卷积)时通道数收缩为

在ResNet中,

  1. 1x1卷积将通道数从收缩为
  2. 3x3卷积提取特征,输入输出通道数均为
  3. 1x1卷积将通道数从扩张为
  4. 与短连接上的特征图相加


在ResNeXt中,

  1. 将原始的残差分支分解为组(上图中),每组分别
    1. 1x1卷积将通道数从收缩为
    2. 3x3卷积提取特征,输入输出通道数均为
    3. 1x1卷积将通道数从扩张为
  1. 将所有分支(包括短连接)相加


可以进一步用分组卷积写成更优雅的表示方式:

image.png

(a, b, c其实是等价的三个结构)


与ResNet的差别仅在于3x3卷积使用了分组卷积,具体简化为,

  1. 1x1卷积将通道数从收缩为
  2. 3x3分组卷积提取特征,输入输出通道数均为
  3. 1x1卷积将通道数从扩张为
  4. 与短连接上的特征图相加


image.png

(ImageNet上的实验结果)


DenseNet

论文:《Densely Connected Convolutional Networks (CVPR2017)

多个堆叠的小卷积逐步累积拓宽通道数量,通过拼接复用浅层特征,加强跨层的信息流通。

image.png

(DenseBlock示意:四组卷积,且取


image.png

(各版本DenseNet的具体配置,命名中数字表示“卷积层数量+全连接层数量”



FractalNet

论文:《FractalNet: Ultra-Deep Neural Networks without Residuals (ICLR2017)》Drop-Path

而FractalNet这篇论文提出残差结构并不是必要的,可以有其他的可选方案——比如本文提出的分形(Fractal)结构。

image.png

主要思路如上图所示,FractalNet由若干Block堆叠而成,这里的Block相当于ResNet的Stage,每个Block之间通过池化进行下采样操作。Block内部则是若干路径。文中以来定义一个分支的Block,每个分支的深度分别是,最后通过Join层聚合起来,并且存在递推关系

其中,

表示合成(Composition),实际上就是卷积的堆叠;

表示聚合(Join),文中用逐元素取平均来实现


训练时结合DropPath正则化策略,具体来说,五个Block的Dropout丢弃率自浅而深分别是0%, 10%, 20%, 30%, 40%;局部DropPath的丢弃概率均为15%。

image.png

(+表示增加平移/翻转的数据增广)

(++表示在+的基础上增加更多的数据增广)


image.png

(ImageNet上实验结果)


image.png

(CIFAR100++实验结果)


image.png

(CIFAR100++实验结果)


SENet

论文:《Squeeze-and-Excitation Networks (CVPR2018)

提出了SE模块,是注意力机制的一种应用,学习特征图上通道间的相关性,作为权重ReScale各个通道;SE模块相当于一个轻量级的插件,可以方便地插入到已有的网络中去。

SE模块深受研究者们的喜爱,可以看到后来的新网络都热衷于使用SE模块。但实际应用中,带有SE模块的网络在量化时容易出现明显的性能下降,目前似乎没有很好的解决方案。


image.png

(红框部分即为SE-Block)

SE-Block结构上非常简单,

首先对特征图做全局平均池化拉成维的向量,再经过两个FC层形成瓶颈结构(第一个FC收缩为维,第二个FC再扩增回维),第一个FC用ReLU激活,第二个FC用Sigmoid激活输出一系列0~1的权重对原始特征图进行ReScale操作。


其中是超参数,作者通过实验指出,取通常能取得比较好的结果(权衡计算量和性能提升)。


image.png

(SE-Inception和SE-ResNet)


image.png

(ImageNet上的实验结果)


SKNet

论文:《Selective Kernel Networks (CVPR2019)

可以看作是SENet的一个改进,提出一个SK模块,与SE模块不同的是SK模块混合了两种大小的卷积核,以此获得不同感受野的特征信息。


image.png

(SK-Block)

SK-Block结构上也不复杂,

  1. 分别对特征图使用不同大小的卷积核进行特征提取(如图为3x3卷积核和5x5卷积核),分别得到
  2. 逐元素相加得到
  3. 沿用SE-Block的思路,得到通道数为的权重向量(数值范围在0~1之间)
  4. 去ReScale特征图,用去ReScale特征图,最后逐元素相加融合为,本质上相当于一个软选择


image.png

(ImageNet上的实验结果)


ResNeSt

论文:《ResNeSt: Split-Attention Networks (2020.04)

代码:https://github.com/zhanghang1989/ResNeSt


image.png

(SA-Block)


SA-Block比SE-Block和SK-Block更复杂。

  1. Input1, ..., Input r是个相同输入,相同结构但不同参数的分支输出
  2. 个输入相加后进行全局平均池化得到维向量
  3. 用一个FC将向量维度收缩为构造瓶颈,论文建议取的含义参见后续ResNeSt Block的描述)
  4. 分别用个FC分别将向量维度扩增回,此时一共有维向量
  5. 沿维度方向,对维向量分别做softmax,作为权重去ReScale这通道的特征图


可以把SA-Block看作是SK-Block的一个多分支版本(对应地,二分类sigmoid就被多分类softmax替代),本质也是为了从组通道中选择出合适的一个(软选择)。


image.png

(ResNeSt Block)


ResNeSt Block借鉴了ResNeXt的设计(看着复杂,实际可以用分组卷积简化实现)。

  1. 通道的输入特征图沿着通道分成组,每组的输入通道数为
  2. 每组的输入又分成小组,分别经过各自的“1x1卷积收缩为通道,3x3卷积扩增回通道”,然后经过前述的SA-Block进行软选择,得到通道的输出
  3. 组输出拼接在一块得到通道的输出,然后由1x1卷积变换到通道,与原始输入的短连接相加


image.png

(ImageNet上的实验结果)


论文只简单对FLOPS进行分析,实际上ResNeSt沿用了ResNeXt的分组卷积,要知道分组卷积的效率是比较低的,尽管表面上ResNeSt-50-fast跟ResNetD-50都是4.34GFLOPS,但ResNeSt-50-fast肯定还是要慢一些。我简单拿开源的Gluon模型在RTX2080Ti上跑了一下,ResNeSt-50的推理速度比ResNetD-101稍慢一些,而只有ResNetD-50的一半,fast版本尚未开源(截止到2020.04.20),不知道其实际效果会如何。


(2020.05.26更新)ResNeSt最近在目标检测、语义分割上也到处刷榜(这玩意看着就难训,做这么多实验是得花多少钱……),与其形成鲜明对比的是ECCV2020给了它一个strong reject。看到论文也挂出latency了(见下图),测试环境为V100,这与GluonCV的测试环境是一致的。ResNeSt50(acc=81.1%)目测约为2ms,而按照GluonCV的报告,ResNet101-v1d(acc=80.5%)约为1.4ms。怎么说呢,ResNeSt还是算有些提升的吧,strong reject好像还是有些过了,但论文里的实验确实也不厚道——训练ResNeSt的时候autoaug, dropblock等等trick就往上怼,都不好说到底是trick带来的提升还是模型结构本身的优势……

除了预测速度之外,训练代价似乎也非常高,按照GluonCV公开的训练日志,在ImageNet数据集上,ResNeSt竟然需要训练270epoch,相比之下ResNet只需要120epoch…

image.png


轻量化网络


其他


速度

参考:Gluon > Model Zoo > Classification


预测速度

bokeh_plot.png

(ImageNet / V100 x1 / BatchSize=64)


训练速度

数据集为ImageNet,假设GluonCV上训练选用的Epoch数为最佳(恰好收敛),为简单起见,速度直接取最后一个Epoch的平均速度。

Model

GPU

(V100)

FP16Epoch

Speed

(sample/sec)

Time

(sec/epoch)

TotalTime

(hour)

ResNet18_v14120275848116
ResNet34_v14120258051317
ResNet50_v18v12048092769
ResNet101_v18v120256751017
ResNet152_v18


120626206869
ResNet50_v1d_mixup8v200490027115
ResNet50_v1d8v12050512638
ResNet101_v1d_mixup8v200291544925
ResNet101_v1d8v120291944915
ResNet152_v1d_mixup8200737176198
ResNet152_v1d8120757169056
ResNet18_v24120275248216
ResNet34_v24120256751617
ResNet50_v28120278147216
ResNet101_v28v120284546115
ResNet152_v28v180203664132
ResNext50_32x4d_mixup8v200293644325
ResNext101_32x4d_mixup8v200208562335
ResNext101_64x4d_v1_mixup8v2001037124769
SE_ResNext50_32x4d_mixup8200158881845
SE_ResNext101_32x4d_mixup8200950136676
SE_ResNext101_64x4d_mixup82005552338130
ResNeSt14_mixup82703206.1740030
MobileNet1.0_mixup8v200563223713
MobileNet0.758v12053132538
MobileNet0.58v120407432711
MobileNet0.258v12057312337
MobileNetv2_1.04150173575331
MobileNetv2_0.754150175374531
MobileNetv2_0.54150176374131
MobileNetv2_0.254150173275431
MobileNetV3_Large8v360862315315
MobileNetV3_Small8v3601110312012
VGG168100806160345
VGG198100757170947


按照上述信息,可以大致估算出各个网络的相对训练难度(数值越大,训练难度越高)

Difficulty的实际含义:

网络在单卡V100上,不使用mixup数据增广,且以float32数据精度训练至收敛所需小时数的估计值


ModelDifficulty
ResNet18_v164
ResNet18_v264
ResNet34_v168
ResNet34_v269
MobileNet0.25107
MobileNet1.0109
MobileNet0.75117
ResNet50_v1d121
MobileNetv2_0.5123
MobileNetv2_0.75124
MobileNetv2_1.0125
MobileNetv2_0.25126
ResNet50_v2126
ResNet50_v1127
ResNeSt14144
MobileNet0.5151
MobileNetV3_Small166
ResNext50_32x4d204
ResNet101_v1d207
MobileNetV3_Large212
ResNet101_v2213
SE_ResNext50_32x4d218
ResNet101_v1235
ResNext101_32x4d287
VGG16356
SE_ResNext101_32x4d364
VGG19380
ResNet152_v2443
ResNet152_v1d451
ResNet152_v1

552

ResNext101_64x4d_v1575
SE_ResNext101_64x4d623