【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。 除了用于连接、发布和订阅的控制报文,…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
