【即插即用模块】注意力篇 | AAAI 2025 | HFP:能涨2个点!双路DCT高通滤波+注意力,又轻又准!
这篇文章介绍了一种名为HS-FPN的模块,专门用于增强微小物体检测性能。该模块的核心是高频感知(HFP)组件,通过离散余弦变换(DCT)在频率域提取高频信息,强化小目标的边缘和纹理特征。HFP采用双路径设计:空间路径生成高频响应掩码,突出目标区域;通道路径利用自适应池化和分组卷积生成通道权重,放大关键特征。实验表明,该模块能显著提升小目标检测精度,特征可视化显示其有效增强了微小物体的特征表达。模块
VX: shixiaodayyds,备注【即插即用】,添加即插即用模块交流群。
模块出处

Paper:HS-FPN: High Frequency and Spatial Perception FPN for Tiny Object Detection
Code:https://github.com/ShiZican/HS-FPN
模块介绍
High Frequency Perception(HFP):通过高通滤波器生成高频响应。这些高频响应被用作空间和通道视角的掩码权重,以丰富和突出原始特征图中微小物体的特征。
HFP设计思路:高频生成→双路径注意力→特征融合。
- 输入特征图先经过DCT 离散余弦变换转换到频率域,再通过高通滤波器(权重矩阵)屏蔽左上角低频区域(对应图像中均匀背景),保留高频区域(对应小目标的边缘、纹理等细节),最后通过逆 DCT 变换将高频信息转回空间域,得到高频响应图。
- 将高频响应图作为空间掩码,与原始特征图逐像素相乘,强化小目标所在空间区域的特征,抑制背景干扰。对高频响应图做自适应池化(最大 + 平均),提取通道级统计信息,通过分组卷积生成通道权重,与原始特征图逐通道相乘,放大包含小目标信息的通道特征。
- 空间路径与通道路径的输出特征相加,再经过 3×3 卷积和分组归一化,消除冗余信息并稳定特征分布,最终输出增强后的小目标特征图(维度与输入一致,确保可插入现有 FPN 结构)。
HS-FPN:
模块提出的动机(Motivation)
特征金字塔网络(FPN)的引入显着提高了目标检测性能。然而,在检测微小物体方面仍然存在重大挑战,因为它们的特征只占特征图的一小部分。虽然 FPN 集成了多尺度特征,但它并没有直接增强或丰富微小物体的特征。此外,FPN缺乏空间感知能力。为了解决这些问题,提出HFP。

适用范围与模块效果
适用范围:最适合小目标检测相关任务,以及其他需要高频信息增强的场景。
缝合位置:放在需要特征增强的位置。
模块效果:HFP以及各组件消融,使用HFP明显涨点(第一行和第四行对比)
HFP前后的特征映射可视化:

