zl程序教程

您现在的位置是:首页 >  其它

当前栏目

RegNet网络结构与搭建

搭建 网络结构
2023-09-11 14:17:50 时间

前言

原论文名称:Designing Network Design Spaces
原论文下载地址:https://arxiv.org/abs/2003.13678.pdf
论文中提供的源码: https://github.com/facebookresearch/pycls
自己使用Pytorch实现的RegNet代码: Test10_regnet/model.py

近些年来,NAS(Neural Architecture Search)网络搜索技术非常火,但这对计算资源要求也比较高(都是大厂玩的东西)。包括这篇论文中的RegNet也有使用到NAS技术。但在论文中作者一再强调这篇论文与之前的一些NAS论文不同(例如MobileNetv3,EfficientNet),之前的一些有关NAS的论文都是在给定的设计空间(designed search space)中通过搜索算法去搜索出一组最佳参数组合。但在这篇论文中作者要探究的是如何去设计设计空间design design spaces)并发现一些网络的通用设计准则network design principles),而不是仅仅去搜索出一组参数。原论文中有这么一段话:

The majority of work in NAS focuses on the search algorithm, i.e., efficiently finding the best network instances within a fixed, manually designed search space (which we call a design space). Instead, our focus is on a paradigm for designing novel design spaces. The two are complementary: better design spaces can improve the efficiency of NAS search algorithms and also lead to existence of better models by enriching the design space.

那RegNet的性能到底如何呢,参考原论文给出的一些指标:

  • 在轻量级网络领域,低FLOPs的RegNet模型也能达到很好的效果,和MobileNetV2以及ShuffleNetV2性能有的一比。
    low_FLOPs
  • 与当时分类网络的天花板EfficientNet对比,可以看到RegNetY-8.0GF的错误率比EfficientNet-B5更低,且推理速度(infer)快五倍。
    在这里插入图片描述

设计设计空间

这篇论文中的主要内容基本都是在讲,如何从一个给定的原始设计空间AnyNet一步步探索出最终的RegNet空间。如下图所示,从最开始的设计空间A设计空间B再到设计空间C,随着加入的限制越来越多搜索范围越来越小,通过右侧的error-cumulative prob.曲线可以看出,设计空间B内的模型效果总体是要好于设计空间A,而设计空间C内的模型效果总体是要好于设计空间B。这就是这篇论文在探索的事情。如果不想看论文中的设计过程,可以直接跳到后面的网络结构解析部分。
design space

AnyNet Design Space

AnyNet设计空间是这篇论文中提出的最原始的设计空间,如下图所示:
regnet framework在该设计空间中,网络的主体就是由三部分组成(stembodyhead)。其中stemhead是固定不变的,stem就是一个普通的卷积层(默认包含bn以及relu),卷积核大小为3x3,步距为2,卷积核个数为32,head就是分类网络中常见的分类器,由一个全局平均池化层和全连接层构成。所以网络中最主要的就是body部分,body是由4个stage堆叠组成,而stage是由一系列block堆叠组成。但block的详细结构以及参数并没有做任何限制,这就是AnyNet。

AnyNetX(A)Design Space

论文作者说,根据他们的经验将block设计为standard residual bottlenecks block with group convolution即带有组卷积的残差结构(和ResNext的block类似),如下图所示,左图为blockstride=1的情况,右图为blockstride=2的情况:
blockx由图可知,主分支都是一个1x1的卷积(包括bnrelu)、一个3x3的group卷积(包括bnrelu)、再接一个1x1的卷积(包括bn)。shortcut捷径分支上当stride=1时不做任何处理,当stride=2时通过一个1x1的卷积(包括bn)进行下采样。图中的r代表分辨率简单理解为特征矩阵的高、宽,当步距s等于1时,输入输出的r保持不变,当s等于2时,输出的r为输入的一半。w代表特征矩阵的channel(注意当s=2时,输入的是 w i − 1 w_{i-1} wi1输出的是 w i w_i wichennel会发生变化)。g代表group卷积中每个group的group widthb代表bottleneck ratio即输出特征矩阵的channel缩减为输入特征矩阵channel的 1 b \frac1b b1.
此时就从AnyNet的设计空间缩小到AnyNetX空间了,该空间也称为 A n y N e t X A AnyNetX_A AnyNetXA。此时的设计空间依旧很大,接着论文中说为了获得有效的模型,又加了些限制: d i ≤ 16 d_i \leq 16 di16(有16种可能), w i ≤ 1024 w_i \leq 1024 wi1024且取8的整数倍(有128种可能), b i ∈ { 1 , 2 , 4 } b_i \in \left\{1, 2, 4\right\} bi{1,2,4}(有3种可能), g i ∈ { 1 , 2 , 4 , 8 , 16 , 32 } g_i \in \left\{1, 2, 4, 8, 16,32\right\} gi{1,2,4,8,16,32}(有6种可能),其中 d i d_i di表示stage中重复block的次数,由于body中由4stage组成。那么现在还有大约 1 0 18 10^{18} 1018种模型配置参数(想要在这么大的空间去搜索基本不可能):
( 16 ⋅ 128 ⋅ 3 ⋅ 6 ) 4 ≈ 1 0 18 (16\cdot128\cdot3\cdot6)^4\approx10^{18} (1612836)41018

