SENet详解及Keras复现代码
转:
SENet详解及Keras复现代码
论文地址:https://arxiv.org/pdf/1709.01507.pdf
代码地址:https://github.com/hujie-frank/SENet
1、通道间的特征关系
近些年来,卷积神经网络在很多领域上都取得了巨大的突破。而卷积核作为卷积神经网络的核心,通常被看做是在局部感受野上,将空间上(spatial)的信息和特征维度上(channel-wise)的信息进行聚合的信息聚合体。卷积神经网络由一系列卷积层、非线性层和下采样层构成,这样它们能够从全局感受野上去捕获图像的特征来进行图像的描述。
我们可以看到,已经有很多工作在空间维度上来提升网络的性能。那么很自然想到,网络是否可以从其他层面来考虑去提升性能,比如考虑特征通道之间的关系?论文的作者就是基于这一点并且提出了Squeeze-and-Excitation Networks(简称 SENet)。作者并不希望引入一个新的维度来进行特征通道间的融合,而是采用一种全新的特征重标定策略。简单来说,就是通过增加一条分支,自动获取到每个通道的重要程度,然后依照这个重要程度去提升有用的信息,同时抑制对当前任务用处不大的特征。

上图是SE模块的示意图。给定一个输入X,其通道数维C’,经过一系列卷积等变换后得到一个通道数维C的特征。接下来的结构有点类似ResNet,但又与ResNet有很大不同。
首先是Squeeze操作,我们顺着空间维度来进行特征压缩,将每个二维特征通道变换成一个实数,这个实数某种程度上具有全局感受野,并且输出和输入的通道数是一样的。它表征着在特征通道上响应的全局分布,而且使得靠近输入的层也可以获得全局的感受野,这一点在很多任务中都是非常有用的。
其次是Excitation操作,他是类似于RNN中门的机制,通过参数W来为每个特征通道生成权重,其中参数W将被用来控制U中每个通道的重要性。
最后一个是Reweight的操作,我们将Excitation的输出权重看做是特征选择后每个特征通道的重要性,然后通过乘法逐通道加权到原来的特征U上,完成在通道维度上的特征重标定。
2、具体的网络结构
由于SE模块并不像GoogLeNet和ResNet一样,提出了全新的网络结构,所以它是可以很灵活的嵌入到已有主流网络中去。

上图左边是将SE模块嵌入到Inception结构的一个示例。
这里的Global pooling对应着Squeeze操作,它将输入特征层的维度压缩至1 x 1 x C。紧接着两个全连接层组成一个Bottleneck结构去建模通道间的相关性,并且最终输出的维度信息保持不变,为1 x 1 x C。
我们可以看到第一个全连接层使用了ReLU作为激活函数,第二个层采用了Sigmoid的作为激活函数。而我们知道Sigmoid会变量映射到0,1之间,也就是说有用的特征通过SE模块让他更偏向于1了,同时无用的特征也更接近0了,那么通过最后Scale操作,将输出权重与原始特征的每个通道逐乘也就增益了原始通道有用的特征,抑制了无用特征。
为什么采用两个全连接层而不是一个的原因在于:
- 通过ReLU可以获得更多的非线性
- 引入r参数可以减少参数量和计算量
除此之外,SE模块也可以嵌入到含有跨层连接的网络中去,上图右边就是将SE嵌入到模块中的一个例子,原理、操作基本和SE-Inception一样,只不过是在最后的Addition前对分支上Residual的特征进行重标定。
目前大多数的主流网络都是基于这两种类似的单元通过 repeat 方式叠加来构造的。由此可见,SE 模块可以嵌入到现在几乎所有的网络结构中。通过在原始网络结构的 building block 单元中嵌入 SE 模块,我们可以获得不同种类的 SENet。如 SE-BN-Inception、SE-ResNet、SE-ReNeXt、SE-Inception-ResNet-v2 等等。
3、实验结果
论文中给出了ResNet、ResNeXt等在当时比较常见的网络对比结果。深度学习经过几年的发展,在数据增强上也有了新的突破,为了公平起见,作者将网络又重新实现了一遍并且采用了同样的数据增强方式。结果如下图所示:

结合试验结果和上面的介绍来看,我们可以发现SENet的构造非常简单,不需要引入新的函数或层。对比原来的网络,仅仅只需要增加2%-10%的参数,就能将误差降低0.4-1.1左右。
4、更多的尝试
参数r的调节