模块代码及使用方式
模块代码(详细注释与特征流前向传播过程中的维度变化):
import torch
import torch.nn as nn
import torch_dct as DCT
import torch.nn.functional as F
from mmcv.cnn import ConvModule
from mmcv.runner import BaseModule
# ------------------------------------------------------------------#
# Spatial Path of HFP
# Only p1&p2 use dct to extract high_frequency response
# ------------------------------------------------------------------#
class DctSpatialInteraction(BaseModule):
def __init__(self,
in_channels,
ratio,
isdct=True, # 核心开关:True(P1/P2层,用DCT提高频);False(P3/P4层,用1×1卷积)
init_cfg=dict(type='Xavier', layer='Conv2d', distribution='uniform')):
super().__init__(init_cfg)
self.ratio = ratio # 高通滤波比例,控制低频抑制范围(如(0.25,0.25)表示屏蔽左上角25%低频区域)
self.isdct = isdct
# 非DCT模式下,用1×1卷积生成空间注意力(适配高分辨率层,降低计算量)
if not self.isdct:
self.spatial1x1 = nn.Sequential(
*[ConvModule(in_channels, 1, kernel_size=1, bias=False)] # 输出1通道空间掩码
)
def forward(self, x):
_, _, h0, w0 = x.size() # x: 输入特征图 (batch, channels, height, width)
# 非DCT模式:直接用1×1卷积生成空间掩码,通过sigmoid归一化权重
if not self.isdct:
return x * torch.sigmoid(self.spatial1x1(x)) # 特征×空间权重,增强目标区域
# DCT模式:从频率域提取高频信息(核心逻辑)
idct = DCT.dct_2d(x, norm='ortho') # 1. 对输入特征做2D离散余弦变换,转换到频率域
# 2. 生成高通滤波权重:左上角(低频区)设为0,其余(高频区)设为1
weight = self._compute_weight(h0, w0, self.ratio).to(x.device)
weight = weight.view(1, h0, w0).expand_as(idct) # 适配特征图维度,批量应用权重
dct = idct * weight # 3. 滤波:屏蔽低频(背景),保留高频(小目标边缘/细节)
dct_ = DCT.idct_2d(dct, norm='ortho') # 4. 逆DCT变换,将频率域信息转回空间域,生成高频掩码
return x * dct_ # 5. 特征×高频掩码,强化小目标空间特征
def _compute_weight(self, h, w, ratio):
# 计算低频屏蔽区域:高度前h0行、宽度前w0列设为0
h0 = int(h * ratio[0]) # 低频高度范围(如h=32,ratio=0.25 → h0=8)
w0 = int(w * ratio[1]) # 低频宽度范围
weight = torch.ones((h, w), requires_grad=False) # 初始全1权重
weight[:h0, :w0] = 0 # 屏蔽低频区域
return weight
# ------------------------------------------------------------------#
# Channel Path of HFP
# Only p1&p2 use dct to extract high_frequency response
# ------------------------------------------------------------------#
class DctChannelInteraction(BaseModule):
def __init__(self,
in_channels,
patch, # 池化补丁大小(如(8,8)),控制通道注意力的感受野
ratio,
isdct=True, # 同空间路径,控制是否启用DCT高频提取
init_cfg=dict(type='Xavier', layer='Conv2d', distribution='uniform')):
super().__init__(init_cfg)
self.in_channels = in_channels
self.h = patch[0] # 补丁高度
self.w = patch[1] # 补丁宽度
self.ratio = ratio
self.isdct = isdct
# 分组卷积(groups=32):降低计算量,增强通道特异性(适配多通道特征)
self.channel1x1 = nn.Sequential(
*[ConvModule(in_channels, in_channels, kernel_size=1, groups=32, bias=False)],
)
self.channel2x1 = nn.Sequential(
*[ConvModule(in_channels, in_channels, kernel_size=1, groups=32, bias=False)],
)
self.relu = nn.ReLU() # 激活函数,增强非线性表达
def forward(self, x):
n, c, h, w = x.size() # n=batch_size, c=channels
# 非DCT模式:用最大/平均池化提取通道统计信息,生成通道权重
if not self.isdct:
amaxp = F.adaptive_max_pool2d(x, output_size=(1, 1)) # 通道最大池化(突出显著特征)
aavgp = F.adaptive_avg_pool2d(x, output_size=(1, 1)) # 通道平均池化(保留全局信息)
# 融合池化结果,生成通道权重(相加而非拼接,避免通道维度膨胀)
channel = self.channel1x1(self.relu(amaxp)) + self.channel1x1(self.relu(aavgp))
return x * torch.sigmoid(self.channel2x1(channel)) # 特征×通道权重,放大目标通道
# DCT模式:结合频率域与通道统计信息(核心逻辑)
idct = DCT.dct_2d(x, norm='ortho') # 1. 特征转频率域
weight = self._compute_weight(h, w, self.ratio).to(x.device)
weight = weight.view(1, h, w).expand_as(idct)
dct = idct * weight # 2. 高通滤波,保留高频
dct_ = DCT.idct_2d(dct, norm='ortho') # 3. 逆DCT转回空间域
# 4. 池化提取高频区域的通道统计信息(聚焦小目标细节)
amaxp = F.adaptive_max_pool2d(dct_, output_size=(self.h, self.w)) # 高频区域最大池化
aavgp = F.adaptive_avg_pool2d(dct_, output_size=(self.h, self.w)) # 高频区域平均池化
# 求和压缩空间维度,得到通道级统计量(n, c, 1, 1)
amaxp = torch.sum(self.relu(amaxp), dim=[2, 3]).view(n, c, 1, 1)
aavgp = torch.sum(self.relu(aavgp), dim=[2, 3]).view(n, c, 1, 1)
# 5. 生成通道权重并应用
channel = self.channel1x1(amaxp) + self.channel1x1(aavgp) # 融合池化结果
return x * torch.sigmoid(self.channel2x1(channel)) # 特征×通道权重,增强目标通道特征
def _compute_weight(self, h, w, ratio):
# 与空间路径一致,生成高通滤波权重(屏蔽低频,保留高频)
h0 = int(h * ratio[0])
w0 = int(w * ratio[1])
weight = torch.ones((h, w), requires_grad=False)
weight[:h0, :w0] = 0
return weight
# ------------------------------------------------------------------#
# High Frequency Perception Module HFP
# ------------------------------------------------------------------#
class HFP(BaseModule):
def __init__(self,
in_channels,
ratio, # 高通滤波比例(如(0.25,0.25),实验验证最优值)
patch=(8, 8), # 通道路径池化补丁大小
isdct=True, # 控制是否启用DCT高频提取
init_cfg=dict(type='Xavier', layer='Conv2d', distribution='uniform')):
super().__init__(init_cfg)
# 初始化双路径模块
self.spatial = DctSpatialInteraction(in_channels, ratio=ratio, isdct=isdct) # 空间路径
self.channel = DctChannelInteraction(in_channels, patch=patch, ratio=ratio, isdct=isdct) # 通道路径
# 输出卷积层:融合双路径特征,调整通道一致性并抑制噪声
self.out = nn.Sequential(
*[ConvModule(in_channels, in_channels, kernel_size=3, padding=1), # 3×3卷积增强局部关联
nn.GroupNorm(32, in_channels)] # 分组归一化,稳定训练(适配多通道)
)
def forward(self, x):
spatial = self.spatial(x) # 1. 空间路径输出:增强小目标空间区域
channel = self.channel(x) # 2. 通道路径输出:增强小目标特征通道
return self.out(spatial + channel) # 3. 双路径特征相加+卷积归一化,输出最终增强特征
if __name__ == '__main__':
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
x = torch.randn(1, 64, 32, 32).to(device)
hfp = HFP(64,2).to(device)
y = hfp(x)
print("微信公众号:十小大的底层视觉工坊")
print("知乎、CSDN:十小大")
print("输入特征维度:", x.shape)
print("输出特征维度:", y.shape)
运行结果:

至此本文结束。
如果本文对你有所帮助,请点赞收藏,创作不易,感谢您的支持!
点击下方👇公众号区域,扫码关注,可免费领取一份200+即插即用模块资料!
更多推荐



所有评论(0)