学习Se-net和Sk-net 附网络简单代码(pytorch)

news2024/11/28 0:34:27

(一)Se-net的原理和思路
    Se-net严格来说是一个小结构,它可以直接插入已有的网络结构中,帮助原有结构获得更好的效果,如插入Resnet网络中。
在这里插入图片描述

Se-net的整个流程如下:
    (1)假设一个特征图,它的维度是(1,3,255,255),首先将它进行一般卷积。这个过程也可以是其他网络的操作过程。之后我们得到一个新的维度的特征图,假设卷积块为64个,那么输出的特征图的维度为(1,64,255,255)。
    (2)在以往的网络中,我们仅仅是对网络通过深度学习的方法来优化参数的值,这Se-net中我们引入了通道注意力机制这是因为64个通道代表了图像不同的特征分布,引入注意力机制我们可以给不同通道不同的权重,以便于该通道在后续的计算中占据更重要的成分,这样有助于我们更好的捕捉不同区域的特征。
    所以这里我们首先需要抽象提取出每一个通道的整体特征参数,这里根据论文的测试,选用的全局平均池化,它将维度从(1,64,255,255)可以变化为(1,64,1,1)然后通过全连接->激活->全连接->sigmoid的连接获得每一个通道的权重参数。这里用sigmoid也是根据测试得出来的。然后在用简单的乘法对原数据进行权重增减。这样就获得了一个新的特征图,它在理论上能够更好的表达的图片的特征。

(二)Se-net网络代码实现
    以下只给出一个网络本身的定义,代码还是很好理解的,在 super里定义清楚每一层的输入输出量就可以了,这里指的注意的是他有一个reduction量,他是用来调节线性层负责度的参数,在综合性能和复杂度的基础上选择16作为默认值。

class SELayer(nn.Module):
    def __init__(self, channel, reduction=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)

(三)Se-net+Resnet
    左图是ResNet结构,右图是ResNet和Se-net联合的网络,可以看到添加的部分就是Se-net的核心。
在这里插入图片描述

    这里也就是在基础的Resnet中添加了Se-net模块,这里这个模块应该添加在哪里在论文中也是做了比较的,给的代码只是一个参考位置。

self.conv1 = nn.Conv2d(mid_channels, mid_channels, 3, 1, 1, bias=True)
self.conv2 = nn.Conv2d(mid_channels, mid_channels, 3, 1, 1, bias=True)
self.avd_layer = nn.AvgPool2d(3, 1, padding=1)
self.relu = nn.ReLU(inplace=True)
self.se = SELayer(64, 16)

residual = x
out = self.conv1(x)
out = self.relu(out)
out = self.conv2(out)
out = self.se(out)

out += residual
out = self.relu(out)

return out

(四)SK-net的原理和思路
    省略掉过程其实SK-net和Se-net的思路是有贴近的地方的,它们都是输入一个图片特征,通过一定处理使得卷积后的图片特征的每个通道的权重不一样。Se-net是根据注意力机制,学习到了不同的权重,而SK-net是根据自适应卷积的方式来挑选和融合出不同的卷积,也就是每一个通道都可以选择最适合自己的卷积块(以及使用不同的感受野来获取图像特征)。
在这里插入图片描述
SK-net的整个流程如下:
(1)Split划分
    首先使用不同的卷积核获得两个不同的特征图。
(2)Fuse融合
    融合两个不同的特征图,然后将它们通过全局平均池化的方式提取出每一个通道的融合值。再通过线性层进行通过压缩,这里和Se-net的通道注意力是一样的。
(3)Select选择
    在通过一个Softmax层进行选择,后续的操作和Se-net是一样的,得到通过挑选的特征图。这里的特征图可以看到每一个通道所使用的卷积核是不一样的,也是通过学习得到的。

(五)SK-net网络代码实现
    在网络里主要有①获得不同的卷积块②全局平均池化层③线性层④softmax层。所以在super函数里主要就是对这几个部分进行初始化。同时因为卷积块可以有多个不只有两个,线性层的压缩量等参数都可以自己设定,所以也需要初始化。这里的d就是线性层压缩后的通道数量,M是采用的卷积块个数,首先要初始化卷积不同的卷积块,再定义全局平均池化,再定义几个线性层和softmax函数,注意每一层的输入输出值。

