SENet(2017)

2024-02-08 11:38
文章标签 2017 senet

本文主要是介绍SENet(2017),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

卷积核作为卷积神经网络的核心,通常被看作是在局部感受野上,将空间上(spatial)的信息和特征维度上(channel-wise)的信息进行聚合的信息聚合体。卷积神经网络由一系列卷积层、非线性层和下采样层构成,这样它们能够从全局感受野上去捕获图像的特征来进行图像的描述。
在这里插入图片描述
去学到一个性能非常强劲的网络是相当困难的,从空间维度层面来提升网络的性能,如Inception结构中嵌入了多尺度信息,聚合多种不同感受野上的特征来获得性能增益;在Inside-Outside网络中考虑了空间中的上下文信息;将Attention机制引入到空间维度上等。
在这里插入图片描述
Squeeze-and-Excitation Networks(简称 SENet)显示的建模特征通道之间的相互依赖关系。采用全新的特征重标定策略,即通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征。
在这里插入图片描述
Squeeze-and-Excitation(SE)block并不是一个完整的网络结构,而是一个子结构,可以嵌到其他分类或检测模型中,作者采用SENet block和ResNeXt结合在ILSVRC2017分类项目中拿到第一,在ImageNet数据集上将top-5 error降低到2.251%,原先的最好成绩是2.991%。

作者在文中将SENet block插入到现有的多种分类网络中,都取得了不错的效果。SENet的核心思想在于通过网络根据loss去学习特征权重,使得有效的feature map权重大,无效或效果小的feature map权重小的方式训练模型达到更好的结果。当然,SE block嵌在原有的一些分类网络中不可避免的增加了一些参数和计算量,但是在效果面前还是可以接受的。

下图是SE模块的示意图,给定一个输入 x x x,其特征通道数为 c 1 c_1 c1,通过一系列卷积等一般变换后得到一个特征通道数为 c 2 c_2 c2的特征。
在这里插入图片描述

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

Excitation操作是一个类似于循环神经网络中门的机制。通过参数 w w w来为每个特征通道生成权重,其中参数 w w w被学习用来显示的建模特征通道间的相关性。
在这里插入图片描述

Reweight操作,将Excitation的输出的权重看作是进过特征选择后的每个特征通道的重要性,然后通过乘法逐通道加权到先前的特征上,完成在通道维度上的对原始特征的重标定。
在这里插入图片描述

在这里插入图片描述
下图是将SE模块嵌入到Inception结构的一个示例,方框旁边的维度信息代表该层的输出。这里使用global average pooling作为squeeze操作,紧接着两个Fully Connected层组成一个Bottleneck结构取构建通道间的相关性,并输出和输入特征同样数目的权重。

  • 首先将特征维度降低到输入的1/16。
  • 然后经过ReLU激活函数后再通过一个Fully Connected层升回到原来的维度。这样做比直接用一个Fully Connected层的好处在于:
    • 具有更多的非线性,可以更好的拟合通道间复杂的相关性;
    • 极大的减少了参数量和计算量。然后通过一个Sigmoid的门获得0~1之间归一化的权重。
  • 最后通过一个Scale的操作来将归一化后的权重加权到每个通道的特征上。

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

目前大多数的主流网络都是基于这两种类似的单元通过repeat方式叠加起来构造的。由此可见,SE模块可以嵌入到现在几乎所有的网络结构中。通过在原始网络结构的building block单元中嵌入SE模块,可以获得不同种类的SENet。
在这里插入图片描述
在这里插入图片描述
SE模块很容易嵌入到其它网络中,作者为了验证SE模块的作用,在其它流行网络如ResNet和VGG中引入SE模块,测试其在ImageNet上的效果,如下表所示:
在这里插入图片描述
可以看到所有网络在加入SE模块后分类准确度均有一定的提升。此外,作者还测试了SE模块在轻量级网络MobileNet和ShuffleNet上的效果,如下表所示,可以看到也是有效果提升的。
在这里插入图片描述
最终作者采用了一系列的SENet进行集成,在ImageNet测试集上的top-5 error为2.251%,赢得了2017年竞赛的冠军。其中最关键的模型是SENet-154,其建立在ResNeXt模型基础上,效果如下表所示:
在这里插入图片描述

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

class SELayer(nn.Module):def __init__(self, channel, recution=16):super(SELayer, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.fc = nn.Sequential(nn.Linear(channel, channel // reduction, bias=False),nn.ReLU(inplace=True),nn.Linear(channel // reduction, channel, bias=False),nn.Sigmoid())def forward(self, x):b, c, _, = x.size()y = self.avg_pool(x).view(b, c)y = self.fc(y).view(b, c, 1, 1)return x * y.expand_as(x)
class SEBottleneck(nn.Module):expansion = 4def __init__(self, inplanes, planes, stride=1, downsample=None, reduction=16):super(SEBottleneck, self).__init__()self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)self.bn1 = nn.BatchNorm2d(planes)self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)self.bn2 = nn.BatchNorm2d(planes)self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)self.bn3 = nn.BatchNorm2d(planes * 4)self.relu = nn.ReLU(inplace=True)self.se = SELayer(planes * 4, reduction)self.downsample = downsampleself.stride = stridedef foward(self, x):residual = xout = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.conv2(out)out = self.bn2(out)out = self.relu(out)out = self.conv3(out)out = self.bn3(out)out = self.se(out)if self.downsample is not None:residual = self.downsample(x)out += residualout = self.relu(out)return out

