【YOLOv8改进[Backbone]】使用SCINet改进YOLOv8在黑暗环境的目标检测效果
目录
一 SCINet
1 本文方法
① 权重共享的照明学习
② 自校准模块
③ 无监督训练损失
二 使用SCINet助力YOLOv8在黑暗环境的目标检测效果
1 整体修改
2 配置文件
3 训练
其他
一 SCINet
官方论文地址:https://arxiv.org/pdf/2204.10137
官方代码地址:GitCode - 开发者的代码家园

现有的弱光图像增强技术不仅难以处理视觉质量和计算效率问题,而且在未知的复杂场景下通常无效。在本文中,提出了一种新的自校准照明(SCI)学习框架,用于在现实世界低光场景下快速,灵活和鲁棒的增亮图像。具体来说,建立了一个具有权重共享的级联照明学习过程来处理这个任务。作者考虑到级联模式的计算负担,构建了自校准模块,实现了各阶段结果之间的收敛,产生了仅使用单个基本块进行推理的增益(但在以往的工作中尚未被利用),大大降低了计算成本。然后,定义了无监督训练损失,以提高模型适应一般场景的能力。进一步,进行了全面的探索,挖掘SCI的固有属性(现有作品所缺乏的),包括操作不敏感的适应性。最后,大量的实验和消融研究充分表明了这一方法在质量和效率上的优势。在微光人脸检测和夜间语义分割等方面的应用充分显示了该方法潜在的实用价值。
在本文中,成功地建立了一个轻量级而有效的框架,即自校准照明(SCI),用于针对不同现实场景的低光图像增强。不仅对SCI的优良特性进行了深入的探索,还进行了大量的实验,证明了在弱光图像增强、暗人脸检测、夜间语义分割等方面的有效性和优越性。
1 本文方法
① 权重共享的照明学习
建立了一个具有权重共享的级联照明学习过程来处理低照度图像增强的任务。各个阶段共享权重。
② 自校准模块
构建了自校准模块,减少计算负担,实现了各阶段结果之间的收敛,产生了仅使用单个基本块进行推理的增益。
③ 无监督训练损失
定义了无监督训练损失,以提高模型适应一般场景的能力。
下图为SCI的整个框架。在训练阶段,SCI由照度估计和自校准模块组成。将自校准的模块映射添加到原始低照度输入中,作为下一阶段照度估计的输入。注意,这两个模块在整个训练过程中分别是共享参数。在测试阶段,只使用单个照明估计模块。权重共享的照明学习和自校准模块的设计为减少计算量并且提升结果的稳定性。

下图为比较是否使用自校准模块时各阶段结果的t-SNE[21]分布。这说明了为什么可以使用单级进行测试,即SCI中每级的结果都可以快速收敛到相同的值,而w/o自校准模块却无法始终实现这一点。

以下为各方法对比结果:


二 使用SCINet助力YOLOv8在黑暗环境的目标检测效果
整个结构的示意图如下所示:

