【LeYOLO】嵌入式和移动端的轻量级YOLO模型

代码地址:https://github.com/LilianHollard/LeYOLO

论文地址:https://arxiv.org/pdf/2406.14239

在深度神经网络中,计算效率对于目标检测至关重要,尤其是在新模型更注重速度而非有效计算(FLOP)的情况下。这一演变某种程度上忽视了嵌入式和面向移动端设备的AI目标检测应用。

在本文中,作者重点关注基于FLOP的高效目标检测计算的神经网络架构设计选择,并提出几项优化措施来提高基于YOLO模型的效率。

1、首先,作者引入了一种受倒置瓶颈(inverted bottlenecks)和来自信息瓶颈(the Information Bottleneck)原理的理论所启发的有效 Backbone 网络缩放方法。

2、其次,作者提出了快速金字塔架构网络(FPAN),旨在促进快速多尺度特征共享同时减少计算资源。

3、最后,作者提出了一个解耦的DNiN检测Head,旨在为分类和回归任务提供快速且轻量级的计算。

在这些优化措施的基础上,并利用更有效的 Backbone 网络,本文为目标检测和以YOLO为中心的模型贡献了一个新的范式,称为LeYOLO。作者的贡献在多种资源限制下始终优于现有模型,实现了前所未有的准确性和FLOP比率。

值得注意的是,LeYOLO-Small在仅使用4.5 FLOP(G)的情况下,在COCO val 上达到了38.2%的竞争性mAP分数,与最新的YOLOv9-Tiny模型相比,计算负载减少了42%,同时保持了相似的准确性。

作者新颖的模型系列实现了前所未有的FLOP到准确性的比率,提供了从超低神经网络配置(< 1 GFLOP)到高效且要求严格的目标检测设置(> 4 GFLOPs)的可扩展性,对于 0.66, 1.47, 2.53, 4.51, 5.8和8.4 FLOP(G)分别达到了25.2, 31.3, 35.2, 38.2, 39.3和41 mAP


本文贡献:

1、Lightweight: 在每个FLOP比率的准确率方面,LeYOLO相比于轻量级目标检测的最先进神经网络(0.5到8 FLOP(G)之间)实现了最佳的准确率。

2、Scaling:LeYOLO为工业、边缘和嵌入式设备提供了使用轻量级YOLO模型与最先进的扩展效率的新机会。

3、Bags of specials:尽管作者的研究专注于精度与计算成本的最佳比例,基于该研究作者也提出了不同的替代方案。

4、New architecture:作者提出在LeYOLO中使用计算效率更高的块,并通过实验提供证据。

5、High reproducibility:作者的研究重点是改进深度神经网络的架构。作者使用ultralytics API的可重用训练方法实现结果,不使用ImageNet预训练。