参考资料
深度学习——分类之SENet
Momenta详解ImageNet 2017夺冠架构SENet
最后一届ImageNet冠军模型:SENet
SENet(Squeeze-and-Excitation Networks)算法笔记—通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大…
Momenta详解ImageNet 2017夺冠架构SENet

这篇关于SENet(2017)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/690903

相关文章

2017 版本的 WebStorm 永久破解

1.  在IntelliJ官网中下载 最新版本的WebStorm   下载地址:https://www.jetbrains.com/webstorm/download/#section=windows 2. 获取注册码    获取地址:http://idea.lanyus.com/   点击获取注册码,然后将注册码复制,再打开最新版的WebStorm,将注册码粘贴到激活框中就大功告

网易2017秋招编程题集合--完全解析

前言 一些大公司的真题里面总有些含金量很高的几个题,网易2017秋招编程题集合里面也有几个题是非常好的,比如说第三题跳石板,第四题黑暗的字符串都是很好的题目。特别是第四题的那种思路之前几乎完全没有接触过,还有第六题最大的奇约数里面还有部分数学思维在里面。 1.回文序列 题目描述:如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如: {1, 2, 1}, {15, 7

Fastjson1.2.24(CVE-2017-18349)分析

前言 Fastjson在1.2.24版本之前存在两条利用链,分别是 JNDI com.sun.rowset.JdbcRowSetImplcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl 我们本次也是对这两条链进行分析和过程复现 在fastjson漏洞中,我们往往是寻找一个类,它的构造函数、 getter,setter 方法有问

NLP-生成模型-2017-Transformer(一):Encoder-Decoder模型【非序列化;并行计算】【O(n²·d),n为序列长度,d为维度】【用正余弦函数进行“绝对位置函数式编码”】

《原始论文:Attention Is All You Need》 一、Transformer 概述 在2017年《Attention Is All You Need》论文里第一次提出Transformer之前,常用的序列模型都是基于卷积神经网络或者循环神经网络,表现最好的模型也是基于encoder- decoder框架的基础加上attention机制。 2018年10月,Google发出一篇

NLP-预训练模型-2017:ULMFiT(Universal LM Fine-tuning for Text Classification)【使用AWD-LSTM;模型没有创新;使用多个训练小技巧】

迁移学习在计算机视觉有很大的影响,但现在的NLP中的方法仍然需要特定任务的修改和 从头开始的训练。我们提出通用语言模型微调,一种可以应用NLP任何任务中的迁移学习方法。我们模型在分类任务中都表现得良好,并且在小数据集上的表现优异。 一、ULMFiT (Universal Language Model Fine- tuning)组成步骤: a) General-domain LM pretr

NLP-文本匹配-2017:BiMPM【Bilateral Multi-Perspective Matching for Natural Language Sentences】

NLP-文本匹配-2016:BiMPM【Bilateral Multi-Perspective Matching for Natural Language Sentences】

2017-择善而从

前言   此文是2017上半年对自己工作和生活的回顾总结,也是给自己一个停下脚步安静思考的机会。每个努力生活的人,老天都会待你不薄。勉励自己在新的日子里,努力生活,择善而从。 Coding-内外兼修   一直觉得中国的武术有着深厚的哲学思想,蕴含着事物的本质。传统中华武术注重内外兼修,既修内容,又练外功。编程也是一样,要内外兼修。不仅要学习层出不穷的“新技术”,更要去思考其本质,掌握

2017年华为精英挑战赛

http://blog.csdn.net/h532600610/article/details/70183608 http://blog.csdn.net/mmy1996/article/details/64443159

2017/05/17 java 基础 随笔

2017/05/17 java 基础 随笔   posted @ 2017-05-17 08:36 酸奶加绿茶 阅读( ...) 评论( ...) 编辑 收藏

2017/05/16 java 基础 随笔

2017/05/16 java 基础 随笔 1,成员变量和局部变量的区别   1)在内存中的位置不同     成员变量:在堆内存(成员变量属于对象,对象进堆内存)     局部变量:在栈内存(局部变量属于方法,方法进栈内存)   2)初始化值不同     成员变量:有默认初始化值     局部变量:没有默认初始化值,必须定义,赋值,然后才能调用。 2.封装   private:被修饰的