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 设计…...
考研数学:有些无穷小不能用等价无穷小的公式?
今天要给大家分享的笔记是:《有些无穷小虽然是无穷小,但却不能用无穷小的相关公式》:...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
智能职业发展系统:AI驱动的职业规划平台技术解析
智能职业发展系统:AI驱动的职业规划平台技术解析 引言:数字时代的职业革命 在当今瞬息万变的就业市场中,传统的职业规划方法已无法满足个人和企业的需求。据统计,全球每年有超过2亿人面临职业转型困境,而企业也因此遭…...
一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
