YOLOv8改进教程|加入可改变核卷积AKConv模块,效果远超DSConv!


⭐⭐ YOLOv8改进专栏|包含主干、模块、注意力机制、检测头等前沿创新 ​ ⭐⭐


 一、 论文介绍

        论文链接:https://arxiv.org/abs/2311.11587

        代码链接:GitHub - CV-ZhangXin/AKConv

论文速览::AKConv是2023年11月发表的一种可变卷积核,赋予卷积核任意数量的参数和任意采样形状,以解决具有固定样本形状和正方形的卷积核不能很好地适应不断变化的目标的问题点可以为网络开销和性能之间的权衡提供更丰富的选择。 AKConv的核心思想在于它为卷积核提供了任意数量的参数和任意采样形状,能够使用任意数量的参数(如1,2,3,4,5,6,7等)来提取姝征,这在标准卷积和可变形卷积中并未实现。AKConv能够根据硬件环境,使卷积参数的数星呈线性增减((非常适用于轻量化模型)。

总结:AKConv是一种具有任意数量的参数和任意采样形状的可变卷积核,对不规则特征有更好的提取效果。


二、 加入到RT-DETR中

2.1 复制代码

        复制代码粘到ultralytics->nn->modules->conv.py文件中,在顶部导入torch.nn.functional包,(torch.nn.functional as F),将代码粘贴于下方,并在__all__中声明,如下图所示:

# Ultralytics YOLO 🚀, AGPL-3.0 license
"""Convolution modules."""import mathimport numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from einops import rearrange__all__ = ("Conv","Conv2","LightConv","DWConv","DWConvTranspose2d","ConvTranspose","Focus","GhostConv","ChannelAttention","SpatialAttention","CBAM","Concat","RepConv","AKConv",
)class AKConv(nn.Module):def __init__(self, inc, outc, num_param, stride=1, bias=None):super(AKConv, self).__init__()self.num_param = num_paramself.stride = strideself.conv = nn.Sequential(nn.Conv2d(inc, outc, kernel_size=(num_param, 1), stride=(num_param, 1), bias=bias),nn.BatchNorm2d(outc),nn.SiLU())  # the conv adds the BN and SiLU to compare original Conv in YOLOv5.self.p_conv = nn.Conv2d(inc, 2 * num_param, kernel_size=3, padding=1, stride=stride)nn.init.constant_(self.p_conv.weight, 0)self.p_conv.register_full_backward_hook(self._set_lr)@staticmethoddef _set_lr(module, grad_input, grad_output):grad_input = (grad_input[i] * 0.1 for i in range(len(grad_input)))grad_output = (grad_output[i] * 0.1 for i in range(len(grad_output)))def forward(self, x):# N is num_param.offset = self.p_conv(x)dtype = offset.data.type()N = offset.size(1) // 2# (b, 2N, h, w)p = self._get_p(offset, dtype)# (b, h, w, 2N)p = p.contiguous().permute(0, 2, 3, 1)q_lt = p.detach().floor()q_rb = q_lt + 1q_lt = torch.cat([torch.clamp(q_lt[..., :N], 0, x.size(2) - 1), torch.clamp(q_lt[..., N:], 0, x.size(3) - 1)],dim=-1).long()q_rb = torch.cat([torch.clamp(q_rb[..., :N], 0, x.size(2) - 1), torch.clamp(q_rb[..., N:], 0, x.size(3) - 1)],dim=-1).long()q_lb = torch.cat([q_lt[..., :N], q_rb[..., N:]], dim=-1)q_rt = torch.cat([q_rb[..., :N], q_lt[..., N:]], dim=-1)# clip pp = torch.cat([torch.clamp(p[..., :N], 0, x.size(2) - 1), torch.clamp(p[..., N:], 0, x.size(3) - 1)], dim=-1)# bilinear kernel (b, h, w, N)g_lt = (1 + (q_lt[..., :N].type_as(p) - p[..., :N])) * (1 + (q_lt[..., N:].type_as(p) - p[..., N:]))g_rb = (1 - (q_rb[..., :N].type_as(p) - p[..., :N])) * (1 - (q_rb[..., N:].type_as(p) - p[..., N:]))g_lb = (1 + (q_lb[..., :N].type_as(p) - p[..., :N])) * (1 - (q_lb[..., N:].type_as(p) - p[..., N:]))g_rt = (1 - (q_rt[..., :N].type_as(p) - p[..., :N])) * (1 + (q_rt[..., N:].type_as(p) - p[..., N:]))# resampling the features based on the modified coordinates.x_q_lt = self._get_x_q(x, q_lt, N)x_q_rb = self._get_x_q(x, q_rb, N)x_q_lb = self._get_x_q(x, q_lb, N)x_q_rt = self._get_x_q(x, q_rt, N)# bilinearx_offset = g_lt.unsqueeze(dim=1) * x_q_lt + \g_rb.unsqueeze(dim=1) * x_q_rb + \g_lb.unsqueeze(dim=1) * x_q_lb + \g_rt.unsqueeze(dim=1) * x_q_rtx_offset = self._reshape_x_offset(x_offset, self.num_param)out = self.conv(x_offset)return out# generating the inital sampled shapes for the AKConv with different sizes.def _get_p_n(self, N, dtype):base_int = round(math.sqrt(self.num_param))row_number = self.num_param // base_intmod_number = self.num_param % base_intp_n_x, p_n_y = torch.meshgrid(torch.arange(0, row_number),torch.arange(0, base_int))p_n_x = torch.flatten(p_n_x)p_n_y = torch.flatten(p_n_y)if mod_number > 0:mod_p_n_x, mod_p_n_y = torch.meshgrid(torch.arange(row_number, row_number + 1),torch.arange(0, mod_number))mod_p_n_x = torch.flatten(mod_p_n_x)mod_p_n_y = torch.flatten(mod_p_n_y)p_n_x, p_n_y = torch.cat((p_n_x, mod_p_n_x)), torch.cat((p_n_y, mod_p_n_y))p_n = torch.cat([p_n_x, p_n_y], 0)p_n = p_n.view(1, 2 * N, 1, 1).type(dtype)return p_n# no zero-paddingdef _get_p_0(self, h, w, N, dtype):p_0_x, p_0_y = torch.meshgrid(torch.arange(0, h * self.stride, self.stride),torch.arange(0, w * self.stride, self.stride))p_0_x = torch.flatten(p_0_x).view(1, 1, h, w).repeat(1, N, 1, 1)p_0_y = torch.flatten(p_0_y).view(1, 1, h, w).repeat(1, N, 1, 1)p_0 = torch.cat([p_0_x, p_0_y], 1).type(dtype)return p_0def _get_p(self, offset, dtype):N, h, w = offset.size(1) // 2, offset.size(2), offset.size(3)# (1, 2N, 1, 1)p_n = self._get_p_n(N, dtype)# (1, 2N, h, w)p_0 = self._get_p_0(h, w, N, dtype)p = p_0 + p_n + offsetreturn pdef _get_x_q(self, x, q, N):b, h, w, _ = q.size()padded_w = x.size(3)c = x.size(1)# (b, c, h*w)x = x.contiguous().view(b, c, -1)# (b, h, w, N)index = q[..., :N] * padded_w + q[..., N:]  # offset_x*w + offset_y# (b, c, h*w*N)index = index.contiguous().unsqueeze(dim=1).expand(-1, c, -1, -1, -1).contiguous().view(b, c, -1)x_offset = x.gather(dim=-1, index=index).contiguous().view(b, c, h, w, N)return x_offset#  Stacking resampled features in the row direction.@staticmethoddef _reshape_x_offset(x_offset, num_param):b, c, h, w, n = x_offset.size()# using Conv3d# x_offset = x_offset.permute(0,1,4,2,3), then Conv3d(c,c_out, kernel_size =(num_param,1,1),stride=(num_param,1,1),bias= False)# using 1 × 1 Conv# x_offset = x_offset.permute(0,1,4,2,3), then, x_offset.view(b,c×num_param,h,w)  finally, Conv2d(c×num_param,c_out, kernel_size =1,stride=1,bias= False)# using the column conv as follow, then, Conv2d(inc, outc, kernel_size=(num_param, 1), stride=(num_param, 1), bias=bias)x_offset = rearrange(x_offset, 'b c h w n -> b c (h n) w')return x_offset

2.2 更改modules.__init__.py文件 

       打开ultralytics->nn->modules->__init__.py,在第64行与81行加入AKConv进行声明。

​2.3 更改task.py文件 

        打开ultralytics->nn路径下的tasks.py文件,首先在第51行加入AKConv导入模块,然后在第928行(或其他合适的位置)加入下方代码:

        elif m is AKConv:c2 = args[0]c1 = ch[f]args = [c1, c2, *args[1:]]

 2.4 更改yaml文件 

        创建yaml文件,使用AKConv替换yaml文件中原有的Conv模块。

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]n: [0.33, 0.25, 1024] # YOLOv8n summary: 225 layers,  3157200 parameters,  3157184 gradients,   8.9 GFLOPss: [0.33, 0.50, 1024] # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients,  28.8 GFLOPsm: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPsl: [1.00, 1.00, 512] # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPsx: [1.00, 1.25, 512] # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs# YOLOv8.0n backbone
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4- [-1, 3, C2f, [128, True]]- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8- [-1, 6, C2f, [256, True]]- [-1, 1, Conv, [512, 3, 2]] # 5-P4/16- [-1, 6, C2f, [512, True]]- [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32- [-1, 1, AKConv, [256, 3]]- [-1, 1, SPPF, [1024, 5]] # 9# YOLOv8.0n head
head:- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 3, C2f, [512]] # 12- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 3, C2f, [256]] # 15 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 12], 1, Concat, [1]] # cat head P4- [-1, 3, C2f, [512]] # 18 (P4/16-medium)- [-1, 1, Conv, [512, 3, 2]]- [[-1, 9], 1, Concat, [1]] # cat head P5- [-1, 3, C2f, [1024]] # 21 (P5/32-large)- [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5)

 2.5 修改train.py文件

        在train.py脚本中填入创建好的yaml路径,运行即可训练。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/12840.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI 写 SQL 真的靠谱吗?腾讯游戏在 AI+ 湖仓一体的实践

