【YOLOv8改进】 ODConv(Omni-Dimensional Dynamic Convolution):全维度动态卷积

news/2024/9/24 18:02:33

摘要

在现代卷积神经网络(CNN)中,每个卷积层中学习单个静态卷积核是常见的训练范式。然而,最近在动态卷积的研究中表明,通过学习 n 个卷积核的线性组合,并且这些卷积核的权重取决于它们的输入相关注意力,可以显著提高轻量级 CNN 的准确性,同时保持高效的推理。但是,我们观察到,现有的工作通过一个维度(关于卷积核数量)赋予卷积核动态属性,但另外三个维度(关于每个卷积核的空间大小、输入通道数和输出通道数)被忽略了。受此启发,我们提出了全方位动态卷积(ODConv),这是一种更通用且优雅的动态卷积设计,以推进这一研究方向。ODConv 利用一种新颖的多维注意力机制和并行策略,在任何卷积层的卷积核空间的所有四个维度上学习卷积核的互补注意力。作为常规卷积的替代品,ODConv 可以插入许多 CNN 架构中。在 ImageNet 和 MS-COCO 数据集上的广泛实验表明,ODConv 为各种主流的 CNN 骨干网络带来了稳固的准确性提升,包括轻量级和大型网络,例如,在 ImageNet 数据集上为 MobileNetV2|ResNet 系列带来了 3.77%∼5.71%|1.86%∼3.72% 的绝对 top-1 改进。有趣的是,由于其改进的特征学习能力,即使只有一个卷积核的 ODConv 也可以与现有的多核动态卷积对应物相竞争或胜过它们,大大减少了额外的参数。此外,ODConv 也优于其他注意力模块,用于调节输出特征或卷积权重。

YOLO目标检测创新改进与实战案例专栏

专栏目录: YOLO有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例

专栏链接: YOLO基础解析+创新改进+实战案例

创新点

ODConv是一种更通用但更优雅的动态卷积设计,它利用一种新颖的多维注意力机制和并行策略来学习卷积核的补充注意力,这些注意力涉及卷积核空间在任何卷积层的所有四个维度(即每个卷积核的空间大小、输入通道数、输出通道数和卷积核数量)。作为常规卷积的直接替代品,ODConv可以嵌入到多种CNN架构中。在ImageNet基准上进行了基础实验,在MS-COCO基准上进行了下游实验。

(a) DyConv(CondConv使用GAP+FC+Sigmoid)与(b) ODConv的示意性比较。与CondConv和DyConv不同,后者为卷积核 $W_{i}$计算单一的注意力标量 $α_{wi}$,ODConv利用一种新颖的多维注意力机制,以并行方式计算 ( W_i ) 在卷积核空间的所有四个维度上的四种类型的注意力 $α_{si}$, $α_{ci}$, $α_{fi}$和 $α_{wi}$。

image-20240117154243631

ODConv中逐步将四种类型的注意力乘以卷积核的示意图。(a) 沿空间维度的位置逐个乘法操作,(b) 沿输入通道维度的通道逐个乘法操作,(c) 沿输出通道维度的滤波器逐个乘法操作,以及 (d) 沿卷积核空间的核维度的核逐个乘法操作。

image-20240117154229110

文章链接

论文地址:论文地址

代码地址:代码地址

yolov8 代码引入


