YOLOv5改进 | 卷积模块 | 提高网络的灵活性和表征能力的动态卷积【附代码+小白可上手】
💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡
轻量级卷积神经网络由于其低计算预算限制了CNNs的深度(卷积层数)和宽度(通道数),导致了性能下降和表示能力受限的问题。而动态卷积恰好能解决这一问题,这是一种增加模型复杂性而不增加网络深度或宽度的新设计。本文给大家带来的教程是将YOLOv5的Conv用Dynamic_conv替换来提取特征。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改,并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。此外还增加了进阶模块,来提高学有能力的同学进一步增长知识。帮助您更好地学习深度学习目标检测YOLO系列的挑战。
专栏地址: YOLOv5改进+入门——持续更新各种有效涨点方法 点击即可跳转
目录
1.原理
2. 代码实现
2.1 将代码添加到YOLOv5中
2.2 新增yaml文件
2.3 注册模块
2.4 执行程序
3. 完整代码分享
4. GFLOPs
5. 进阶
6. 总结
1. 原理

论文地址:Dynamic Convolution: Attention over Convolution Kernels——点击即可跳转
官方代码:官方代码仓库——点击即可跳转
动态卷积的是基于注意力机制的,它允许网络动态地选择和组合多个卷积核,以适应输入数据的不同部分或特征。
-
多个卷积核的选择:
在传统的卷积操作中,每个卷积层通常使用固定的卷积核。而在动态卷积中,会事先定义一组多个卷积核,这些卷积核可能具有不同的大小和形状。 -
注意力机制:
动态卷积通过引入注意力机制来决定在每个位置使用哪些卷积核。这个注意力可以根据输入数据的不同部分或特征动态地调整,以使网络能够更好地捕捉输入数据的相关信息。 -
卷积核的组合:
根据注意力机制的输出,动态卷积会动态地选择并组合多个卷积核。这种组合可以通过加权求和的方式进行,其中每个卷积核的权重由注意力机制确定。 -
非线性激活:
组合后的卷积核将应用于输入数据,并通过非线性激活函数(如ReLU)产生输出特征图。 -
网络训练:
在训练过程中,网络将根据损失函数反向传播并更新注意力机制的参数,以使网络能够学习到适合任务的最佳注意力分配方式。
总的来说,动态卷积通过引入注意力机制和动态地选择和组合多个卷积核,使网络能够更灵活地适应输入数据的不同部分或特征,从而提高网络的表征能力和性能。
2. 代码实现
2.1 将代码添加到YOLOv5中
关键步骤一: 将下面代码粘贴到/projects/yolov5-6.1/models/common.py文件中

