Octave Convolution 八度卷积

本文介绍了Facebook提出的Octave Convolution(八度卷积),一种旨在减少计算量和显存占用的卷积方法。通过将特征图分为高频和低频部分,八度卷积在低频部分降低维度,同时保持高频信息。实验表明,这种方法在ResNet/ResNeXt系列网络中提高了性能,降低了计算复杂度,并且适用于不同类型的卷积操作。

Facebook在2019年时推出了一种新的卷积方法,叫做Octave Convolution,中文名是八度卷积。这个名字借鉴了音乐中高音低音的命名方法,来表示图像中高低频的数据。

图像和特征图的高低频表示

对于一张图片来说,低频的数据是比较平滑的部分,也就是图像的整体结构,高频的数据是那些细节的纹理,也就是边缘像素变化比较大的部分。如图1(a)所示。

图1. 图像和特征图的高低频表示
在这里插入图片描述

图1(a)中左图是一张企鹅的原始图片,中间是图片分离出来的低频的部分,也就是整体轮廓图,右图是图像的高频部分,也就是图片的边缘图(有点像素描)。

图1(b)是普通卷积特征图,通常情况下可以分成高频和低频两个部分。由于低频部分的特征基本上比较平滑,所以在特征图上其实不需要和高频一样的维度去表达图像的信息,如图1(c)所示,论文在低频的特征图上将宽高维度降了一半。

图1(d)表示高低频的特征信息的更新和交换,高低频的特征既有各自频率内的卷积操作,也有低频向高频和高频向低频的特征交换和融合,具体怎么操作下面会介绍。

八度卷积的操作

图2. 八度卷积的操作方式
在这里插入图片描述

八度卷积的具体操作方式如图2(a)所示。其中αin\alpha_{in}αinαout\alpha_{out}αout是输入和输出特征图的低频维度在总维度中的占比,在论文中一般假设αin=αout\alpha_{in}=\alpha_{out}αin=αout。图2(b)中间绿色的线表示高低频在各自频域内的卷积,卷积核分别是WH→HW^{H\rightarrow H}WHHWL→LW^{L\rightarrow L}W

### 八度卷积概述 八度卷积Octave Convolution, OctConv)是一种旨在降低计算成本并提高模型效率的卷积方法。它通过将特征图分为高分辨率和低分辨率两部分来减少冗余计算,从而优化资源利用[^4]。 具体来说,在传统的卷积神经网络中,每一层都会对整个输入图像进行密集的操作,这可能导致大量的重复计算以及不必要的内存消耗。而八度卷积则引入了一种分层次的方法:一部分数据保持较高的分辨率用于捕捉细节信息;另一部分被下采样到较低分辨率以提取更广泛的上下文信息。这种方法不仅能够有效减少运算次数,还能够在一定程度上维持甚至提升最终性能表现[^5]。 以下是关于八度卷积的具体概念及其算法实现: --- ### 八度卷积的核心原理 八度卷积的主要思想在于将输入张量拆分成高低频两个分支,并分别应用不同尺度上的卷积核对其进行处理后再重新组合起来形成输出结果。这样做的好处是可以让高频部分专注于局部区域内的精细结构变化检测,同时允许低频路径负责更大范围的空间模式识别任务,进而达到节省算力的目的[^6]。 #### 数学表达形式 假设 \( X_h \) 和 \( X_l \) 分别代表原始输入中的高频率子集与低频率子集,则经过一次标准八度变换后的对应输出可以表示如下: \[ Y_h = W_{hh} * D(X_h) + U(W_{lh} * A(X_l)) \] \[ Y_l = V(W_{hl} * P(X_h)) + W_{ll} * D(X_l) \] 其中, - \( W_{ij}, i,j\in{h,l}\): 表示连接各维度间关系权重矩阵; - \( D(\cdot)\),\(P(\cdot)\): 下/上取样的操作符; - \(U,V:\) 调整大小适配器函数。 上述公式清晰展示了如何通过跨级别交互完成端到端训练流程的同时保留足够的灵活性去适应多种应用场景需求[^7]。 --- ### Python 实现代码片段 下面提供了一个基于 PyTorch 的简单版本八度卷积层定义方式作为参考实例: ```python import torch.nn as nn from functools import partial class OctConv(nn.Module): def __init__(self, in_channels, out_channels, kernel_size=3, alpha_in=0.5, alpha_out=0.5, stride=1, padding=1): super(OctConv, self).__init__() self.alpha_in = alpha_in self.alpha_out = alpha_out hi_in_ch = int((1-alpha_in)*in_channels) lo_in_ch = in_channels - hi_in_ch hi_out_ch = int((1-alpha_out)*out_channels) lo_out_ch = out_channels - hi_out_ch self.h2h = None if hi_in_ch==0 or hi_out_ch==0 else \ nn.Conv2d(hi_in_ch, hi_out_ch, kernel_size, stride=stride, padding=padding) self.l2l = None if lo_in_ch==0 or lo_out_ch==0 else \ nn.Conv2d(lo_in_ch, lo_out_ch, kernel_size, stride=stride, padding=padding) self.h2l = None if hi_in_ch==0 or lo_out_ch==0 else \ nn.Sequential( nn.AvgPool2d(kernel_size=(2, 2), stride=2), nn.Conv2d(hi_in_ch, lo_out_ch, kernel_size, stride=stride, padding=padding)) self.l2h = None if lo_in_ch==0 or hi_out_ch==0 else \ nn.Sequential( nn.Upsample(scale_factor=2, mode='nearest'), nn.Conv2d(lo_in_ch, hi_out_ch, kernel_size, stride=stride, padding=padding)) def forward(self,x): x_h, x_l = x if isinstance(x,tuple) else (x,None) h2h = self.h2h(x_h) if self.h2h is not None and x_h is not None else None l2l = self.l2l(x_l) if self.l2l is not None and x_l is not None else None h2l = self.h2l(x_h) if self.h2l is not None and x_h is not None else None l2h = self.l2h(x_l) if self.l2h is not None and x_l is not None else None y_h = h2h.clone() if h2h is not None else 0. y_l = l2l.clone() if l2l is not None else 0. if l2h is not None: y_h += l2h if h2l is not None: y_l += h2l return ((y_h,y_l),(y_h,) )[self.alpha_out<1e-8 ] ``` 此段程序实现了基本功能框架下的前向传播逻辑描述[^8]。 --- ### 深度学习中的实际应用案例分析 在现代计算机视觉领域内,诸如目标检测、语义分割等复杂任务均可以从采用八度卷积技术获得显著收益。例如 MobileNetV3 中便融入了此类机制使得整体架构更加紧凑高效而不失精度优势[^9]。 此外,在视频理解方向也有不少研究探索将其应用于动作分类或者异常事件监测等方面取得不错效果。由于其天然具备多尺度特性因此非常适合用来建模长时间序列依赖关系等问题情境之中[^10]。 ---
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值