0. 前言本文介绍了FAAFusion傅里叶角度对齐融合模块其通过频域分析精准估计物体主方向在特征金字塔融合前将高层语义特征显式旋转对齐至低层细节特征的方向首次在旋转目标检测领域实现跨尺度特征的方向一致性建模有效破解了传统特征金字塔直接融合时高低频方向信号冲突导致的角点预测模糊与定位精度下降难题。将其作为即插即用模块轻松融入Oriented R-CNN、YOLO、LSKNet等主流检测框架精准抑制跨尺度方向噪声、增强旋转特征表达让模型在面对任意朝向的舰船、飞机、车辆等遥感目标时依然能够保持锐利的边界感知与高精度的角度回归能力。专栏链接即插即用系列专栏链接可点击跳转免费订阅目录0. 前言1. FAAFusion模块简介2. FAAFusion模块基本原理与创新点 FAAFusion模块的基本原理 FAAFusion模块主要创新点3. 适用范围与模块效果适用范围⚡模块效果4. FAAFusion模块代码实现1. FAAFusion模块简介在遥感旋转目标检测中主流方法面临着两个瓶颈检测颈部的方向不一致性和检测头的任务冲突。利用傅里叶旋转等变性我们提出了傅里叶角度对齐Fourier Angle Alignment, FAA该方法通过频谱分析角度信息并将主方向对齐到特定角度。然后我们提出了两个即插即用的模块FAAFusion和FAA Head。FAAFusion在检测颈部工作将高层特征的主方向与低层特征对齐后再进行融合。FAA Head作为一个新的检测头在分类和回归之前将RoI特征预先对齐到一个规范角度并将其与原始特征相加。在DOTA-v1.0、DOTA-v1.5和HRSC2016上的实验表明我们的方法能显著提升现有工作。特别地我们的方法在单尺度训练和测试下在DOTA-v1.0数据集上取得了78.72% mAP的新SOTA结果在DOTA-v1.5数据集上取得了72.28% mAP验证了我们的方法在遥感目标检测中的有效性。原始论文https://arxiv.org/pdf/2602.23790原始代码https://github.com/gcy0423/Fourier-Angle-Alignment2. FAAFusion模块基本原理与创新点 FAAFusion模块的基本原理FAAFusion模块的核心思想是在特征金字塔网络FPN进行特征融合之前先解决不同层级特征之间存在的方向不一致问题。它利用傅里叶变换在频域中的旋转等变性将包含清晰方向信息但语义较弱的低层特征作为“引导”去校准包含丰富语义但方向模糊的高层特征从而实现方向一致的信息融合。具体实现过程可分为以下几个关键步骤特征准备与局部展开首先模块接收来自FPN的高层特征和低层特征。为了进行精细的对齐它会将这两个特征图通过unfold操作划分为多个局部特征块。每个局部特征块对应原图中的一个空间位置这使得模块能够对不同位置的目标进行独立的方位估计。低层特征主导方向估计对于每一个空间位置模块会提取对应的低层局部特征块并送入傅里叶角度估计器。通过计算该局部块的频谱并分析其能量在极坐标下的分布找到能量最大的方向。这个方向被视为该局部区域目标的“主方向”它包含了由锐利边缘和纹理提供的精确方位信息。高层特征旋转对齐得到主方向后模块会提取相同位置的高层局部特征块并利用傅里叶角度对齐操作将该特征块沿着其中心点旋转使其主方向与刚才由低层特征估计出的方向保持一致。这一过程有效地将高层特征中“模糊”的语义信息与低层特征中“精确”的方向信息进行了统一。特征重建与融合所有位置的高层特征块经过方向对齐后通过fold操作被重新组装成一张完整的特征图。最后这张经过方向校准的高层特征图与原始的低层特征图进行逐元素相加完成最终的融合。这样得到的融合特征既具备了高层特征的强语义又保证了与低层特征方向的一致性从而避免了直接相加带来的方向噪声。 FAAFusion模块主要创新点频域驱动的方向一致性融合首次将傅里叶变换引入FPN的特征融合阶段利用频域中能量分布与物体方向的确定性关系显式地对不同尺度特征进行方向对齐从根本上解决了多尺度特征融合时的方向冲突问题。即插即用的轻量化模块FAAFusion被设计为一个通用的、轻量化的模块可以无缝嵌入到现有的任意基于FPN的检测框架中如YOLO系列无需对原有模型结构进行大幅改动即可有效提升模型对旋转目标的检测能力。高IoU下的性能优势通过在频域进行精确的方向对齐使得模型对目标边界和角度的预测更加精细在严格的高IoUIntersection over Union评价指标下性能优势尤为明显证明了其在精确定位方面的有效性。3. 适用范围与模块效果适用范围FAAFusion适用于通用视觉领域中所有涉及多尺度特征融合的检测任务特别是对方向信息敏感的场景包括但不限于遥感图像旋转目标检测、场景文字检测、任意方向物体检测、以及需要精确定向框回归的视觉任务。该模块的适用性源于其核心设计原理方向不一致性是跨尺度特征融合中的普遍问题不仅存在于遥感旋转目标检测中也广泛存在于其他需要精确角度预测的任务中。FAAFusion通过频域方向估计和空间域旋转对齐能够有效解决高层语义特征与低层细节特征之间的方向错位问题。此外该模块对输入特征的分辨率和通道数无特殊要求可以灵活适配不同深度的特征金字塔结构因此具备良好的通用性和可移植性。⚡模块效果表4第8页消融实验在LSKNet-S骨干网络上单独添加FAAFusion模块可使mAP从77.49%提升至77.91%0.42%单独添加FAA Head可使mAP提升至78.27%0.78%两者联合使用则达到78.49%1.00%充分验证了两个模块各自的有效性和协同增益作用。表5第8页检测头对比在Oriented R-CNN、LSKNet、Strip R-CNN三种检测框架上FAA Head相比原始检测头和最新的Strip Head均取得最高mAP值。以LSKNet为例FAA Head达到78.27% mAP超越Strip Head的78.04%和原始头的77.49%同时参数量和计算量远低于Strip Head展现了优越的性能效率比。图6第8页高IoU性能分析当IoU阈值从0.70提升至0.90时原始方法性能急剧下降而FAAFusion增强后的模型始终保持更优的检测精度且随着阈值提高优势愈发明显。这表明FAAFusion显著提升了模型的精确定向建模能力对高精度要求的实际应用场景具有重要价值。总结表4和表5的消融与对比实验验证了FAAFusion和FAA Head模块在多个骨干网络上的普适有效性而图6的高IoU性能曲线则证明了该模块在精确定向建模方面的核心优势。4. FAAFusion模块代码实现以下为FAAFusion模块的官方pytorch实现代码import math import torch import torch.nn as nn import torch.nn.functional as F class FAAFusion(nn.Module): 轻量级傅里叶角度对齐融合模块基于通道降维折叠归一化实现跨分辨率特征融合 核心改进单通道降维投影、折叠输出重叠计数归一化、空间旋转对齐、LayerScale特征增强 Args: m (int): 局部窗口尺寸必须为奇数默认7 c_mid (int): 1×1卷积投影后的中间通道维度默认16 eps (float): 数值稳定性小值默认1e-8 layer_scale_init_value (float): LayerScale初始化值默认1e-5 Inputs: x_high (Tensor): 高分辨率特征 [B, C, H_h, W_h] x_low (Tensor): 低分辨率特征 [B, C, H_l, W_l]融合基准 Output: fused (Tensor): 融合后的低分辨率特征 [B, C, H_l, W_l] def __init__( self, m: int 7, c_mid: int 16, eps: float 1e-8, layer_scale_init_value: float 1e-5, ): super().__init__() self.m m # 局部特征窗口尺寸 self.c_mid c_mid # 中间降维通道数 self.eps eps # 防止除零的数值稳定项 # 可学习LayerScale逐通道标量初始值较小避免初始融合过度 self.layer_scale nn.Parameter( torch.full((1, 1, 1, 1), layer_scale_init_value), requires_gradTrue ) # 通道投影将256维高/低频特征统一降维到c_mid减少计算量仅一次投影非逐通道 self.proj_low nn.Conv2d(in_channels256, out_channelsc_mid, kernel_size1, biasFalse) self.proj_high nn.Conv2d(in_channels256, out_channelsc_mid, kernel_size1, biasFalse) # 通道恢复将对齐后的c_mid维特征还原为原始256维 self.recon nn.Conv2d(in_channelsc_mid, out_channels256, kernel_size1, biasFalse) self._init_freq_grids(m) # 初始化傅里叶频率网格预计算极坐标参数 def _init_freq_grids(self, m: int): 初始化傅里叶频率网格计算极坐标(ρ:极径, θ:极角)仅在初始化时执行一次 # 计算m×m窗口的傅里叶频率 h_freq torch.fft.fftfreq(m, d1.0) * m w_freq torch.fft.fftfreq(m, d1.0) * m h_grid, w_grid torch.meshgrid(h_freq, w_freq) # 生成[m, m]频率网格 rho torch.sqrt(h_grid ** 2 w_grid ** 2) # 计算极径频率幅值 theta torch.atan2(h_grid, w_grid) # 计算极角频率方向 theta (theta 2 * math.pi) % (2 * math.pi) # 极角归一化到[0,2π) mask rho self.eps # 过滤零频率直流分量仅保留有效频率 # 注册为缓冲区不参与训练供后续角度估计使用 self.register_buffer(valid_thetas, theta[mask]) self.register_buffer(valid_rhos, rho[mask]) self.register_buffer(mask_flat, mask.view(-1)) def _estimate_main_direction(self, x_local: torch.Tensor) - torch.Tensor: 从局部特征块的傅里叶幅度谱估计**主方向优势取向** x_local: [Bn, 1, m, m] 批量局部特征块 Returns: [Bn] 每个特征块对应的主方向极角 Bn, _, m, _ x_local.shape device x_local.device x_fft torch.fft.fft2(x_local.squeeze(1), normortho) # 2D傅里叶变换 x_fft_shifted torch.fft.fftshift(x_fft, dim(-2, -1)) # 频域中心移到窗口中心 mag x_fft_shifted.abs() self.eps # 计算幅度谱加eps避免零 mag_flat mag.view(Bn, -1) # 展平幅度谱 mag_valid mag_flat[:, self.mask_flat] # 过滤零频率的有效幅度 rho_valid self.valid_rhos.to(device) # 有效频率的极径 weighted_energy mag_valid * rho_valid.unsqueeze(0) # 极径加权能量突出高频主方向 max_idx torch.argmax(weighted_energy, dim1) # 取加权能量最大的索引 theta_e self.valid_thetas.to(device)[max_idx] # 索引对应主方向极角 return theta_e def _rotate_spatial_patch(self, patch: torch.Tensor, theta: torch.Tensor) - torch.Tensor: 根据估计的角度旋转局部特征块实现**空间方向对齐** patch: [K, 1, m, m] 待旋转特征块 theta: [K] 每个特征块的旋转角度 Returns: [K, 1, m, m] 旋转对齐后的特征块 K, _, m, _ patch.shape device patch.device cos_t torch.cos(theta).view(K, 1, 1) # 余弦值维度适配 sin_t torch.sin(theta).view(K, 1, 1) # 正弦值维度适配 center (m - 1) / 2.0 # 窗口中心坐标奇数窗口 # 初始化仿射旋转矩阵 [K, 2, 3]适配torch.nn.functional.affine_grid rot_mat torch.zeros(K, 2, 3, devicedevice) rot_mat[:, 0, 0] cos_t.squeeze() # 旋转矩阵第一行第一列 rot_mat[:, 0, 1] -sin_t.squeeze() # 旋转矩阵第一行第二列 rot_mat[:, 1, 0] sin_t.squeeze() # 旋转矩阵第二行第一列 rot_mat[:, 1, 1] cos_t.squeeze() # 旋转矩阵第二行第二列 # 平移量保证旋转后特征块中心不变 rot_mat[:, 0, 2] center - cos_t.squeeze() * center sin_t.squeeze() * center rot_mat[:, 1, 2] center - sin_t.squeeze() * center - cos_t.squeeze() * center # 生成仿射变换网格 grid F.affine_grid(rot_mat, patch.size(), align_cornersFalse) # 双线性插值旋转零填充边缘 rotated F.grid_sample(patch, grid, modebilinear, padding_modezeros, align_cornersFalse) return rotated def forward(self, x_high: torch.Tensor, x_low: torch.Tensor) - torch.Tensor: FAAFusion前向传播高分辨率特征上采样→通道降维→局部块傅里叶角度估计→ 高维特征旋转对齐→折叠归一化→通道恢复→LayerScale增强→跨分辨率融合 B, C, H_l, W_l x_low.shape # 低分辨率特征尺寸融合基准 _, _, H_h, W_h x_high.shape # 高分辨率特征尺寸 device x_low.device # 步骤1高分辨率特征上采样到低分辨率尺寸作为融合基础 if (H_h, W_h) ! (H_l, W_l): x_high_up F.interpolate(x_high, size(H_l, W_l), modebilinear, align_cornersFalse) else: x_high_up x_high # 步骤2高/低特征统一通道降维到c_mid大幅减少后续计算量 xl_proj self.proj_low(x_low) # [B, c_mid, H_l, W_l] xh_proj self.proj_high(x_high_up) # [B, c_mid, H_l, W_l] pad 0 # 无填充保证局部块不重叠边缘 # 计算有效局部特征块数量m×m窗口滑窗步长1 N (H_l - self.m 1) * (W_l - self.m 1) # 初始化高特征对齐后的中间张量 xh_aligned_cmid torch.zeros_like(xh_proj) # [B, c_mid, H_l, W_l] # 步骤3逐中间通道处理实现**通道级的精细角度对齐** for c in range(self.c_mid): # 提取单通道特征降维后 xl_c xl_proj[:, c:c 1] # [B, 1, H_l, W_l] xh_c xh_proj[:, c:c 1] # [B, 1, H_l, W_l] # 滑窗展开为局部特征块 [B, m*m, N] xl_unfold F.unfold(xl_c, kernel_sizeself.m, stride1, paddingpad) xh_unfold F.unfold(xh_c, kernel_sizeself.m, stride1, paddingpad) # 重塑为批量局部块适配傅里叶变换 [B*N, 1, m, m] xl_patches xl_unfold.transpose(1, 2).reshape(B * N, 1, self.m, self.m) xh_patches xh_unfold.transpose(1, 2).reshape(B * N, 1, self.m, self.m) # 傅里叶域估计主方向极角 theta_low self._estimate_main_direction(xl_patches) # [B*N] 低特征块主方向 theta_high self._estimate_main_direction(xh_patches) # [B*N] 高特征块主方向 # 极角归一化到[0,π)消除方向冗余旋转π与原方向一致 theta_low_norm torch.remainder(theta_low, math.pi) theta_high_norm torch.remainder(theta_high, math.pi) theta_ theta_low_norm - theta_high_norm # 计算高特征需要旋转的角度 # 空间域旋转高特征块与低特征块主方向对齐 xh_rotated self._rotate_spatial_patch(xh_patches, theta_) # [B*N, 1, m, m] # 展平旋转后的特征块准备折叠回原尺寸 xh_rotated_flat xh_rotated.reshape(B, N, -1).transpose(1, 2) # [B, m*m, N] # 折叠回特征图尺寸 [B, 1, H_l, W_l] xh_aligned_map F.fold( xh_rotated_flat, output_size(H_l, W_l), kernel_sizeself.m, stride1, paddingpad ) # 折叠归一化根据滑窗重叠计数归一化避免重叠区域特征值累积 ones torch.ones(1, 1, H_l, W_l, devicedevice) ones_unfold F.unfold(ones, kernel_sizeself.m, stride1, paddingpad) ones_fold F.fold(ones_unfold, output_size(H_l, W_l), kernel_sizeself.m, stride1, paddingpad) xh_aligned_map xh_aligned_map / (ones_fold self.eps) # 保存当前通道的对齐结果 xh_aligned_cmid[:, c:c 1] xh_aligned_map # 步骤4将对齐后的c_mid维特征恢复为原始C维 xh_recon self.recon(xh_aligned_cmid) # [B, C, H_l, W_l] # 步骤5LayerScale可学习增强再与原上采样高特征融合 x_high_modulated self.layer_scale * xh_recon x_high_up # 最终融合低分辨率基准特征 对齐增强后的高分辨率特征 fused x_low x_high_modulated return fused if __name__ __main__: device torch.device(cuda:0 if torch.cuda.is_available() else cpu) x_low torch.randn(1, 256, 32, 32).to(device) x_high torch.randn(1, 256, 64, 64).to(device) model FAAFusion(7, 64).to(device) y model(x_high, x_low) print(输入高频特征维度, x_high.shape) print(输入低频特征维度, x_low.shape) print(输出特征维度, y.shape)结合自己的思路可将其即插即用至任何模型做结构创新设计该模块博主已成功嵌入至YOLO26模型中可订阅博主YOLO系列算法改进或YOLO26自研改进专栏YOLO系列算法改进专栏链接、YOLO26自研改进系列专栏
即插即用系列 | CVPR 2026 | FAAFusion:傅里叶频域角度对齐!跨尺度方向一致性与检测头任务解耦,旋转目标检测新SOTA! | 代码分享
发布时间:2026/5/24 10:41:34
0. 前言本文介绍了FAAFusion傅里叶角度对齐融合模块其通过频域分析精准估计物体主方向在特征金字塔融合前将高层语义特征显式旋转对齐至低层细节特征的方向首次在旋转目标检测领域实现跨尺度特征的方向一致性建模有效破解了传统特征金字塔直接融合时高低频方向信号冲突导致的角点预测模糊与定位精度下降难题。将其作为即插即用模块轻松融入Oriented R-CNN、YOLO、LSKNet等主流检测框架精准抑制跨尺度方向噪声、增强旋转特征表达让模型在面对任意朝向的舰船、飞机、车辆等遥感目标时依然能够保持锐利的边界感知与高精度的角度回归能力。专栏链接即插即用系列专栏链接可点击跳转免费订阅目录0. 前言1. FAAFusion模块简介2. FAAFusion模块基本原理与创新点 FAAFusion模块的基本原理 FAAFusion模块主要创新点3. 适用范围与模块效果适用范围⚡模块效果4. FAAFusion模块代码实现1. FAAFusion模块简介在遥感旋转目标检测中主流方法面临着两个瓶颈检测颈部的方向不一致性和检测头的任务冲突。利用傅里叶旋转等变性我们提出了傅里叶角度对齐Fourier Angle Alignment, FAA该方法通过频谱分析角度信息并将主方向对齐到特定角度。然后我们提出了两个即插即用的模块FAAFusion和FAA Head。FAAFusion在检测颈部工作将高层特征的主方向与低层特征对齐后再进行融合。FAA Head作为一个新的检测头在分类和回归之前将RoI特征预先对齐到一个规范角度并将其与原始特征相加。在DOTA-v1.0、DOTA-v1.5和HRSC2016上的实验表明我们的方法能显著提升现有工作。特别地我们的方法在单尺度训练和测试下在DOTA-v1.0数据集上取得了78.72% mAP的新SOTA结果在DOTA-v1.5数据集上取得了72.28% mAP验证了我们的方法在遥感目标检测中的有效性。原始论文https://arxiv.org/pdf/2602.23790原始代码https://github.com/gcy0423/Fourier-Angle-Alignment2. FAAFusion模块基本原理与创新点 FAAFusion模块的基本原理FAAFusion模块的核心思想是在特征金字塔网络FPN进行特征融合之前先解决不同层级特征之间存在的方向不一致问题。它利用傅里叶变换在频域中的旋转等变性将包含清晰方向信息但语义较弱的低层特征作为“引导”去校准包含丰富语义但方向模糊的高层特征从而实现方向一致的信息融合。具体实现过程可分为以下几个关键步骤特征准备与局部展开首先模块接收来自FPN的高层特征和低层特征。为了进行精细的对齐它会将这两个特征图通过unfold操作划分为多个局部特征块。每个局部特征块对应原图中的一个空间位置这使得模块能够对不同位置的目标进行独立的方位估计。低层特征主导方向估计对于每一个空间位置模块会提取对应的低层局部特征块并送入傅里叶角度估计器。通过计算该局部块的频谱并分析其能量在极坐标下的分布找到能量最大的方向。这个方向被视为该局部区域目标的“主方向”它包含了由锐利边缘和纹理提供的精确方位信息。高层特征旋转对齐得到主方向后模块会提取相同位置的高层局部特征块并利用傅里叶角度对齐操作将该特征块沿着其中心点旋转使其主方向与刚才由低层特征估计出的方向保持一致。这一过程有效地将高层特征中“模糊”的语义信息与低层特征中“精确”的方向信息进行了统一。特征重建与融合所有位置的高层特征块经过方向对齐后通过fold操作被重新组装成一张完整的特征图。最后这张经过方向校准的高层特征图与原始的低层特征图进行逐元素相加完成最终的融合。这样得到的融合特征既具备了高层特征的强语义又保证了与低层特征方向的一致性从而避免了直接相加带来的方向噪声。 FAAFusion模块主要创新点频域驱动的方向一致性融合首次将傅里叶变换引入FPN的特征融合阶段利用频域中能量分布与物体方向的确定性关系显式地对不同尺度特征进行方向对齐从根本上解决了多尺度特征融合时的方向冲突问题。即插即用的轻量化模块FAAFusion被设计为一个通用的、轻量化的模块可以无缝嵌入到现有的任意基于FPN的检测框架中如YOLO系列无需对原有模型结构进行大幅改动即可有效提升模型对旋转目标的检测能力。高IoU下的性能优势通过在频域进行精确的方向对齐使得模型对目标边界和角度的预测更加精细在严格的高IoUIntersection over Union评价指标下性能优势尤为明显证明了其在精确定位方面的有效性。3. 适用范围与模块效果适用范围FAAFusion适用于通用视觉领域中所有涉及多尺度特征融合的检测任务特别是对方向信息敏感的场景包括但不限于遥感图像旋转目标检测、场景文字检测、任意方向物体检测、以及需要精确定向框回归的视觉任务。该模块的适用性源于其核心设计原理方向不一致性是跨尺度特征融合中的普遍问题不仅存在于遥感旋转目标检测中也广泛存在于其他需要精确角度预测的任务中。FAAFusion通过频域方向估计和空间域旋转对齐能够有效解决高层语义特征与低层细节特征之间的方向错位问题。此外该模块对输入特征的分辨率和通道数无特殊要求可以灵活适配不同深度的特征金字塔结构因此具备良好的通用性和可移植性。⚡模块效果表4第8页消融实验在LSKNet-S骨干网络上单独添加FAAFusion模块可使mAP从77.49%提升至77.91%0.42%单独添加FAA Head可使mAP提升至78.27%0.78%两者联合使用则达到78.49%1.00%充分验证了两个模块各自的有效性和协同增益作用。表5第8页检测头对比在Oriented R-CNN、LSKNet、Strip R-CNN三种检测框架上FAA Head相比原始检测头和最新的Strip Head均取得最高mAP值。以LSKNet为例FAA Head达到78.27% mAP超越Strip Head的78.04%和原始头的77.49%同时参数量和计算量远低于Strip Head展现了优越的性能效率比。图6第8页高IoU性能分析当IoU阈值从0.70提升至0.90时原始方法性能急剧下降而FAAFusion增强后的模型始终保持更优的检测精度且随着阈值提高优势愈发明显。这表明FAAFusion显著提升了模型的精确定向建模能力对高精度要求的实际应用场景具有重要价值。总结表4和表5的消融与对比实验验证了FAAFusion和FAA Head模块在多个骨干网络上的普适有效性而图6的高IoU性能曲线则证明了该模块在精确定向建模方面的核心优势。4. FAAFusion模块代码实现以下为FAAFusion模块的官方pytorch实现代码import math import torch import torch.nn as nn import torch.nn.functional as F class FAAFusion(nn.Module): 轻量级傅里叶角度对齐融合模块基于通道降维折叠归一化实现跨分辨率特征融合 核心改进单通道降维投影、折叠输出重叠计数归一化、空间旋转对齐、LayerScale特征增强 Args: m (int): 局部窗口尺寸必须为奇数默认7 c_mid (int): 1×1卷积投影后的中间通道维度默认16 eps (float): 数值稳定性小值默认1e-8 layer_scale_init_value (float): LayerScale初始化值默认1e-5 Inputs: x_high (Tensor): 高分辨率特征 [B, C, H_h, W_h] x_low (Tensor): 低分辨率特征 [B, C, H_l, W_l]融合基准 Output: fused (Tensor): 融合后的低分辨率特征 [B, C, H_l, W_l] def __init__( self, m: int 7, c_mid: int 16, eps: float 1e-8, layer_scale_init_value: float 1e-5, ): super().__init__() self.m m # 局部特征窗口尺寸 self.c_mid c_mid # 中间降维通道数 self.eps eps # 防止除零的数值稳定项 # 可学习LayerScale逐通道标量初始值较小避免初始融合过度 self.layer_scale nn.Parameter( torch.full((1, 1, 1, 1), layer_scale_init_value), requires_gradTrue ) # 通道投影将256维高/低频特征统一降维到c_mid减少计算量仅一次投影非逐通道 self.proj_low nn.Conv2d(in_channels256, out_channelsc_mid, kernel_size1, biasFalse) self.proj_high nn.Conv2d(in_channels256, out_channelsc_mid, kernel_size1, biasFalse) # 通道恢复将对齐后的c_mid维特征还原为原始256维 self.recon nn.Conv2d(in_channelsc_mid, out_channels256, kernel_size1, biasFalse) self._init_freq_grids(m) # 初始化傅里叶频率网格预计算极坐标参数 def _init_freq_grids(self, m: int): 初始化傅里叶频率网格计算极坐标(ρ:极径, θ:极角)仅在初始化时执行一次 # 计算m×m窗口的傅里叶频率 h_freq torch.fft.fftfreq(m, d1.0) * m w_freq torch.fft.fftfreq(m, d1.0) * m h_grid, w_grid torch.meshgrid(h_freq, w_freq) # 生成[m, m]频率网格 rho torch.sqrt(h_grid ** 2 w_grid ** 2) # 计算极径频率幅值 theta torch.atan2(h_grid, w_grid) # 计算极角频率方向 theta (theta 2 * math.pi) % (2 * math.pi) # 极角归一化到[0,2π) mask rho self.eps # 过滤零频率直流分量仅保留有效频率 # 注册为缓冲区不参与训练供后续角度估计使用 self.register_buffer(valid_thetas, theta[mask]) self.register_buffer(valid_rhos, rho[mask]) self.register_buffer(mask_flat, mask.view(-1)) def _estimate_main_direction(self, x_local: torch.Tensor) - torch.Tensor: 从局部特征块的傅里叶幅度谱估计**主方向优势取向** x_local: [Bn, 1, m, m] 批量局部特征块 Returns: [Bn] 每个特征块对应的主方向极角 Bn, _, m, _ x_local.shape device x_local.device x_fft torch.fft.fft2(x_local.squeeze(1), normortho) # 2D傅里叶变换 x_fft_shifted torch.fft.fftshift(x_fft, dim(-2, -1)) # 频域中心移到窗口中心 mag x_fft_shifted.abs() self.eps # 计算幅度谱加eps避免零 mag_flat mag.view(Bn, -1) # 展平幅度谱 mag_valid mag_flat[:, self.mask_flat] # 过滤零频率的有效幅度 rho_valid self.valid_rhos.to(device) # 有效频率的极径 weighted_energy mag_valid * rho_valid.unsqueeze(0) # 极径加权能量突出高频主方向 max_idx torch.argmax(weighted_energy, dim1) # 取加权能量最大的索引 theta_e self.valid_thetas.to(device)[max_idx] # 索引对应主方向极角 return theta_e def _rotate_spatial_patch(self, patch: torch.Tensor, theta: torch.Tensor) - torch.Tensor: 根据估计的角度旋转局部特征块实现**空间方向对齐** patch: [K, 1, m, m] 待旋转特征块 theta: [K] 每个特征块的旋转角度 Returns: [K, 1, m, m] 旋转对齐后的特征块 K, _, m, _ patch.shape device patch.device cos_t torch.cos(theta).view(K, 1, 1) # 余弦值维度适配 sin_t torch.sin(theta).view(K, 1, 1) # 正弦值维度适配 center (m - 1) / 2.0 # 窗口中心坐标奇数窗口 # 初始化仿射旋转矩阵 [K, 2, 3]适配torch.nn.functional.affine_grid rot_mat torch.zeros(K, 2, 3, devicedevice) rot_mat[:, 0, 0] cos_t.squeeze() # 旋转矩阵第一行第一列 rot_mat[:, 0, 1] -sin_t.squeeze() # 旋转矩阵第一行第二列 rot_mat[:, 1, 0] sin_t.squeeze() # 旋转矩阵第二行第一列 rot_mat[:, 1, 1] cos_t.squeeze() # 旋转矩阵第二行第二列 # 平移量保证旋转后特征块中心不变 rot_mat[:, 0, 2] center - cos_t.squeeze() * center sin_t.squeeze() * center rot_mat[:, 1, 2] center - sin_t.squeeze() * center - cos_t.squeeze() * center # 生成仿射变换网格 grid F.affine_grid(rot_mat, patch.size(), align_cornersFalse) # 双线性插值旋转零填充边缘 rotated F.grid_sample(patch, grid, modebilinear, padding_modezeros, align_cornersFalse) return rotated def forward(self, x_high: torch.Tensor, x_low: torch.Tensor) - torch.Tensor: FAAFusion前向传播高分辨率特征上采样→通道降维→局部块傅里叶角度估计→ 高维特征旋转对齐→折叠归一化→通道恢复→LayerScale增强→跨分辨率融合 B, C, H_l, W_l x_low.shape # 低分辨率特征尺寸融合基准 _, _, H_h, W_h x_high.shape # 高分辨率特征尺寸 device x_low.device # 步骤1高分辨率特征上采样到低分辨率尺寸作为融合基础 if (H_h, W_h) ! (H_l, W_l): x_high_up F.interpolate(x_high, size(H_l, W_l), modebilinear, align_cornersFalse) else: x_high_up x_high # 步骤2高/低特征统一通道降维到c_mid大幅减少后续计算量 xl_proj self.proj_low(x_low) # [B, c_mid, H_l, W_l] xh_proj self.proj_high(x_high_up) # [B, c_mid, H_l, W_l] pad 0 # 无填充保证局部块不重叠边缘 # 计算有效局部特征块数量m×m窗口滑窗步长1 N (H_l - self.m 1) * (W_l - self.m 1) # 初始化高特征对齐后的中间张量 xh_aligned_cmid torch.zeros_like(xh_proj) # [B, c_mid, H_l, W_l] # 步骤3逐中间通道处理实现**通道级的精细角度对齐** for c in range(self.c_mid): # 提取单通道特征降维后 xl_c xl_proj[:, c:c 1] # [B, 1, H_l, W_l] xh_c xh_proj[:, c:c 1] # [B, 1, H_l, W_l] # 滑窗展开为局部特征块 [B, m*m, N] xl_unfold F.unfold(xl_c, kernel_sizeself.m, stride1, paddingpad) xh_unfold F.unfold(xh_c, kernel_sizeself.m, stride1, paddingpad) # 重塑为批量局部块适配傅里叶变换 [B*N, 1, m, m] xl_patches xl_unfold.transpose(1, 2).reshape(B * N, 1, self.m, self.m) xh_patches xh_unfold.transpose(1, 2).reshape(B * N, 1, self.m, self.m) # 傅里叶域估计主方向极角 theta_low self._estimate_main_direction(xl_patches) # [B*N] 低特征块主方向 theta_high self._estimate_main_direction(xh_patches) # [B*N] 高特征块主方向 # 极角归一化到[0,π)消除方向冗余旋转π与原方向一致 theta_low_norm torch.remainder(theta_low, math.pi) theta_high_norm torch.remainder(theta_high, math.pi) theta_ theta_low_norm - theta_high_norm # 计算高特征需要旋转的角度 # 空间域旋转高特征块与低特征块主方向对齐 xh_rotated self._rotate_spatial_patch(xh_patches, theta_) # [B*N, 1, m, m] # 展平旋转后的特征块准备折叠回原尺寸 xh_rotated_flat xh_rotated.reshape(B, N, -1).transpose(1, 2) # [B, m*m, N] # 折叠回特征图尺寸 [B, 1, H_l, W_l] xh_aligned_map F.fold( xh_rotated_flat, output_size(H_l, W_l), kernel_sizeself.m, stride1, paddingpad ) # 折叠归一化根据滑窗重叠计数归一化避免重叠区域特征值累积 ones torch.ones(1, 1, H_l, W_l, devicedevice) ones_unfold F.unfold(ones, kernel_sizeself.m, stride1, paddingpad) ones_fold F.fold(ones_unfold, output_size(H_l, W_l), kernel_sizeself.m, stride1, paddingpad) xh_aligned_map xh_aligned_map / (ones_fold self.eps) # 保存当前通道的对齐结果 xh_aligned_cmid[:, c:c 1] xh_aligned_map # 步骤4将对齐后的c_mid维特征恢复为原始C维 xh_recon self.recon(xh_aligned_cmid) # [B, C, H_l, W_l] # 步骤5LayerScale可学习增强再与原上采样高特征融合 x_high_modulated self.layer_scale * xh_recon x_high_up # 最终融合低分辨率基准特征 对齐增强后的高分辨率特征 fused x_low x_high_modulated return fused if __name__ __main__: device torch.device(cuda:0 if torch.cuda.is_available() else cpu) x_low torch.randn(1, 256, 32, 32).to(device) x_high torch.randn(1, 256, 64, 64).to(device) model FAAFusion(7, 64).to(device) y model(x_high, x_low) print(输入高频特征维度, x_high.shape) print(输入低频特征维度, x_low.shape) print(输出特征维度, y.shape)结合自己的思路可将其即插即用至任何模型做结构创新设计该模块博主已成功嵌入至YOLO26模型中可订阅博主YOLO系列算法改进或YOLO26自研改进专栏YOLO系列算法改进专栏链接、YOLO26自研改进系列专栏