Octave Convolution学习笔记 (附代码)
论文地址:https://export.arxiv.org/pdf/1904.05049
代码地址:https://gitcode.com/mirrors/lxtgh/octaveconv_pytorch/overview?utm_source=csdn_github_accelerator
1.是什么?
OctaveNet网络属于paper《Drop an Octave: Reducing Spatial Redundancy in Convolutional Neural Networks with Octave Convolution》,是CVPR2019中的一篇论文。
Octave Convolution是一种用于卷积神经网络的新型卷积操作,旨在减少卷积神经网络中的空间冗余。它通过将输入特征图分成高频和低频两个部分,然后在这两个部分上执行不同的卷积操作,从而实现减少计算量和内存占用的目的。Octave Convolution的主要思想是将高频和低频特征图分开处理,以便更好地利用它们的特性。这种方法可以在不损失精度的情况下减少计算量和内存占用,从而提高卷积神经网络的效率。
2.为什么
从频域的角度理解图像
我们都知道,一副图像从空间域的角度看,它一般情况下是一个3 × W × H 3 \times W \times H3×W×H的矩阵,矩阵中每一个位置都有一个[0,255]的值,而从频域的角度出发的话,一副图像都可以被分解为描述平稳变化结构的低空间频率分量(低频域、low-frequency)和描述快速变化的精细细节的高空间频率分量(高频域、high-frequency),就像下面这幅图:
最左侧为原始图像,中间为低频的部分,它比较多的反应的是图像的整体信息,最右侧为高频部分,它更多的反应图像的细节信息,比如边缘。这就好比空间域下的梯度,图像中存在边缘的地方,往往就是梯度大的地方。
特征图的高频与低频表示
既然对于图像来说可以区分高频与低频,那么对于特征图也是这样,特征图无非就是一个channel更多的矩阵而已,但是对于一个端对端的CNN模型,总不能在网络中引入一种频域计算,所以Octave Convolution显示的定义了“下采样”操作后的特征图叫做“低频域”,而不做下采样的原始尺寸叫做“高频域”。这样一来由于下采样带来的特征图尺寸减小,从而使得Octave Convolution计算量降低,此外网络有了不同尺度的信息(两个频域),并且两个频域的信息会在卷积完成后聚合,这个特性使得Octave Convolution具有比之前更好的性能。“下采样”的scale,采用的是2的幂次,而目前文章只讨论了2 的1 次幂的情况,说白了就是特征图的长宽都缩小了2,就像下面这张图:

