学习资源站

YOLOv11改进-特殊场景检测篇-低照度图像增强网络SCINet改进黑暗目标检测(全网独家首发)

一、本文介绍

本文给大家带来的改进机制是低照度 图像增强 网络SCINet, SCINet(自校正照明网络) 是一种专为 低光照图像增强设计 的框架。它通过 级联照明学习过程和权重共享机制 来处理图像,优化了照明部分以提升图像质量。我将该网络集成在YOLOv11的主干上针对于图像的输入进行增强,同时该网络的并不会增加参数和计算量,基本和普通的网络结构保持一致,同时该结构支持自定义调节层数,来控制图像增强的效果 ,非常适合想要在黑夜 目标检测 领域发表文章的读者, 该基本网络不会影响模型的速度。

欢迎大家订阅我的专栏一起学习YOLO!



二、SCINet原理

​​

论文地址: 论文官方地址

代码地址: 代码官方地址

​​


2.2  SCINet原理

SCINet(自校正照明网络) 是一种专为 低光照图像增强设计 的框架。它通过 级联照明学习过程和权重共享机制 来处理图像,优化了照明部分以提升图像质量。SCINet引入了 自校正模块 ,用于减少计算负担并提高结果的稳定性。此外,其 无监督训练损失 功能使得 模型 能够适应不同场景。SCINet还显示出对简单操作设置的稳定性能适应性,以及可以提升现有照明增强工作性能的普适性。

SCINet的基本原理 可以分为以下几个主要部分:

1. 级联照明学习与权重共享: SCINet采用了一个级联的照明学习过程,其中各个阶段共享权重。这种设计旨在优化照明 组件 ,从而提升低光照图像的增强效果。

2. 自校正模块: 为了减少计算负担并提高暴¶稳定性,SCINet构建了一个自校正模块。这个模块能够使每个阶段的结果收敛,从而在测试阶段仅需使用单个基础块。

3. 无监督训练损失: 作者定义了一种无监督训练损失来约束自校正模块下每个阶段的输出,使模型能够适应多种场景。

注意: YOLO网络只涉及到“级联照明学习与权重共享”,所以本篇文章着重介绍其级联照明学习与权重共享的相关内容。


2.3 级联照明学习与权重共享

级联照明学习与权重共享 是SCINet的核心特性之一,主要包含以下几个方面:

1. 级联过程 :在级联照明学习中,模型由多个阶段组成,每个阶段都对输入图像的照明进行估计。这种多阶段的处理方式有助于逐步改善图像亮度,每个阶段都在前一个阶段的基础上进一步提升图像质量。

2. 权重共享: 在这些阶段中,模型的参数(权重)是共享的。这意味着,尽管每个阶段都执行相似的任务,但它们使用相同的模型参数来执行这些任务。权重共享可以减少模型的整体参数数量,从而减少了模型的复杂性和 过拟合 的风险。

3. 自校正模块: 在每个阶段之后,一个自校正模块被用来校正当前阶段的输出。这一校正确保了随着级联过程的进行,每个阶段的输出逐渐趋于稳定,并且最终输出的质量不会因为过多的处理步骤而退化。

4. 计算效率: 由于使用了权重共享,模型在训练时可以有效地学习如何处理低光照图像。在测试阶段,只需使用单个照明估计模块,这大大简化了模型并提高了推理速度。

5. 性能提升: 级联照明学习与权重共享的结合使得模型不仅在处理单一图像时表现出色,也能够适应不同的低光照条件和场景,提升了模型的 泛化 能力和实际应用价值。

下图为大家展示了 SCINet的整体框架 特别是在训练阶段包括照明估计和自校正模块两部分。

自校正模块的输出被添加到原始的低光照输入中,作为下一阶段照明估计的输入。这两个模块在整个训练过程中共享参数。在测试阶段,仅使用单个照明估计模块。这与SCINet基本原理的第一点和第二点紧密相关,即级联照明学习过程和权重共享以及自校正模块的设计来减少计算负担并提高结果的稳定性。


三、SCINet的核心代码

  1. import torch
  2. import torch.nn as nn
  3. __all__ = ['SCINet']
  4. class SCINet(nn.Module):
  5. def __init__(self, channels=3, layers=3):
  6. super(SCINet, self).__init__()
  7. kernel_size = 3
  8. dilation = 1
  9. padding = int((kernel_size - 1) / 2) * dilation
  10. self.in_conv = nn.Sequential(
  11. nn.Conv2d(in_channels=3, out_channels=channels, kernel_size=kernel_size, stride=1, padding=padding),
  12. nn.ReLU()
  13. )
  14. self.conv = nn.Sequential(
  15. nn.Conv2d(in_channels=channels, out_channels=channels, kernel_size=kernel_size, stride=1, padding=padding),
  16. nn.BatchNorm2d(channels),
  17. nn.ReLU()
  18. )
  19. self.blocks = nn.ModuleList()
  20. for i in range(layers):
  21. self.blocks.append(self.conv)
  22. self.out_conv = nn.Sequential(
  23. nn.Conv2d(in_channels=channels, out_channels=3, kernel_size=3, stride=1, padding=1),
  24. nn.Sigmoid()
  25. )
  26. def forward(self, input):
  27. fea = self.in_conv(input)
  28. for conv in self.blocks:
  29. fea = fea + conv(fea)
  30. fea = self.out_conv(fea)
  31. illu = fea + input
  32. illu = torch.clamp(illu, 0.0001, 1)
  33. return illu
  34. if __name__ == "__main__":
  35. # Generating Sample image
  36. image_size = (1, 3, 640, 640)
  37. image = torch.rand(*image_size)
  38. # Model
  39. mobilenet_v1 = SCINet(3, 3)
  40. out = mobilenet_v1(image)
  41. print(out.size())


