当前位置: 首页 > news >正文

SCNet:自校正卷积网络(附代码)

论文地址:https://mftp.mmcheng.net/Papers/20cvprSCNet.pdf

代码地址:https://github.com/MCG-NKU/SCNet

1.是什么?

SCNet是一种卷积神经网络,它使用自校准卷积(Self-Calibrated Convolutions)来增强子任务之间的关系,包括分类、检测和分割。不同于标准卷积采用小尺寸核同时融合空域与通道信息,所设计的SCConv可以通过自矫正操作自适应构建long-range空域与通道间相关性。SCConv的这种特性可以帮助CNN生成更具判别能力的特征表达,因其具有更丰富的信息。作者所设计的SCConv极为简单且通用,可以轻易嵌入到现有CNN架构中,而不会导致参数量增加与计算复杂度提升。

2.为什么?

传统卷积:存在输入x,卷积核k,输出z,则传统卷积操作的公式:

存在的问题;提取到的特征图没有很强的区分性
1. 每个输出的特征图都是通过所有通道求和来计算的,所有的特征图都是通过重复同一公式得到。
2. 每个空间位置的感受野主要由预定义的卷积核大小控制。

所提出了一种由多个卷积注意力组合的自校准模块,用于替换基本的卷积结构,在不增加额外参数和计算量的情况下,该模块能够产生全局的感受野。相比于标准卷积,该模块产生的特征图更具有区分度。
该模块的优势所在:
1、传统卷积只能对小区域进行卷积操作,而自校准卷积模块使每个空间位置可以自适应的编码来自长范围区域的相关信息。
2、自校准卷积是普遍适用的,能够轻易地应用到标准的卷积层中,而不需要引入任何参数和复杂的头部或改变超参数。
 

3.怎么样:

3.1 SCONV网络结构

自校正卷积具体步骤如上图所示:

第一步,输入特征图X为C X H X W大小,拆分为两个C/2 X H X W大小的X1,X2;

第二步,卷积核K的维度为C X C X H X W,将K分为4个部分,每份的作用各不相同,分别记为K1,K2,K3,K4,其维度均为C/2 X C/2 X H X W;

为了有效地收集每个空间位置的丰富的上下文信息,作者提出在两个不同的尺度空间中进行卷积特征转换:原始尺度空间中的特征图(输入共享相同的分辨率)和下采样后的具有较小分辨率的潜在空间(用于自校正) 。利用下采样后特征具有较大的感受野,因此在较小的潜在空间中进行变换后的嵌入将用作参考,以指导原始特征空间中的特征变换过程。

第三步,对自校正尺度空间进行处理(Self-Calibration)

 对T使用卷积核组K_{2}进行特征变换︰

其中Up(⋅)表示线性插值操作,得到中间参考量从小尺度空间到原始特征空间的映射,则自校准操作可以表示为:
 

 其中F_{3}(X_{1})=X_{1}*K_{3},σ表示sigmoid函数,符号“.”表示逐元素乘运算,X’被用作残差项,建立权重,用于自校准。自校准后的最终输出可以写作:
 

3.2 代码实现

 自校正卷积SCConv

class SCConv(nn.Module):def __init__(self, inplanes, planes, stride, padding, dilation, groups, pooling_r, norm_layer):super(SCConv, self).__init__()# k2(Self-Calibration上半分支):先下采样,再通过卷积K2self.k2 = nn.Sequential(nn.AvgPool2d(kernel_size=pooling_r, stride=pooling_r), nn.Conv2d(inplanes, planes, kernel_size=3, stride=1,padding=padding, dilation=dilation,groups=groups, bias=False),norm_layer(planes),)# k3(Self-Calibration下半分支):通过卷积K3self.k3 = nn.Sequential(nn.Conv2d(inplanes, planes, kernel_size=3, stride=1,padding=padding, dilation=dilation,groups=groups, bias=False),norm_layer(planes),)# k4(Self-Calibration下半分支):通过卷积K4self.k4 = nn.Sequential(nn.Conv2d(inplanes, planes, kernel_size=3, stride=stride,padding=padding, dilation=dilation,groups=groups, bias=False),norm_layer(planes),)def forward(self, x):identity = x# Self-Calibration上半分支:输入特征x通过k2后,上采样到和输入特征的大小一样,再与输入特征进行残差连接,再通过sigmoid函数out = torch.sigmoid(torch.add(identity, F.interpolate(self.k2(x), identity.size()[2:]))) # sigmoid(identity + k2)# Self-Calibration下半分支:输入特征x通过k3后,与Self-Calibration上半分支输出进行矩阵乘法out = torch.mul(self.k3(x), out) # k3 * sigmoid(identity + k2)# 最后,将输出out通过k4out = self.k4(out) # k4return out

