[Attention]SE-Net论文讲解

转自两篇解析,第一篇作者本人的解析,第二篇某位博主的解析
文章1: 链接

编者按:Momenta Paper Reading致力于打造一个自动驾驶学术前沿知识的分享沟通平台,深入浅出让你轻松读懂AI。本次我们分享的主题是ImageNet冠军模型SENet。

论文链接:[1709.01507] Squeeze-and-Excitation Networks

GitHub:hujie-frank/SENet


在CVPR 2018上,有一篇来自Momenta的高级研发工程师胡杰及其所在WMW团队的文章——获得ImageNet冠军的模型SENet。以下是对胡杰本人关于文章分享的整理。

我是Momenta高级研发工程师胡杰,很高兴可以和大家分享我们的SENet。借助我们提出 SENet,我们团队(WMW)以极大的优势获得了最后一届ImageNet 2017竞赛 Image Classification任务的冠军。下面我将介绍我们提出的SENet,论文和代码会在公布在arXiv上,欢迎大家follow我们的工作,并给出宝贵的建议和意见。

我们从最基本的卷积操作开始说起。近些年来,卷积神经网络在很多领域上都取得了巨大的突破。而卷积核作为卷积神经网络的核心,通常被看做是在局部感受野上,将空间上(spatial)的信息和特征维度上(channel-wise)的信息进行聚合的信息聚合体。卷积神经网络由一系列卷积层、非线性层和下采样层构成,这样它们能够从全局感受野上去捕获图像的特征来进行图像的描述。

然而去学到一个性能非常强劲的网络是相当困难的,其难点来自于很多方面。最近很多工作被提出来从空间维度层面来提升网络的性能,如Inception结构中嵌入了多尺度信息,聚合多种不同感受野上的特征来获得性能增益;在Inside-Outside网络中考虑了空间中的上下文信息;还有将Attention机制引入到空间维度上等等。这些工作都获得了相当不错的成果。

我们可以看到,已经有很多工作在空间维度上来提升网络的性能。那么很自然想到,网络是否可以从其他层面来考虑去提升性能,比如考虑特征通道之间的关系?我们的工作就是基于这一点并提出了Squeeze-and-Excitation Networks(简称SENet)。在我们提出的结构中,Squeeze和Excitation是两个非常关键的操作,所以我们以此来命名。我们的动机是希望显式地建模特征通道之间的相互依赖关系。另外,我们并不打算引入一个新的空间维度来进行特征通道间的融合,而是采用了一种全新的“特征重标定”策略。具体来说,就是通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征。

上图是我们提出的SE模块的示意图。给定一个输入x,其特征通道数为c_1,通过一系列卷积等一般变换后得到一个特征通道数为c_2的特征。与传统的CNN不一样的是,接下来我们通过三个操作来重标定前面得到的特征。

首先是Squeeze操作,我们顺着空间维度来进行特征压缩,将每个二维的特征通道变成一个实数,这个实数某种程度上具有全局的感受野,并且输出的维度和输入的特征通道数相匹配。它表征着在特征通道上响应的全局分布,而且使得靠近输入的层也可以获得全局的感受野,这一点在很多任务中都是非常有用的。

其次是Excitation操作,它是一个类似于循环神经网络中门的机制。通过参数 来为每个特征通道生成权重,其中参数 被学习用来显式地建模特征通道间的相关性。

最后是一个Reweight的操作,我们将Excitation的输出的权重看做是进过特征选择后的每个特征通道的重要性,然后通过乘法逐通道加权到先前的特征上,完成在通道维度上的对原始特征的重标定。

上左图是将SE模块嵌入到Inception结构的一个示例。方框旁边的维度信息代表该层的输出。这里我们使用global average pooling作为Squeeze操作。紧接着两个Fully Connected 层组成一个Bottleneck结构去建模通道间的相关性,并输出和输入特征同样数目的权重。我们首先将特征维度降低到输入的1/16,然后经过ReLu激活后再通过一个Fully Connected 层升回到原来的维度。这样做比直接用一个Fully Connected层的好处在于:1)具有更多的非线性,可以更好地拟合通道间复杂的相关性;2)极大地减少了参数量和计算量。然后通过一个Sigmoid的门获得0~1之间归一化的权重,最后通过一个Scale的操作来将归一化后的权重加权到每个通道的特征上。