import torch
import torch.nn as nn
import torch.nn.functional as Fclass attention2d(nn.Module):def __init__(self, in_planes, ratios, K, temperature, init_weight=True):super(attention2d, self).__init__()assert temperature%3==1self.avgpool = nn.AdaptiveAvgPool2d(1)if in_planes!=3:hidden_planes = int(in_planes*ratios)else:hidden_planes = Kself.fc1 = nn.Conv2d(in_planes, hidden_planes, 1, bias=False)self.fc2 = nn.Conv2d(hidden_planes, K, 1, bias=False)self.temperature = temperatureif init_weight:self._initialize_weights()def _initialize_weights(self):for m in self.modules():if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')if m.bias is not None:nn.init.constant_(m.bias, 0)def updata_temperature(self):if self.temperature!=1:self.temperature -=3print('Change temperature to:', str(self.temperature))def forward(self, x):x = self.avgpool(x)x = self.fc1(x)x = F.relu(x)x = self.fc2(x).view(x.size(0), -1)return F.softmax(x/self.temperature, 1)class Dynamic_conv2d(nn.Module):def __init__(self, in_planes, out_planes, kernel_size, ratio=0.25, stride=1, padding=0, dilation=1, groups=1, bias=True, K=4,temperature=34, init_weight=True):super(Dynamic_conv2d, self).__init__()assert in_planes%groups==0self.in_planes = in_planesself.out_planes = out_planesself.kernel_size = kernel_sizeself.stride = strideself.padding = paddingself.dilation = dilationself.groups = groupsself.bias = biasself.K = Kself.attention = attention2d(in_planes, ratio, K, temperature)self.weight = nn.Parameter(torch.Tensor(K, out_planes, in_planes//groups, kernel_size, kernel_size), requires_grad=True)if bias:self.bias = nn.Parameter(torch.Tensor(K, out_planes))else:self.bias = Noneif init_weight:self._initialize_weights()#TODO 初始化def _initialize_weights(self):for i in range(self.K):nn.init.kaiming_uniform_(self.weight[i])def update_temperature(self):self.attention.updata_temperature()def forward(self, x): # 将batch视作维度变量,进行组卷积,因为组卷积的权重是不同的,动态卷积的权重也是不同的softmax_attention = self.attention(x)batch_size, in_planes, height, width = x.size()x = x.view(1, -1, height, width)# 变化成一个维度进行组卷积weight = self.weight.view(self.K, -1)# 动态卷积的权重的生成, 生成的是batch_size个卷积参数(每个参数不同)aggregate_weight = torch.mm(softmax_attention, weight).view(-1, self.in_planes, self.kernel_size, self.kernel_size)if self.bias is not None:aggregate_bias = torch.mm(softmax_attention, self.bias).view(-1)output = F.conv2d(x, weight=aggregate_weight, bias=aggregate_bias, stride=self.stride, padding=self.padding,dilation=self.dilation, groups=self.groups*batch_size)else:output = F.conv2d(x, weight=aggregate_weight, bias=None, stride=self.stride, padding=self.padding,dilation=self.dilation, groups=self.groups * batch_size)output = output.view(batch_size, self.out_planes, output.size(-2), output.size(-1))return output
动态卷积的流程如下:
-
准备多个卷积核:
首先,定义一组多个卷积核,这些卷积核可能具有不同的大小和形状。这些卷积核将作为动态卷积的基本构建单元。 -
计算注意力分布:
对于输入数据的每个位置,通过一个注意力网络或者其他注意力机制,计算出相应位置的注意力分布。这个注意力分布表示了不同卷积核在当前位置的重要程度。 -
动态卷积操作:
根据注意力分布,动态地选择和组合多个卷积核。通常是通过对每个卷积核的权重进行加权求和来实现,其中每个卷积核的权重由对应位置的注意力分布确定。 -
应用非线性激活:
将组合后的卷积核应用于输入数据,并通过非线性激活函数(如ReLU)产生输出特征图。 -
网络训练:
训练过程中,通过反向传播算法优化注意力网络或其他注意力机制的参数,以使网络能够学习到适合任务的最佳注意力分配方式。同时,也会更新卷积核的参数,使得网络能够学习到更好的特征表示。 -
重复步骤3至5:
在每个位置上重复执行动态卷积操作,直到整个输入数据被处理完毕,生成最终的输出特征图。
总结,动态卷积通过引入注意力机制来动态选择和组合多个卷积核,从而使网络能够更灵活地适应输入数据的不同部分或特征,从而提高网络的表征能力和性能。