nc: 80  # number of classes
scales:# [depth, width, max_channels]n: [1.0, 1.33, 576]  # LeYOLO Small backbone
backbone:# [from, repeats, module, args]- [-1, 1, mn_conv, [16, 3, 2, "SI"]]  # 0-P1/2- [-1, 1, mn_conv, [16, 1, 1, "SI"]]- [-1, 1, MobileNetV3_BLOCK, [16, 3, 16, False, "SI", 2, False]]  # 2-P2/4- [-1, 1, MobileNetV3_BLOCK, [32, 3, 96, False, "SI", 2]]  # 3-P3/8- [-1, 1, MobileNetV3_BLOCK, [32, 3, 96, False, "SI", 1]]- [-1, 1, MobileNetV3_BLOCK, [64, 5, 96, True, "SI", 2]]  # 5-P4/16- [-1, 1, MobileNetV3_BLOCK, [64, 5, 192, True, "SI", 1]]- [-1, 1, MobileNetV3_BLOCK, [64, 5, 192, True, "SI", 1]]- [-1, 1, MobileNetV3_BLOCK, [64, 5, 192, True, "SI", 1]]- [-1, 1, MobileNetV3_BLOCK, [64, 5, 192, True, "SI", 1]]- [-1, 1, MobileNetV3_BLOCK, [96, 5, 576, True, "SI", 2]] # 10-P5/32- [-1, 1, MobileNetV3_BLOCK, [96, 5, 576, True, "SI", 1]]- [-1, 1, MobileNetV3_BLOCK, [96, 5, 576, True, "SI", 1]]- [-1, 1, MobileNetV3_BLOCK, [96, 5, 576, True, "SI", 1]]- [-1, 1, SPPF, [96, 5]]  # 14# LeYOLO Small head
head:- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 9], 1, Concat, [1]]  # 16 cat backbone P4- [-1, 1, MobileNetV3_BLOCK, [64, 5, 128, True, "SI", 1]]- [-1, 1, MobileNetV3_BLOCK, [64, 5, 128, True, "SI", 1]]- [-1, 1, MobileNetV3_BLOCK, [64, 5, 128, True, "SI", 1]]- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 4], 1, Concat, [1]]  # 21 cat backbone P3- [-1, 1, MobileNetV3_BLOCK, [32, 3, None, True, "SI", 1, False]] - [-1, 1, MobileNetV3_BLOCK, [32, 3, 64, True, "SI", 1]] - [-1, 1, MobileNetV3_BLOCK, [32, 3, 64, True, "SI", 1]] - [-1, 1, mn_conv, [64, 3, 2, "SI"]]- [[-1, 19], 1, Concat, [1]]  # 26 cat head P4- [-1, 1, MobileNetV3_BLOCK, [64, 5, 128, True, "SI", 1]] - [-1, 1, MobileNetV3_BLOCK, [64, 5, 128, True, "SI", 1]] - [-1, 1, MobileNetV3_BLOCK, [64, 5, 128, True, "SI", 1]] - [-1, 1, mn_conv, [96, 3, 2, "SI"]]- [[-1, 14], 1, Concat, [1]]  # 31 cat head P5- [-1, 1, MobileNetV3_BLOCK, [96, 5, 192, True, "SI", 1]] - [-1, 1, MobileNetV3_BLOCK, [96, 5, 192, True, "SI", 1]] - [-1, 1, MobileNetV3_BLOCK, [96, 5, 192, True, "SI", 1]] - [[24, 29, 34], 1, Detect, [nc]]  # Detect(P3, P4, P5)

Leyolo-small的配置文件


Base building block

class MobileNetV3_BLOCK(nn.Module):def __init__(self, c1, c2, k=3, e=None, sa="None", act="RE", stride=1, pw=True):#input_channels, output_channels, repetition, stride, expension ratiosuper().__init__()#act = nn.ReLU6(inplace=True) if NL=="RE" else nn.Hardswish()c_mid = e if e != None else c1self.residual = c1 == c2 and stride == 1features = [mn_conv(c1, c_mid, act=act)] if pw else [] #if c_mid != c1 else []features.extend([mn_conv(c_mid, c_mid, k, stride, g=c_mid, act=act),#attn,nn.Conv2d(c_mid, c2, 1),nn.BatchNorm2d(c2),#nn.SiLU(),])self.layers = nn.Sequential(*features)def forward(self, x):#print(x.shape)if self.residual:return x + self.layers(x)else:return self.layers(x)class mn_conv(nn.Module):def __init__(self, c1, c2, k=1, s=1, act="RE", p=None, g=1, d=1):super().__init__()padding = 0 if k==s else autopad(k,p,d)self.c = nn.Conv2d(c1, c2, k, s, padding, groups=g)self.bn = nn.BatchNorm2d(c2)self.act = activation_function(act)#nn.ReLU6(inplace=True) if act=="RE" else nn.Hardswish()def forward(self, x):return self.act(self.bn(self.c(x)))

倒置瓶颈(inverted bottleneck)结构,最初由MobileNetV2提出,是许多新的最先进模型的核心,因其轻量级计算和简洁性而受到重视。在FLOP计算方面,要超越深度可分离卷积(depthwise convolutions)达到一定有效性水平是比较困难的。点卷积(pointwise convolutions)解决了通道间相关性的缺失问题。然而,在作者对倒置瓶颈块的实验中,作者观察到优化通道数量可以有效地减少计算需求,特别是在大特征图尺寸上。

实际上,如果块的扩展比率为1,或者由于拼接效果,输入通道C_{in}等于计算出的扩展层数C_{mid},那么在作者的块中就没有必要使用第一个点卷积。只要输入C_{in}和输出C_{out}的张量相等,如图2和公式(1)所示,即使第一个pointwise卷积不存在,作者也总是使用残差连接。

“即使第一个pointwise卷积不存在,作者也总是使用残差连接”,即:

- [-1, 1, mn_conv, [16, 1, 1, "SI"]]

- [-1, 1, MobileNetV3_BLOCK, [16, 3, 16, False, "SI", 2, False]] # 2-P2/4  最后一个False表示第一个pointwise卷积不存在的情况

