YOLOv8改进 | 图像去雾 | 特征融合注意网络FFA-Net增强YOLOv8对于模糊图片检测能力(北大和北航联合提出)
一、本文介绍
本文给大家带来的改进机制是由北大和北航联合提出的FFA-net: Feature Fusion Attention Network for Single Image Dehazing图像增强去雾网络,该网络的主要思想是利用特征融合注意力网络(Feature Fusion Attention Network)直接恢复无雾图像,FFA-Net通过特征注意力机制和特征融合注意力结构的创新设计,有效地提升了单图像去雾技术的性能。通过巧妙地结合通道和像素注意力,以及局部残差学习,网络能够更加精准地处理不同区域的雾霾,实现了在细节保留和色彩保真度上的显著提升。
欢迎大家订阅我的专栏一起学习YOLO!

专栏目录:YOLOv8改进有效系列目录 | 包含卷积、主干、检测头、注意力机制、Neck上百种创新机制
专栏回顾:YOLOv8改进系列专栏——本专栏持续复习各种顶会内容——科研必备
目录
一、本文介绍
二、原理介绍
三、核心代码
四、添加方式教程
4.1 修改一
4.2 修改二
4.3 修改三
4.4 修改四
五、yaml文件和运行记录
5.1 yaml文件1
5.2 训练代码
5.3 训练过程截图
五、本文总结
二、原理介绍

官方论文地址: 官方论文地址点击此处即可跳转
官方代码地址: 官方代码地址点击此处即可跳转