除此之外,SE模块还可以嵌入到含有skip-connections的模块中。上右图是将SE嵌入到 ResNet模块中的一个例子,操作过程基本和SE-Inception一样,只不过是在Addition前对分支上Residual的特征进行了特征重标定。如果对Addition后主支上的特征进行重标定,由于在主干上存在0~1的scale操作,在网络较深BP优化时就会在靠近输入层容易出现梯度消散的情况,导致模型难以优化。

目前大多数的主流网络都是基于这两种类似的单元通过repeat方式叠加来构造的。由此可见,SE模块可以嵌入到现在几乎所有的网络结构中。通过在原始网络结构的building block 单元中嵌入SE模块,我们可以获得不同种类的SENet 。如SE-BN-Inception、SE-ResNet 、SE-ReNeXt、SE-Inception-ResNet-v2等等。

从上面的介绍中可以发现,SENet构造非常简单,而且很容易被部署,不需要引入新的函数或者层。除此之外,它还在模型和计算复杂度上具有良好的特性。拿ResNet-50和SE-ResNet-50对比举例来说,SE-ResNet-50相对于ResNet-50有着10%模型参数的增长。额外的模型参数都存在于Bottleneck设计的两个Fully Connected中,由于ResNet结构中最后一个stage的特征通道数目为2048,导致模型参数有着较大的增长,实验发现移除掉最后一个stage中3个build block上的SE设定,可以将10%参数量的增长减少到2%。此时模型的精度几乎无损失。

另外,由于在现有的GPU实现中,都没有对global pooling和较小计算量的Fully Connected进行优化,这导致了在GPU上的运行时间SE-ResNet-50相对于ResNet-50有着约10% 的增长。尽管如此,其理论增长的额外计算量仅仅不到1%,这与其在CPU 运行时间上的增长相匹配(~2%)。可以看出,在现有网络架构中嵌入SE模块而导致额外的参数和计算量的增长微乎其微。

在训练中,我们使用了一些常见的数据增强方法和Li Shen提出的均衡数据策略。为了提高训练效率,我们使用了我们自己优化的分布式训练系统ROCS, 并采用了更大的batch-size 和初始学习率。所有的模型都是从头开始训练的。

接下来,为了验证SENets的有效性,我们将在ImageNet数据集上进行实验,并从两个方面来进行论证。一个是性能的增益vs.网络的深度; 另一个是将SE嵌入到现有的不同网络中进行结果对比。另外,我们也会展示在ImageNet竞赛中的结果。

首先我们来看一下网络的深度对SE的影响。上表分别展示了ResNet-50、ResNet-101、ResNet-152和嵌入SE模型的结果。第一栏Original是原作者实现的结果,为了进行公平的比较,我们在ROCS上重新进行了实验得到Our re-implementation的结果(ps. 我们重实现的精度往往比原paper中要高一些)。最后一栏SE-module是指嵌入了SE模块的结果,它的训练参数和第二栏Our re-implementation一致。括号中的红色数值是指相对于Our re-implementation的精度提升的幅值。

从上表可以看出,SE-ResNets在各种深度上都远远超过了其对应的没有SE的结构版本的精度,这说明无论网络的深度如何,SE模块都能够给网络带来性能上的增益。值得一提的是,SE-ResNet-50可以达到和ResNet-101一样的精度;更甚,SE-ResNet-101远远地超过了更深的ResNet-152。

上图展示了ResNet-50和ResNet-152以及它们对应的嵌入SE模块的网络在ImageNet上的训练过程,可以明显看出加入了SE模块的网络收敛到更低的错误率上。

另外,为了验证SE模块的泛化能力,我们也在除ResNet以外的结构上进行了实验。从上表可以看出,将SE模块嵌入到ResNeXt、BN-Inception、Inception-ResNet-v2上均获得了不菲的增益效果。由此看出,SE的增益效果不仅仅局限于某些特殊的网络结构,它具有很强的泛化性。

上图展示的是SE嵌入在ResNeXt-50和Inception-ResNet-v2的训练过程对比。

在上表中我们列出了一些最新的在ImageNet分类上的网络的结果。其中我们的SENet实质上是一个SE-ResNeXt-152(64x4d),在ResNeXt-152上嵌入SE模块,并做了一些其他修改和训练优化上的小技巧,这些我们会在后续公开的论文中进行详细介绍。可以看出 SENet获得了迄今为止在single-crop上最好的性能。