作者在图2(c)中描述了LeYOLO的基础构建块,突出了经典瓶颈(图2(a))、倒置瓶颈(图2(b))以及作者提出的方法(图2(c))之间的区别。

作者用\otimes表示两个值之间的卷积。对于F_{in} \in \mathbb{R}^{1,1,C_{in},C_{mid}}F_{out} \in \mathbb{R}^{1,1,C_{mid},C_{out}}F_{mid} \in \mathbb{R}^{k,k,1,C_{mid}},这里的卷积具有个C_{in}输入通道,C_{mid}个在倒置瓶颈中扩展的通道,以及C_{out}个输出通道


Stride strategy

一些模型在倒置瓶颈结构中包含了步长。然而,作者采用了一种特定的通道扩展策略

每个语义信息 Level  P_{i}在其所有隐藏层中都具有输入通道数C_{in}P_{i}、输出通道数C_{out}P_{i}和扩展通道数C_{mid}P_{i}。作者的目标是丰富从语义信息 Level P_{i}的隐藏层h_{i}到后续隐藏层h_{i+1}的信息流,通过按比例增加通道C_{in}P_{i},以扩展到预期的C_{mid}P_{i+1}通道。

倒置瓶颈采取以下步骤:

具有步长的倒置瓶颈中的语义信息表示为P如下——图3:

因此,步长大于一的通道扩展策略可能类似于以下形式:

作者本可以简单地为每个块应用丰富的扩展比例,不仅仅是那些步长大于一的块,但这样做会显著增加整个网络的计算成本。虽然这种策略不是整个模型所必需的,但在某些节点上这样做是有意义的,比如在stem,从昂贵的特征图空间大小中最大限度地扩展信息,特别是使用最终的逐点卷积。

            if m in (InvertedBottleneck,MobileNetV3_BLOCK):if isinstance(args[3],int): #might use "None"args[3] = make_divisible(min(args[3], max_channels) * width, 8)

STEM

作者经常用“STEM”这个术语来描述最初几层,这些层直接处理输入图像和低语义信息,以快速有效地减少空间尺寸,并将初始信息通道数(通常是3,代表红、绿、蓝三个颜色通道)激发到一个更高的通道数。主要的好处是减少了计算成本,因为如果处理的层在空间上过大,对于目标检测的总成本会迅速爆炸。

一些最先进的YOLO模型,只有YOLOv6和YOLOv8是具有低计算资源STEM的好例子,当将通道数和层缩放到1/4时,它们的总成本都是0.32 GFLOP。这两个模型迅速将特征图缩小到160x160p,以补偿在过高空间尺寸上的滑动卷积的成本。

为了在大特征图尺寸上有效地使用卷积,作者在整个STEM中使用了pointwisestandard卷积,从P0(640x640)缩小到P2(160x160)过程中将通道数限制在一个严格的低数值内 - 表1。


Efficient backbone feature extractor

作者认识到深度神经网络(DNNs)并不完全符合马尔可夫链X\rightarrow \widetilde{X}\rightarrow Y,其中X\widetilde{X}Y分别是输入、从X提取的最小充分统计量和输出。因此,为了得到\widetilde{X}作为提取对Y有意义特征的最小充分统计量,DNN需要学习如何使用最小充分统计量提取特征,并采用尽可能紧凑的结构

其次,因为DNN只处理前一层h_{i-1}的输入,一个直接的后果可能是丢失后续层无法恢复的信息。如公式(5)

诸如[5; 21]中提出的列式网络等昂贵的解决方案通过在每个块之间进行密集的特征共享来解决这一问题,通过结合密集的训练块或在信息分割的关键点添加额外的检测Head,正如最近在YOLOv9中看到的那样。由于在上述方程中实现公平是可行的,[66]建议每一层应尽可能最大化自身的信息I(Y;h_{i}),同时最小化层间信息交换I(h_{i-1};h_{i})。因此,作者没有像[71; 73; 21; 5]那样增加模型的计算复杂性,而是选择更高效地扩展它,整合Dangyoon等人的倒瓶颈理论。

作者的实现包括,通过确保输入/输出通道的数量不超过第一隐藏层到最后一层通道的差比,以形式I(h_{0};h_{n})最小化层间信息交换,其中n等于神经网络的最后一个隐藏层。隐藏层通道的数量应保持在由输入通道P1和输出通道P5定义的范围内,比小于6,以形式I(h_{1};h_{n})最小化I(h_{i-1};h_{i})

