YOLOv5改进(五)-- 轻量化模型MobileNetv3
文章目录
- 1、MobileNetV3论文
- 2、代码实现
- 2.1、MobileNetV3-small
- 2.2、MobileNetV3-large
- 3、运行效果
- 4、目标检测系列文章
1、MobileNetV3论文
Searching for MobileNetV3论文
MobileNetV3代码
MobileNetV3 是 Google 提出的一种轻量级神经网络结构,旨在在移动设备上实现高效的图像识别和分类任务。与之前的 MobileNet 系列相比,MobileNetV3 在模型结构和性能上都有所改进。
MobileNetV3 的结构主要包括以下几个关键组件:
-
基础模块(Base Module):MobileNetV3 使用了一种称为**“倒残差”(Inverted Residuals)**的基础模块结构。该结构采用了深度可分离卷积和线性瓶颈,它由一个1x1卷积层和一个3x3深度可分离卷积层组成。这个操作单元通过使用非线性激活函数,如ReLU6,并且在残差连接中使用线性投影,以减少参数数量和计算复杂度来提高网络的特征表示能力,并且保持了模型的有效性。
-
Squeeze-and-Excitation 模块:MobileNetV3 引入了 Squeeze-and-Excitation 模块,使用全局平均池化层来降低特征图的维度,并使用一个1x1卷积层将特征图的通道数压缩成最终的类别数量。最后,使用softmax函数对输出进行归一化,得到每个类别的概率分布。通过学习通道之间的相互关系,动态地调整通道权重,以增强模型的表征能力。这有助于提高模型对关键特征的感知能力,从而提高分类性能。
-
Hard-Swish 激活函数:MobileNetV3 使用了一种称为 Hard-Swish 的激活函数。与传统的 ReLU 激活函数相比,Hard-Swish 具有更快的计算速度和更好的性能。
-
网络架构优化:MobileNetV3 在网络结构上进行了优化,包括通过网络宽度和分辨率的动态调整,以适应不同的计算资源和任务需求。
总体而言,MobileNetV3 通过这些创新设计和优化,实现了更高的性能和更低的计算成本,使其成为移动设备上图像识别任务的理想选择之一。
MobileNetV3 的主要处理流程如下:
-
输入处理:输入图像首先经过预处理步骤,例如归一化和大小调整,以使其适应网络的输入要求。
-
特征提取:经过输入处理后,图像通过一系列基础模块(Base Module)进行特征提取。每个基础模块通常包含深度可分离卷积、激活函数(如 Hard-Swish)和通道注意力(如 Squeeze-and-Excitation)模块。
-
特征增强:在特征提取的过程中,通过 Squeeze-and-Excitation 模块对提取的特征图进行增强,以加强对重要特征的感知能力。
-
全局平均池化:在特征提取的最后阶段,通过全局平均池化操作将特征图的空间维度降低到一个固定大小。
-
分类器:全局平均池化后的特征图输入到分类器中,进行分类或其他任务的预测。分类器通常由一个或多个全连接层组成,最后输出预测结果。
2、代码实现
2.1、MobileNetV3-small
(1) 在models/common.py
的引入MobileNetV3模块
# 引入MobileNetV3模块
class StemBlock(nn.Module):def __init__(self, c1, c2, k = 3, s = 2, p = None, g = 1, act = True):super(StemBlock, self).__init__()self.stem_1 = Conv(c1, c2, k, s, p, g, act)self.stem_2a = Conv(c2, c2 // 2, 1, 1, 0)self.stem_2b = Conv(c2 // 2, c2, 3, 2, 1)self.stem_2p = nn.MaxPool2d(kernel_size = 2, stride = 2, ceil_mode = True)self.stem_3 = Conv(c2 * 2, c2, 1, 1, 0)def forward(self, x):stem_1_out = self.stem_1(x)stem_2a_out = self.stem_2a(stem_1_out)stem_2b_out = self.stem_2b(stem_2a_out)stem_2p_out = self.stem_2p(stem_1_out)out = self.stem_3(torch.cat((stem_2b_out, stem_2p_out), 1))return outclass h_sigmoid(nn.Module):def __init__(self, inplace = True):super(h_sigmoid, self).__init__()self.relu = nn.ReLU6(inplace = inplace)def forward(self, x):return self.relu(x + 3) / 6class h_swish(nn.Module):def __init__(self, inplace = True):super(h_swish, self).__init__()self.sigmoid = h_sigmoid(inplace = inplace)def forward(self, x):y = self.sigmoid(x)return x * yclass SELayer(nn.Module):def __init__(self, channel, reduction = 4):super(SELayer, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.fc = nn.Sequential(nn.Linear(channel, channel // reduction),nn.ReLU(inplace = True),nn.Linear(channel // reduction, channel),h_sigmoid())def forward(self, x):b, c, _, _ = x.size()y = self.avg_pool(x)y = y.view(b, c)y = self.fc(y).view(b, c, 1, 1)return x * yclass Conv_bn_hswish(nn.Module):"""This equals todef conv_3x3_bn(inp, oup, stride):return nn.Sequential(nn.Conv2d(inp, oup, 3, stride, 1, bias=False),nn.BatchNorm2d(oup),h_swish())"""def __init__(self, c1, c2, stride):super(Conv_bn_hswish, self).__init__()self.conv = nn.Conv2d(c1, c2, 3, stride, 1, bias = False)self.bn = nn.BatchNorm2d(c2)self.act = h_swish()def forward(self, x):return self.act(self.bn(self.conv(x)))def fuseforward(self, x):return self.act(self.conv(x))class MobileNetV3(nn.Module):def __init__(self, inp, oup, hidden_dim, kernel_size, stride, use_se, use_hs):super(MobileNetV3, self).__init__()assert stride in [1, 2]self.identity = stride == 1 and inp == oup# 输入通道图 = 扩张通道数 则不进行通道扩张if inp == hidden_dim:self.conv = nn.Sequential(# dwnn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size - 1) // 2, groups = hidden_dim,bias = False),nn.BatchNorm2d(hidden_dim),h_swish() if use_hs else nn.ReLU(inplace = True),# Squeeze-and-ExciteSELayer(hidden_dim) if use_se else nn.Sequential(),# Eca_layer(hidden_dim) if use_se else nn.Sequential(),#1.13.2022# pw-linearnn.Conv2d(hidden_dim, oup, 1, 1, 0, bias = False),nn.BatchNorm2d(oup),)else:# 否则先进行扩张self.conv = nn.Sequential(# pwnn.Conv2d(inp, hidden_dim, 1, 1, 0, bias = False),nn.BatchNorm2d(hidden_dim),h_swish() if use_hs else nn.ReLU(inplace = True),# dwnn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size - 1) // 2, groups = hidden_dim,bias = False),nn.BatchNorm2d(hidden_dim),# Squeeze-and-ExciteSELayer(hidden_dim) if use_se else nn.Sequential(),# Eca_layer(hidden_dim) if use_se else nn.Sequential(), # 1.13.2022h_swish() if use_hs else nn.ReLU(inplace = True),# pw-linearnn.Conv2d(hidden_dim, oup, 1, 1, 0, bias = False),nn.BatchNorm2d(oup),)def forward(self, x):y = self.conv(x)if self.identity:return x + yelse:return y
(2) 在models/yolo.py
的parse_model函数,添加Conv_bn_hswish,MobileNetV3
两个模块
if m in [Conv, GhostConv, Bottleneck, GhostBottleneck, SPP, DWConv, MixConv2d, Focus, CrossConv, BottleneckCSP,C3, C3TR,Conv_bn_hswish,MobileNetV3]:
(3) 构建yolov5s-mobileNetV3-samll.yaml
网络模型
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license# Parameters
nc: 6 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.5 # 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# Mobilenetv3-small backbone# MobileNetV3_InvertedResidual [out_ch, hid_ch, k_s, stride, SE, HardSwish]
backbone:# [from, number, module, args]# /2 /4 /6 /8,/16,/32 位置特征图的大小降半# MobileNetV3模块包含六个参数[out_ch, hidden_ch, kernel_size, stride, use_se, use_hs][[-1, 1, Conv_bn_hswish, [16, 2]], # 0-p1/2 320*320[-1, 1, MobileNetV3, [16, 16, 3, 2, 1, 0]], # 1-p2/4 160*160[-1, 1, MobileNetV3, [24, 72, 3, 2, 0, 0]], # 2-p3/8 80*80[-1, 1, MobileNetV3, [24, 88, 3, 1, 0, 0]], # 3 80*80[-1, 1, MobileNetV3, [40, 96, 5, 2, 1, 1]], # 4-p4/16 40*40[-1, 1, MobileNetV3, [40, 240, 5, 1, 1, 1]], # 5 40*40[-1, 1, MobileNetV3, [40, 240, 5, 1, 1, 1]], # 6 40*40[-1, 1, MobileNetV3, [48, 120, 5, 1, 1, 1]], # 7 40*40[-1, 1, MobileNetV3, [48, 144, 5, 1, 1, 1]], # 8 40*40[-1, 1, MobileNetV3, [96, 288, 5, 2, 1, 1]], # 9-p5/32 20*20[-1, 1, MobileNetV3, [96, 576, 5, 1, 1, 1]], # 10 20*20[-1, 1, MobileNetV3, [96, 576, 5, 1, 1, 1]], # 11 20*20]# YOLOv5 v6.0 head
head:[[-1, 1, Conv, [96, 1, 1]], # 12 20*20[-1, 1, nn.Upsample, [None, 2, 'nearest']], # 13 40*40[[-1, 8], 1, Concat, [1]], # cat backbone P4 40*40[-1, 3, C3, [144, False]], # 15 40*40[-1, 1, Conv, [144, 1, 1]], # 16 40*40[-1, 1, nn.Upsample, [None, 2, 'nearest']], # 17 80*80[[-1, 3], 1, Concat, [1]], # cat backbone P3 80*80[-1, 3, C3, [168, False]], # 19 (P3/8-small) 80*80[-1, 1, Conv, [168, 3, 2]], # 20 40*40[[-1, 16], 1, Concat, [1]], # cat head P4 40*40[-1, 3, C3, [312, False]], # 22 (P4/16-medium) 40*40[-1, 1, Conv, [312, 3, 2]], # 23 20*20[[-1, 12], 1, Concat, [1]], # cat head P5 20*20[-1, 3, C3, [408, False]], # 25 (P5/32-large) 20*20[[19, 22, 25], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)]
MobileNetV3-samll网络结构

- out_ch: 输出通道
- hidden_ch: 表示在Inverted residuals中的扩张通道数
- kernel_size: 卷积核大小
- stride: 步长
- use_se: 表示是否使用 SELayer,使用了是1,不使用是0
- use_hs: 表示使用 h_swish 还是 ReLU,使用h_swish是1,使用 ReLU是0
2.2、MobileNetV3-large
MobileNetV3-large和MobileNetV3-small 区别在于网络层数加深,深度因子,宽度因子不同以及yaml文件中head中concat不同层数拼接。我们就直接改动yaml的部分,其余参考上面步骤。
MobileNetV3-large.yaml
# Parameters
nc: 6 # number of classes
depth_multiple: 1 # model depth multiple
width_multiple: 0.5 # 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:[[-1, 1, conv_bn_hswish, [16, 2]], # 0-p1/2 320*320[-1, 1, MobileNetV3, [ 16, 16, 3, 1, 0, 0]], # 1-p1/2 320*320[-1, 1, MobileNetV3, [ 24, 64, 3, 2, 0, 0]], # 2-p2/4 160*160[-1, 1, MobileNetV3, [ 24, 72, 3, 1, 0, 0]], # 3-p2/4 160*160[-1, 1, MobileNetV3, [ 40, 72, 5, 2, 1, 0]], # 4-p3/8 80*80[-1, 1, MobileNetV3, [ 40, 120, 5, 1, 1, 0]], # 5-p3/8[-1, 1, MobileNetV3, [ 40, 120, 5, 1, 1, 0]], # 6-p3/8[-1, 1, MobileNetV3, [ 80, 240, 3, 2, 0, 1]], # 7-p4/16 40*40[-1, 1, MobileNetV3, [ 80, 200, 3, 1, 0, 1]], # 8-p4/16[-1, 1, MobileNetV3, [ 80, 184, 3, 1, 0, 1]], # 9-p4/16[-1, 1, MobileNetV3, [ 80, 184, 3, 1, 0, 1]], # 10-p4/16[-1, 1, MobileNetV3, [112, 480, 3, 1, 1, 1]], # 11-p4/16[-1, 1, MobileNetV3, [112, 672, 3, 1, 1, 1]], # 12-p4/16[-1, 1, MobileNetV3, [160, 672, 5, 1, 1, 1]], # 13-p4/16[-1, 1, MobileNetV3, [160, 960, 5, 2, 1, 1]], # 14-p5/32 20*20[-1, 1, MobileNetV3, [160, 960, 5, 1, 1, 1]], # 15-p5/32]
# YOLOv5 v6.0 head
head:[ [ -1, 1, Conv, [ 512, 1, 1 ] ],[ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],[ [ -1, 13], 1, Concat, [ 1 ] ], # cat backbone P4[ -1, 1, C3, [ 512, False ] ], # 19[ -1, 1, Conv, [ 256, 1, 1 ] ],[ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],[ [ -1, 6 ], 1, Concat, [ 1 ] ], # cat backbone P3[ -1, 1, C3, [ 256, False ] ], # 23 (P3/8-small)[ -1, 1, Conv, [ 256, 3, 2 ] ],[ [ -1, 20 ], 1, Concat, [ 1 ] ], # cat head P4[ -1, 1, C3, [ 512, False ] ], # 26 (P4/16-medium)[ -1, 1, Conv, [ 512, 3, 2 ] ],[ [ -1, 16 ], 1, Concat, [ 1 ] ], # cat head P5[ -1, 1, C3, [ 1024, False ] ], # 29 (P5/32-large)[ [ 23, 26, 29 ], 1, Detect, [ nc, anchors ] ], # Detect(P3, P4, P5)]
3、运行效果
如果训练之后发现掉点纯属正常现象,因为轻量化网络在提速减少计算量的同时会降低精度
4、目标检测系列文章
- YOLOv5s网络模型讲解(一看就会)
- 生活垃圾数据集(YOLO版)
- YOLOv5如何训练自己的数据集
- 双向控制舵机(树莓派版)
- 树莓派部署YOLOv5目标检测(详细篇)
- YOLO_Tracking 实践 (环境搭建 & 案例测试)
- 目标检测:数据集划分 & XML数据集转YOLO标签
- DeepSort行人车辆识别系统(实现目标检测+跟踪+统计)
- YOLOv5参数大全(parse_opt篇)
- YOLOv5改进(一)-- 轻量化YOLOv5s模型
- YOLOv5改进(二)-- 目标检测优化点(添加小目标头检测)
- YOLOv5改进(三)-- 引进Focaler-IoU损失函数
- YOLOv5改进(四)–轻量化模型ShuffleNetv2
相关文章:

YOLOv5改进(五)-- 轻量化模型MobileNetv3
文章目录 1、MobileNetV3论文2、代码实现2.1、MobileNetV3-small2.2、MobileNetV3-large 3、运行效果4、目标检测系列文章 1、MobileNetV3论文 Searching for MobileNetV3论文 MobileNetV3代码 MobileNetV3 是 Google 提出的一种轻量级神经网络结构,旨在在移动设备上…...

用户流失分析:如何使用Python训练一个用户流失预测模型?
引言 在当今商业环境中,客户流失分析是至关重要的一环。随着市场竞争的加剧,企业需要更加注重保持现有客户,并深入了解他们的离开原因。本文探讨了用户流失分析的核心概念以及如何构建客户流失预测模型的案例。通过分析用户行为数据和交易模式…...

【计算机毕设】基于SpringBoot的社区医院信息平台设计与实现 - 源码免费(私信领取)
免费领取源码 | 项目完整可运行 | v:chengn7890 诚招源码校园代理! 1. 引言 随着医疗信息化的不断推进,社区医院作为基层医疗机构,需要建立高效、便捷的信息管理平台以提高服务质量和工作效率。基于SpringB…...

LLM——深入探索 ChatGPT在代码解释方面的应用研究
1.概述 OpenAI在自然语言处理(NLP)的征途上取得了令人瞩目的进展,这一切得益于大型语言模型(LLM)的诞生与成长。这些先进的模型不仅是技术创新的典范,更是驱动着如GitHub Copilot编程助手和Bing搜索引擎等广…...
Android中ANR的分析和解决
一 ANR概述 2、ANR的类型 (1)KeyDispatchTimeout(常见) input事件在5S内没有处理完成发生了ANR。 logcat日志关键字:Input event dispatching timed out (2)BroadcastTimeout 前台Broadcast…...
Kotlin 类
文章目录 什么是类类的属性类的方法(行为)构造函数主构造次构造 类的实例化(对象)伴生对象this 什么是类 在 Kotlin 中,变量类型都是类,像我们常见的Int、String等等,都是类。 为什么要分类&a…...
Forth Python语言:深度解析其四维、五维、六维与七维之奥秘
Forth Python语言:深度解析其四维、五维、六维与七维之奥秘 在编程语言的浩瀚星空中,Forth Python以其独特的魅力与深邃的内涵,吸引着众多探索者的目光。然而,这门语言究竟有何独到之处?本文将从四维、五维、六维和七…...

MySQL--复合查询
之前学过了基本的查询,虽然已经够80%的使用场景了,但是依旧需要了解剩下的20%。 一、多表笛卡尔积(多表查询) 以前我们使用基本查询的时候,from后面就跟一张表名,在多表查询这里,from后面可以跟…...

前端项目开发,3个HTTP请求工具
这一小节,我们介绍一下前端项目开发中,HTTP请求会用到的3个工具,分别是fetch、axios和js-tool-big-box中的jsonp请求。那么他们都有哪些小区别呢?我们一起来看一下。 目录 1 fetch 2 axios 3 js-tool-big-box 的 jsonp 请求 …...

Java_Mybatis
Mybatis是一款优秀的持久层框架,用户简化JDBC(使用Java语言操作关系型数据库的一套API)开发 使用Mybatis查询所有用户数据: 代码演示: UserMapper: Mapper //被调用时会通过动态代理自动创建实体类,并放入IOC容器中…...

2024HW|常见红队使用工具
目录 什么是HW? 什么是网络安全红蓝对抗? 红队 常见工具 信息收集工具 Nmap 简介 漏洞扫描工具 Nessus简介 AWVS 简介 抓包工具 Wireshark简介 TangGo 简介 web 应用安全工具 Burpsuite 简介 SQLMap webshell 管理工具 蚁剑 冰蝎 后…...

Redisson集成SpringBoot
前言:Redisson集成SpringBoot主要有两种方式,一个是使用redisson-spring-boot-starter依赖(优先推荐),毕竟springboot主打的就是约定大于配置,这个依赖就是为springboot准备的。 再一种方式就是引入rediss…...

设计模式(十二)行为型模式---模板方法模式
文章目录 模板方法模式结构优缺点UML图具体实现UML图代码实现 模板方法模式 模板方法模式(Template Method)是一种基于继承实现的设计模式,主要思想是:将定义的算法抽象成一组步骤,在抽象类中定义算法的骨架ÿ…...

【气象常用】剖面图
效果图: 主要步骤: 1. 数据准备:我用的era5的散度数据(大家替换为自己的就好啦,era5数据下载方法可以看这里【数据下载】ERA5 各高度层月平均数据下载_era5月平均数据-CSDN博客) 2. 数据处理:…...

LabVIEW高低温试验箱控制系统
要实现LabVIEW高低温试验箱控制系统,需要进行硬件配置、软件设计和系统集成,确保LabVIEW能够有效地监控和控制试验箱的温度。以下是详细说明: 硬件配置 选择合适的试验箱: 确定高低温试验箱的型号和品牌。 确认试验箱是否支持外…...
Flutter 中的 SliverFillViewport 小部件:全面指南
Flutter 中的 SliverFillViewport 小部件:全面指南 Flutter 是一个由 Google 开发的跨平台 UI 框架,它允许开发者使用 Dart 语言来构建高性能、美观的移动、Web 和桌面应用。在 Flutter 的丰富组件库中,SliverFillViewport 是一个用于 Custo…...

明日周刊-第12期
以前小时候最期待六一儿童节了,父母总会给你满足一个愿望,也许是一件礼物也许是一次陪伴。然而这个世界上其实还有很多儿童过不上儿童节,比如某些地区的小孩子,他们更担心的是能不能见到明天的太阳。 文章目录 一周热点航天探索火…...
算法之美阅读笔记
这里写自定义目录标题 序04 缓存 -- 忘了它吧 序 在图书馆闲逛时,一本封面为绿色的清新的书引起了我的兴趣,书名是算法之美。我心里不禁嘀咕,大家好喜欢使用某某之美作为书名,比如:数学之美、架构之美。美丽美好的事物…...
新手学习STM32还是ESP32
对于新手来说,选择学习STM32还是ESP32取决于个人的学习目标和背景。以下是针对这两种微控制器的详细分析,以便您做出更明智的选择: STM32 1. 处理器架构与性能 STM32采用单核或多核处理器架构,基于ARM Cortex-M0,M0…...

关于vlookup的第一个参数的个人理解
VLOOKUP(查阅值,包含查阅值和返回值的查找区域,查找区域中返回值的列号,精确查找或近似查找) 我个人理解,第一个参数应该叫线索值,因为我们要通过它去找与其对应的(也就是与其同行的…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

C++--string的模拟实现
一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现,其目的是加强对string的底层了解,以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量,…...

中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点
中科院1区顶刊|IF14:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点 当下,免疫与代谢性疾病的关联研究已成为生命科学领域的前沿热点。随着研究的深入,我们愈发清晰地认识到免疫系统与代谢系统之间存在着极为复…...