SKNet(2019)

2024-02-08 11:38
文章标签 2019 sknet

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

在神经科学界,视皮层神经元的感受野大小受到刺激的调节,即对不同刺激,感受野的大小应该不同。目前很多卷积神经网络的相关工作都只是通过改进网络的空间结构来优化模型,如Inception模型通过引入不同大小的卷积核来获得不同感受野上的信息。但在构建传统CNN时一般在同一层只采用一种卷积核,即对于特定任务特定模型,卷积核大小是确定的,很少考虑多个卷积核的作用。

我们在看不同尺寸不同远近的物体时,视觉皮层神经元接受域大小是会根据刺激来进行调节的。作者提出了一种在CNN中对卷积核的动态选择机制,该机制允许每个神经元根据输入信息的多尺度自适应的调整其感受野(卷积核)的而大小。具体的,设计了一个称为选择内核单元(SK)的构建块,其中多个具有不同内核打下的分支在这些分支的信息引导下,使用Softmax进行融合。由多个SK单元组成SKNet,SKNet中的神经元能够捕获不同尺度的目标物体。

SKNet的全称是“Selective Kernel Network”,和SENet是一个团队提出来的,SENet对通道执行注意力机制,而SKNet则是对卷积核执行注意力机制,即让网络自己选择合适的卷积核。

SKNet的核心模块如下图所示,在该模块中,作者使用了多分支卷积网络、组卷积、空洞卷积以及注意力机制。
在这里插入图片描述

多分支卷积网络

多分支卷积网络,即含有多于一个分支的卷积网络,例如经典的残差网络模块和Inception模块都属于多分支卷积网络。残差网络模块,使用了双分支结构,跨层连接的那条分支是一条单纯的恒等映射分支。Inception模块与残差网络的多支不同的是,该模块的每个分支都进行了卷积处理,并不是一个恒等映射。

组卷积

组卷积相比标准卷积,减少了一些参数量。假设feature map的尺寸大小为 W × H × C 1 W \times H \times C_1 W×H×C1,卷积核的尺寸为 w × h × C 1 w \times h \times C_1 w×h×C1,生成的feature map的尺寸大小为 W × H × C 2 W \times H \times C_2 W×H×C2,那么标准卷积的参数量为 w × h × C 1 × C 2 w \times h \times C_1 \times C_2 w×h×C1×C2;如果换为分组卷积,假设分为 g g g组,原feature map和生成的feature map 尺寸同上,那么每组卷积的参数量为 w × h × ( C 1 / g ) × ( C 2 / g ) w \times h \times (C_1 / g) \times (C_2 / g) w×h×(C1/g)×(C2/g),共有 g g g组,那么总参数量为 w × h × C 1 × C 2 / g w \times h \times C_1 \times C2/g w×h×C1×C2/g,参数量与标准卷积相比,减少为原来的 1 / g 1/g 1/g

空洞卷积

空洞卷积与标准卷积相比,增大了感受野。一般情况下,卷积之后的池化操作缩小feature map的尺寸也能达到增加感受野的效果,但是池化过程会导致信息丢失,所以引入了空洞卷积操作。下图为Dilation=2时的卷积效果,当Dilation=2时,3x3的卷积核的感受野变为5x5。空洞卷积与标准卷积相比,在不增加参数量的同时增大了感受野。
在这里插入图片描述

注意力机制

下图为SENet中的注意力机制模块,该通道注意力模块很好理解,图中Ftr函数表示标准卷积,Fsq函数表示一个全局平均池化,通过该函数,生成1x1xC的feature map。然后将该feature map 送人Fex函数(该函数由两个全连接层组成),输出1x1xC的feature map。将该feature map通过sigmoid函数将值控制到(0, 1)之间,然后与最开始的HxWxC的feature map对应相乘,即实现了对各个通道的权重控制,实现了注意力机制。
在这里插入图片描述

SKNet