1 整体修改
① 添加SCINet.py文件
在ultralytics/nn/modules目录下新建SCINet.py文件,文件的内容如下:
import torch
import torch.nn as nn__all__ = ['EnhanceNetwork']class EnhanceNetwork(nn.Module):def __init__(self, layers, channels):super(EnhanceNetwork, self).__init__()kernel_size = 3dilation = 1padding = int((kernel_size - 1) / 2) * dilationself.in_conv = nn.Sequential(nn.Conv2d(in_channels=3, out_channels=channels, kernel_size=kernel_size, stride=1, padding=padding),nn.ReLU())self.conv = nn.Sequential(nn.Conv2d(in_channels=channels, out_channels=channels, kernel_size=kernel_size, stride=1, padding=padding),nn.BatchNorm2d(channels),nn.ReLU())self.blocks = nn.ModuleList()for i in range(layers):self.blocks.append(self.conv)self.out_conv = nn.Sequential(nn.Conv2d(in_channels=channels, out_channels=3, kernel_size=3, stride=1, padding=1),nn.Sigmoid())def forward(self, input):fea = self.in_conv(input)for conv in self.blocks:fea = fea + conv(fea)fea = self.out_conv(fea)illu = fea + inputillu = torch.clamp(illu, 0.0001, 1)return illuclass CalibrateNetwork(nn.Module):def __init__(self, layers, channels):super(CalibrateNetwork, self).__init__()kernel_size = 3dilation = 1padding = int((kernel_size - 1) / 2) * dilationself.layers = layersself.in_conv = nn.Sequential(nn.Conv2d(in_channels=3, out_channels=channels, kernel_size=kernel_size, stride=1, padding=padding),nn.BatchNorm2d(channels),nn.ReLU())self.convs = nn.Sequential(nn.Conv2d(in_channels=channels, out_channels=channels, kernel_size=kernel_size, stride=1, padding=padding),nn.BatchNorm2d(channels),nn.ReLU(),nn.Conv2d(in_channels=channels, out_channels=channels, kernel_size=kernel_size, stride=1, padding=padding),nn.BatchNorm2d(channels),nn.ReLU())self.blocks = nn.ModuleList()for i in range(layers):self.blocks.append(self.convs)self.out_conv = nn.Sequential(nn.Conv2d(in_channels=channels, out_channels=3, kernel_size=3, stride=1, padding=1),nn.Sigmoid())def forward(self, input):fea = self.in_conv(input)for conv in self.blocks:fea = fea + conv(fea)fea = self.out_conv(fea)delta = input - feareturn deltaclass Network(nn.Module):def __init__(self, stage=3):super(Network, self).__init__()self.stage = stageself.enhance = EnhanceNetwork(layers=1, channels=3)self.calibrate = CalibrateNetwork(layers=3, channels=16)self._criterion = LossFunction()def weights_init(self, m):if isinstance(m, nn.Conv2d):m.weight.data.normal_(0, 0.02)m.bias.data.zero_()if isinstance(m, nn.BatchNorm2d):m.weight.data.normal_(1., 0.02)def forward(self, input):ilist, rlist, inlist, attlist = [], [], [], []input_op = inputfor i in range(self.stage):inlist.append(input_op)i = self.enhance(input_op)r = input / ir = torch.clamp(r, 0, 1)att = self.calibrate(r)input_op = input + attilist.append(i)rlist.append(r)attlist.append(torch.abs(att))return ilist, rlist, inlist, attlistdef _loss(self, input):i_list, en_list, in_list, _ = self(input)loss = 0for i in range(self.stage):loss += self._criterion(in_list[i], i_list[i])return lossclass Finetunemodel(nn.Module):def __init__(self, weights):super(Finetunemodel, self).__init__()self.enhance = EnhanceNetwork(layers=1, channels=3)self._criterion = LossFunction()base_weights = torch.load(weights)pretrained_dict = base_weightsmodel_dict = self.state_dict()pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}model_dict.update(pretrained_dict)self.load_state_dict(model_dict)def weights_init(self, m):if isinstance(m, nn.Conv2d):m.weight.data.normal_(0, 0.02)m.bias.data.zero_()if isinstance(m, nn.BatchNorm2d):m.weight.data.normal_(1., 0.02)def forward(self, input):i = self.enhance(input)r = input / ir = torch.clamp(r, 0, 1)return i, rdef _loss(self, input):i, r = self(input)loss = self._criterion(input, i)return loss
② 修改ultralytics/nn/tasks.py文件
具体的修改内容如下图所示:

修改parse_model函数的内容如下所示:

2 配置文件
yolov8_SCINet.yaml 的内容与原版对比:

3 训练
上述修改完毕后,开始训练吧!🌺🌺🌺🌺🌺🌺
训练示例:
yolo task=detect mode=train model=cfg/models/v8/yolov8_SCINet.yaml data=cfg/datasets/coco128.yaml epochs=200 batch=16 device=cpu project=yolov8