d = max(in_channels//r, L)
self.M = M
self.out_channels = out_channels
self.conv = nn.ModuleList()
for i in range(M):
    self.conv.append(nn.Sequential(nn.Conv2d(in_channels, out_channels, 3, stride, padding=1+i, dilation=1+i, groups=32, bias=False),
                                   nn.BatchNorm2d(out_channels),
                                   nn.ReLU(inplace=True)))
self.global_pool = nn.AdaptiveAvgPool2d(output_size=1)
self.fc1 = nn.Sequential(nn.Conv2d(out_channels, d, 1, bias=False),
                           nn.BatchNorm2d(d),
                           nn.ReLU(inplace=True))
self.fc2 = nn.Conv2d(d, out_channels*M, 1, 1, bias=False)
self.softmax = nn.Softmax(dim=1)

    在前馈函数里,首先需要执行split的过程,使用reduce将对初始特征图采用不同卷积块卷积后的特征图进行相加。然后全局池化,之后进行两个线性层,再通过softmax,后续操作和Se-net相同,注意一下每一层的参数,和怎么进行拼贴等问题就行了。

def forward(self, input):
    batch_size = input.size(0)
    output = []

    for i, conv in enumerate(self.conv):
        output.append(conv(input))
    U = reduce(lambda x, y:x+y, output)

    s = self.global_pool(U)
    z = self.fc1(s)
    a_b = self.fc2(z)
    a_b = a_b.reshape(batch_size,self.M,self.out_channels,-1)
    a_b = self.softmax(a_b)

    a_b = list(a_b.chunk(self.M,dim=1))
    a_b = list(map(lambda x:x.reshape(batch_size,self.out_channels,1,1),a_b))
    V = list(map(lambda x,y:x*y,output,a_b))
    V = reduce(lambda x,y:x+y,V)
    return V

    SK-net网络和Se-net网络其实是一样的不能称作一个完整的网络,它可以是一个增加模块嵌入到一些网络中,SK-net也可以嵌入和Resnet中进行补强,嵌入和方法和Se-net类似。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/537842.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能Python-opencv_python打开摄像头

OpenCV Python打开摄像头:一种简单的图像处理方式 OpenCV是一种常用的图像处理库,可以用Python编程轻松进行图像和视频处理。其中,打开摄像头也是OpenCV中常用的一种方法。在这篇文章中,我们将介绍OpenCV Python打开摄像头的原理…

chatgpt赋能Python-numpy开根

NumPy开根 在科学计算中,开根运算是一个经常需要进行的操作,它非常有用,可以用来求解方程、计算距离或者简单地将数据压缩成更容易理解的形式等。NumPy是一个强大的库,被广泛地用于Python编程中,它提供了用于开根的特…

chatgpt赋能Python-mofan_python

Mofan Python:一个优秀的入门编程网站 介绍 Mofan Python 是一个致力于帮助人们快速入门 Python 编程的网站。该网站提供了各种编程资源,包括 Python 相关的教程、实例、项目,以及机器学习和深度学习课程等。它的特点在于提供了详细的代码解…

华为OD机试真题 Java 实现【投篮大赛】【2023Q1 100分】

一、题目描述 你现在是一场采用特殊赛制投篮大赛的记录员。 这场比赛由若于回合组成,过去几回合的得分可能会影响以后几回合的得分,比赛开始时,记录是空白的。 你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录…

FastDDS安全机制1 - 安全配置

背景 OMG组织对于DDS的安全机制有着对应的定义,其定义在DDS-SECURITY文档中。 这其中主要包含了对应的身份认证、访问控制、通信加密和审计相关的插件。 资料来源:DDS-SECURITY 其实也主要保护了通信过程中的相关安全风险。 资料来源:DDS-S…

轻松保护文档安全:三种实用的PDF加密方法

在我们的日常工作中,经常会使用到PDF格式的文件。为了保护版权和隐私,有时候我们需要对文档进行加密处理。那么,如何对PDF进行加密呢?今天我将为大家介绍几种方法,其中包括记灵在线工具、迅捷PDF编辑器和Speedpdf。 方…

Debian11之 RKE2 部署 K8S 集群

官方地址 资源列表 主机IP主机名称主机角色软件192.168.111.50server1主节点1API Server、controller-manager 和 scheduler192.168.111.51server2主节点2API Server、controller-manager 和 scheduler192.168.111.52server3主节点3API Server、controller-manager 和 schedu…

SocketTools crack所有安全连接的默认安全协议

SocketTools crack所有安全连接的默认安全协议 在所有HTTP客户端组件中添加了对HTTP/2.0协议的支持。 更新了TLS 1.2(及更高版本)和SSH 2.0的安全选项,以使用Microsoft Windows 11和Windows Server 2022中提供的密码套件。较旧、安全性较低的密码套件已被弃用&#…

JavaScript 基础 DOM (二)

事件流 事件流是对事件执行过程的描述 事件捕获 从DOM的根元素开始去执行对应的事件 (从外到里) 事件冒泡 当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒 泡 addEventListener 第3个参数决定了事件是在捕获阶…

(数据结构)栈的实现——再一次保姆级教学

目录 1. 栈 ​编辑 1.2 栈的实现 2. 代码的实现 2.1 初始化栈和销毁栈 2.2栈顶元素的插入 2.3栈顶元素的删除 栈元素删除 2.4栈顶元素的获取和栈元素的个数 1. 栈 1.1 栈的概念和结构 栈(Stack)是一种线性存储结构,它具有如下特点: &#xff0…

git的学习3

文章目录 一、git status 命令二、git diff 命令三、git commit 命令四、git reset 命令五、git rm 命令六、git mv 命令七、提交日志1、Git 查看提交历史2、git blame 总结 提交与修改部分 一、git status 命令 git status 命令用于查看在你上次提交之后是否有对文件进行再次…

jenkins集成sonarqube进行代码质量检测

Jenkins集成Sonar Qube实现代码扫描需要先下载整合插件 安装SonarQube scanner 插件,安装完后,插件展示如下 配置SonarQube 的配置信息 这里给名称取为:sonarqubeFirst, server Url设置为SonarQube的地址,为http:19…

类和对象【1】初识

全文目录 引言(初识面向对象)类和对象定义类访问限定及封装类定义的两种方式 类实例化与类对象大小this指针 总结 引言(初识面向对象) C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通…

如何使用Understand软件查看STM32单片机HAL库函数调用关系

在使用STM32单片机的HAL库函数编程时,会发现好多中断函数里面都有各种回调函数,还有好多函数的调用深度比较深,在编写代码的时候,有时候想查看某个函数是如何被调用的,查看起来非常麻烦。这时候就可以使用Understand软…

Android活动生命周期

GitHub:https://github.com/MADMAX110/Stopwatch 活动的生命不只是有创建和撤销,onCreate和onDestroy方法用来处理整个生命周期,除了这两个方法,另外还有一些处理活动可见性的生命周期方法。 具体来讲,有三个关键的生…

Flink学习——DataStream API

一个flink程序,其实就是对DataStream的各种转换。具体可以分成以下几个部分: 获取执行环境(Execution Environment)读取数据源(Source)定义基于数据的转换操作(Transformations)定义…

.net6 接收json数据 Controller http post

.net6 接收json数据 Controller http post 要添加这两个包 前端ajax请求 function tst() {$.ajax({type: "POST",contentType: "application/json",url: "/HelloWorld/Welcome",data: JSON.stringify({ "ID":1,"name": &…

Qt实现undo和redo功能--连续后退

刚开始想做这个的时候,我专门去找了Qt官方的测试例子,运行起来点了点,代码翻了翻。然后照猫画虎般的写了个测试例子。 不明白,为什么每个例子旁边会有个命令的显示列表,还巨丑的那种,这如果要放在别的程序…

DJ6-4 文件存储空间的管理

目录 6.4.1 空闲表 1、存储空间的分配与回收 2、空闲表法的优缺点 6.4.2 空闲链表 1、空闲盘块链 2、空闲盘区链 6.4.3 位示图 1、位示图的表示 2、存储空间的分配 3、存储空间的回收 4、位示图法的优缺点 6.4.4 成组链接 1、空闲盘块的组织 plus 个人理解图…

前端web入门-HTML-day01

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 HTML初体验 HTML 定义 标签语法 总结: HTML 基本骨架 基础知识: 总结&#…