0. 前言本文介绍了SACFSpectral-guided Adaptive Cross-layer Fusion光谱引导自适应跨层融合模块其通过光谱特征聚合器SFA与空间细节增强器SDE的双路协同机制首次在多光谱图像目标检测中实现对光谱相似性特征的自适应聚合与高频纹理细节的精准保留有效破解了跨层融合过程中信息丢失与背景噪声干扰导致的检测性能下降难题。将其作为即插即用模块轻松助力CNN、YOLO、Transformer等深度学习模型精准增强目标内特征相关性、抑制无关背景响应让模型在面对小目标、低光照、遮挡等挑战性场景时依然能够保持清晰的边界感知与稳定的检测精度。专栏链接即插即用系列专栏链接可点击跳转免费订阅目录0. 前言1. SACF注意力简介2. SACF注意力原理与创新点 SACF注意力基本原理 SACF注意力创新点3. 适用范围与模块效果适用范围⚡模块效果4. SACF模块代码实现1. SACF注意力简介多光谱图像MSIs通过捕获多个波段的光谱信息为目标检测提供了补充性的判别线索然而现有方法在利用光谱-空间信息时面临三大挑战一是现有的多光谱目标检测方法通过PCA降维或波段选择等方式解耦光谱与空间信息采用双流网络独立处理带来高昂的计算成本和光谱信息损失二是现有航空目标检测方法主要利用空间特征光谱线索未被充分利用三是复杂场景中广泛的背景干扰会稀释目标特征削弱模型注意力并影响目标光谱-空间特征学习导致检测器性能下降。为解决上述问题本文提出SACF模块通过自适应聚合光谱相关特征来增强目标内相关性在保留空间纹理细节的同时抵抗噪声干扰最小化跨层融合过程中的信息损失。原始论文https://arxiv.org/pdf/2512.09489原始代码https://github.com/shuaihao-han/MODA2. SACF注意力原理与创新点 SACF注意力基本原理SACFSpectral-guided Adaptive Cross-layer Fusion光谱引导自适应跨层融合是一个专门设计用于多光谱图像目标检测的跨层特征融合模块其核心思想是在特征金字塔的跨层融合过程中同时保留并增强两类关键信息——光谱维度上的目标内相关性和空间维度上的纹理细节。该模块采用双路并行的设计架构一路是光谱特征聚合器SFA它通过计算中心光谱特征向量与其邻域向量之间的相似度自适应地聚合空间邻域内光谱特征相似的像素从而增强同一目标内部的特征相关性另一路是空间细节增强器SDE它通过对特征进行高低频分解专门增强承载纹理细节的高频分量同时保留承载结构信息的低频分量以弥补下采样过程中的细节损失。两条路径的输出通过自适应加权融合的方式嵌入到低层特征中实现光谱信息与空间纹理的协同增强。其具体实现包含以下几个关键步骤1光谱特征聚合SFA对于输入的高层特征图将其视为由若干光谱特征向量组成的二维网格。对每个中心位置提取其周围k×k邻域内的所有光谱向量通过欧氏距离计算中心向量与邻域向量之间的光谱相似度生成相似度权重。利用这些权重对邻域向量进行加权聚合将聚合结果与原始中心向量相加实现光谱信息的自适应增强。这一机制能够有效强化同一目标内部不同像素之间的光谱一致性提升目标特征的鲁棒性。2空间细节增强SDE针对低层特征图首先通过平均池化提取低频分量代表整体结构信息然后用原始特征减去上采样后的低频分量得到高频分量代表边缘、纹理等细节信息。高频分量通过轻量级的卷积层进行非线性增强低频分量则通过卷积层进行结构信息提炼。最后将增强后的高频纹理与提炼后的低频结构进行通道拼接和融合形成细节增强后的特征表示。3自适应跨层融合将SFA增强后的高层特征与SDE增强后的低层特征进行空间尺寸对齐后分别计算其全局置信度通过全局平均池化。将两个置信度向量拼接后送入卷积层和激活函数生成逐通道的融合权重。最终通过加权求和的方式实现高层光谱特征与低层空间特征的深度融合有效提升前景与背景的对比度。 SACF注意力创新点1光谱引导的自适应聚合机制首次在跨层融合中引入基于光谱相似性的特征聚合通过计算中心特征向量与邻域向量的相似度权重实现目标内光谱相关特征的自适应增强显著提升目标特征的判别能力。2高低频解耦的空间细节增强创新性地将特征分解为低频结构分量和高频纹理分量仅对高频细节进行针对性增强在保留结构信息的同时有效弥补下采样过程中的细节损失。3双路协同的自适应融合通过全局置信度引导的通道级加权融合策略实现光谱特征与空间纹理的自适应平衡避免传统简单相加或拼接带来的信息冗余。3. 适用范围与模块效果适用范围SACF模块适用于通用视觉领域中涉及多模态特征融合、跨层信息交互的场景特别是需要同时保留光谱/通道相关性与空间纹理细节的视觉任务。具体而言该模块的适用范围包括1多光谱图像目标检测任务如航空图像中的车辆、行人检测遥感图像中的地物分类等2高光谱图像分析任务如高光谱图像分类、变化检测、显著性目标检测等3需要跨层特征融合的通用检测分割网络可作为特征金字塔网络的增强模块4小目标检测任务因为小目标对纹理细节和光谱特征更为敏感SACF的双路增强机制能够有效提升小目标的特征表达质量。⚡模块效果消融实验结果论文Table 6该表格展示了SACF模块内部各组件SDE空间细节增强器、SFA光谱特征聚合器的消融实验结果。单独使用SDE时mAP50为67.8%单独使用SFA时mAP50为68.2%而两者联合使用时mAP50达到69.0%mAP75达到45.9%mAP达到42.7%。实验结论SDE和SFA两个组件具有互补性联合使用能够获得最佳检测性能验证了光谱聚合与空间细节增强协同机制的有效性。消融实验结果论文Table 7该表格展示了SACF中邻域窗口大小k的消融实验。当k3时取得最佳性能mAP5069.0%k1和k5时性能下降k7和k9时性能显著恶化mAP50降至61.4%和61.4%。实验结论适中的邻域窗口3×3能够有效聚合光谱相似特征过大的窗口会引入无关特征反而损害目标特异性。4. SACF模块代码实现以下为SACF模块的官方pytorch实现代码import torch import torch.nn as nn import torch.nn.functional as F import math class AdaptiveSpectralFeatureRefinementEuclidean(nn.Module): 基于欧氏距离的自适应光谱特征精修模块(ASFR-Eu) 核心通过局部patch的欧氏距离相似度加权融合精修光谱特征的细节表达 Args: patch_size: 局部特征块尺寸默认3 Inputs: fe_lv: 待精修的基础光谱特征 [B, C, H, W] fused_features: 参考光谱特征 [B, C, H, W] Output: 残差连接的精修后光谱特征 [B, C, H, W] def __init__(self, patch_size: int 3): super().__init__() self.patch_size patch_size self.unfold nn.Unfold(kernel_sizepatch_size, paddingpatch_size // 2) # 滑窗提取局部patch保持尺寸不变 def forward(self, fe_lv: torch.Tensor, fused_features: torch.Tensor) - torch.Tensor: B, C, H, W fe_lv.shape # 滑窗展开为局部patch[B, C*k*k, H*W] → 重塑为[B, C, k*k, H*W] patches self.unfold(fused_features).reshape(B, C, self.patch_size * self.patch_size, H * W) fe_lv_flat fe_lv.reshape(B, C, H * W) # 基础特征展平 [B, C, H*W] # 计算每个像素与周围patch的欧氏距离衡量特征相似性 distances torch.norm( patches.permute(0, 3, 2, 1) - fe_lv_flat.permute(0, 2, 1).unsqueeze(2), dim-1 ) # [B, H*W, k*k] weights F.softmax(-distances, dim-1) # 距离取负做softmax相似patch权重更高 # 加权融合局部patch特征精修基础特征 refined torch.matmul(weights.unsqueeze(2), patches.permute(0, 3, 2, 1).reshape(B, H * W, self.patch_size * self.patch_size, C)) # 重塑为原特征尺寸并添加残差连接保留原始特征信息 refined refined.squeeze(2).permute(0, 2, 1).reshape(B, C, H, W) return refined fe_lv class AdaptiveSpectralFeatureRefinementCosine(nn.Module): 基于余弦相似度的自适应光谱特征精修模块(ASFR-Cos) 核心通过局部patch的余弦相似度加权融合聚焦光谱特征的方向一致性精修 参数/输入输出与ASFR-Eu一致 def __init__(self, patch_size: int 3): super().__init__() self.patch_size patch_size self.unfold nn.Unfold(kernel_sizepatch_size, paddingpatch_size // 2) def forward(self, fe_lv: torch.Tensor, fused_features: torch.Tensor) - torch.Tensor: B, C, H, W fe_lv.shape patches self.unfold(fused_features).reshape(B, C, self.patch_size * self.patch_size, H * W) fe_lv_flat fe_lv.reshape(B, C, H * W) # 特征L2归一化计算余弦相似度衡量特征方向相似性 patches_norm F.normalize(patches, dim1) fe_lv_norm F.normalize(fe_lv_flat, dim1) cosine_sim torch.einsum(bhkc,bhc-bhk, patches_norm.permute(0, 3, 2, 1), fe_lv_norm.permute(0, 2, 1)) weights F.softmax(cosine_sim, dim-1) # 相似度越高权重越大 # 加权融合残差连接 refined torch.matmul(weights.unsqueeze(2), patches.permute(0, 3, 2, 1).reshape(B, H * W, self.patch_size * self.patch_size, C)) refined refined.squeeze(2).permute(0, 2, 1).reshape(B, C, H, W) return refined fe_lv class AdaptiveSpectralFeatureRefinementCombined(nn.Module): 融合欧氏距离余弦相似度的自适应光谱特征精修模块(ASFR-Com) 核心结合距离特征幅值和余弦特征方向的双重相似性更全面精修光谱特征 Args: fusion_method: 权重融合方式add(加权相加)/concat(拼接后softmax) alpha: add模式下余弦相似度的权重系数默认0.5 其他参数/输入输出与ASFR-Eu一致 def __init__(self, patch_size: int 3, fusion_method: str add, alpha: float 0.5): super().__init__() self.patch_size patch_size self.unfold nn.Unfold(kernel_sizepatch_size, paddingpatch_size // 2) self.fusion_method fusion_method self.alpha alpha # 余弦权重系数 def forward(self, fe_lv: torch.Tensor, fused_features: torch.Tensor) - torch.Tensor: B, C, H, W fe_lv.shape patches self.unfold(fused_features).reshape(B, C, self.patch_size * self.patch_size, H * W) fe_lv_flat fe_lv.reshape(B, C, H * W) # 余弦相似度分支 patches_norm F.normalize(patches, dim1) fe_lv_norm F.normalize(fe_lv_flat, dim1) cosine_sim torch.einsum(bhkc,bhc-bhk, patches_norm.permute(0, 3, 2, 1), fe_lv_norm.permute(0, 2, 1)) cosine_weights F.softmax(cosine_sim, dim-1) # 欧氏距离分支 distances torch.norm(patches.permute(0, 3, 2, 1) - fe_lv_flat.permute(0, 2, 1).unsqueeze(2), dim-1) euclidean_weights F.softmax(-distances, dim-1) # 双重权重融合 patches_reshaped patches.permute(0, 3, 2, 1).reshape(B, H * W, self.patch_size * self.patch_size, C) if self.fusion_method add: weights self.alpha * cosine_weights (1 - self.alpha) * euclidean_weights refined torch.matmul(weights.unsqueeze(2), patches_reshaped) else: # concat模式 refined_cos torch.matmul(cosine_weights.unsqueeze(2), patches_reshaped) refined_euc torch.matmul(euclidean_weights.unsqueeze(2), patches_reshaped) refined torch.cat([refined_cos, refined_euc], dim-1) refined refined.squeeze(2).permute(0, 2, 1).reshape(B, -1, H, W) return refined fe_lv class StripConvBlock(nn.Module): 条带卷积块水平垂直分离卷积提取空间方向特征为边缘增强做基础 Args: in_channels/out_channels: 输入/输出通道数 kernel_size: 卷积核尺寸默认3 def __init__(self, in_channels: int, out_channels: int, kernel_size: int 3): super().__init__() self.h_conv nn.Conv2d(in_channels, out_channels, (1, kernel_size), padding(0, kernel_size//2), biasFalse) # 水平卷积 self.v_conv nn.Conv2d(in_channels, out_channels, (kernel_size, 1), padding(kernel_size//2, 0), biasFalse) # 垂直卷积 def forward(self, x: torch.Tensor) - torch.Tensor: return self.h_conv(x) self.v_conv(x) # 水平垂直特征融合 class EdgeEnhanceSpatialFeatureRefinement(nn.Module): 边缘增强的空间特征精修模块(ESFR) 核心分离特征的低频全局结构和高频边缘细节对高频做注意力增强融合后精修空间特征 Args: in_channels: 输入通道数 Input: x - 待精修的空间特征 [B, C, H, W] Output: 残差连接的边缘增强后空间特征 [B, C, H, W] def __init__(self, in_channels: int): super().__init__() self.avgpool nn.AvgPool2d(3, stride2, padding1) # 下采样提取低频 self.conv3 nn.Conv2d(in_channels, in_channels, 3, padding1, biasFalse) # 低频特征精修 self.conv1_1 nn.Conv2d(in_channels, 1, 1, biasFalse) # 高频注意力掩码生成 self.conv1_2 nn.Conv2d(in_channels * 2, in_channels, 1, biasFalse) # 高低频融合卷积 def forward(self, x: torch.Tensor) - torch.Tensor: # 提取低频特征下采样→卷积精修→上采样恢复尺寸保留全局结构 F_L self.avgpool(x) F_L F.interpolate(self.conv3(F_L), sizex.shape[2:], modebilinear, align_cornersTrue) # 提取高频特征原始特征 - 下采样再上采样的特征保留边缘细节 F_H x - F.interpolate(self.avgpool(x), sizex.shape[2:], modebilinear, align_cornersTrue) # 高频注意力增强生成空间注意力掩码强化有效边缘细节 weight torch.sigmoid(self.conv1_1(F_H)) F_H F_H * weight F_H # 高低频融合残差连接 out self.conv1_2(torch.cat([F_H, F_L], dim1)) return out x class SpectralSpatialAdaptiveFusion(nn.Module): 光谱-空间自适应融合模块(SSAF)即SACF核心模块 核心先分别精修光谱特征ASFR和空间特征ESFR再通过自适应权重实现跨层/跨模态特征融合 Args: in_channels: 输入通道数 patch_size: ASFR的局部patch尺寸默认3 Inputs: fh: 高光谱/低分辨率跨层特征 [B, C, Hh, Wh] fs: 空间/高分辨率跨层特征 [B, C, Hs, Ws] Output: 自适应融合后的特征 [B, C, Hs, Ws] def __init__(self, in_channels: int, patch_size: int 3, **kwargs): 初始化函数支持接收额外参数兼容YOLO的解析器 :param in_channels: 输入通道数 :param patch_size: ASFR的局部patch尺寸默认3 :param kwargs: 其他参数YOLO可能会传入这里忽略 super().__init__() self.in_channels in_channels self.asfr AdaptiveSpectralFeatureRefinementEuclidean(patch_sizepatch_size) # 光谱特征精修 self.esfr EdgeEnhanceSpatialFeatureRefinement(in_channels) # 空间特征精修 self.adp_conv nn.Conv2d(2, 2, 1, biasFalse) # 自适应权重生成卷积 self.fuse_conv nn.Sequential( # 融合后特征精修 nn.Conv2d(in_channels, in_channels, 1, biasFalse), nn.BatchNorm2d(in_channels), nn.ReLU(inplaceTrue) ) # 添加用于序列格式的投影层 self.seq_proj nn.Linear(in_channels, in_channels) def forward(self, fh, fs, HNone, WNone): 前向主流程支持两种调用模式 1. 独立测试模式传入H和W参数序列格式输入 2. Ultralytics框架模式图像格式输入 :param fh: 高光谱/低分辨率特征 [B, C, Hh, Wh] 或 [B, N, C] :param fs: 空间/高分辨率特征 [B, C, Hs, Ws] 或 [B, N, C] :param H: 输出特征图高度独立测试模式使用 :param W: 输出特征图宽度独立测试模式使用 :return: 自适应融合后的特征 # 独立测试模式输入为序列格式 [B, N, C] if H is not None and W is not None: return self.forward_seq(fh, fs, H, W) # Ultralytics框架模式输入为图像格式 [B, C, H, W] return self.forward_img(fh, fs) def forward_img(self, fh: torch.Tensor, fs: torch.Tensor) - torch.Tensor: 图像格式的前向传播 :param fh: 低分辨率特征 [B, C, Hh, Wh] :param fs: 高分辨率特征 [B, C, Hs, Ws] :return: 融合特征 [B, C, Hs, Ws] # 步骤1光谱特征精修尺寸对齐将fh上采样至fs的尺寸 fh self.asfr(fh, fh) fh F.interpolate(fh, sizefs.shape[2:], modebilinear, align_cornersTrue) # 步骤2空间特征边缘增强精修 fs self.esfr(fs) # 步骤3生成自适应融合权重基于特征的通道平均池化 fh_avg, fs_avg fh.mean(1, keepdimTrue), fs.mean(1, keepdimTrue) # [B,1,H,W] weights torch.sigmoid(self.adp_conv(torch.cat([fh_avg, fs_avg], dim1))) # [B,2,H,W] # 步骤4权重加权融合光谱和空间特征 out weights[:, 0:1] * fh weights[:, 1:2] * fs # 步骤5融合后特征精修提升特征表达一致性 return self.fuse_conv(out) def forward_seq(self, fh_seq: torch.Tensor, fs_seq: torch.Tensor, H: int, W: int) - torch.Tensor: 序列格式的前向传播兼容CGTA的接口 :param fh_seq: 低分辨率特征 [B, N, C] :param fs_seq: 高分辨率特征 [B, N, C] :param H: 特征图高度 :param W: 特征图宽度 :return: 融合特征 [B, N, C] B, N, C fh_seq.shape # 将序列转换为图像格式 [B, C, H, W] fh_img fh_seq.transpose(1, 2).view(B, C, H, W).contiguous() fs_img fs_seq.transpose(1, 2).view(B, C, H, W).contiguous() # 调用图像格式的前向传播 out_img self.forward_img(fh_img, fs_img) # 转换回序列格式 [B, N, C] out_seq out_img.view(B, C, -1).transpose(1, 2).contiguous() return out_seq class SACF(nn.Module): SACF (Spectral-Spatial Adaptive Fusion) 的封装类 提供统一的接口支持单输入和多输入模式 def __init__(self, c1, c2None, patch_size: int 3, **kwargs): 初始化函数兼容YOLO的解析器 :param c1: 输入通道数第一个输入特征 :param c2: 第二个输入通道数可选如果不提供则使用c1 :param patch_size: ASFR的局部patch尺寸默认3 :param kwargs: 其他参数YOLO可能会传入这里忽略 super().__init__() # 如果c2未提供则使用c1 if c2 is None: c2 c1 # 确保输入通道一致 assert c1 c2, fSACF expects same input channels, but got c1{c1}, c2{c2} self.in_channels c1 self.ssaf SpectralSpatialAdaptiveFusion(c1, patch_size) def forward(self, x, yNone, HNone, WNone): 前向传播 :param x: 主特征 [B, C, H, W] 或 [B, N, C] :param y: 辅助特征可选如果不提供则使用x自身 :param H: 特征图高度序列模式 :param W: 特征图宽度序列模式 :return: 融合后的特征 # 如果只提供一个输入则使用x作为两个输入自融合 if y is None: y x # 序列模式 if H is not None and W is not None: return self.ssaf(x, y, H, W) # 图像模式 return self.ssaf(x, y) # 模块测试代码 if __name__ __main__: device torch.device(cuda:0 if torch.cuda.is_available() else cpu) print( * 60) print(测试模式1YOLO兼容性测试) print( * 60) # 测试YOLO解析器的调用方式 model SACF(64, 64, patch_size3).to(device) print(SACF模块初始化成功) print(f输入通道数: {model.in_channels}) print() print( * 60) print(测试模式2图像格式 - 高低分辨率特征融合) print( * 60) # 测试图像格式输入高低分辨率融合 f_low torch.randn(1, 64, 16, 16).to(device) # 低分辨率特征 f_high torch.randn(1, 64, 32, 32).to(device) # 高分辨率特征 y_img model(f_low, f_high) print(输入低分辨率特征维度, f_low.shape) print(输入高分辨率特征维度, f_high.shape) print(输出特征维度, y_img.shape) print() print( * 60) print(测试模式3图像格式 - 自融合模式) print( * 60) # 测试自融合模式 f_single torch.randn(1, 64, 32, 32).to(device) y_self model(f_single) print(输入特征维度, f_single.shape) print(输出特征维度自融合, y_self.shape) print() print( * 60) print(测试模式4序列格式兼容CGTA接口) print( * 60) # 测试序列格式输入 H, W 32, 32 N H * W f_seq1 torch.randn(1, N, 64).to(device) f_seq2 torch.randn(1, N, 64).to(device) y_seq model(f_seq1, f_seq2, HH, WW) print(输入特征维度1序列, f_seq1.shape) print(输入特征维度2序列, f_seq2.shape) print(输出特征维度序列, y_seq.shape) print() print( * 60) print(测试模式5批量处理测试) print( * 60) # 测试批量处理 batch_size 4 f_low_batch torch.randn(batch_size, 64, 16, 16).to(device) f_high_batch torch.randn(batch_size, 64, 32, 32).to(device) y_batch model(f_low_batch, f_high_batch) print(批量输入低分辨率特征维度, f_low_batch.shape) print(批量输入高分辨率特征维度, f_high_batch.shape) print(批量输出特征维度, y_batch.shape) print() print( * 60) print(测试通过) print( * 60)结合自己的思路可将其即插即用至任何模型做结构创新设计该模块博主已成功嵌入至YOLO26模型中可订阅博主YOLO系列算法改进或YOLO26自研改进专栏YOLO系列算法改进专栏链接、YOLO26自研改进系列专栏