当前位置: 首页 > news >正文

YOLO算法改进6【中阶改进篇】:depthwise separable convolution轻量化C3

常规卷积操作

对于一张5×5像素、三通道(shape为5×5×3),经过3×3卷积核的卷积层(假设输出通道数为4,则卷积核shape为3×3×3×4,最终输出4个Feature Map,如果有same padding则尺寸与输入层相同(5×5),如果没有则为尺寸变为3×3

在这里插入图片描述

深度可分离卷积

  • 逐通道卷积Depthwise Convolution

Depthwise Convolution的一个卷积核负责一个通道,一个通道只被一个卷积核卷积。

一张5×5像素、三通道彩色输入图片(shape为5×5×3),Depthwise Convolution首先经过第一次卷积运算,DW完全是在二维平面内进行。卷积核的数量与上一层的通道数相同(通道和卷积核一一对应)。所以一个三通道的图像经过运算后生成了3个Feature map(如果有same padding则尺寸与输入层相同为5×5),如下图所示。
Depthwise Convolution完成后的Feature map数量与输入层的通道数相同,无法扩展Feature map。而且这种运算对输入层的每个通道独立进行卷积运算,没有有效的利用不同通道在相同空间位置上的feature信息。因此需要Pointwise Convolution来将这些Feature map进行组合生成新的Feature map
在这里插入图片描述

  • 逐点卷积Pointwise Convolution

Pointwise Convolution的运算与常规卷积运算非常相似,它的卷积核的尺寸为 1×1×M,M为上一层的通道数。所以这里的卷积运算会将上一步的map在深度方向上进行加权组合,生成新的Feature map。有几个卷积核就有几个输出Feature map

经过Pointwise Convolution之后,同样输出了4张Feature map,与常规卷积的输出维度相同

YOLOV5s中ConvBottleNeckC3的代码如下:

原始common.py配置

class Conv(nn.Module):# Standard convolution  通用卷积模块,包括1卷积1BN1激活,激活默认SiLU,可用变量指定,不激活时用nn.Identity()占位,直接返回输入def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groupssuper(Conv, self).__init__()self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)self.bn = nn.BatchNorm2d(c2)self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())def forward(self, x):return self.act(self.bn(self.conv(x)))def fuseforward(self, x):return self.act(self.conv(x))class Bottleneck(nn.Module):# Standard bottleneck 残差块def __init__(self, c1, c2, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, shortcut, groups, expansionsuper(Bottleneck, self).__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c_, c2, 3, 1, g=g)self.add = shortcut and c1 == c2def forward(self, x):  # 如果shortcut并且输入输出通道相同则跳层相加return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))class C3(nn.Module):  # CSP Bottleneck with 3 convolutionsdef __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansionsuper(C3, self).__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c1, c_, 1, 1)self.cv3 = Conv(2 * c_, c2, 1)  # act=FReLU(c2)self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])  # n个残差组件(Bottleneck)# self.m = nn.Sequential(*[CrossConv(c_, c_, 3, 1, g, 1.0, shortcut) for _ in range(n)])def forward(self, x):return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1))

1.轻量化C3模块

在models/common.py文件中按以下思路修改代码:
轻量化C3的改进思路是将原C3模块中使用的普通卷积,全部替换为深度可分离卷积,其余结构不变,改进后的DP_Conv、DP_BottleNeck、DP_C3的代码如下:

class DP_Conv(nn.Module):def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groupssuper(DP_Conv, self).__init__()self.conv1 = nn.Conv2d(c1, c1, kernel_size=3, stride=1, padding=1, groups=c1)self.conv2 = nn.Conv2d(c1, c2, kernel_size=1, stride=s)self.bn = nn.BatchNorm2d(c2)self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())def forward(self, x):return self.act(self.bn(self.conv2(self.conv1(x))))def fuseforward(self, x):return self.act(self.conv2(self.conv1(x)))class DP_Bottleneck(nn.Module):def __init__(self, c1, c2, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, shortcut, groups, expansionsuper(DP_Bottleneck, self).__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = DP_Conv(c1, c_, 1)self.cv2 = DP_Conv(c_, c2, 1)self.add = shortcut and c1 == c2def forward(self, x):  # 如果shortcut并且输入输出通道相同则跳层相加return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))class DP_C3(nn.Module):# CSP Bottleneck with 3 convolutionsdef __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansionsuper(DP_C3, self).__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = DP_Conv(c1, c_, 1)self.cv2 = DP_Conv(c1, c_, 1)self.cv3 = DP_Conv(2 * c_, c2, 1)  # act=FReLU(c2)self.m = nn.Sequential(*[DP_Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])  # n个残差组件(Bottleneck)# self.m = nn.Sequential(*[CrossConv(c_, c_, 3, 1, g, 1.0, shortcut) for _ in range(n)])def forward(self, x):return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1))

2.添加DP_C3.yaml文件
添加至/models/文件中

# parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple# anchors
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 backbone
backbone:# [from, number, module, args][[-1, 1, DP_Conv, [64, 6, 2, 2]],  # 0-P1/2[-1, 1, DP_Conv, [128, 3, 2]],  # 1-P2/4[-1, 3, DP_C3, [128]],[-1, 1, DP_Conv, [256, 3, 2]],  # 3-P3/8[-1, 9, DP_C3, [256]],[-1, 1, DP_Conv, [512, 3, 2]],  # 5-P4/16[-1, 9, DP_C3, [512]],[-1, 1, DP_Conv, [1024, 3, 2]],  # 7-P5/32[-1, 3, DP_C3, [1024]],[-1, 1, SPPF, [1024, 5]], # 9]# YOLOv5 head
head:[[-1, 1, DP_Conv, [512, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 6], 1, Concat, [1]],  # cat backbone P4  # PANet是add, yolov5是concat[-1, 3, C3, [512, False]],  # 13[-1, 1, DP_Conv, [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, DP_Conv, [256, 3,2]],[[-1, 14], 1, Concat, [1]],  # cat head P4[-1, 3, C3, [512, False]],  # 20 (P4/16-medium)[-1, 1, DP_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)  必须在最后一层, 原代码很多默认了Detect是最后, 并没有全改]

3.yolo.py配置
找到 models/yolo.py 文件中 parse_model()for i, (f, n, m, args) in enumerate(d['backbone'] + d['head']):,在列表中添加DP_ConvDP_BottleNeckDP_C3,这样可以获得我们要传入的参数。

 if m in {Conv, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, MixConv2d, Focus, CrossConv,BottleneckCSP, C3, C3TR, C3SPP, C3Ghost, nn.ConvTranspose2d, DWConvTranspose2d, C3x,Attention, CondConv, DP_Conv, DP_BottleNeck, DP_C3}:c1, c2 = ch[f], args[0]if c2 != no:  # if not outputc2 = make_divisible(c2 * gw, 8)args = [c1, c2, *args[1:]]if m in {BottleneckCSP, C3, C3TR, C3Ghost, C3x, DP_C3}:args.insert(2, n)  # number of repeatsn = 1elif m is nn.BatchNorm2d:args = [ch[f]]elif m is Concat:c2 = sum(ch[x] for x in f)# TODO: channel, gw, gd

4.训练模型

python train.py --cfg DP_C3.yaml

相关文章:

YOLO算法改进6【中阶改进篇】:depthwise separable convolution轻量化C3

常规卷积操作 对于一张55像素、三通道(shape为553),经过33卷积核的卷积层(假设输出通道数为4,则卷积核shape为3334,最终输出4个Feature Map,如果有same padding则尺寸与输入层相同(…...

自定义类型枚举

目录 枚举类型枚举类型的声明扩展枚举类型的优点枚举的优点 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 🐒🐒🐒 个人主页 🥸🥸🥸 C语言 🐿️🐿️&#x1f43f…...

PHP foreach 循环跳过本次循环

$a [[id>1],[id>2],[id>3],[id>4],[id>5],[id>6],[id>7],[id>18],];foreach($a as $v){if($v[id] 5){continue;}$b[] $v[id];}return show_data(,$b); 结果:...

lua-web-utils库

lua--导入所需的库local web_utilsrequire("lua-web-utils")--定义要下载的URLlocal url"https://jshk.com.cn/"--定义代理服务器的主机名和端口号local proxy_port8000--使用web_utils的download函数下载URLlocal file_pathweb_utils.download(url,proxy_…...

大数据毕业设计选题推荐-热门旅游景点数据分析-Hadoop-Spark-Hive

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…...

Oracle-执行计划

执行计划生成的几种方式 1. EXPLAIN FOR 语法: EXPLAIN PLAN FOR SQL语句SELECT * FROM TABLE(dbms_xplan.display());优点: 无需真正执行SQL 缺点: 没有输出相关的统计信息,例如产生了多少逻辑读、物理读、递归调用等情况无法判…...

Pytho入门教程之Python运行的三种方式

文章目录 一、交互式编程二、脚本式编程三、方式三关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 一、交互式编…...

如何修改docker容器中的MySQL数据库的密码?

查看容器中MySQL的ID:docker ps | grep mysql进入容器:docker exec -it {容器ID} /bin/bash调整MySQL配置文件,设置跳过权限控制:echo "skip-grant-tables" >> /etc/mysql/conf.d/docker.cnf 警 告:这…...

JOSEF约瑟 数显三相电压继电器 HJY-931A/D 导轨安装

名称:数字交流三相电压继电器型号:HJY-93系列品牌:JOSEF约瑟电压整定范围:10~450VAC额定电压:200、400VAC功率消耗:≤5W HJY系列 数字交流三相电压继电器 系列型号 HJY-931A/D数字式交流三相电压继电器&am…...

第6章_多表查询

文章目录 多表查询概述1 一个案例引发的多表连接1.1 案例说明1.2 笛卡尔积理解演示代码 2 多表查询分类讲解2.1 等值连接 & 非等值连接2.1.1 等值连接2.1.2 非等值连接 自连接 & 非自连接内连接与外连接演示代码 3 SQL99语法实现多表查询3.1 基本语法3.2 内连接&#x…...

吴恩达《机器学习》4-1->4-5:多变量线性回归

一、引入多维特征 在多维特征中,我们考虑的不再是单一的特征,而是一组特征,例如房价模型中可能包括房间数、楼层等多个特征。这些特征将组成一个向量,表示为(𝑥₁, 𝑥₂, . . . , 𝑥ₙ)&#x…...

搜索引擎系统简要分析

目录 一、搜索引擎简单介绍 二、搜索引擎整体架构和工作过程 (一)整体分析 (二)爬虫系统 三个基本点 爬虫系统的工作流程 关键考虑因素和挑战 (三)索引系统 网页处理阶段 预处理阶段 反作弊分析…...

蓝桥杯(C++ 扫雷)

题目&#xff1a; 思想&#xff1a; 1、遍历每个点是否有地雷&#xff0c;有地雷则直接返回为9&#xff0c;无地雷则遍历该点的周围八个点&#xff0c;计数一共有多少个地雷&#xff0c;则返回该数。 代码&#xff1a; #include<iostream> using namespace std; int g[…...

LuatOS-SOC接口文档(air780E)--mobile - 蜂窝网络

示例 -- 简单演示log.info("imei", mobile.imei()) log.info("imsi", mobile.imsi()) local sn mobile.sn() if sn thenlog.info("sn", sn:toHex()) end log.info("muid", mobile.muid()) log.info("iccid", mobile.icc…...

c++创建函数对象的不同方式

在C中&#xff0c;创建任何一个对象&#xff08;即使我们创建的是一个没有任何成员变量的对象&#xff09;时&#xff0c;需要占用一定的内存空间。 应用程序会将可用的内存&#xff08;排除源代码运行的内存等&#xff09;分出两个部分&#xff1a;栈&#xff08;stack&#x…...

python实现从字符串中识别出省市区信息

从字符串中识别出省市区的信息分别存储,是我们经常会碰到的问题。如果用分词的方法去匹配获取比较麻烦,cpca包提供了便捷的调用函数transform。只要把含省市区的信息放进去,即可返回标准的含省市区的数据框。    本文详细阐述如何安装cpca包、transform函数参数定义,以及…...

GCN火车票识别项目 P1 火车票识别项目介绍 Pytorch LSTM/GCN

从本节开始&#xff0c;我将带大家完成一个深度学习项目&#xff1a;用图卷积神经网络(GCN)&#xff0c;实现一个「火车票文字信息提取」的项目&#xff0c;由于火车票上每个节点文字不是等长的&#xff0c;所以还需要添加一个前置的 LSTM 来提取句子特征。 课前说明 1、这是…...

shell script 的默认变量$0,$1,$2...,参数偏移的shift

简单来说&#xff0c;在scirpt脚本里面&#xff0c;$0表示文件名&#xff0c;$1表示第一个参数&#xff0c;以此类推&#xff0c;还有 $# 后面接参数的个数 $ 代表"$1","$2","$3"&#xff0c;每个都是独立的&#xff0c;用双引号括起来 $* 代…...

2023年【危险化学品经营单位安全管理人员】复审考试及危险化学品经营单位安全管理人员模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位安全管理人员复审考试考前必练&#xff01;安全生产模拟考试一点通每个月更新危险化学品经营单位安全管理人员模拟考试题库题目及答案&#xff01;多做几遍&#xff0c;其实通过危险化学品经营单位…...

Java 正则表达式重复匹配篇

重复匹配 * 可以匹配任意个字符&#xff0c;包括0个字符。 可以匹配至少一个字符。? 可以匹配0个或一个字符。{n} 可以精确指定 n 个字符。{n,m} 可以精确匹配 n-m 个字符。你可以是 0 。 匹配任意个字符 匹配 D 开头&#xff0c;后面是任意数字的字符&#xff0c; String …...

Applied Intelligence投稿实战:从格式要求到高接受率的5个关键策略

1. 精准匹配期刊范围&#xff1a;避免编辑秒拒的第一道防线 投稿Applied Intelligence期刊时&#xff0c;最容易被忽视却最关键的一步就是研究范围匹配。我审过30篇稿件&#xff0c;发现80%的"desk rejection"&#xff08;编辑直接拒稿&#xff09;都源于研究方向与…...

RMBG-2.0企业级应用:集成至Shopify后台实现订单图自动去背流水线

RMBG-2.0企业级应用&#xff1a;集成至Shopify后台实现订单图自动去背流水线 想象一下&#xff0c;你是一家Shopify店铺的运营负责人。每天&#xff0c;团队需要处理上百张来自不同供应商的商品图片&#xff0c;手动抠图、换背景&#xff0c;只为让商品主图在网站上看起来统一…...

douyin-downloader:3大核心能力破解抖音内容高效下载难题

douyin-downloader&#xff1a;3大核心能力破解抖音内容高效下载难题 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback su…...

CodeMaker:让编码效率提升3倍的智能代码生成工具

CodeMaker&#xff1a;让编码效率提升3倍的智能代码生成工具 【免费下载链接】CodeMaker A idea-plugin for Java/Scala, support custom code template. 项目地址: https://gitcode.com/gh_mirrors/co/CodeMaker 一、核心价值&#xff1a;重新定义开发效率 你是否也曾…...

ViT在语义分割中的性能优化:从VOC2012数据集看如何提升自行车识别准确率

ViT在语义分割中的性能优化&#xff1a;从VOC2012数据集看如何提升自行车识别准确率 语义分割作为计算机视觉领域的核心任务之一&#xff0c;其目标是为图像中的每个像素分配类别标签。近年来&#xff0c;Vision Transformer&#xff08;ViT&#xff09;凭借其强大的全局建模能…...

Amlogic S9XXX设备系统改造完全指南:从入门到进阶

Amlogic S9XXX设备系统改造完全指南&#xff1a;从入门到进阶 【免费下载链接】amlogic-s9xxx-armbian Supports running Armbian on Amlogic, Allwinner, and Rockchip devices. Support a311d, s922x, s905x3, s905x2, s912, s905d, s905x, s905w, s905, s905l, rk3588, rk35…...

聊聊 Comsol 仿真方形锂离子电池那些事儿

comsol仿真 锂离子电池 电化学 仿真 comsol 方形锂离子电池的三维模型&#xff1a;三维模型有助于准确的评估电芯中的集流体和极耳等对电流、电位以及产热分布的影响。 模型基于三维 Newman 模型&#xff0c;其中包括了在颗粒尺度描述锂粒子插层和扩散的额外维度。 此外&#…...

[模电]从PN结到实用电路:二极管的深度解析与设计指南

1. PN结&#xff1a;二极管的物理基础 想象一下把一块P型半导体和N型半导体紧密贴合在一起&#xff0c;就像把两块不同颜色的橡皮泥揉捏在一起。P型半导体里充满了带正电的"空穴"&#xff08;可以理解为缺少电子的位置&#xff09;&#xff0c;而N型半导体则富含自由…...

PDF-Extract-Kit-1.0保姆级部署教程:4090D单卡一键启动Jupyter实战

PDF-Extract-Kit-1.0保姆级部署教程&#xff1a;4090D单卡一键启动Jupyter实战 你是不是经常需要从PDF里提取表格、公式或者分析文档布局&#xff1f;手动操作不仅费时费力&#xff0c;还容易出错。今天&#xff0c;我要给你介绍一个神器——PDF-Extract-Kit-1.0。这是一个功能…...

AW88195音频编解码器驱动从MTK到RK平台的移植实践

1. 认识AW88195音频编解码器驱动移植 第一次接触AW88195音频编解码器驱动移植时&#xff0c;我也是一头雾水。这个来自艾为的音频芯片主要用于提升扬声器音质&#xff0c;但厂商提供的驱动包往往只适配特定平台。比如这次遇到的AW88195_Driver_MTK_V0.1.6.zip就是专门为MTK平台…...