FFA-Net的主要思想是利用特征融合注意力网络(Feature Fusion Attention Network)直接恢复无雾图像。这种架构通过三个关键组件实现高效的图像去雾效果:
1. 特征注意力(Feature Attention, FA)模块:结合通道注意力(Channel Attention)和像素注意力(Pixel Attention)机制,因为不同通道的特征包含完全不同的加权信息,且雾的分布在不同的图像像素上是不均匀的。FA通过不平等地对待不同的特征和像素,提供了处理不同信息类型的额外灵活性,从而扩展了卷积神经网络的表示能力。
2. 基本块结构:包含局部残差学习(Local Residual Learning)和特征注意力。局部残差学习允许如轻雾区域或低频等不那么重要的信息通过多个局部残差连接被绕过,使主网络架构可以专注于更有效的信息。
3. 基于注意力的不同级别特征融合(FFA)结构:通过特征注意力(FA)模块自适应学习的特征权重,给予重要特征更多的权重。这种结构还可以保留浅层的信息,并将其传递到深层。
个人总结:
FFA-Net通过特征注意力机制和特征融合注意力结构的创新设计,有效地提升了单图像去雾技术的性能。通过巧妙地结合通道和像素注意力,以及局部残差学习,网络能够更加精准地处理不同区域的雾霾,实现了在细节保留和色彩保真度上的显著提升。
三、核心代码
核心代码的使用方式看章节四!
import torch.nn as nn
import torchdef default_conv(in_channels, out_channels, kernel_size, bias=True):return nn.Conv2d(in_channels, out_channels, kernel_size, padding=(kernel_size // 2), bias=bias)class PALayer(nn.Module):def __init__(self, channel):super(PALayer, self).__init__()self.pa = nn.Sequential(nn.Conv2d(channel, channel // 8, 1, padding=0, bias=True),nn.ReLU(inplace=True),nn.Conv2d(channel // 8, 1, 1, padding=0, bias=True),nn.Sigmoid())def forward(self, x):y = self.pa(x)return x * yclass CALayer(nn.Module):def __init__(self, channel):super(CALayer, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.ca = nn.Sequential(nn.Conv2d(channel, channel // 8, 1, padding=0, bias=True),nn.ReLU(inplace=True),nn.Conv2d(channel // 8, channel, 1, padding=0, bias=True),nn.Sigmoid())def forward(self, x):y = self.avg_pool(x)y = self.ca(y)return x * yclass Block(nn.Module):def __init__(self, conv, dim, kernel_size, ):super(Block, self).__init__()self.conv1 = conv(dim, dim, kernel_size, bias=True)self.act1 = nn.ReLU(inplace=True)self.conv2 = conv(dim, dim, kernel_size, bias=True)self.calayer = CALayer(dim)self.palayer = PALayer(dim)def forward(self, x):res = self.act1(self.conv1(x))res = res + xres = self.conv2(res)res = self.calayer(res)res = self.palayer(res)res += xreturn resclass Group(nn.Module):def __init__(self, conv, dim, kernel_size, blocks):super(Group, self).__init__()modules = [Block(conv, dim, kernel_size) for _ in range(blocks)]modules.append(conv(dim, dim, kernel_size))self.gp = nn.Sequential(*modules)def forward(self, x):res = self.gp(x)res += xreturn resclass FFA(nn.Module):def __init__(self, gps=3, blocks=1, conv=default_conv):super(FFA, self).__init__()self.gps = gpsself.dim = 8kernel_size = 3pre_process = [conv(3, self.dim, kernel_size)]assert self.gps == 3self.g1 = Group(conv, self.dim, kernel_size, blocks=blocks)self.g2 = Group(conv, self.dim, kernel_size, blocks=blocks)self.g3 = Group(conv, self.dim, kernel_size, blocks=blocks)self.ca = nn.Sequential(*[nn.AdaptiveAvgPool2d(1),nn.Conv2d(self.dim * self.gps, self.dim // 4, 1, padding=0),nn.ReLU(inplace=True),nn.Conv2d(self.dim // 4, self.dim * self.gps, 1, padding=0, bias=True),nn.Sigmoid()])self.palayer = PALayer(self.dim)post_precess = [conv(self.dim, self.dim, kernel_size),conv(self.dim, 3, kernel_size)]self.pre = nn.Sequential(*pre_process)self.post = nn.Sequential(*post_precess)def forward(self, x1):x = self.pre(x1)res1 = self.g1(x)res2 = self.g2(res1)res3 = self.g3(res2)w = self.ca(torch.cat([res1, res2, res3], dim=1))w = w.view(-1, self.gps, self.dim)[:, :, :, None, None]out = w[:, 0, ::] * res1 + w[:, 1, ::] * res2 + w[:, 2, ::] * res3out = self.palayer(out)x = self.post(out)return x + x1if __name__ == "__main__":image_size = (1, 3, 640, 640)image = torch.rand(*image_size)net = FFA(gps=3, blocks=1)out = net(image)print(out.size())
四、添加方式教程
4.1 修改一
第一还是建立文件,我们找到如下ultralytics/nn/modules文件夹下建立一个目录名字呢就是'Addmodules'文件夹(用群内的文件的话已经有了无需新建)!然后在其内部建立一个新的py文件将核心代码复制粘贴进去即可。

4.2 修改二
第二步我们在该目录下创建一个新的py文件名字为'__init__.py'(用群内的文件的话已经有了无需新建),然后在其内部导入我们的检测头如下图所示。

4.3 修改三
第三步我门中到如下文件'ultralytics/nn/tasks.py'进行导入和注册我们的模块(用群内的文件的话已经有了无需重新导入直接开始第四步即可)!
从今天开始以后的教程就都统一成这个样子了,因为我默认大家用了我群内的文件来进行修改!!
4.4 修改四
按照我的添加在parse_model里添加即可。

到此就修改完成了,大家可以复制下面的yaml文件运行。
五、yaml文件和运行记录
5.1 yaml文件1
# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]n: [0.33, 0.25, 1024] # YOLOv8n summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPss: [0.33, 0.50, 1024] # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients, 28.8 GFLOPsm: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients, 79.3 GFLOPsl: [1.00, 1.00, 512] # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPsx: [1.00, 1.25, 512] # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs# YOLOv8.0n backbone
backbone:# [from, repeats, module, args]- [-1, 1, FFA, []] # 0-P1/2- [-1, 1, Conv, [64, 3, 2]] # 1-P1/2- [-1, 1, Conv, [128, 3, 2]] # 2-P2/4- [-1, 3, C2f, [128, True]]- [-1, 1, Conv, [256, 3, 2]] # 4-P3/8- [-1, 6, C2f, [256, True]]- [-1, 1, Conv, [512, 3, 2]] # 6-P4/16- [-1, 6, C2f, [512, True]]- [-1, 1, Conv, [1024, 3, 2]] # 8-P5/32- [-1, 3, C2f, [1024, True]]- [-1, 1, SPPF, [1024, 5]] # 10# YOLOv8.0n head
head:- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 7], 1, Concat, [1]] # cat backbone P4- [-1, 3, C2f, [512]] # 13- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 5], 1, Concat, [1]] # cat backbone P3- [-1, 3, C2f, [256]] # 16 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 13], 1, Concat, [1]] # cat head P4- [-1, 3, C2f, [512]] # 19 (P4/16-medium)- [-1, 1, Conv, [512, 3, 2]]- [[-1, 10], 1, Concat, [1]] # cat head P5- [-1, 3, C2f, [1024]] # 22 (P5/32-large)- [[16, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5)
5.2 训练代码
大家可以创建一个py文件将我给的代码复制粘贴进去,配置好自己的文件路径即可运行。
import warnings
warnings.filterwarnings('ignore')
from ultralytics import YOLOif __name__ == '__main__':model = YOLO('ultralytics/cfg/models/v8/yolov8-C2f-FasterBlock.yaml')# model.load('yolov8n.pt') # loading pretrain weightsmodel.train(data=r'替换数据集yaml文件地址',# 如果大家任务是其它的'ultralytics/cfg/default.yaml'找到这里修改task可以改成detect, segment, classify, posecache=False,imgsz=640,epochs=150,single_cls=False, # 是否是单类别检测batch=4,close_mosaic=10,workers=0,device='0',optimizer='SGD', # using SGD# resume='', # 如过想续训就设置last.pt的地址amp=False, # 如果出现训练损失为Nan可以关闭ampproject='runs/train',name='exp',)
5.3 训练过程截图