相反,Dangyonn等人的倒瓶颈通道扩展实验表明,扩展或缩减比例不应超过6。因此,作者通过在整个网络中扩展3倍来最大化I(Y;h_{i})。同时,在采用pointwise通道扩展策略的间隔倒瓶颈中,通过总共扩展6倍进一步激发信息,最大化(P_{i};P_{i+1})之间的I(Y;h_{i})。然而,作者从P4到P5的倒瓶颈进一步激发信息,通过扩展9倍最大化(P_{4};P_{5})I(Y;h_{i})(与扩展6倍相比,增加了+0.5 mAP)。

块之间残差连接的实施有助于通过提供前一层h_{i-1}的信息来最小化I(h_{i-1};h_{i})。密集连接可能增强模型,但它们需要额外的内存。


Neck

在目标检测中,作者将模型中聚合多个语义信息层次的部分称为“neck”,它将更远层的提取层次共享到第一层。

从历史上看,研究者使用PANet或FPN有效地共享特征图,通过将几个语义信息P_{i}链接到PANet及其各自的输出,如图4(a)所示,实现了多个检测层次。

在本文中,作者主要关注两个算法:BiFPN和YOLOF的SiSO。BiFPN与作者模型的中心思想相同:使用低计算成本的层(连接和加法,深度卷积和逐点卷积)。然而,BiFPN需要太多的语义信息和太多的阻塞状态(等待前一层,复杂的图),这使得难以保持快速执行速度。

SiSO中,可以看到YOLOF的作者决定为模型“neck”使用单一的输入和输出。与YOLOF论文中提出的其他解决方案相比,作者观察到多输出“neck”(单入多出-SiMO)与单输出“neck”(单入单出-SiSO)之间存在显著退化。作者特别感兴趣的是他们关于SiMO潜在效率的工作,证明仅通过优化单一丰富输入的语义信息流,就可以改进YOLO模型“neck”的第一层。

受到PAN和FPNnet的启发,作者提出了一个快速PANnet(FPANet),该网络具有更少的卷积层,较低的通道数和更有效的语义信息共享。作者的方法与YOLOv8中的“neck”概念相似。作者减少了post-backbone和 Head 之间的P3和P5的计算流,直接强化了P4的语义信息层次,如图4(b)所示。此外,作者简化了“neck”,最小化了锁和等待时间。而且,如图4(c)所示,作者优化了通道数量以减少P3中的计算,其中初始逐点步骤是不必要的,因为从P4和backbone来的P3信息的自底向上的路径的连接与PAN在P3处的倒置瓶颈中扩展的通道相匹配,即C_{out}P_{4} + C_{in}P_{3} = C_{mid}P_{3}

通过用P3和P4的最小计算加强单一输入(P4)来指导“neck”信息,作者实现了介于SiMO和MiMO之间的方法,并显著减少了MiMO的变化。


Decoupled Network in Network Head

直到YOLOv5时期,分类和目标检测任务使用单一Head 。然而,自YOLOv6起,模型 Head 变成了一个更强大的工具,将块分成了两部分:一个用于分类的分支和一个用于目标回归的分支。尽管这种方法非常高效,但它意味着成本几乎翻倍,需要为分类和检测进行卷积。

作者理论地认为,除了通过轻量级的Depthwise卷积按通道细化 Backbone 和stem提取的特征外,无需添加空间信息。

从历史上看,YOLO模型作为一个网格工作,为每个网格像素通过 Anchor 框进行分类 Proposal 。Anchor 框提供了几种可能的检测大小,不仅仅是像素级的检测。

通过YOLO的点对点网格操作,作者认为可以使用pointwise卷积作为滑动多层感知机解决方案,逐像素地简化检测 Head ,类似于每个像素的分类 Proposal --几个Depthwise卷积用于仅空间方式,改进两个pointwise卷积之间的空间关系,每个像素进行分类和回归。

通过消融研究(见原文第B.4章),作者证明仅在模型 Head 使用pointwise卷积就能在LeYOLO-Nano@640尺度上取得令人印象深刻的33.4 mAP结果。在pointwise卷积之间使用Depthwise卷积细化空间信息,将模型性能提升到34.3 mAP