2.2 新增yaml文件
关键步骤二:在/projects/yolov5-6.1/models下新建文件 yolov5_dynamic.yaml并将下面代码复制进去
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license# Parameters
nc: 80 # number of classes
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple
anchors:- [10,13, 16,30, 33,23] # P3/8- [30,61, 62,45, 59,119] # P4/16- [116,90, 156,198, 373,326] # P5/32# YOLOv5 v6.0 backbone
backbone:# [from, number, module, args][[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2[-1, 1, Conv, [128, 3, 2]], # 1-P2/4[-1, 3, C3, [128]],[-1, 1, Conv, [256, 3, 2]], # 3-P3/8[-1, 6, C3, [256]],[-1, 1, Conv, [512, 3, 2]], # 5-P4/16[-1, 9, C3, [512]],[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32[-1, 3, C3, [1024]],[-1, 1, SPPF, [1024, 5]], # 9]# YOLOv5 v6.0 head
head:[[-1, 1, Dynamic_conv2d, [512, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 6], 1, Concat, [1]], # cat backbone P4[-1, 3, C3, [512, False]], # 13[-1, 1, Dynamic_conv2d, [256, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 4], 1, Concat, [1]], # cat backbone P3[-1, 3, C3, [256, False]], # 17 (P3/8-small)[-1, 1, Conv, [256, 3, 2]],[[-1, 14], 1, Concat, [1]], # cat head P4[-1, 3, C3, [512, False]], # 20 (P4/16-medium)[-1, 1, Conv, [512, 3, 2]],[[-1, 10], 1, Concat, [1]], # cat head P5[-1, 3, C3, [1024, False]], # 23 (P5/32-large)[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)]
温馨提示:本文只是对yolov5l基础上添加swin模块,如果要对yolov8n/l/m/x进行添加则只需要指定对应的depth_multiple 和 width_multiple。
# YOLOv5n
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.25 # layer channel multiple# YOLOv5s
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple# YOLOv5l
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple# YOLOv5m
depth_multiple: 0.67 # model depth multiple
width_multiple: 0.75 # layer channel multiple# YOLOv5x
depth_multiple: 1.33 # model depth multiple
width_multiple: 1.25 # layer channel multiple
2.3 注册模块
关键步骤三:在yolo.py中注册, 大概在260行左右添加 ‘Dynamic_conv2d’

2.4 执行程序
在train.py中,将cfg的参数路径设置为yolov5_AKConv.yaml的路径
建议大家写绝对路径,确保一定能找到

🚀运行程序,如果出现下面的内容则说明添加成功🚀

3. 完整代码分享
https://pan.baidu.com/s/1iePDb_lNUhRKhWOevDRp3g?pwd=xs2y
提取码: xs2y
4. GFLOPs
关于GFLOPs的计算方式可以查看:百面算法工程师 | 卷积基础知识——Convolution
未改进的YOLOv5l的GFLOPs

改进后的YOLOv5l的GFLOPs

5. 进阶
如果想计算量变化更小,如何修改呢,看过我的修改你是否学会了呢?不如动手试试吧
如果你想尝试但又不知从何下手,可以在评论区问问大家,我看到后也会及时回复
6. 总结
动态卷积是一种通过引入注意力机制,动态选择和组合多个卷积核的方法,以提高卷积神经网络的表征能力和性能。通过在每个位置上根据输入数据的不同部分或特征动态调整卷积核的选择和权重,动态卷积能够更灵活地捕获输入数据的相关信息,并产生更具表征能力的特征表示。在训练过程中,网络通过反向传播算法优化注意力机制的参数,并更新卷积核的参数,从而学习到适合任务的最佳注意力分配方式和特征表示,进而提高了网络的性能,优化图像分类或目标检测的准确率。
相关文章:
YOLOv5改进 | 卷积模块 | 提高网络的灵活性和表征能力的动态卷积【附代码+小白可上手】
💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 轻量级卷积神经网络由于其低计算预算限制了CNNs的深度(卷积层数)和宽度(通道数),…...
23、linux系统文件和日志分析
linux文件系统与日志分析 文件时存储在硬盘上的,硬盘上的最小存储单位是扇区,每个扇区大大小是512字节。 inode:元信息(文件的属性 权限,创建者,创建日期等) block:块,…...
安装VS2017后,离线安装Debugging Tools for Windows(QT5.9.2使用MSVC2017 64bit编译器)
1、背景 安装VS2017后,Windows Software Development Kit - Windows 10.0.17763.132的Debugging Tools for Windows默认不会安装,如下图。这时在QT5.9.2无法使用MSVC2017 64bit编译器。 2、在线安装 如果在线安装参考之前的文章: Qt5.9.2初…...
路由策略实验2
对R7,重发布直连路由 对R2,做双向 对R3同样 先不改优先级 查看,知道所有给R3的路由为151,全部为OSPF。 知道了是错误的,先把3,4之间的线路断掉 接着对R3,让优先级全部回到100(displa…...
Linux网络-守护进程版字典翻译服务器
文章目录 前言一、pid_t setsid(void);二、守护进程翻译字典服务器(守护线程版)效果图 前言 根据上章所讲的后台进程组和session会话,我们知道如果可以将一个进程放入一个独立的session,可以一定程度上守护该进程。 一、pid_t se…...
Python 推导式详解:高效简洁的数据处理技巧
推导式是 Python 提供的一种简洁而强大的语法,用于创建列表、集合和字典。它可以让代码更简洁、更易读,同时提高运行效率。 基本语法 列表推导式 基本语法: [expression for item in iterable if condition]示例: # 生成平方…...
车联网安全入门——ICSim模拟器使用
文章目录 车联网安全入门——ISCim模拟器使用介绍主要特点:使用场景: 安装使用捕获can流量candumpcansnifferwiresharkSavvyCAN主要特点:使用场景: 重放can报文cansendSavvyCAN 总结 车联网安全入门——ISCim模拟器使用 …...
leetcode - 20.有效的括号(LinkedHashMap)
leetcode题目有效的括号,分类是easy,但是博主前前后后提交了几十次才通过,现在记录一下使用Java语言的写法。 题目链接: 20.有效的括号 题目描述: 给定一个只包括 (,),{,},[&…...
多维数组的动态内存分配(malloc和new)
一.区别指针类型 动态分配二维数组的内存不要赋值给行指针,而要赋值给二级指针。 二.分配动态二维数组的方法 1.使用指针数组 然后对指针数组的每一个元素分别malloc一维数组 2.直接使用malloc // 分配了一个指针数组,row为二维数组行数 int **p (i…...
71、评测OrangePi AIpro开发板和USB CAMERAOAK视频解码+推理+编码+推流测试
基本思想:csdn赞助了OrangePi AIpro开发板,花点时间简单和oak深度相机绑定测试一下,反正之前玩过atlas 200 dk A2,应该差不多,引用了之前的usb相机,方便小伙伴测试使用 第一步:系统刷机,参考官方吧,懒得刷机了,参考官方手册即可链接:https://pan.baidu.com/s/1umXM3i…...
为什么需要开局调用函数?
初始化操作:在你的应用程序启动时,可能需要执行一些初始化操作,例如设置默认值、加载配置、建立数据库连接等。开局调用函数可以帮助你集中管理这些操作,确保它们在应用程序启动时顺利执行。 统一入口:通过一个统一的…...
QT-demo:0轴分布图表
版本:5.9 第一种: 使用 PyQt5 和 Matplotlib 库 安装所需的库: pip install PyQt5 matplotlib创建和显示图表: import sys import numpy as np import matplotlib.pyplot as plt from PyQt5.QtWidgets import QApplication, QMainWindow f…...
git远程仓库限额的解决方法——大文件瘦身
Git作为世界上最优秀的分布式版本控制工具,也是优秀的文件管理工具,它赋予了项目成员对项目进行远程协同开发能力,因此受到越来越多的行业从业人员的喜爱。很多优秀的项目管理平台,比如国内的Gitee,国外的Github&#…...
碰撞检测技术在AI中的重要作用
引言: 随着人工智能技术的不断发展,AI已经渗透到我们生活的方方面面。在游戏、机器人、虚拟现实等领域中,碰撞检测技术扮演着至关重要的角色。本文将探讨碰撞检测技术在AI中的作用,以及如何利用这项技术来改善AI系统的性能和用户体…...
UE5 Cesium2 最新使用地理配准子关卡构造全球场景
参考官方最新教程:Building Global Scenes with Georeferenced Sublevels – Cesium 创建持久关卡(主关卡) 这里一般包含DynamicPawn、CesiumSunSky 和 Cesium World Terrain 全球场景通用的对象。子关卡的创立,官方教程分为了两…...
【Java数据结构】详解LinkedList与链表(二)
目录 1.❤️❤️前言~🥳🎉🎉🎉 2.反转一个单链表 3. 找到链表的中间节点 4.输入一个链表,输出该链表中倒数第k个结点。 5.合并两个有序链表 6.链表分割 7. 判定链表的回文结构 8.输入两个链表,找…...
【精读文献】J. Environ. Manage.|青藏高原生态恢复项目下植被覆盖动态及其对生态系统服务的约束效应
目录 文章简介 01 文章摘要 02 研究背景、目标及创新点 2.1 研究背景 2.2 研究现状 03 研究区域与数据集 3.1 研究区域 3.2 研究数据 04 研究方法 4.1 趋势分析 4.2 残差趋势分析 4.3 偏相关 4.4 生态系统服务评价 4.5 约束线的定义和提取 05 研究结果 5.1 植被…...
QT之常用控件
一个图形化界面当然需要有各种各样的控件,QT也不例外,在QT designer中就有提供各种各样的控件,用以开发图形化界面。 而想使用好一个QT控件,就需要了解这些控件。 QWidget 在QT中,所有控件都继承自 QWidget 类&…...
【嵌入式硬件】DRV8874电机驱动
目录 1 芯片介绍 1.1 特性简介 1.2 引脚配置 1.3 最佳运行条件 2 详细说明 2.1 PMODE配置控制模式 2.1.1 PH/EN 控制模式 2.1.2 PWM 控制模式 2.1.3 独立半桥控制模式 2.2 电流感测和调节 2.2.1 IPROPI电流感测 2.2.2 IMODE电流调节 3.应用 3.1设计要求 3.2 设计…...
考研数学:有些无穷小不能用等价无穷小的公式?
今天要给大家分享的笔记是:《有些无穷小虽然是无穷小,但却不能用无穷小的相关公式》:...
告别官方镜像!手把手教你将自编译Android系统刷入AVD(基于Android Studio 4.2+)
告别官方镜像!手把手教你将自编译Android系统刷入AVD(基于Android Studio 4.2) 在Android开发领域,模拟器(AVD)一直是开发者调试和测试应用的重要工具。然而,大多数开发者仅限于使用Google提供的…...
FMQL开发板实战:从Vivado到IAR的BOOT.bin生成全流程(附避坑指南)
FMQL开发板实战:从Vivado到IAR的BOOT.bin生成全流程(附避坑指南) 在嵌入式开发领域,复旦微电子FMQL系列开发板因其高性能和灵活性备受开发者青睐。然而,对于刚接触该平台的工程师来说,从零开始生成可启动的…...
OpenClaw+Qwen3.5-4B-Claude镜像:30分钟搭建逻辑推理自动化工作流
OpenClawQwen3.5-4B-Claude镜像:30分钟搭建逻辑推理自动化工作流 1. 为什么需要逻辑推理自动化 上周我遇到一个典型的技术问题:需要从200多行Python日志中找出导致接口超时的根本原因。手动排查不仅耗时,还容易遗漏关键线索。这让我开始思考…...
ParrelSync跨平台终极指南:Windows、macOS和Linux完整配置教程
ParrelSync跨平台终极指南:Windows、macOS和Linux完整配置教程 【免费下载链接】ParrelSync (Unity3D) Test multiplayer without building 项目地址: https://gitcode.com/gh_mirrors/pa/ParrelSync ParrelSync是一款专为Unity3D开发者设计的高效工具&#…...
3大核心功能构建反检测浏览器:Camoufox实战指南
3大核心功能构建反检测浏览器:Camoufox实战指南 【免费下载链接】camoufox 🦊 Anti-detect browser 项目地址: https://gitcode.com/gh_mirrors/ca/camoufox 在当今数据驱动的时代,网站反爬虫系统日益严苛,传统浏览器在访问…...
PDF-Parser-1.0保姆级教程:5分钟搞定PDF文档智能解析,小白也能快速上手
PDF-Parser-1.0保姆级教程:5分钟搞定PDF文档智能解析,小白也能快速上手 1. 为什么选择PDF-Parser-1.0? 你是否遇到过这些烦恼: 从PDF复制文字到Word后格式全乱表格数据粘贴后变成一堆乱码论文里的数学公式无法编辑双栏排版的文…...
ScanTailor Advanced:免费开源扫描文档处理终极指南
ScanTailor Advanced:免费开源扫描文档处理终极指南 【免费下载链接】scantailor-advanced ScanTailor Advanced is the version that merges the features of the ScanTailor Featured and ScanTailor Enhanced versions, brings new ones and fixes. 项目地址: …...
Python自动化运维实战:用Paramiko库5分钟搞定SSH批量管理(附完整代码)
Python自动化运维实战:用Paramiko库5分钟搞定SSH批量管理(附完整代码) 运维工程师的日常工作中,服务器管理往往占据大量时间。想象一下,当你需要同时更新50台服务器的安全补丁,或者批量收集100台设备的日志…...
Telegram用户必看:Grok聊天机器人全功能实测与隐藏技巧大公开
Telegram用户必看:Grok聊天机器人全功能实测与隐藏技巧大公开 作为Telegram深度用户,你可能已经注意到聊天界面顶部多了一个新面孔——Grok聊天机器人。这款由xAI打造的AI助手正在悄然改变我们的通讯体验。不同于市面上大多数聊天机器人,Grok…...
STM32F411 USB声卡时钟同步优化与中文命名实战
1. STM32F411 USB声卡开发基础 第一次接触STM32F411的USB声卡开发时,我被它的简洁配置流程惊艳到了。用CubeMX生成代码,接上PCM5102A解码芯片,不到半小时就能让电脑识别出音频设备。但很快我就发现事情没那么简单——播放音乐时总会出现周期…...