AnyNetX(B)Design Space

接着作者又尝试将所有stage中的block b i b_i bi都设置为同一个参数 b b bshared bottleneck ratio),此时的设计空间记为 A n y N e t X B AnyNetX_B AnyNetXB,然后在 A n y N e t X A AnyNetX_A AnyNetXA A n y N e t X B AnyNetX_B AnyNetXB中通过log-uniform sampling采样方法分别采样500的模型,并在imagenet上训练10个epochs,绘制的error-cumulative prob.对比如下图所示:
anyab通过上图可以发现,将所有stage中的block b i b_i bi都设置为同一个参数 b b bshared bottleneck ratio)后并没有什么明显的变化。

AnyNetX(C)Design Space

接着作者又尝试将所有stage中的block g i g_i gi都设置为同一个参数 g g gshared group width),此时的设计空间记为 A n y N e t X C AnyNetX_C AnyNetXC,和之前同样采样500个模型样本并进行训练接着与 A n y N e t X B AnyNetX_B AnyNetXB进行比较,如下图所示:

anybc通过上图可以发现,将所有stage中的block g i g_i gi都设置为同一个参数 g g gshared group width)后并没有什么明显的变化。并且作者发现了一个有趣的现象当 g > 1 g > 1 g>1时,效果会更好。

AnyNetX(D)Design Space

作者进一步分析了 A n y N e t X C AnyNetX_C AnyNetXC空间中效果好的模型以及效果差的模型,发现在好的模型中 w i w_i wi是呈现递增的趋势。如下图所示,第一行是效果好的模型 w i w_i wi的变化趋势,第二行是效果差的模型 w i w_i wi的变化趋势:

goodandbad然后在 A n y N e t X C AnyNetX_C AnyNetXC空间的基础上加上 w i + 1 ≥ w i w_{i+1} \geq w_i wi+1wi限制得到 A n y N e t X D AnyNetX_D AnyNetXD空间。下图展示了不对 w i w_i wi做限制以及对 w i w_i wi做不同限制的对比,明显加上 w i + 1 ≥ w i w_{i+1} \geq w_i wi+1wi限制后效果更好:
wi

AnyNetX(E)Design Space

作者在 A n y N e t X D AnyNetX_D AnyNetXD空间中进一步分析,发现对于好的模型 d i d_i di同样有递增的趋势(注意,这个趋势仅指stage1stage3,不包括stage4). 然后在 A n y N e t X D AnyNetX_D AnyNetXD空间基础上加上 d i + 1 ≥ d i d_{i+1} \geq d_i di+1di的限制得到 A n y N e t X E AnyNetX_E AnyNetXE空间。下图展示了不对 d i d_i di做限制以及对 d i d_i di做不同限制的对比,可以发现加上 d i + 1 ≥ d i d_{i+1} \geq d_i di+1di限制后效果更好:

anynete

RegNet Design Space