四、SCINet的添加方式

这个添加方式和之前的变了一下,以后的添加方法都按照这个来了,是为了和群内的文件适配。


4.1 修改一

第一还是建立文件,我们找到如下 ultralytics /nn文件夹下建立一个目录名字呢就是'Addmodules'文件夹( 用群内的文件的话已经有了无需新建) !然后在其内部建立一个新的py文件将核心代码复制粘贴进去即可。


4.2 修改二

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


4.3 修改三

第三步我门中到如下文件'ultralytics/nn/tasks.py'进行导入和注册我们的模块( 用群内的文件的话已经有了无需重新导入直接开始第四步即可)

从今天开始以后的教程就都统一成这个样子了,因为我默认大家用了我群内的文件来进行修改!!


4.4 修改四

按照我的添加在parse_model里添加即可。


五、SCINet的yaml文件和运行记录

5.1 SCINet的yaml文件

此版本训练信息:YOLO11-SCINet summary: 331 layers, 2,591,073 parameters, 2,591,057 gradients, 7.5 GFLOPs

  1. # Ultralytics YOLO 🚀, AGPL-3.0 license
  2. # YOLO11 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect
  3. # Parameters
  4. nc: 80 # number of classes
  5. scales: # model compound scaling constants, i.e. 'model=yolo11n.yaml' will call yolo11.yaml with scale 'n'
  6. # [depth, width, max_channels]
  7. n: [0.50, 0.25, 1024] # summary: 319 layers, 2624080 parameters, 2624064 gradients, 6.6 GFLOPs
  8. s: [0.50, 0.50, 1024] # summary: 319 layers, 9458752 parameters, 9458736 gradients, 21.7 GFLOPs
  9. m: [0.50, 1.00, 512] # summary: 409 layers, 20114688 parameters, 20114672 gradients, 68.5 GFLOPs
  10. l: [1.00, 1.00, 512] # summary: 631 layers, 25372160 parameters, 25372144 gradients, 87.6 GFLOPs
  11. x: [1.00, 1.50, 512] # summary: 631 layers, 56966176 parameters, 56966160 gradients, 196.0 GFLOPs
  12. # YOLO11n backbone
  13. backbone:
  14. # [from, repeats, module, args]
  15. - [-1, 1, SCINet, []] # 0-P1/2
  16. - [-1, 1, Conv, [64, 3, 2]] # 1-P1/2
  17. - [-1, 1, Conv, [128, 3, 2]] # 2-P2/4
  18. - [-1, 2, C3k2, [256, False, 0.25]]
  19. - [-1, 1, Conv, [256, 3, 2]] # 4-P3/8
  20. - [-1, 2, C3k2, [512, False, 0.25]]
  21. - [-1, 1, Conv, [512, 3, 2]] # 6-P4/16
  22. - [-1, 2, C3k2, [512, True]]
  23. - [-1, 1, Conv, [1024, 3, 2]] # 8-P5/32
  24. - [-1, 2, C3k2, [1024, True]]
  25. - [-1, 1, SPPF, [1024, 5]] # 10
  26. - [-1, 2, C2PSA, [1024]] # 11
  27. # YOLO11n head
  28. head:
  29. - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  30. - [[-1, 7], 1, Concat, [1]] # cat backbone P4
  31. - [-1, 2, C3k2, [512, False]] # 14
  32. - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  33. - [[-1, 5], 1, Concat, [1]] # cat backbone P3
  34. - [-1, 2, C3k2, [256, False]] # 17 (P3/8-small)
  35. - [-1, 1, Conv, [256, 3, 2]]
  36. - [[-1, 14], 1, Concat, [1]] # cat head P4
  37. - [-1, 2, C3k2, [512, False]] # 20 (P4/16-medium)
  38. - [-1, 1, Conv, [512, 3, 2]]
  39. - [[-1, 11], 1, Concat, [1]] # cat head P5
  40. - [-1, 2, C3k2, [1024, True]] # 23 (P5/32-large)
  41. - [[17, 20, 23], 1, Detect, [nc]] # Detect(P3, P4, P5)


5.2 SCINet的训练过程截图


五、本文总结

到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv11改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~