最后,在ILSVRC 2017竞赛中,我们的融合模型在测试集上获得了2.251% Top-5错误率。对比于去年第一名的结果2.991%,我们获得了将近25%的精度提升。

------------------------------------------------

知乎机构号:Momenta,打造自动驾驶大脑。

基于深度学习的环境感知、高精度地图、驾驶决策技术,让无人驾驶成为可能。


知乎专栏:Paper Reading,集聚自动驾驶知名大咖的前沿知识分享平台,欢迎申请加入或直接投稿。

文章2:链接

论文链接:https://arxiv.org/abs/1709.01507

代码地址:https://github.com/hujie-frank/SENet

PyTorch代码地址:https://github.com/miraclewkf/SENet-PyTorch

Sequeeze-and-Excitation(SE) block并不是一个完整的网络结构,而是一个子结构,可以嵌到其他分类或检测模型中,作者采用SENet block和ResNeXt结合在ILSVRC 2017的分类项目中拿到第一,在ImageNet数据集上将top-5 error降低到2.251%,原先的最好成绩是2.991%。
作者在文中将SENet block插入到现有的多种分类网络中,都取得了不错的效果。SENet的核心思想在于通过网络根据loss去学习特征权重,使得有效的feature map权重大,无效或效果小的feature map权重小的方式训练模型达到更好的结果。当然,SE block嵌在原有的一些分类网络中不可避免地增加了一些参数和计算量,但是在效果面前还是可以接受的。

也许通过给某一层特征配备权重的想法很多人都有,那为什么只有SENet成功了?个人认为主要原因在于权重具体怎么训练得到。就像有些是直接根据feature map的数值分布来判断;有些可能也利用了loss来指导权重的训练,不过全局信息该怎么获取和利用也是因人而异

Figure1表示一个SE block。主要包含Squeeze和Excitation两部分,接下来结合公式来讲解Figure1。

这里写图片描述

首先Ftr这一步是转换操作(严格讲并不属于SENet,而是属于原网络,可以看后面SENet和Inception及ResNet网络的结合),在文中就是一个标准的卷积操作而已,输入输出的定义如下表示。

这里写图片描述

那么这个Ftr的公式就是下面的公式1(卷积操作,vc表示第c个卷积核,xs表示第s个输入)。

这里写图片描述

Ftr得到的U就是Figure1中的左边第二个三维矩阵,也叫tensor,或者叫C个大小为H*W的feature map。而uc表示U中第c个二维矩阵,下标c表示channel。

接下来就是Squeeze操作,公式非常简单,就是一个global average pooling:

这里写图片描述

因此公式2就将HWC的输入转换成11C的输出,对应Figure1中的Fsq操作。为什么会有这一步呢?这一步的结果相当于表明该层C个feature map的数值分布情况,或者叫全局信息。

再接下来就是Excitation操作,如公式3。直接看最后一个等号,前面squeeze得到的结果是z,这里先用W1乘以z,就是一个全连接层操作,W1的维度是C/r * C,这个r是一个缩放参数,在文中取的是16,这个参数的目的是为了减少channel个数从而降低计算量。又因为z的维度是11C,所以W1z的结果就是11C/r;然后再经过一个ReLU层,输出的维度不变;然后再和W2相乘,和W2相乘也是一个全连接层的过程,W2的维度是C*C/r,因此输出的维度就是11C;最后再经过sigmoid函数,得到s。

这里写图片描述

也就是说最后得到的这个s的维度是11C,C表示channel数目。这个s其实是本文的核心,它是用来刻画tensor U中C个feature map的权重。而且这个权重是通过前面这些全连接层和非线性层学习得到的,因此可以end-to-end训练。这两个全连接层的作用就是融合各通道的feature map信息,因为前面的squeeze都是在某个channel的feature map里面操作。

在得到s之后,就可以对原来的tensor U操作了,就是下面的公式4。也很简单,就是channel-wise multiplication,什么意思呢?uc是一个二维矩阵,sc是一个数,也就是权重,因此相当于把uc矩阵中的每个值都乘以sc。对应Figure1中的Fscale。