将自校正卷积融入到BottleNeck模块中:SCBottleNeck

class SCBottleneck(nn.Module):"""SCNet SCBottleneck将SCConv放入BottleNeck中"""expansion = 4# 平均池化的下采样率为4pooling_r = 4 # down-sampling rate of the avg pooling layer in the K3 path of SC-Conv.def __init__(self, inplanes, planes, stride=1, downsample=None,cardinality=1, bottleneck_width=32,avd=False, dilation=1, is_first=False,norm_layer=None):super(SCBottleneck, self).__init__()group_width = int(planes * (bottleneck_width / 64.)) * cardinality # int(planes * (32 /64)) * 1 = int(0.5 * planes)self.conv1_a = nn.Conv2d(inplanes, group_width, kernel_size=1, bias=False)self.bn1_a = norm_layer(group_width)self.conv1_b = nn.Conv2d(inplanes, group_width, kernel_size=1, bias=False)self.bn1_b = norm_layer(group_width)self.avd = avd and (stride > 1 or is_first)if self.avd:self.avd_layer = nn.AvgPool2d(3, stride, padding=1)stride = 1# k1:通过卷积K1self.k1 = nn.Sequential(nn.Conv2d(group_width, group_width, kernel_size=3, stride=stride,padding=dilation, dilation=dilation,groups=cardinality, bias=False),norm_layer(group_width),)self.scconv = SCConv(group_width, group_width, stride=stride,padding=dilation, dilation=dilation,groups=cardinality, pooling_r=self.pooling_r, norm_layer=norm_layer)self.conv3 = nn.Conv2d(group_width * 2, planes * 4, kernel_size=1, bias=False)self.bn3 = norm_layer(planes*4)self.relu = nn.ReLU(inplace=True)self.downsample = downsampleself.dilation = dilationself.stride = stridedef forward(self, x):residual = x# 通过卷积分别得到两个通道数为输入特征通道数一半的特征out_a和out_bout_a = self.conv1_a(x)out_a = self.bn1_a(out_a)out_b = self.conv1_b(x)out_b = self.bn1_b(out_b)out_a = self.relu(out_a)out_b = self.relu(out_b)# out_a通过k1,out_b通过scconvout_a = self.k1(out_a)out_b = self.scconv(out_b)out_a = self.relu(out_a)out_b = self.relu(out_b)if self.avd:out_a = self.avd_layer(out_a)out_b = self.avd_layer(out_b)# 沿着dim=1(channel)进行拼接,再通过conv3out = self.conv3(torch.cat([out_a, out_b], dim=1))out = self.bn3(out)if self.downsample is not None:residual = self.downsample(x)# 对输出out进行残差连接out += residualout = self.relu(out)return out

参考:南开大学程明明团队新作 | ResNet的又一改进:SCNet

2D关键点检测之SCNet:Improving Convolutional Networks with Self-Calibrated Convolutions

相关文章:

SCNet:自校正卷积网络(附代码)

论文地址:https://mftp.mmcheng.net/Papers/20cvprSCNet.pdf 代码地址:https://github.com/MCG-NKU/SCNet 1.是什么? SCNet是一种卷积神经网络,它使用自校准卷积(Self-Calibrated Convolutions)来增强子…...

【PG】PostgreSQL客户端认证pg_hba.conf文件