五、本文总结
到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv8改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~
专栏目录:YOLOv8改进有效系列目录 | 包含卷积、主干、检测头、注意力机制、Neck上百种创新机制
相关文章:
YOLOv8改进 | 图像去雾 | 特征融合注意网络FFA-Net增强YOLOv8对于模糊图片检测能力(北大和北航联合提出)
一、本文介绍 本文给大家带来的改进机制是由北大和北航联合提出的FFA-net: Feature Fusion Attention Network for Single Image Dehazing图像增强去雾网络,该网络的主要思想是利用特征融合注意力网络(Feature Fusion Attention Network)直接…...
Python (用户登录、身份归属地查询添加异常处理、绘制多角星、电影信息提取)
任务一:用户登录 登录系统通常分为普通用户与管理员权限,在用户登录系统时,可以根据自身权限进行选择登录。本任务要求实现一个用户登录的程序,该程序分为管理员用户与普通用户,其中管理员账号密码在程序中设定&#…...
Set cancelled by MemoryScratchSinkOperator
Bug信息 Caused by: com.starrocks.connector.spark.exception.StarrocksInternalException: StarRocks server StarRocks BE{host=10.9.14.39, port=9060} internal failed, status code [CANCELLED] error message is [Set cancelled by MemoryScratchSinkOperator]Bug产生的…...
Python 查找PDF中的指定文本并高亮显示
在处理大量PDF文档时,有时我们需要快速找到特定的文本信息。本文将提供以下三个Python示例来帮助你在PDF文件中快速查找并高亮指定的文本。 查找并高亮PDF中所有的指定文本查找并高亮PDF某个区域内的指定文本使用正则表达式搜索指定文本并高亮 本文将用到国产第三方…...
岩土工程渗流问题之有限单元法:理论、模块化编程实现、开源程序应用
有限单元法在岩土工程问题中应用非常广泛,很多商业软件如Plaxis/Abaqus/Comsol等都采用有限单元解法。尽管各类商业软件使用方便,但其使用对用户来说往往是一个“黑箱子”。相比而言,开源的有限元程序计算方法透明、计算过程可控,…...
解决 :nvrtc: error: invalid value for --gpu-architecture (-arch)
核心:在显卡安装的cuda版本适配的pytorch中,更换pytorch的版本 刚遇到这个错误时,在网上搜索了一下,感谢博主1和博主2的解决方法带给我的启发。 标题服务器cuda是11.3版本,配置其他环境“御用”的pytorch安装语句 co…...
Rust教程:How to Rust-从开始之前到Hello World
本文为第0篇 专栏简介 本专栏是优质Rust技术专栏,推荐精通一门技术栈的蟹友,不建议基础的同学(无基础学Rust也是牛人[手动捂脸]) 感谢Rust圣经开源社区的同学,为后来者提供了非常优秀的Rust学习资源 本文使用&…...
浅谈人工智能
☕️各位观众老爷好,路过点个免费的赞再走呗!❤️❤️(*•̀ᴗ•́*)و 前言 随着2024年的到来,人工智能领域正迎来前所未有的变革和发展。随着计算能力的增强、大数据的积累以及机器学习算法的进步, AI的定义和本质 人工智能…...
OpenFeign服务接口调用
OpenFeign服务接口调用 1、OpenFeign简介 Feign是一个声明性web服务客户端。它使编写web服务客户端变得更容易。使用Feign创建一个接口并对其进行注释。它具有可插入的注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud添加…...
SQLiteC/C++接口详细介绍之sqlite3类(五)
快速跳转文章列表:SQLite—系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(四) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(六)(未发表) 14.sqlite3_busy_handle…...
Linux 之二:CentOS7 的 IP 常用命令和配置及 xshell 基本使用方法
1. 进入虚拟机 点击右键---进入终端--输入 ip adrr 或 ifconfig 查看ip地址 下面输入命令 ifconfig(注意:不是 ipconfig ) 或 ip addr 来查看当前系统 IP 查看到IP 后,比如:上面是 192.168.184.137 1.1 IP 常用命令…...
24-Java策略模式 ( Strategy Pattern )
Java策略模式 摘要实现范例 策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。 策略模式属于行为型模式 摘要 1. 意图 针对一组算法,将每一个算法封装到具有共…...
突破编程_C++_C++11新特性(模板的改进与细节)
1 模板右尖括号的改进 在 C11 之前,模板的解析和实例化过程中,右尖括号 > 的处理有时会导致一些意外的结果,特别是在嵌套模板或模板模板参数中。这是因为 C 编译器通常会试图“查看前方”来确定何时结束模板参数的列表,这有时…...
云原生消息流系统 Apache RocketMQ 在腾讯云的大规模生产实践
导语 随着云计算技术的日益成熟,云原生应用已逐渐成为企业数字化转型的核心驱动力。在这一大背景下,高效、稳定、可扩展的消息流系统显得尤为重要。腾讯云高级开发工程师李伟先生,凭借其深厚的技术功底和丰富的实战经验,为我们带…...
Node.js的事件驱动模型(非阻塞I/O)
Node.js的事件驱动模型是它能高效处理并发的关键。这个模型允许Node.js在单个线程上运行,同时通过非阻塞I/O操作来处理成千上万的并发连接。下面是对Node.js事件驱动模型的详细解释: 事件循环(Event Loop) 事件循环是Node.js事件…...
java过滤器Filter相关知识点汇总
1.Filter概述 Servlet Filter又称Servlet过滤器,它是在Servlet2.3规范中定义的,能够对Servlet容器传给Web资源的request对象和response对象执行检查和修改。 Filter不是Servlet,不能直接访问,其本身也不能生成request对象和resp…...
旅游景区公共广播 园区广播 公路服务区广播
旅游景区公共广播 园区广播 公路服务区广播 旅游景区公共广播 旅游景区公共广播(又称背景音乐)简称BGM,它的主要作用是掩盖噪声并创造一种轻松和谐的气氛,是一种创造轻松愉快环境气氛的音乐。掩盖环境噪声,创造与旅游景区相适应的气氛&#…...
Elastic Stack--09--ElasticsearchRestTemplate
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 spring-data-elasticsearch提供的APIQueryBuildersElasticsearchRestTemplate 方法ElasticsearchRestTemplate ---操作索引 ElasticsearchRestTemplate ---文档操作…...
论坛管理系统|基于Spring Boot+ Mysql+Java+B/S架构的论坛管理系统设计与实现(可运行源码+数据库+设计文档+部署说明+视频演示)
推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 目录 前台功能效果图 管理员功能登录前台功能效果图 用户功能模块 系统功能设计 数据库E-R图设计 l…...
2022 Task 2 Max Sum of 2 integers sharing first and last digits
Task 2 There is an array A consisting of N integers. What’s the maximum sum of two integers from A that share their first and last digits? For example, 1007 and 167 share their first(1) and last(7) digits, whereas 2002 and 55 do not. Write a function: …...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
