YOLO12 改进、魔改|频域自注意力求解器FSAS,通过频域高效计算自注意力,在降低时间与空间复杂度的同时保留关键特征信息,提升遮挡、小目标检测
传统 Transformer 中的缩放点积注意力机制在空间域依赖矩阵乘法运算,其时间和空间复杂度均为O(N2)(N为像素或 token 数量),在处理高分辨率图像时面临计算成本激增的问题。为降低复杂度,现有方法常采用降采样或减少 token 数量,但这类策略会导致空间信息丢失,难以建模细节与长距离依赖关系,最终限制图像恢复等任务的性能。因此,需一种能高效计算注意力、同时保留关键信息的方法,FSAS(Frequency Domain-based Self-Attention Solver)应运而生。
1.FSAS原理
FSAS 的核心原理源于卷积定理 —— 空间域中两个信号的卷积或相关运算,在频域等价于二者频谱的元素 - wise 乘积。基于此,FSAS 将注意力计算从空间域迁移至频域:对于特征图的查询(Fq)和键(Fk),先通过快速傅里叶变换(FFT)转换至频域,再通过频域内的元素乘积(F(Fq)⋅F(Fk),其中⋅为共轭转置)计算二者的相关性,最后通过逆快速傅里叶变换(IFFT)得到注意力图。这一过程避免了空间域中高复杂度的矩阵乘法,将注意力计算的时间复杂度降至O(NlogN),空间复杂度降至O(N),在高效建模全局依赖的同时,减少了信息丢失。
FSAS 的结构可分为四个关键步骤:①特征映射生成:通过 1×1 点卷积和 3×3 深度卷积对输入特征X进行转换,得到查询特征Fq、键特征Fk和值特征Fv;②频域注意力计算:对Fq和Fk分别执行 FFT,在频域中通过元素乘积与共轭转置操作计算相关性,再经 IFFT 得到注意力图A;③注意力聚合:对注意力图A进行层归一化(L(⋅)),并与值特征Fv相乘,得到聚合特征Vatt;④残差连接:通过 1×1 卷积对Vatt进行维度调整,再与原始输入特征X进行残差连接,输出最终特征Xatt。这一结构通过频域转换与残差设计,在保证计算效率的同时,增强了特征的表达能力。
2.FSAS习作思路
FSAS 在目标检测中的优点
FSAS 在频域中高效建模全局注意力的特性,对目标检测任务尤为重要。目标检测需同时捕捉小目标细节与大目标的全局上下文,而传统注意力机制在高分辨率图像中易因计算限制牺牲信息完整性。FSAS 通过频域元素乘积替代空间域矩阵乘法,在降低计算负担的同时,能完整保留目标的高低频信息 —— 高频信息有助于捕捉目标边缘、纹理等细节,低频信息则利于建模目标与背景的全局关联,从而更精准地区分重叠目标、模糊目标或小目标,提升检测的鲁棒性与精度。
FSAS 在图像分割中的优点
图像分割要求精确划分像素所属类别,既需精细的局部边界信息,也需全局的区域关联性。FSAS 的频域注意力机制能兼顾二者:一方面,频域处理避免了空间域分割 token 导致的信息割裂,可有效捕捉跨区域的全局依赖(如同一类别的离散区域关联);另一方面,其高效的计算特性支持处理高分辨率图像,保留更多局部细节(如物体边缘的细微变化),减少因信息丢失导致的分割边界模糊问题,从而提升分割结果的区域一致性与边界精度。
3. YOLO与FSAS的结合
YOLO 以实时性著称,但在复杂场景中对全局上下文的捕捉能力有限。FSAS 的低复杂度特性可适配 YOLO 的实时需求,避免增加过多计算负担;同时,其全局注意力机制能增强 YOLO 对目标与背景关系、多目标间关联的建模能力,尤其在小目标或遮挡场景中,可提升检测的准确率,实现 “速度与精度” 的双重优化。
4.FSAS代码部分
YOLO12模型改进方法,快速发论文,总有适合你的改进,还不改进上车_哔哩哔哩_bilibili
代码获取:YOLOv8_improve/YOLOV12.md at master · tgf123/YOLOv8_improve · GitHub
5. FSAS引入到YOLOv12中
第一: 先新建一个v12_changemodel,将下面的核心代码复制到下面这个路径当中,如下图如所示。E:\Part_time_job_orders\YOLO_NEW\YOLOv12\ultralytics\v12_changemodel。
第二:在task.py中导入包
第三:在task.py中的模型配置部分下面代码
第四:将模型配置文件复制到YOLOV11.YAMY文件中
第五:运行代码
from ultralytics.models import NAS, RTDETR, SAM, YOLO, FastSAM, YOLOWorld
import torch
if __name__=="__main__":# 使用自己的YOLOv8.yamy文件搭建模型并加载预训练权重训练模型model = YOLO("/home/shengtuo/tangfan/YOLO11/ultralytics/cfg/models/11/yolo12_FSAS.yaml")\# .load(r'E:\Part_time_job_orders\YOLO\YOLOv11\yolo11n.pt') # build from YAML and transfer weightsresults = model.train(data="/home/shengtuo/tangfan/YOLO11/ultralytics/cfg/datasets/VOC_my.yaml",epochs=300,imgsz=640,batch=4,# cache = False,# single_cls = False, # 是否是单类别检测# workers = 0,# resume=r'D:/model/yolov8/runs/detect/train/weights/last.pt',amp = True)