我们在第一个全连接中引入了参数r,使得第一个全连接层的通道数减少,整体呈现一个瓶颈状的结构。作者的试验结果发现r=8时会有一个比较好的效果。
Pooling的方式

对于空间维度的压缩方式,作者尝试了Global Max Pooling和Global Average Pooling两种方式,无论是top-1还是top-5,结果都表明,AvgPool效果会更好。
激活函数的选择

接下来是最后一个全连接层激活函数的选择,用tanh替换sigmoid会略微恶化性能,而使用ReLU会显著恶化,实际上会导致SE-ResNet-50的性能低于ResNet-50基线。这表明,为了使SE块有效,激活函数的选择是很重要的。
SE Block添加的位置

作者还对SE模块添加的位置做了对比,在top-5上在越靠后的Stage上填加SE模块比在越靠前的Stage上添加效果要好,当然如果在所有Stage都添加效果是最好的。
SE的四种结构

最后是对SE模块的结构进行了对比:
(a) 普通的残差
(b) 标准的SE模块
先进行SE再进行残差
(d) 先完成残差计算再进行SE模块计算
(e) 在跨层连接上完成SE模块计算

从结果上看,是SE-PRE的结构略胜一筹,但个人觉得只是在ResNet-50上对比了一下还不具有说服力。但是无论是什么结构都会提高ResNet的准确率,说明SE模块是有起作用的。
5、总结
SENet作为ImageNet竞赛的最后一届图像识别冠军,作者是付出了很多的时间,在网络架构上做了大量的尝试和实验,论文中还有些细节没有在本文中展开解释,读者可以下载论文详细阅读。作者开源的代码是基于caffe的,笔者自己也尝试在keras和tf2上进行复现,比较直观的效果是分类的置信度比原本ResNet要高很多。可能是因为在SE-ResNet中进行了多次sigmoid函数激活。
- Keras-SEResNet
论文地址:https://arxiv.org/pdf/1709.01507.pdf
代码地址:https://github.com/hujie-frank/SENet
1、通道间的特征关系
近些年来,卷积神经网络在很多领域上都取得了巨大的突破。而卷积核作为卷积神经网络的核心,通常被看做是在局部感受野上,将空间上(spatial)的信息和特征维度上(channel-wise)的信息进行聚合的信息聚合体。卷积神经网络由一系列卷积层、非线性层和下采样层构成,这样它们能够从全局感受野上去捕获图像的特征来进行图像的描述。
我们可以看到,已经有很多工作在空间维度上来提升网络的性能。那么很自然想到,网络是否可以从其他层面来考虑去提升性能,比如考虑特征通道之间的关系?论文的作者就是基于这一点并且提出了Squeeze-and-Excitation Networks(简称 SENet)。作者并不希望引入一个新的维度来进行特征通道间的融合,而是采用一种全新的特征重标定策略。简单来说,就是通过增加一条分支,自动获取到每个通道的重要程度,然后依照这个重要程度去提升有用的信息,同时抑制对当前任务用处不大的特征。
上图是SE模块的示意图。给定一个输入X,其通道数维C’,经过一系列卷积等变换后得到一个通道数维C的特征。接下来的结构有点类似ResNet,但又与ResNet有很大不同。
首先是Squeeze操作,我们顺着空间维度来进行特征压缩,将每个二维特征通道变换成一个实数,这个实数某种程度上具有全局感受野,并且输出和输入的通道数是一样的。它表征着在特征通道上响应的全局分布,而且使得靠近输入的层也可以获得全局的感受野,这一点在很多任务中都是非常有用的。
其次是Excitation操作,他是类似于RNN中门的机制,通过参数W来为每个特征通道生成权重,其中参数W将被用来控制U中每个通道的重要性。
最后一个是Reweight的操作,我们将Excitation的输出权重看做是特征选择后每个特征通道的重要性,然后通过乘法逐通道加权到原来的特征U上,完成在通道维度上的特征重标定。
2、具体的网络结构
由于SE模块并不像GoogLeNet和ResNet一样,提出了全新的网络结构,所以它是可以很灵活的嵌入到已有主流网络中去。
上图左边是将SE模块嵌入到Inception结构的一个示例。
这里的Global pooling对应着Squeeze操作,它将输入特征层的维度压缩至1 x 1 x C。紧接着两个全连接层组成一个Bottleneck结构去建模通道间的相关性,并且最终输出的维度信息保持不变,为1 x 1 x C。
我们可以看到第一个全连接层使用了ReLU作为激活函数,第二个层采用了Sigmoid的作为激活函数。而我们知道Sigmoid会变量映射到0,1之间,也就是说有用的特征通过SE模块让他更偏向于1了,同时无用的特征也更接近0了,那么通过最后Scale操作,将输出权重与原始特征的每个通道逐乘也就增益了原始通道有用的特征,抑制了无用特征。
为什么采用两个全连接层而不是一个的原因在于:
- 通过ReLU可以获得更多的非线性
- 引入r参数可以减少参数量和计算量
除此之外,SE模块也可以嵌入到含有跨层连接的网络中去,上图右边就是将SE嵌入到模块中的一个例子,原理、操作基本和SE-Inception一样,只不过是在最后的Addition前对分支上Residual的特征进行重标定。
目前大多数的主流网络都是基于这两种类似的单元通过 repeat 方式叠加来构造的。由此可见,SE 模块可以嵌入到现在几乎所有的网络结构中。通过在原始网络结构的 building block 单元中嵌入 SE 模块,我们可以获得不同种类的 SENet。如 SE-BN-Inception、SE-ResNet、SE-ReNeXt、SE-Inception-ResNet-v2 等等。
3、实验结果
论文中给出了ResNet、ResNeXt等在当时比较常见的网络对比结果。深度学习经过几年的发展,在数据增强上也有了新的突破,为了公平起见,作者将网络又重新实现了一遍并且采用了同样的数据增强方式。结果如下图所示:
结合试验结果和上面的介绍来看,我们可以发现SENet的构造非常简单,不需要引入新的函数或层。对比原来的网络,仅仅只需要增加2%-10%的参数,就能将误差降低0.4-1.1左右。
4、更多的尝试
参数r的调节
我们在第一个全连接中引入了参数r,使得第一个全连接层的通道数减少,整体呈现一个瓶颈状的结构。作者的试验结果发现r=8时会有一个比较好的效果。
Pooling的方式
对于空间维度的压缩方式,作者尝试了Global Max Pooling和Global Average Pooling两种方式,无论是top-1还是top-5,结果都表明,AvgPool效果会更好。
激活函数的选择
接下来是最后一个全连接层激活函数的选择,用tanh替换sigmoid会略微恶化性能,而使用ReLU会显著恶化,实际上会导致SE-ResNet-50的性能低于ResNet-50基线。这表明,为了使SE块有效,激活函数的选择是很重要的。
SE Block添加的位置
作者还对SE模块添加的位置做了对比,在top-5上在越靠后的Stage上填加SE模块比在越靠前的Stage上添加效果要好,当然如果在所有Stage都添加效果是最好的。
SE的四种结构
最后是对SE模块的结构进行了对比:
(a) 普通的残差
(b) 标准的SE模块
先进行SE再进行残差
(d) 先完成残差计算再进行SE模块计算
(e) 在跨层连接上完成SE模块计算
从结果上看,是SE-PRE的结构略胜一筹,但个人觉得只是在ResNet-50上对比了一下还不具有说服力。但是无论是什么结构都会提高ResNet的准确率,说明SE模块是有起作用的。
5、总结
SENet作为ImageNet竞赛的最后一届图像识别冠军,作者是付出了很多的时间,在网络架构上做了大量的尝试和实验,论文中还有些细节没有在本文中展开解释,读者可以下载论文详细阅读。作者开源的代码是基于caffe的,笔者自己也尝试在keras和tf2上进行复现,比较直观的效果是分类的置信度比原本ResNet要高很多。可能是因为在SE-ResNet中进行了多次sigmoid函数激活。
- Keras-SEResNet
转:
SENet详解及Keras复现代码
SENet详解及Keras复现代码的更多相关文章
- 训练技巧详解【含有部分代码】Bag of Tricks for Image Classification with Convolutional Neural Networks
训练技巧详解[含有部分代码]Bag of Tricks for Image Classification with Convolutional Neural Networks 置顶 2018-12-1 ...
- 详解计算miou的代码以及混淆矩阵的意义
详解计算miou的代码以及混淆矩阵的意义 miou的定义 ''' Mean Intersection over Union(MIoU,均交并比):为语义分割的标准度量.其计算两个集合的交集和并集之比. ...
- Console命令详解,让调试js代码变得更简单
Firebug是网页开发的利器,能够极大地提升工作效率. 但是,它不太容易上手.我曾经翻译过一篇<Firebug入门指南>,介绍了一些基本用法.今天,继续介绍它的高级用法. ======= ...
- [转] Console命令详解,让调试js代码变得更简单
http://www.cnblogs.com/see7di/archive/2011/11/21/2257442.html Firebug是网页开发的利器,能够极大地提升工作效率. 但是,它不太容易上 ...
- rabbitmq五种模式详解(含实现代码)
一.五种模式详解 1.简单模式(Queue模式) 当生产端发送消息到交换机,交换机根据消息属性发送到队列,消费者监听绑定队列实现消息的接收和消费逻辑编写.简单模式下,强调的一个队列queue只被一个消 ...
- 【小白学PyTorch】12 SENet详解及PyTorch实现
文章来自微信公众号[机器学习炼丹术].我是炼丹兄,有什么问题都可以来找我交流,近期建立了微信交流群,也在朋友圈抽奖赠书十多本了.我的微信是cyx645016617,欢迎各位朋友. 参考目录: @ 目录 ...
- jquery轮播图详解,40行代码即可简单解决。
我在两个月以前没有接触过html,css,jquery,javascript.今天我却在这里分享一篇技术贴,可能在技术大牛面前我的文章漏洞百出,也请斧正. 可以看出来,无论是div+css布局还是jq ...
- Bullet核心类介绍(Bullet 2.82 HelloWorld程序及其详解,附程序代码)
实验平台:win7,VS2010 先上结果截图: 文章最后附有生成该图的程序. 1. 刚体模拟原理 Bullet作为一个物理引擎,其任务就是刚体模拟(还有可变形体模拟).刚体模拟,就是要计算预测物体的 ...
- 通俗易懂详解Java代理及代码实战
一.概述 代理模式是Java常用的设计模式之一,实现代理模式要求代理类和委托类(被代理的类)具有相同的方法(提供相同的服务),代理类对象自身并不实现真正的核心逻辑,而是通过调用委托类对象的相关方法来处 ...
随机推荐
- lca讲解 && 例题 HDU - 4547
一. 最普通的找树中两个点x,y最近公共祖先: 在进行lca之前我们要先对这一颗树中的每一个点进行一个编号,像下图一样.这个编号就是tarjan算法中的dfn[]数组 这样的话我们可以在跑tarjan ...
- AtCoder Beginner Contest 173 E - Multiplication 4 (思维)
题意:有\(n\)个数,从中选\(k\)个数累乘,求最大的乘积\((mod\ 10^9+7)\). 题解: 1.假如全是负数,并且选奇数个,那么从小到大选. 2.否则,考虑当前状态,假如\(k\)是奇 ...
- Gym 102263 ArabellaCPC 2019 J - Thanos Power (DP,数学)
题意:有一个整数\(n\),每次可以对加\(10^x\)或减\(10^x\),问最少操作多少次能得到\(n\). 题解:对于某一位上的数,我们可以从\(0\)加几次得到,或者从前一位减几次得到.所以对 ...
- MySQL菜鸟实录(一):MySQL服务安装实战
CentOS 7 基本信息 系统版本: CentOS 7.3 64bit 系统配置: 4vCPUs | 8GB 磁盘空间: [root@ecs-ce5a-0001 ~]# df -h Filesyst ...
- Linux系统诊断必备技能之三:查看信息系统常用命令
一.概述 Linux操作系统的学习中,CLI下进行操作,需要掌握大量命令,Linux的命令有很多,对于命令的学习大家记住只能是熟能生巧,所以现在把日常使用命令为大家罗列一部分,仅供参考. 二.常用命令 ...
- 多线程(四) AQS底层原理分析
J.U.C 简介 Java.util.concurrent 是在并发编程中比较常用的工具类,里面包含很多用来在并发 场景中使用的组件.比如线程池.阻塞队列.计时器.同步器.并发集合等等.并 发包的作者 ...
- 推荐一个vuepress模板,一键快速搭建文档站
介绍 vuepress-template是一个简单的VuePress案例模板,目的是让用户可以直接clone这个仓库,作为初始化一个VuePress网站启动项目,然后在这个项目的基础上新增自定义配置和 ...
- TypeScript callback Object params
TypeScript callback Object params 回调函数 对象 参数 const func = (options = {}) => { // do somthing retu ...
- Google Developer Profile
Google Developer Profile https://google.dev/u/me https://google.dev/u/109030792841960772125 Google D ...
- 微前端 & 微前端实践 & 微前端教程
微前端 & 微前端实践 & 微前端教程 微前端 micro frontends https://micro-frontends.org/ https://github.com/neul ...