SKNet如下图所示,其本质就是在网络中使用多尺寸的卷积核,与Inception网络中的多尺度不同,SKNet是让网络自己选择合适的尺度。
在这里插入图片描述
Split操作是将原feature map分别通过一个 3 × 3 3\times3 3×3的分组/深度卷积和 3 × 3 3\times3 3×3的空洞卷积(感受野为 5 × 5 5\times5 5×5)生成两个feature map: U 1 U_1 U1(图中黄色)和 U 2 U_2 U2(图中绿色)。然后将这两个feature map进行相加,生成 U U U。生成的 U U U通过 F q p F_{qp} Fqp函数(全局平均池化)生成 1 × 1 × C 1\times1\times C 1×1×C的feature map(图中的 s s s),该feature map通过 F f c F_{fc} Ffc函数(全连接层)生成 d × 1 d\times1 d×1的向量(图中的 z z z),公式如图中所示( δ \delta δ表示ReLU的激活函数, B B B表示BatchNormlization, W W W是一个 d × C d\times C d×C维的)。 d d d的取值是由公式 d = m a x ( C / r , L ) d=max(C/r, L) d=max(C/r,L)确定, r r r是一个缩小的比率(与SENet中相似), L L L表示 d d d的最小值,实验中 L L L的值为32。生成的 z z z通过 a c a_c ac b c b_c bc两个函数,并将生成的函数值与原先的 U 1 U_1 U1 U 2 U_2 U2相乘。由于 a c a_c ac b c b_c bc的函数值相加等于1,因此能够实现对分支中的feature map设置权重,因为不同的分支卷积核尺寸不同,因此实现了让网络自己选择合适的卷积核( a c a_c ac b c b_c bc中的 A 、 B A、B AB矩阵均是需要在训练之前初始化的,其尺寸均为 C × d C\times d C×d

import torch
from torch import nnclass SKConv(nn.Module):def __init__(self, features, WH, M, G, r, stride=1, L=32):"""ConstructorArgs:features:input channel dimensionality.WH: input spatial dimensionality, used for GAP kernel size.M: the number of branches.G: number of convlution groups.r: the ratio for compute d, the length of z.stride: stride, default 1.L: the minimum dim of the vector z in paper, default 32."""super(SKConv, self).__init__()d = max(int(features/r), L)self.M = Mself.features = featuresself.convs = nn.ModuleList([])for i in range(M):self.convs.append(nn.Sequential(nn.Conv2d(features, features, kernel_size=3+i*2, stride=stride, padding=1+i, groups=G),nn.BatchNorm2d(features),nn.ReLU(inplace=False)))self.gap = nn.AvgPool2d(int(WH/stride))self.fc = nn.Linear(features, d)self.fcs = nn.ModuleList([])for i in range(M):self.fcs.append(nn.Linear(d, features))self.softmax = nn.Softmax(dim=1)def forward(self, x):for i, conv in enumerate(self.convs):fea = conv(x).unsqueeze_(dim=1)if i == 0:feas = feaelse:feas = torch.cat([feas, fea], dim=1)fea_U = torch.sum(feas, dim=1)fea_s = self.gap(fea_U).squeeze_()fea_z = self.fc(fea_s)for i, fc in enumerate(self.fcs):vector = fc(fea_z).unsqueeze_(dim=1)if i == 0:attention_vectors = vectorelse:attention_vectors = torch.cat([attention_vectors, vector], dim=1)attention_vectors = self.softmax(attention_vectors)attention_vectors = attention_vectors.unsqueeze(-1).unsqueeze(-1)fea_v = (feas * attenstion_vectors).sum(dim=1)return fea_vclass SKUnit(nn.Module):def __init__(self, in_features, out_features, WH, M, G, r, mid_features=None, stride=1, L=32):"""ConstructorArgs:in_features: input channel dimensionalityout_feauters: output channel dimensionality.WH: input spatial dimensionality, used for GAP kernel size.M: the number of branchs.G: number of convolution groups.r: the ratio for compute d, the length of z.mid_features: the channel dim of the middle conv with stride not 1, default out_features/2.stride: stride.L: the minimum dim of the vector z in paper."""super(SKUnit, self).__init__()if mid_features is None:mid_features = int(out_features/2)self.feas = nn.Sequential(nn.Conv2d(in_features, mid_features, 1, stride=1),nn.BatchNorm2d(mid_features),SKConv(mide_features, WH, M, G, r, stride=stride, L=L),nn.BatchNorm2d(mid_features),nn.Conv2d(mid_features, out_features, 1, stride=1),nn.BatchNorm2d(out_features))if in_features == out_features: #when dim not change, in could be added directly to out self.shortcut = nn.Sequential()else: # when dim not change, in should also change dim to be added to outself.shortcut = nn.Sequential(nn.Conv2d(in_features, out_features, 1, stride=stride),nn.BatchNorm2d(out_features))def forward(self, x):fea = self.feas(x)return fea + self.shortcut(x)class SKNet(nn.Module):def __init__(self, class_num):super(SKNet, self).__init__()self.basic_conv = nn.Sequential(nn.Conv2d(3, 64, 3, padding=1),nn.BatchNorm2d(64))# 32x32self.stage_1 = nn.Sequential(SKUnit(64, 256, 32, 2, 8, 2, stride=2),nn.ReLU(),SKUnit(256, 256, 32, 2, 8, 2),nn.ReLU(),SKUnit(256, 256, 32, 2, 8, 2),nn.ReLU()) # 32x32self.stage_2 = nn.Sequential(SKUnit(256, 512, 32, 2, 8, 2, stride=2),nn.ReLU(),SKUnit(512, 512, 32, 2, 8, 2),nn.ReLU()SKUnit(512, 512, 32, 2, 8, 2),nn.ReLU()) # 16 x 16self.stage_3 = nn.Sequential(SKUnit(512, 1024, 32, 2, 8, 2, stride=2),nn.ReLU(),SKUnit(1024, 1024, 32, 2, 8, 2),nn.ReLU(),SKUnit(1024, 1024, 32, 2, 8, 2),nn.ReLU(),)# 8x8self.pool = nn.AvgPool2d(8)self.classifier = nn.Sequential(nn.Linear(1024, class_num))def forward(self, x):fea = self.basic_conv(x)fea = self.stage_1(fea)fea = self.stage_2(fea)fea = self.stage_3(fea)fea = self.pool(fea)fea = torch.squeeze(fea)fea = self.classifier(fea)return fea
if __name__ == '__main__':x = torch.rand(8, 64, 32, 32)conv = SKConv(64, 32, 3, 8, 2)out = conv(x)criterion = nn.L1Loss()loss = criterion(out, x)loss.backward()print('out shape: {}'.format(out.shape))print('loss value: {}'.format(loss))

参考资料
SKNet解读
Selective Kernel Networks(2019)
implus/SKNet
人工智能 SKNet

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



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

相关文章

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

2019学习计划

工作三年了,第一年感觉是荒废的,第二年开始学习python,第三年开始自动化 感觉自己会的东西比较少,而且不够深入,流于表面 现制定一下今年大概的学习计划 需持续巩固加强:python、ui自动化、接口自动化、sql等 代码量需提升,敲的不够(重点) 学习: 1.移动端测试,appium等 2.前端知识系统整理学习  3.性能测试 4.docker入门,环境搭建 5.shell

最简单的使用JDBC[连接数据库] mysql 2019年3月18日

最极简版本的, 我们这里以mysql为例: 首先要创建maven工程, 需要引入jar包:,这里需要注意, 如果你安装的是mysql最新版本8以上的, 下面有些地方需要更改,具体就是mysql连接的url, 和5版本的不一样,具体解决请自行百度哈.这里只演示mysql5版本的? 依赖: <dependency>   <groupId>mysql</groupId>   <artifactId

(php伪随机数生成)[GWCTF 2019]枯燥的抽奖

审核源码发现加载check.php,审计发现使用了mt_rand()函数,这个函数生成的值是伪随机的 参考下面这篇文章 PHP mt_rand安全杂谈及应用场景详解 - FreeBuf网络安全行业门户 kali里面输入下载工具 git clone https://github.com/openwall/php_mt_seed.git cd进去输入make后编译出的文件先

2019年2月17日

今天又重新看了一下输出第1500个丑数 在我错了八次之后发现要输出一个句号还要输出换行 接下来的两天应该进入复习阶段了。

National Contest for Private Universities (NCPU), 2019 E. Generalized Pascal's Triangle

编辑代码 2000ms 262144K Generalized Pascal's Triangle Pascal's triangle is a triangular array in which each number can be calculated by the sum of the two numbers directly above that number as shown i

Hinton等人最新研究:大幅提升模型准确率,标签平滑技术 2019-7-8

导读:损失函数对神经网络的训练有显著影响,也有很多学者人一直在探讨并寻找可以和损失函数一样使模型效果更好的函数。后来,Szegedy 等学者提出了标签平滑方法,该方法通过计算数据集中 hard target 的加权平均以及平均分布来计算交叉熵,有效提升了模型的准确率。近日,Hinton 团队等人在新研究论文《When Does Label Smoothing Help?》中,就尝试对标签平滑技术对

Photoshop CC 2019圆形的抠图

快速进入矩形选区 快速在矩形和圆形选区之前切换: shift+M 选择的时候,按住shift,可以选中正方形/圆形   以中心点画圆: alt + 拖拽 再利用变换选区功能即可实现圆的选中 效果如图所示: 再使用自由变换,即可放大,缩小球的大小: ctrl + T 阴影部分的处理: 1)去其他球那里选择个椭圆形选区 2)选择编辑-填充 3)使用滤镜里

Windows Server 2019 中文版、英文版下载 (updated Aug 2024)

Windows Server 2019 中文版、英文版下载 (updated Aug 2024) Windows Server 2019 Version 1809 请访问原文链接:https://sysin.org/blog/windows-server-2019/,查看最新版。原创作品,转载请保留出处。 本站将不定期发布官方原版风格月度更新 ISO。 Windows Server