# ODConv2d类继承自nn.Module 
class ODConv2d(nn.Module):def __init__(self, in_planes, out_planes, kernel_size, stride=1, padding=0, dilation=1, groups=1,reduction=0.0625, kernel_num=4):super(ODConv2d, self).__init__()self.in_planes = in_planes  # 输入通道数self.out_planes = out_planes  # 输出通道数self.kernel_size = kernel_size  # 卷积核尺寸self.stride = stride  # 步长self.padding = padding  # 填充self.dilation = dilation  # 膨胀self.groups = groups  # 分组卷积的组数self.kernel_num = kernel_num  # 核数目,用于核注意力机制# 初始化注意力模块self.attention = Attention(in_planes, out_planes, kernel_size, groups=groups,reduction=reduction, kernel_num=kernel_num)# 初始化权重参数self.weight = nn.Parameter(torch.randn(kernel_num, out_planes, in_planes//groups, kernel_size, kernel_size),requires_grad=True)self._initialize_weights()# 根据卷积核尺寸和核数目选择不同的前向传播实现if self.kernel_size == 1 and self.kernel_num == 1:self._forward_impl = self._forward_impl_pw1xelse:self._forward_impl = self._forward_impl_commondef _initialize_weights(self):# 初始化权重for i in range(self.kernel_num):nn.init.kaiming_normal_(self.weight[i], mode='fan_out', nonlinearity='relu')def update_temperature(self, temperature):# 更新注意力机制的温度参数,用于调整注意力的强度self.attention.update_temperature(temperature)def _forward_impl_common(self, x):# 通用的前向传播实现,适用于多种注意力机制channel_attention, filter_attention, spatial_attention, kernel_attention = self.attention(x)batch_size, in_planes, height, width = x.size()x = x * channel_attention  # 应用通道注意力x = x.reshape(1, -1, height, width)# 合并多个注意力权重aggregate_weight = spatial_attention * kernel_attention * self.weight.unsqueeze(dim=0)aggregate_weight = torch.sum(aggregate_weight, dim=1).view([-1, self.in_planes // self.groups, self.kernel_size, self.kernel_size])# 执行卷积操作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))output = output * filter_attention  # 应用滤波器注意力return outputdef _forward_impl_pw1x(self, x):# 点卷积1x1的特殊前向传播实现channel_attention, filter_attention, spatial_attention, kernel_attention = self.attention(x)x = x * channel_attention  # 应用通道注意力output = F.conv2d(x, weight=self.weight.squeeze(dim=0), bias=None, stride=self.stride, padding=self.padding,dilation=self.dilation, groups=self.groups)output = output * filter_attention  # 应用滤波器注意力return outputdef forward(self, x):# 根据初始化时选择的实现进行前向传播return self._forward_impl(x)

task与yaml配置

详见:https://blog.csdn.net/shangyanaf/article/details/139389091

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

使用mongodb、Kafka保存mqtt消息

一、引言 随着物联网技术的迅猛发展,大量的设备和传感器产生了海量的数据。本文利用了 MQTT、Kafka 和 MongoDB 各自的优点,满足实时数据处理和大规模数据存储的需求。 如图:二、总结 优点:1. 可靠和解耦: Kafka的复制机制和持久化存储确保了数据在传输过程中的可靠性,即…

【C#】WPF 类库项目 无法创建 “资源字典” 文件

解决办法 打开项目工程文件 ( project.csproj) 在 标签添加 下面红色的三句话<Deterministic>true</Deterministic><ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <…

视频通话源码,使用线程池的两大要点分析

视频通话源码,使用线程池的两大要点分析:1、实现动态调整线程池参数2、对线程池运行情况进行监控一,线程池可调整的参数1、核心线程数2、超时时间3、最大线程数4、拒绝策略 而队列BlockingQueue因为是final类型,所以没有对外修改入口。但可以通过重写LinkedBlockingQueue并…

1v1直播源码,保证请求时序的两种常用方法

1v1直播源码,保证请求时序的两种常用方法 在1v1直播源码中经常遇到请求输入查找场景,防抖与截流很好处理了频繁输入问题,但是不能解决最先发起请求结果后返回,覆盖了最后一次的搜索结果,导致搜索结果不正确。我总结一下自己常用的两种方法。一、使用时间戳来过滤返回结果…

WebView2UI - 在WPF之中使用WebView2的一些经验总结

项目地址:https://github.com/skyw18/skyw18-WebView2UI webview简介与生命周期:WPF 应用中的 WebView2 入门 - Microsoft Edge Developer documentation | Microsoft Learn 具体代码可以参考微软官方示例文档 WPF 示例应用 - Microsoft Edge Developer documentation | Micr…

AbpVnext系列三 添加种子项目

一、src下面增加DbMigrations类库,注意是要.Net Framework 类型的类库,不能是.Net Standard 的。 二、添加类库后为项目添加如上三个项目 appsetting.json 配置信息{"ConnectionStrings": {"AidenAdmin": "Server=127.0.0.1;port=3306;Database=…

6. 在WEB中应用MyBatis(使用MVC架构模式)

学习目标:掌握mybatis在web应用中怎么用 mybatis三大对象的作用域和生命周期 ThreadLocal原理及使用 巩固MVC架构模式 为学习MyBatis的接口代理机制做准备实现功能:银行账户转账 使用技术:HTML + Servlet + Mybatis1. 需求描述 ​​ 2. 数据库表的设计和准备数据 创建数据库…

数字园区规划

数字园区规划 | 数字经济产业园规划、数字孪生产业园区规划设计 2024-03-10 19:00书生产业规划内容导读: 【一】数字产业园区发展环境 【二】数字产业园区市场现状 【三】数字产业园区建设需求 【四】数字园区建设赋能手段 【五】数字园区规划建设建议当下,数字经济已上升为我…