目录 文件格式 连接类型(TYPE) 数据库(database) 用户(user) 连接地址(address) 格式 IPv4 IPv6 字符 主机名 主机名后缀 IP-address/IP-mask auth-method trust reject scram-sha-256 md5 password gss sspi …...

信创优选,国产开源。Solon v2.5.11 发布

Solon 是什么框架? Java 生态级应用开发框架。从零开始构建,有自己的标准规范与开放生态(历时五年,具备全球第二级别的生态规模)。与其他框架相比,解决了两个重要的痛点:启动慢,费内…...

180.188.16.1网站高并发,导致网站卡了,有什么方案处理?

处理网站高并发需要考虑多方面的因素,以下是一些解决方法: 增加服务器硬件:增加服务器内存、CPU、带宽等硬件资源,以提高服务器的处理能力,从而增强网站处理请求的能力。 使用CDN:将网站的静态资源&#x…...

P1077 [NOIP2012 普及组] 摆花 题解

文章目录 题目描述输入格式输出格式样例样例输入样例输出 数据范围与提示思路与部分实现完整代码 题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共 m m m 盆。通过调查顾客的喜好,小明列出了顾客最喜欢的…...

kubernetes源码阅读与实战(3)

kubernetes源码二次开发系列 1、k8s二次开发之kubernetes开发概念 2、k8s二次开发之自定义的example展示 3、k8s二次开发之如何扩展kubernetes系统 4、k8s二次开发之kubernetes控制器的控制循环 5、k8s二次开发之kubernetes控制器的watch事件及event对象 6、k8s二次开发之…...

ESP8266模块常规调试过程讲解

ESP8266-WIFI模块串口调试过程讲解 一、ESP8266介绍 ESP8266是一个高度集成的无线SoC(System on a Chip)模块,基于ESP8266芯片,集成了Wi-Fi功能。具有丰富的特性和功能,广泛应用于各种物联网项目中。 ESP8266模块支持802.11b/g/n无线标准,内置TCP/IP协议栈,可以实现串…...

使用onnxruntime推理Bert模型

Bert模型类别:onnx 输入输出数据格式:.npz import onnxruntime import numpy as np import os# 加载 ONNX 模型 ort_session onnxruntime.InferenceSession(bert-base-uncased_final.onnx)# 指定输入文件夹和输出文件夹 input_folder output_folder …...

SQL group by、where和having语句用法

SQL 语句中的 GROUP BY 子句用于将具有相同值的行分组在一起,通常与聚合函数(如 COUNT、SUM、AVG 等)一起使用。WHERE 子句用于筛选符合条件的行。HAVING 子句则在分组后对分组结果进行进一步筛选。 以下是一个使用 SQL 语句中的 GROUP BY、W…...

贝叶斯变分方法:初学者指南--平均场近似