如下图所示,作者在 A n y N e t X E AnyNetX_E AnyNetXE空间采样的一系列模型中选取了Top-20,并绘制了他们每个block输出特征矩阵的width变化趋势。图中每一条灰色实线就代表一个模型。图中的黑色实线是作者通过一个线性函数来拟合的(注意图中的纵坐标刻度不是线性的,所以黑色的实线看着是一条曲线)。
w j = 48 ⋅ ( j + 1 )       f o r     0 ≤ j ≤ 20 w_j = 48 \cdot (j+1) \ \ \ \ \ {\rm for} \ \ \ 0 \leq j \leq 20 wj=48(j+1)     for   0j20
regnet刚刚提到作者是用一个线性函数来拟合的,也就是说每个blockwidth都是不一样的,但在我们实际搭建网络过程中,每个stage中的所有blockwidth应该是一样的,即应该是分段常数函数形式(piecewise constant function)。所以接下来的工作就是去想办法获得这个分段常数函数(To see if a similar pattern applies to individual models, we need a strategy to quantize a line to a piecewise constant function.)。接下来就是作者给出的关于获取分段常数函数的流程:

  • 首先引入一个线性参数化函数,其中 j j jblock的索引, d d dblock的总数量论文中称depth,初始化 w 0 > 0 w_0 > 0 w0>0(线性函数中的 y = a x + b y=ax+b y=ax+b b b b),斜率 w a > 0 w_a > 0 wa>0 u j u_j uj为对应blockwidth
    u j = w 0 + w a ⋅ j      f o r    0 ≤ j < d      ( 2 ) u_j = w_0 + w_a \cdot j \ \ \ \ {\rm for} \ \ 0 \leq j < d \ \ \ \ (2) uj=w0+waj    for  0j<d    (2)

  • 为了量化 u j u_j uj,作者引入了一个新的参数 w m > 0 w_m > 0 wm>0,根据下面的公式(3)以及上面的公式(2)可以计算得到每个 u j u_j uj对应的 s j s_j sj
    u j = w 0 ⋅ w m s j       ( 3 ) u_j = w_0 \cdot w_m^{s_j} \ \ \ \ \ (3) uj=w0wmsj     (3)

  • 接着将上一步计算得到的每个 u j u_j uj对应的 s j s_j sj进行四舍五入(记为 ⌈ s j ⌋ \left\lceil s_j \right\rfloor sj),并根据下面的公式(4)可以得到量化后的 w j w_j wj
    w j = w 0 ⋅ w m ⌈ s j ⌋       ( 4 ) w_j = w_0 \cdot w_m^{\left\lceil s_j \right\rfloor} \ \ \ \ \ (4) wj=w0wmsj     (4)

  • 其实在源码实现中还有两个小细节,一个是将刚刚计算得到的 w j w_j wj给调整到离他最近的8的整数倍。还有一个是会根据传入的参数 g g gGroup Conv中每个groupgroup width)进一步调整,将 w j w_j wj给调整到离他最近的 g g g的整数倍(详情可看下源码)。

通过上面公式我们就能对每个blockwidth进行量化,量化后相同的width就属于同一stage,如下图所示,作者也说了,该论文只讨论stage的个数4的情况,所以使用论文中给的参数计算得到的stage数肯定等于4:

block_width通过以上分析,我们在 A n y N e t X E AnyNetX_E AnyNetXE空间基础上指定 d , w 0 , w a , w m , b , g d,w_0, w_a, w_m, b, g d,w0,wa,wm,b,g的值(通过上面的公式(2)-(4)可以得到blockwidthdepths),那么整个网络的结构就固定了。所以作者称在 A n y N e t X E AnyNetX_E AnyNetXE空间基础上使用 d , w 0 , w a , w m , b , g d,w_0, w_a, w_m, b, g d,w0,wa,wm,b,g这6个自由变量来控制网络结构的空间为RegNet空间。接着我们再看论文中的一张表,下表展示了从 A n y N e t X a AnyNetX_a AnyNetXa R e g N e t RegNet RegNet空间的变化过程(记录了限制条件,自由度以及空间内所有可能的组合的数):

design_space_summary
后面还有一些内容,大家可以去看下原论文,这里就不在赘述了。对于论文中给的每个网络的 d , w 0 , w a , w m , b , g d,w_0, w_a, w_m, b, g d,w0,wa,wm,b,g参数在RegNetX/Y模型详细参数章节有给出,可通过本文目录跳转至相应章节。


RegNet网络结构详解

RegNet结构框架