图(b)是一个原始的特征图,并人为的切分特征图为Low Frequency和High Frequency,切分的标准是0.25,0.5,0.75三个系数,比如一个channel=64的特征图,系数为0.5的情况下,那么32个通道为低频,另外32个为高频。图©是用下采样操作实现低频域,就是上面说到缩小2倍。图(d)想要说明这个低频和高频要通过卷积做update,然后还有聚合交换的部分,反正只看(d)是看不出来,后面再具体介绍。
在这里不得不吐槽一点,论文由图像引出了高频和低频,但是到了卷积的地方直接过渡到了“下采样”,此后low-frequency和high-frequency还一直贯穿全文,这给人一种写论文写的过劲的感觉,毕竟Low Frequency、High Frequency和Octave 要比upsample和subsample好听,但是其实就是下采样完了上采样,尤其是我们要去实现它的时候。
3.怎么样?
3.1网络结构图
一个特征图的通道数根据预设系数
切分为高频
与低频
的部分,低频部分的宽高都缩小为原来的一半。然后Octave Convolution会做下面四个部分
(1)高频部分直接卷积:,即高频到高频的卷积,输出通道数
(2)高频部分先做下采样再卷积,这里的下采样是,然后
,即高频到低频的卷积,输出通道数
(3)低频部分直接卷积后做上采样:,这里的 upsample
所用的上采样方法我们后面再说,即低频到高频的卷积,输出通道数
(4)低频部分直接卷积:,即低频到低频的卷积,输出通道数
这四个部分完成之后,接下来就要做信息的聚合,也就是(1)和(3)的结果做一个对应位置的按位加操作,(2)和(4)的结果做一个对应位置的按位加操作。
这样Octave Convolution就完成了,它其实在做的就是把原来的一个卷积操作,拆成了4个,而这4个中有三个处理的输入都是原来特征图w,h的一半,所以计算量就下来了。
3.2代码实现
class OctaveConv(nn.Module):def __init__(self, in_channels, out_channels, kernel_size, alpha_in=0.5, alpha_out=0.5, stride=1, padding=1, dilation=1,groups=1, bias=False, up_kwargs = up_kwargs):super(OctaveConv, self).__init__()self.weights = nn.Parameter(torch.Tensor(out_channels, in_channels, kernel_size[0], kernel_size[1]))self.stride = strideself.padding = paddingself.dilation = dilationself.groups = groupsif bias:self.bias = nn.Parameter(torch.Tensor(out_channels))else:self.bias = torch.zeros(out_channels).cuda()self.up_kwargs = up_kwargsself.h2g_pool = nn.AvgPool2d(kernel_size=(2,2), stride=2)self.in_channels = in_channelsself.out_channels = out_channelsself.alpha_in = alpha_inself.alpha_out = alpha_outdef forward(self, x):X_h, X_l = xif self.stride ==2:X_h, X_l = self.h2g_pool(X_h), self.h2g_pool(X_l)X_h2l = self.h2g_pool(X_h)end_h_x = int(self.in_channels*(1- self.alpha_in))end_h_y = int(self.out_channels*(1- self.alpha_out))X_h2h = F.conv2d(X_h, self.weights[0:end_h_y, 0:end_h_x, :,:], self.bias[0:end_h_y], 1,self.padding, self.dilation, self.groups)X_l2l = F.conv2d(X_l, self.weights[end_h_y:, end_h_x:, :,:], self.bias[end_h_y:], 1,self.padding, self.dilation, self.groups)X_h2l = F.conv2d(X_h2l, self.weights[end_h_y:, 0: end_h_x, :,:], self.bias[end_h_y:], 1,self.padding, self.dilation, self.groups)X_l2h = F.conv2d(X_l, self.weights[0:end_h_y, end_h_x:, :,:], self.bias[0:end_h_y], 1,self.padding, self.dilation, self.groups)X_l2h = F.upsample(X_l2h, scale_factor=2, **self.up_kwargs)X_h = X_h2h + X_l2hX_l = X_l2l + X_h2lreturn X_h, X_l
参考:
Octave Convolution 代码详解
『深度概念』一文读懂Octave Convolution(OctConv)八度卷积
Octave Convolution原理与Caffe实现
相关文章:
Octave Convolution学习笔记 (附代码)
论文地址:https://export.arxiv.org/pdf/1904.05049 代码地址:https://gitcode.com/mirrors/lxtgh/octaveconv_pytorch/overview?utm_sourcecsdn_github_accelerator 1.是什么? OctaveNet网络属于paper《Drop an Octave: Reducing Spatia…...
SpringSecurity 认证实战
一. 项目数据准备 1.1 添加依赖 <dependencies><!--spring security--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!--web起步依赖-…...
echarts中横向柱状图的数字在条纹上方
实现效果: 数字在条纹的上方 实现方法:这些数字是用新添加一个坐标轴来实现的 直接添加坐标轴数字显示是在条纹的正右边 所以需要配置一下偏移 完整代码 var option {grid: {left: "3%",right: "4%",bottom: "3%",cont…...
【仙逆】尸阴宗始祖现身,王林修得黄泉生窍诀,阿呆惊险逃生
【侵权联系删除】【文/郑尔巴金】 深度爆料最新集,王林终于成功筑基,这一集的《仙逆》动漫真是让人热血沸腾啊!在这个阶段,王林展现出了他的决心和毅力,成功地击杀了藤厉,并采取了夺基大法,从藤…...
C++二叉树剪枝
文章目录 C二叉树剪枝题目链接题目描述解题思路代码复杂度分析 C二叉树剪枝 题目链接 LCR 047. 二叉树剪枝 - 力扣(LeetCode) 题目描述 给定一个二叉树 根节点 root ,树的每个节点的值要么是 0,要么是 1。请剪除该二叉树中所有节…...
ZooKeeper中节点的操作命令(查看、创建、删除节点)
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...
el-table多选表格 实现默认选中 删除选中列表取消勾选等联动效果
实现效果如下: 代码如下: <template><div><el-tableref"multipleTable":data"tableData"tooltip-effect"dark"style"width: 100%"selection-change"handleSelectionChange"><…...
预安装win11的电脑怎么退回正版win10?
对于新购的笔记本 通常来讲预装的系统是全新安装的,是没有之前Windows10系统文件的,无法回退。 可以打开设置-----系统----恢复-----看下是否有该选项。 ------------------------------------------------------------------------------- 若是在上述…...
MATLAB——多层小波的重构
%% 学习目标:多层小波的重构 %% 程序1 clear all; close all; load noissin.mat; xnoissin; [C,L]wavedec(x,3,db1); %小波多层分解 ywaverec(C,L,db1); %重构,必须小波类型一致 emax(abs(x-y)) %重构的误差 %% 程序2 clear all;…...
解锁高效创作艺术!AI助力文章生成与精美插图搭配完美融合
在当今这个信息爆炸的时代,高效创作文章已经成为了一种必备的技能。然而,创作一篇高质量的文章并插入精美插图,往往需要耗费大量的时间和精力。现在,随着AI技术的发展,我们迎来了一个全新的文章创作时代——利用AI高效…...
✔ ★【备战实习(面经+项目+算法)】 10.29学习
✔ ★【备战实习(面经项目算法)】 坚持完成每天必做如何找到好工作1. 科学的学习方法(专注!效率!记忆!心流!)2. 每天认真完成必做项,踏实学习技术 认真完成每天必做&…...
微服务-Ribbon负载均衡
文章目录 负载均衡原理流程原理源码分析负载均衡流程 负载均衡策略饥饿加载总结 负载均衡原理 流程 原理 LoadBalanced 标记RestTemplate发起的http请求要被Ribbon进行拦截和处理 源码分析 ctrlshiftN搜索LoadBalancerInterceptor,进入。发现实现了ClientHttpRequ…...
UC3845BD1R2G一款专门针对离线和 DC-DC 转换器应用 高性能电流模式PWM控制器
UC3845BD1R2G为高性能固定频率电流模式控制器。专门针对离线和 DC-DC 转换器应用而设计,提供了外部部件极少的成本高效方案。这些集成电路具有振荡器、温度补偿参考、高增益误差放大器、电流传感比较器和高电流图腾柱输出,适用于驱动功率 MOSFET。还包括…...
vivo自研AI大模型即将问世,智能手机行业加速迈向AI时代
当前,以大模型为代表的人工智能技术已发展为新一轮科技革命和产业变革的重要驱动力量,被视作推动经济社会发展的关键增长极。 AI大模型潮起,千行百业走向百舸争流的AI创新应用期,前沿信息技术向手机、PC、车机等消费级终端加速渗…...
探索JavaScript事件流:DOM中的神奇旅程
🎬 江城开朗的豌豆:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想,就是为了理想的生活 ! 目录 引言 1. 事件流的发展流程 1.1 传统的DOM0级事件 1.2 DOM2级事件和addEventListener方法 1.3 W3C DOM3级…...
听GPT 讲Rust源代码--library/std(8)
题图来自Why is Rust programming language so popular?[1] File: rust/library/std/src/sys/sgx/abi/reloc.rs 在Rust源代码中,sgx/abi/reloc.rs文件的作用是定义了针对Intel Software Guard Extensions (SGX)的重定位相关结构和函数。 该文件中的Rela 结构定义了…...
Hbase基本使用,读写原理,性能优化学习
文章目录 HBase简介HBase定义HBase数据模型**HBase** **逻辑结构****HBase** **物理存储结构****HBase** **基本架构** HBase 入门**HBase** **安装部署****HBase** 配置文件**HBase** 启动停止**HBase** **访问页面****HBase** **高可用****HBase Shell****HBase API**HBaseCo…...
添加主仓库后报错error: remote upstream already exists.
可能的原因 远程名 upstream 已经被使用: 这通常意味着你在之前已经添加了一个名为 upstream 的远程仓库。 解决方案 检查现有的远程仓库: 运行 git remote -v 来查看所有配置的远程仓库。这个命令会列出所有远程仓库的URL,你可以检查是否已…...
香港服务器如何做负载均衡?
在现代互联网时代,随着网站访问量的不断增加,服务器的负载也越来越重。为了提高网站的性能和可用性,负载均衡成为了一种常见的解决方案。 什么是负载均衡? 负载均衡是一种技术解决方案,用于在多个服务器之间分配负载&#…...
前端 :用HTML , CSS ,JS 做一个秒表
1.HTML: <body><div id "content"><div id "top"><div id"time">00:00:000</div></div><div id "bottom"><div id "btn_start">开始</div><div …...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