Eric Jang: A Beginners Guide to Variational Methods: Mean-Field Approximation (evjang.com) 一、说明 变分贝叶斯 (VB) 方法是统计机器学习中非常流行的一系列技术。VB 方法允许我们将 统计推断 问题(即,给定另一个随机变量的值来推断随机变量的值&…...

Node学习笔记之user用户API模块

1、获取用户的基本信息 步骤 获取登录会话存储的session中用户的id判断是否获取到id根据用户id查询数据库中的个人信息检查指定 id 的用户是否存在将密码设置为空将数据返回给前端 // 获取用户信息数据 exports.userinfo (req, res) > {(async function () {// 1. 获取…...

智慧公厕:为公众提供全新的公共厕所使用体验

智慧公厕管理系统通过智能化技术的应用,为公众提供了全新的公厕使用体验。不仅仅是一个普通的提供“方便”的公共设施,智慧公厕更融合了精准环境监测、厕位占用监测、设备状态实时监控等功能,同时还提供了自动化清洁、灯光照明、除臭杀菌消毒…...

共谈信创谋发展 | 开源网安主办的信创生态构建沙龙圆满完成

​10月26日,由珠海市工业和信息化局、珠海市高新区科技创新和产业发展局指导,珠海华发产业园与开源网安珠海公司等联合主办的“赋能数字转型 提速国产替代”—Uni-Idea信创生态构建沙龙在华发信创产业园成功举办,近百位行业代表参加本次活动&…...

第四章认识Node.js模块化开发

Node.js系统模块 续上一篇文章第三章认识Node.js模块化开发-CSDN博客,这次继续来认识和总结以下node的常用模块开发 Node.js系统模块是指Node.js自带的一些模块,这些模块可以直接在Node.js中使用,无需安装其他包。以下是常用的Node.js系统模块…...

Widget必须在GUI线程中创建

背景:miniblink的vip版本,下载功能是独立线程,我希望在下载后弹出窗口,就在其中创建了QWidget子类对象。然后出现了上面的错误。 解决方法: 使用信号和槽来处理。 具体来讲,在独立线程中创建QObject子类…...

Kubernetes概念及实践

Kubernetes(K8S)中文文档_Kubernetes中文社区 Kubernetes 文档 | Kubernetes K8S 是负责自动化运维管理多个跨机器 Docker 程序的 集群。 kubeadm快速部署K8s集群的工具,如: 创建master node:kubeadm init 将worker node加入到集群中&#x…...

洛谷 B2007 A+B问题 C++代码

目录 题目描述 AC Code 题目描述 AC Code #include<bits/stdc.h> using namespace std; typedef long long ll; int main() { int a,b;cin>>a>>b;cout<<ab<<endl;return 0; }...

Git基础 | 原理、配置、用法、分支 合并

目录 1 git初步了解 1.1 git的安装 1.2 git原理模型 1.3 git基础配置 1.4 git基础用法 1 将文件加入暂存区 2 查看当前的git仓库状态 3 删除文件 4 commit 将暂存区文件加入本地git版本仓库 5 查看提交历史 更改 2 分支 2.1 创建分支 2.2 查看分支 2.3 切换分支 …...

刀具磨损状态识别(Python代码,MSCNN_LSTM_Attention模型,初期磨损、正常磨损和急剧磨损分类,解压缩直接运行)

1.运行效果&#xff1a;刀具磨损状态识别&#xff08;Python代码&#xff0c;MSCNN_LSTM_Attention模型&#xff0c;初期磨损、正常磨损和急剧磨损&#xff09;_哔哩哔哩_bilibili 环境库&#xff1a; NumPy 版本: 1.19.4 Pandas 版本: 0.23.4 Matplotlib 版本: 2.2.3 Keras …...

web:[网鼎杯 2020 青龙组]AreUSerialz

题目 点进题目发现 需要进行代码审计 function __destruct() {if($this->op "2")$this->op "1";$this->content "";$this->process();}这里有__destruct()函数&#xff0c;在对象销毁时自动调用&#xff0c;根据$op属性的值进行…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

门静脉高压——表现

一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构&#xff1a;由肠系膜上静脉和脾静脉汇合构成&#xff0c;是肝脏血液供应的主要来源。淤血后果&#xff1a;门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血&#xff0c;引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...

React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?

系列回顾&#xff1a; 在上一篇《React核心概念&#xff1a;State是什么&#xff1f;》中&#xff0c;我们学习了如何使用useState让一个组件拥有自己的内部数据&#xff08;State&#xff09;&#xff0c;并通过一个计数器案例&#xff0c;实现了组件的自我更新。这很棒&#…...

深度解析云存储:概念、架构与应用实践

在数据爆炸式增长的时代&#xff0c;传统本地存储因容量限制、管理复杂等问题&#xff0c;已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性&#xff0c;成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理&#xff0c;云存储正重塑数据存储与…...

背包问题双雄:01 背包与完全背包详解(Java 实现)

一、背包问题概述 背包问题是动态规划领域的经典问题&#xff0c;其核心在于如何在有限容量的背包中选择物品&#xff0c;使得总价值最大化。根据物品选择规则的不同&#xff0c;主要分为两类&#xff1a; 01 背包&#xff1a;每件物品最多选 1 次&#xff08;选或不选&#…...