如图5所示,作者提出了DNiN Head,一种以pointwise卷积为中心的方法,具有两个单独的pointwise操作,用于每个网络 Proposal :分类和回归(边界框)。pointwise操作在目标检测中至关重要,在网络中网络框架内作为逐像素的分类器和回归器。Depthwise卷积被分成两个3x3卷积,以降低与单个5x5卷积相比的整体成本。

作者操作两个独立的pointwise卷积:一个专用于分类,另一个用于回归。这种区别源于分类和边界框提取之间不同的需求。作者提出的DNiN Head 在保持 Level P_{i}的空间尺寸的同时,扩展通道以匹配类数量。每个像素因此代表一个潜在的预测。


Results

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

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

相关文章

ChatGPT-4o大语言模型优化、本地私有化部署、从0-1搭建、智能体构建技术

在过去几年中&#xff0c;人工智能领域的发展迅猛&#xff0c;尤其是大语言模型的应用&#xff0c;为各行各业带来了前所未有的创新与突破。从ChatGPT-3.5的推出到GPT Store的上线&#xff0c;再到最新的多模态交互ChatGPT-4o&#xff0c;OpenAI不断引领科技潮流&#xff0c;推…

Docker安装BRIA-RMBG-1.4模型,背景去除

目录 前言 模型描述 训练数据 定性评估 docker安装 运行 结论 Tip&#xff1a; 问题1&#xff1a; 问题2&#xff1a; 前言 BRIA 背景去除 v1.4 模型 RMBG v1.4 是我们最先进的背景去除模型&#xff0c;旨在有效地将各种类别和图像类型的前景与背景分开。该模型已在…

ch552g中使用SPI进行主从机通信时发现的问题

参考 基本硬件准备 两块独立的ch552g的板子&#xff0c;开始连接时数据传输出现数据错误&#xff0c;本来猜想是通信线连接问题&#xff0c;后来用了较短的连接线依然没有改善。 SPI通信的认知 SPI一般都是全双工实时通信&#xff0c;所以在发送数据时一般有短暂的停留使得…

到底哪款护眼大路灯好?五款适合学生用的护眼落地灯分享

到底哪款护眼大路灯好&#xff1f;影响青少年近视的最大“杀手”竟是学习环境光的影响。而对于这种情形&#xff0c;尤其是对于需要长时间用眼的学生群体和伏案工作者来说&#xff0c;护眼大路灯简直就是必备神器&#xff0c;但有人会问&#xff0c;我手机打开一搜就出现了那么…

防火墙综合实验一

目录 实验要求 防火墙准备 IP地址分配 需求一 需求二 需求三 需求四 需求五 需求六 实验要求 1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问。 2、生产区不允许访问互联网&#xff0c;办公区和游客…

qq动态删了怎么恢复?五分钟找回您的QQ动态

在使用QQ空间时&#xff0c;我们经常会发现自己误删了一些重要的动态。这可能是由于手指滑动不慎或者误操作引起的。无论是珍贵的回忆还是重要的信息&#xff0c;一旦被删除&#xff0c;我们都希望能够找回来。那么&#xff0c;qq动态删了怎么恢复&#xff1f; 在本文中&#…

vue2/3代码格式化问题,看着太难受了

1.原本的代码&#xff1a; 格式化后的代码&#xff1a; 太难受了&#xff01; 2.原本的代码 格式化后的代码 格式化跟有病似的&#xff0c;看着非常难受&#xff01; 有没有什么插件解决&#xff01;&#xff1f;

你知道的和你不知道的DOM操作技巧

你知道的和你不知道的DOM操作技巧 亲爱的前端小伙伴们&#xff0c;今天我们来聊聊那些你可能知道或者不知道的DOM操作技巧。作为一名前端开发者&#xff0c;如果你还在为DOM操作头疼&#xff0c;那么这篇文章绝对能让你茅塞顿开。让我们一起来探索一下DOM的奥秘吧&#xff01;…

2024春秋杯网络安全联赛夏季赛-PWN