作者:腾讯游戏数据技术负责人 刘岩 导读 腾讯游戏是全球领先的游戏开发和运营商,其数据团队拥有十余年、700 款大型游戏的数据工作沉淀。复杂的业务环境下,腾讯游戏数据团队每年需要处理超过 3 万个数据提取需求,SQL 编写需要耗费…

Mysql面试夺命18问

文章目录 1.简要说明一下数据库范式 第一范式: 属性不可再分.第二范式: 在一范式的基础上, 要求数据库表中的每个实例或行必须可以被惟一地区分. 通常需要为表加上一个列, 以存储各个实例的惟一标识. 这个惟一属性列被称为主关键字或主键.第三范式: 在二范式的基础上, 要求一个…

mysql----武侠剑客之-----MEMORY 存储引擎

文章目录 mysql--------MEMORY 存储引擎1、1 特点:1、2 代码演示: mysql--------MEMORY 存储引擎 1、1 特点: 1.frm文件存储表的结构信息 2 数据存放在内存中,没有表数据文件,重启后,数据丢失 3 使用表…

Go微服务: 接入Prometheus性能监控平台与Grafana平台

接入Prometheus 在 go-micro 生成的模板中, 我们一如既往的完成基础工作之后 进入main.go工作的代码编写,main.go package mainimport ("fmt""log""strconv""github.com/go-micro/plugins/v4/registry/consul"opentracing…

RT-Thread中使用Mqtt

环境: 开发板:Panduola(stm32L475) KEIL5 开发环境 rtthread 4.0.3内核 使用ENV 配置Rtt MQTT 1.MQTT介绍 ​ 客户端 Client 使用MQTT的程序或设备。客户端总是通过网络连接到服务端。它可以发布应用消息给其它相关的客户端。订…

解决Word文档中页眉有部分有,有部分没有的问题

问题描述:一个Word文档中,在页眉上添加文档名称和页码,但是有的有,有的没有,选择“链接到前一节”也无法解决该问题。 原因分析:页眉页脚中,勾选了“首页不同”的选项,如下图&#…

【OpenHarmony IDL工具规格及使用说明书】

OpenHarmony IDL工具规格及使用说明书 IDL接口描述语言简介 当客户端和服务器进行IPC通信时,需要定义双方都认可的接口,以保障双方可以成功通信,OpenHarmony IDL(OpenHarmony Interface Definition Language)则是一种…

ARM基于DWT实现硬件延时(GD32)

软件延时的缺点 软件延时的精度差&#xff0c;受系统主频影响&#xff0c;调教困难 硬件延时 DWT数据跟踪监视点单元硬件延时 硬件延时实现代码 delay.c #include <stdint.h> #include "gd32f30x.h"/** *****************************************************…

初步揭开缓存神秘面纱之双map实现缓存管理的类

在应用程序中&#xff0c;缓存是一种常见的优化手段&#xff0c;可以提高数据的访问速度。针对缓存管理&#xff0c;我们通常会实现一些类来方便地管理缓存数据。缓存具体是如何实现的&#xff0c;这里我们利用双map做一个缓存的基本实现。 1.考虑缓存有哪些属性 1.是否是永久…

谷歌Google搜索广告开户流程与费用?

谷歌Google作为全球领先的搜索引擎&#xff0c;其广告平台——Google Ads&#xff0c;无疑是企业捕获潜在客户的黄金钥匙。想要在广阔的互联网海洋中精准航行&#xff0c;了解Google搜索广告的开户流程与费用至关重要。通过云衔科技的专业服务&#xff0c;让您的谷歌Google广告…

【数据分析面试】44.分析零售客户群体(Python 集合Set的用法)

题目 假设你是一家在线零售商的数据库管理员&#xff0c;需要分析两类客户的数据。一个集合 purchased_customers 包含在最近一次促销活动中购买了商品的客户ID&#xff0c;另一个集合 newsletter_subscribers 包含订阅了新闻通讯的客户ID。编写一个函数 analyze_customers&am…

【回溯算法】【Python实现】0-1背包

文章目录 [toc]问题描述形式化描述 回溯法时间复杂性Python实现 问题描述 给定 n n n种物品和一背包&#xff0c;物品 i i i的重量是 w i w_{i} wi​&#xff0c;其价值为 v i v_{i} vi​&#xff0c;背包的容量为 c c c如何选择装入背包中的物品&#xff0c;使得装入背包中物…

《云原生安全攻防》-- 构建云原生攻防场景

在本节课程中&#xff0c;我们将学习云原生攻防场景的构建。为了研究云原生安全攻击案例&#xff0c;我们需要搭建一个云原生攻击测试环境&#xff0c;以便进行攻防研究和攻击手法的复现。 在这个课程中&#xff0c;我们将学习以下内容&#xff1a; 构建云原生攻防场景&#xf…

Jetpack Compose 初探

官方文档永远是第一学习渠道。 Jetpack Compose 初探 前言命令式UI与声明式UIJetpack Compose 的优势开始使用Jetpack Compose创建支持 Compose 的新应用可组合函数布局Material Design列表和动画前言 Jetpack Compose 是用于构建原生 Android 界面的新工具包。它使用更少的代…

创建和选择数据库

如果管理员在设置权限时为您创建了数据库&#xff0c;您可以开始使用它。否则&#xff0c;您需要自己创建&#xff1a; mysql> CREATE DATABASE menagerie; 在Unix系统下&#xff0c;数据库名称区分大小写&#xff08;与SQL关键词不同&#xff09;&#xff0c;因此您必须始…

ModuleNotFoundError: No module named ‘openpyxl‘的解决方案

问题描述&#xff1a; ModuleNotFoundError: No module named ‘openpyxl’ 这个错误表示你的 Python 环境中没有安装 openpyxl 这个模块。openpyxl 是一个用于读写 Excel 2010 xlsx/xlsm/xltx/xltm 文件的 Python 库。 解决方案&#xff1a; 要解决这个问题&#xff0c;你需…

深入理解MySQL三大日志:redo log、binlog、undo log

前言 MySQL是一个功能强大的关系型数据库管理系统&#xff0c;它的高可靠性、高性能和易用性使得它成为众多企业和开发者的首选。在MySQL内部&#xff0c;为了保证数据的完整性、恢复能力和并发性能&#xff0c;设计了一套复杂的日志系统。其中&#xff0c;redo log、bin log和…

云服务器和物理机该怎样分别呢

随着网络的不断发展&#xff0c;服务器的类型也在以不同的方式更新。现在云服务器的兴起占据了很大一部分市场&#xff0c;物理机的市场份额受到了很大的冲击。物理机和云服务器有什么区别&#xff1f;如何选择适合自己需求的&#xff1f;虽然物理服务器和云服务器都是服务器&a…

hvigor ERROR: Task PreviewBuild,--watch not found in hvigor node: entry.”

harmony deveco 配置问题处理 这是第三次配置 harmony&#xff0c;以为会一切顺利&#xff0c;不想会遇到这个问题。环境都安装好后创建一个 demo 后预览失效&#xff0c;虚拟机启动运行正常。 通常遇到失败的情况直接把 devtool 的命令直接拿到命令行中执行一遍就能看到错误…

618洗地机如何选?洗地机哪个牌子好?洗地机详解

快节奏的生活方式使得清洁工作成为许多人难以应付的任务。不过&#xff0c;洗地机的出现为这个问题提供了完美的解决方案。洗地机以其强劲的吸力和高效的清洁功能&#xff0c;能够快速清理地面的污渍和灰尘&#xff0c;极大地提升了清洁效率。不仅如此&#xff0c;洗地机的操作…