首先看下下面这幅图,这幅图是原论文中给出的General Network structure,Regnet的框架结构也是一样的。
regnet framework
(a)图中展示了网络主要由三部分组成,stembodyhead

  • 其中stem就是一个普通的卷积层(默认包含bn以及relu),卷积核大小为3x3,步距为2,卷积核个数为32.
  • 其中body就是由4个stage堆叠组成,如图(b)所示。每经过一个stage都会将输入特征矩阵的height和width缩减为原来的一半。而每个stage又是由一系列block堆叠组成,每个stage的第一个block中存在步距为2的组卷积(主分支上)和普通卷积(捷径分支上),剩下的block中的卷积步距都是1,和ResNet类似。
  • 其中head就是分类网络中常见的分类器,由一个全局平均池化层和全连接层构成。

RegNet block详解

接下来再看下论文中关于block的结构图,(a)图为步距stride=1的情况,(b)图是步距stride=2的情况。
blockx
通过上图可知,文中的blockResNext网络中的block基本一致。主分支都是一个1x1的卷积(包括bnrelu)、一个3x3的group卷积(包括bnrelu)、再接一个1x1的卷积(包括bn)。shortcut捷径分支上当stride=1时不做任何处理,当stride=2时通过一个1x1的卷积(包括bn)进行下采样。图中的r代表分辨率简单理解为特征矩阵的高、宽,当步距s等于1时,输入输出的r保持不变,当s等于2时,输出的r为输入的一半。w代表特征矩阵的channel(注意当s=2时,输入的是 w i − 1 w_{i-1} wi1输出的是 w i w_i wichennel会发生变化)。g代表group卷积中每个group的group widthb代表bottleneck ratio即输出特征矩阵的channel缩减为输入特征矩阵channel的 1 b \frac1b b1.
而在论文章节四中,作者给出了一个结论:

We also observe that the best models use a bottleneck ratio b of 1.0 (top-middle), which effectively removes the bottleneck (commonly used in practice).

就是说当b取1时效果最好(感觉和ShuffleNetV2中G1准则相似)。下面这副图是我重绘的,比原图要更清楚点。

block2这里还要注意一点,论文中有RegNetX和RegNetY,两者的区别仅在于RegNetY在block中的Group Conv后接了个SE(Squeeze-and-Excitation)模块。 自从SENet的提出,近些年的网络基本都会使用SE模块。在RegNet中的SE模块与EfficientNet中的SE模块类似。如下图所示,SE模块一般是由一个全局平均池化层和两个全连接层组成。在RegNet中,全连接层1(FC1)的节点个数是等于输入该block的特征矩阵channel的四分之一(不是Group Conv输出特征矩阵channal的四分之一),并且激活函数是ReLU。全连接层2(FC2)的节点个数是等于Group Conv输出特征矩阵的channal,并且激活函数是Sigmoid。

se module


RegNetX模型详细参数

下图为论文中给出的不同FLOPs下的RegNetX模型详细参数。搭建网络我们仅需使用 d i d_i di w i w_i wi g g g这三个参数,加上刚刚讲的内容就能搭建网络了( b b b参数都是1)。其中 d i d_i di代表每个stage重复block的次数(前面说了body都是由4个stage堆叠组成的,所以 d i d_i di中都是4个元素)。 w i w_i wi代表每个stage输出特征矩阵的channel g g g代表blockGroup Conv每个group的group width
至于 w a w_a wa w 0 w_0 w0 w m w_m wm这三个参数是用来计算 d i d_i di w i w_i wi这两个参数的(在上文RegNet Design Space章节有讲,有兴趣的可以看下),在源码实现中都是通过 w a w_a wa w 0 w_0 w0 w m w_m wm来计算 d i d_i di w i w_i wi的。但如果嫌麻烦,可以直接使用图中标注好的 d i d_i di w i w_i wi参数。
regnetx_cnf
下表展示了RegNetX这一系列网络在ImegeNet上训练100epoch后的top-1 error
regnetx_acc


RegNetY模型详细参数

下图为论文中给出的不同FLOPs下的RegNetY模型详细参数(刚刚也说了,RegNetY和RegNetX在结构上的唯一不同就是在Group Conv后加上了Squeeze-and-Excitation模块)。同样我们仅需使用 d i d_i di w i w_i wi g g g这三个参数即可搭建出网络。其中 d i d_i di代表每个stage重复block的次数。 w i w_i wi代表每个stage输出特征矩阵的channel g g g代表blockGroup Conv每个group的group width
regnety_cnf
下表展示了RegNetY这一系列网络在ImegeNet上训练100epoch后的top-1 error

regnety_acc