文章目录 stdout测试setvbuf(stdout, 0LL, 2, 0LL)绕过或者输出直到缓冲区满使用system("/bin/sh")或者onegadget即使setvbuf(stdout, 0LL, 0, 0LL);也能立即有回显参考[https://starrysky1004.github.io/2024/07/05/2024-shu-qi-xue-xi-ji-lu/#toc-heading-4](https…

搜维尔科技:【研究】Scalefit是一款可在工作场所自动处理3D姿势分析结果的软件

Scalefit是一款可在工作场所自动处理 3D 姿势分析结果的软件。这甚至可以在衡量员工的同时发生。然后&#xff0c;Scalefit 根据国际标准对姿势、压缩力和关节力矩进行分析和可视化。 3D姿势分析 如今&#xff0c;Xsens 技术可让您快速测量工作场所员工的态度。一套带有 17 个…

开源无人机从入门到炸机,共需要几步?

阿木实验室2024年的重磅新品 Prometheus 仿真笔记本已经上架有一段时间了&#xff0c;近日&#xff0c;该产品的研发负责人廖工受邀到直播间与开发者们深度解读了Prometheus仿真笔记本的设计理念。直播过程中&#xff0c;廖工不仅展示了该产品的功能demo&#xff0c;解答技术开…

leetcode:1332. 删除回文子序列(python3解法)

难度&#xff1a;简单 给你一个字符串 s&#xff0c;它仅由字母 a 和 b 组成。每一次删除操作都可以从 s 中删除一个回文 子序列。 返回删除给定字符串中所有字符&#xff08;字符串为空&#xff09;的最小删除次数。 「子序列」定义&#xff1a;如果一个字符串可以通过删除原字…

本地部署,图片细节处理大模型Tile Controlnet

目录 什么是 Tile ControlNet&#xff1f; 工作原理 应用场景 优势与挑战 优势 挑战 本地部署 运行结果 未来展望 结论 Tip&#xff1a; 在近年来的深度学习和计算机视觉领域&#xff0c;生成对抗网络&#xff08;GAN&#xff09;和扩散模型等技术取得了显著的进展。…

技术文件国产化准备

技术文档的本地化涉及调整内容以满足特定目标市场的文化、语言和技术要求。这一过程超越了简单的翻译&#xff0c;确保文件在文化上适合预期受众&#xff0c;在技术上准确无误。适当的准备对于成功的本地化至关重要&#xff0c;以下步骤概述了一种全面的方法。 分析目标受众 …

在Visutal Studio 2022中完成D3D12初始化

在Visutal Studio 2022中完成DirectX设备初始化 1 DirectX121.1 DirectX 简介1.2 DirectX SDK安装2 D3D12初始化2.1 创建Windwos桌面项目2.2 修改符合模式2.3 下载d3dx12.h文件2.4 创建一个异常类D3DException,定义抛出异常实例的宏ThrowIfFailed3 D3D12的初始化步骤3.1 初始化…

pytorch实现水果2分类(蓝莓,苹果)

1.数据集的路径&#xff0c;结构 dataset.py 目的&#xff1a; 输入&#xff1a;没有输入&#xff0c;路径是写死了的。 输出&#xff1a;返回的是一个对象&#xff0c;里面有self.data。self.data是一个列表&#xff0c;里面是&#xff08;图片路径.jpg&#xff0c;标签&…

JMH325【剑侠情缘3】第2版80级橙武网游单机更稳定亲测视频安装教学更新整合收集各类修改教学补丁兴趣可以慢慢探索

资源介绍&#xff1a; 是否需要虚拟机&#xff1a;是 文件大小&#xff1a;压缩包约14G 支持系统&#xff1a;win10、win11 硬件需求&#xff1a;运行内存8G 4核及以上CPU独立显卡 下载方式&#xff1a;百度网盘 任务修复&#xff1a; 1&#xff0c;掌门任务&#xff08…

【Android组件】封装加载弹框

&#x1f4d6;封装加载弹框 ✅1. 构造LoadingDialog✅2. 调用LoadingDialog 效果&#xff1a; ✅1. 构造LoadingDialog 构造LoadingDialog类涉及到设计模式中的建造者模式&#xff0c;进行链式调用&#xff0c;注重的是构建的过程&#xff0c;设置需要的属性。 步骤一&#x…

[数据结构] 归并排序快速排序 及非递归实现

&#xff08;&#xff09;标题&#xff1a;[数据结构] 归并排序&&快速排序 及非递归实现 水墨不写bug &#xff08;图片来源于网络&#xff09; 目录 (一)快速排序 类比递归谋划非递归 快速排序的非递归实现&#xff1a; &#xff08;二&#xff09;归并排序 归…

Elasticsearch文档_id以数组方式返回

背景需求是只需要文档的_id字段&#xff0c;并且_id组装成一个数组。 在搜索请求中使用 script_fields 来整理 _id 为数组输出&#xff1a; POST goods_info/_search?size0 {"query": {"term": {"brand": {"value": "MGC"…