其他
说明:私信问题,不回答了哈,有问题可以评论,会随缘回答哈。希望理解哈!💛 💙 💜 ❤️ 💚 💛 💙 💜 ❤️ 💚
到此,本文分享的内容就结束啦!遇见便是缘,感恩遇见!!!💛 💙 💜 ❤️ 💚
相关文章:
【YOLOv8改进[Backbone]】使用SCINet改进YOLOv8在黑暗环境的目标检测效果
目录 一 SCINet 1 本文方法 ① 权重共享的照明学习 ② 自校准模块 ③ 无监督训练损失 二 使用SCINet助力YOLOv8在黑暗环境的目标检测效果 1 整体修改 2 配置文件 3 训练 其他 一 SCINet 官方论文地址:https://arxiv.org/pdf/2204.10137 官方代码地址&…...
ASE docker related research
ASE 2022 Understanding and Predicting Docker Build Duration: An Empirical Study of Containerized Workflow of OSS Projects 理解和预测 Docker 构建持续时间:OSS 项目容器化工作流程的实证研究 Docker 构建是容器化工作流程的关键组成部分,它…...
maven .lastUpdated文件作用
现象 有时候我在用maven管理项目时会发现有些依赖报错,这时你可以看一下本地仓库中是否有.lastUpdated文件,也许与它有关。 原因 有这个文件就表示依赖下载过程中发生了错误导致依赖没成功下载,可能是网络原因,也有可能是远程…...
gtest的编译与使用
文章目录 gtest的编译与使用概述笔记CMake参数官方文档测试程序测试效果END gtest的编译与使用 概述 gTest是 googletest的缩写,如果直接找gTest项目,是找不到的。 库地址 https://github.com/google/googletest.git 迁出到本地后,切到最新…...
【 npm详解:从入门到精通】
文章目录 npm详解:从入门到精通1. [npm](https://www.npmjs.com/)的安装2. npm的基础用法2.1 初始化项目2.2 安装依赖2.3 卸载依赖2.4 更新依赖 3. npm的高级用法3.1 运行脚本3.2 使用npm scope3.3 使用npm link 4. npm资源5. 使用npm进行依赖树分析和可视化6. npm进…...
【Web后端】实现文件上传
表单必须使用post提交 ,enctype 必须是multipart/form-data在Servlet上填加注解 MultipartConfiglocation :默认情况下将存储文件的目录,默认值为“”。maxFileSize :允许上传文件的最大大小,其值以字节为单位。 默认值为-1L表示无…...
react 逻辑 AND 运算符 ()
在 React 组件中,当你想在条件为 true 时渲染一些 JSX 时,它经常会出现,或者什么都不渲染。使用 ,只有在以下情况下才能有条件地呈现复选标记:&&isPackedtrue return (<li className"item">{…...
Redis详解(二)
事务 什么是事务? 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都…...
嵌入式:基于STM32的智能家居照明控制系统
在智能家居系统中,自动照明控制不仅提高了居住舒适度,还有助于节能减排。本教程旨在引导读者通过使用STM32微控制器来开发一个智能照明控制系统。该系统能够根据环境光线自动调整室内照明的亮度,并支持通过简单的用户界面手动控制光线。 一、…...
三种基本排序-冒泡,选择,二分
闲话不多说,直接上代码,简明易懂,条理清晰,交互性强,尽善尽美 码住,建议copy下来: 先上二分法吧,稍复杂点的,代码多一些,用了函数调用 二分排序࿱…...
windows查找重复的物理地址
单独查询所有物理(mac)地址(cmd执行):arp -a 查找同一局域网下重复的mac,打开power shell执行以下命令: Get-NetNeighbor | Where-Object { $_.State -eq "Reachable" } | Select-O…...
linux进阶高级配置,你需要知道的有哪些(8)-shell脚本应用(三)
1、for循环语句的结构: for 变量名 in 取值列表 do 命令序列 done 2、while循环语句结构: while 条件测试 do 命令序列 done 3、for和while的区别 for:控制循环来自于取值列表 while:控制循环来自于条件测试 4、case语句的…...
安全测试|常见SQL注入攻击方式、影响及预防
SQL注入 什么是SQL注入? SQL注入是比较常见的网络攻击方式之一,主要攻击对象是数据库,针对程序员编写时的疏忽,通过SQL语句,实现无账号登录,篡改数据库。 SQL注入简单来说就是通过在表单中填写包含SQL关键…...
【Git】Git在Gitee上的基本操作指南
文章目录 1. 查看 git 版本2. 从Gitee克隆仓库:3. 复制文件到工作目录:4. 将未跟踪的文件添加到暂存区:5. 在本地提交更改:6. 将更改推送到远程仓库(Gitee):7. Windows特定提示: 1. …...
国债期货怎么买?十年国债交易手册
国债,简单来说,就是国家为了筹集资金而向大众借钱的一种方式。国家通过发行债券,向投资者承诺在约定的时间里支付利息,并在到期时归还本金。因为是国家发行的,所以国债的信用等级非常高,通常被认为是非常安…...
公司申请增加公众号数量
一般可以申请多少个公众号?众所周知,在2013年前后,公众号申请是不限制数量的,后来企业开始限制申请50个,直到2018年的11月tx又发布,其中个人主体可申请公众号由2个调整为1个,企业主体由50个调整…...
什么是.faust勒索病毒?应该如何防御?
faust勒索病毒详细介绍 faust勒索病毒是一种新型的勒索软件,最早出现在2018年。该病毒通过加密计算机系统中的文件并要求支付赎金来解锁文件,从而获取经济利益。与传统的勒索软件相比,faust勒索病毒采用了更加先进的加密算法和隐藏技术&#…...
邓闲小——生存、生活、生命|真北写作
人生有三个层次∶生存、生活、生命。 生存就是做必须做的事。生存的模式是邓,是交易,是买卖。别人需要的东西,你生产出来,卖给他。哪怕这个东西没啥用,也可以卖,情绪也可以卖。你需要的东西,你花…...
品牌舆情都包含什么内容?建议收藏
一个品牌的声誉、形象、产品质量、服务质量等,无时无刻不在接受着大众的检验。互联网传播迅速,一个不好的舆论直接导致整个品牌的声誉受到严重影响。品牌舆情都包含什么内容?接下来伯乐网络传媒就来给大家讲一讲。 一、品牌舆情的基本构成 1…...
MQTT 5.0 报文解析 04:PINGREQ 与 PINGRESP
欢迎阅读 MQTT 5.0 报文系列 的第四篇文章。在上一篇中,我们已经介绍了 MQTT 5.0 中的 SUBSCRIBE 报文和 UNSUBSCRIBE 报文。现在,我们将介绍用于维持连接的控制报文:PINGREQ 和 PINGRESP。 除了用于连接、发布和订阅的控制报文,…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
DeepSeek越强,Kimi越慌?
被DeepSeek吊打的Kimi,还有多少人在用? 去年,月之暗面创始人杨植麟别提有多风光了。90后清华学霸,国产大模型六小虎之一,手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水,单月光是投流就花费2个亿。 疯…...
【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space
问题:IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案:将编译的堆内存增加一点 位置:设置setting-》构建菜单build-》编译器Complier...