这里写图片描述

了解完上面的公式,就可以看看在实际网络中怎么添加SE block。Figure2是在Inception中加入SE block的情况,这里的Inception部分就对应Figure1中的Ftr操作。

这里写图片描述

Figure3是在ResNet中添加SE block的情况。

这里写图片描述

看完结构,再来看添加了SE block后,模型的参数到底增加了多少。其实从前面的介绍可以看出增加的参数主要来自两个全连接层,两个全连接层的维度都是C/r * C,那么这两个全连接层的参数量就是2*C^2/r。以ResNet为例,假设ResNet一共包含S个stage,每个Stage包含N个重复的residual block,那么整个添加了SE block的ResNet增加的参数量就是下面的公式:

这里写图片描述

除了公式介绍,文中还举了更详细的例子来说明参数增加大概是多少百分比:In total, SE-ResNet-50 introduces 2.5 million additional parameters beyond the 25 million parameters required by ResNet-50, corresponding to a 10% increase in the total number of parameters。而且从公式5可以看出,增加的参数和C关系很大,而网络越到高层,其feature map的channel个数越多,也就是C越大,因此大部分增加的参数都是在高层。同时作者通过实验发现即便去掉最后一个stage的SE block,对模型的影响也非常小(<0.1% top-1 error),因此如果你对参数量的限制要求很高,倒是可以这么做,毕竟具体在哪些stage,哪些block中添加SE block都是自由定义的。

Table2是将SE block添加到ResNet,ResNeXt和Inception三个模型中的效果对比,数据集都是ImageNet,可以看出计算复杂度的增加并不明显(增加的主要是全连接层,全连接层其实主要还是增加参数量,对速度影响不会太大)。

这里写图片描述

既然是冠军算法,文中也介绍了当时取得冠军时的算法大致组成:Our winning entry comprised a small ensemble of SENets that employed a standard multi-scale and multi-crop fusion strategy to obtain a 2.251% top-5 error on the test set.This result represents a 25% relative improvement on the winning entry of 2016 (2.99% top-5 error). 也就是说其实是多模型做了融合。

而在融合的多个模型之中:One of our high-performing networks is constructed by integrating SE blocks with a modified ResNeXt,也就是Table3中最后一行的SENet!具体而言是在64*4d 的ResNeXt-152网络中引入了SE block。而这个ResNeXt-152是在ResNeXt-101的基础上根据ResNet-152的叠加方式改造出来的,因为原来的ResNeXt文章中并没有提到152层的ResNeXt,具体改造可以看文章的附录,附录的一些细节可以在以后应用中参考。从Table3可以看出即便是单模型,SENet的效果也比其他算法要好。

这里写图片描述

另外前面提到过在SE block中第一个全连接层的维度是C/r * C,这个r在文中取的是16,作用在于将原来输入是11C的feature map缩减为11C/r的feature map,这一就降低了后面的计算量。而下面的Table5则是关于这个参数r取不同值时对结果和模型大小的影响。

这里写图片描述

最后,除了在ImageNet数据集上做实验,作者还在Places365-Challenge数据集上做了对比,更多实验结果可以参看论文。

附:看了下caffe代码(.prototxt文件),和文章的实现还有些不一样。下图是在Inception中添加SENet的可视化结果:SE-BN-Inception,在Inception中是在每个Inception的后面连上一个SENet,下图的上面一半就是一个Inception,下面一半就是一个SENet,然后这个SENet下面又连着一个新的Inception。

这里写图片描述

注意看这个SENet的红色部分都是用卷积操作代替文中的全连接层操作实现的,本质上没有什么区别。具体来说,inception_3a_11_down是输出channel为16的11卷积,其输入channel是256,这也符合文中说的缩减因子为16(256/16=16);而inception_3a_11_up是输出channel为256的11卷积。其它层都和文中描述一致,比如inception_3a_global_pool是average pooling,inception_3a_prob是sigmoid函数。

SE-ResNet-50的情况也类似,如下图。在ResNet中都是在Residual block中嵌入SENet。下图最左边的长条连线是原来Residual block的skip connection,右下角的conv2_2_global_pool到conv2_2_prob以及左边那条连线都是SENet。不过也是用两个1*1卷积代替文中的两个全连接层。

这里写图片描述

  • 2
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值