DERT:End-to-End Object Detection with Transformers

news2024/11/24 16:09:54

文章目录

  • 摘要
  • 1、简介
  • 2、相关工作
    • 2.1、集合预测
    • 2.2、Transformer与并行解码
    • 2.3、目标检测
  • 3、DETR模型
    • 3.1、目标检测集合预测损失
    • 3.2、DETR架构
  • 4、实验
    • 4.1、与Faster R-CNN的对比
    • 4.2、消融
    • 4.3、分析
    • 4.4、用于全景分割的DETR
  • 5、结论
  • 附录 A
    • A.1、初步:多头注意层
    • A.2、损失
    • A.3、详细架构
    • A.4、训练超参数
    • A.5、其他结果
    • A.6、PyTorch推理代码

摘要

https://arxiv.org/pdf/2005.12872.pdf
本文提出一种新方法,将目标检测视为直接的集合预测问题。该方法简化了检测管道,有效地消除了对许多手工设计组件的需要,如非最大抑制程序或锚点生成,这些组件显式编码了我们关于任务的先验知识。新框架称为检测TRansformer或DETR,其主要成分是基于集合的全局损失,通过二分图匹配强制进行独特的预测,以及TRansformer编码器-解码器架构。给定一个固定的小集合的学习对象查询,DETR对对象和全局图像上下文的关系进行推理,以直接并行输出最终的预测集。与许多其他现代检测器不同,新模型在概念上很简单,不需要专门的库。在具有挑战性的COCO目标检测数据集上,DETR展示了与完善的、高度优化的Faster RCNN基线相当的准确性和运行时间性能。此外,DETR易于推广,以统一的方式产生全景分割。实验表明,它明显优于有竞争力的基线。训练代码和预训练模型可以在https://github.com/facebookresearch/detr上找到。

1、简介

目标检测的目标是预测每个感兴趣物体的一组边界框和类别标签。现代的检测器通过在大量的提议集合[37,5]、锚点[23]或窗口中心[53,46]上定义代理回归和分类问题,以间接的方式解决这一集合预测任务。它们的性能受到以下因素的显著影响:瓦解近似重复预测的后处理步骤、锚集的设计以及将目标框分配给锚[52]的启发式方法。为简化这些管道,本文提出一种直接集预测方法来绕过代理任务。这种端到端哲学在复杂的结构化预测任务(如机器翻译或语音识别)中取得了重大进展,但在目标检测方面还没有:以前的尝试[43,16,4,39]要么添加了其他形式的先验知识,要么没有被证明在具有挑战性的基准上与强大的基线具有竞争力。本文旨在弥合这一差距。

在这里插入图片描述

通过将目标检测视为直接的集合预测问题,简化了训练管道。采用基于transformer的编码器-解码器架构[47],这是一种流行的序列预测架构。transformer的自注意力机制显式地对序列中元素之间的所有成对交互进行了建模,使这些架构特别适合集合预测的特定约束,如删除重复的预测。

我们的检测TRansformer (DETR,见图1)一次预测所有对象,并使用一组损失函数进行端到端训练,该函数在预测对象和真实对象之间执行二部匹配。DETR通过删除多个手工设计的组件来简化检测流程,这些组件编码先验知识,如空间锚定或非最大抑制。与大多数现有的检测方法不同,DETR不需要任何自定义层,因此可以在包含标准CNN和Transformer类的任何框架中轻松复制。1 .

与之前大多数直接集合预测工作相比,DETR的主要特征是将二部匹配损失和Transformer与(非自回归)并行解码结合在一起[29,12,10,8]。相比之下,之前的工作主要集中在rnn的自回归解码[43,41,30,36,42]。我们的匹配损失函数唯一地将预测分配给一个基本真值对象,并且对预测对象的排列是不变的,因此我们可以并行地发射它们。

我们在最流行的目标检测数据集COCO[24]上评估了DETR,对比了非常有竞争力的Faster R-CNN基线[37]。更快的RCNN经历了许多设计迭代,其性能自最初发布以来有了很大的提高。我们的实验表明,我们的新模型达到了相当的性能。更准确地说,DETR在大型对象上表现出明显更好的性能,这可能是由Transformer的非局部计算实现的。然而,它在小对象上获得较低的性能。我们希望未来的工作能够像FPN[22]的发展为Faster R-CNN所做的那样,在这方面进行改进。

DETR的训练设置在许多方面与标准目标检测器不同。新模型需要超长的训练计划,并且受益于Transformer的辅助解码损耗。我们将彻底探讨哪些组件对演示的性能至关重要。

DETR的设计特质很容易扩展到更复杂的任务。在我们的实验中,我们证明了在预训练的DETR之上训练的简单分割头在全景分割上的表现优于竞争基线[19],这是一项具有挑战性的像素级识别任务,最近得到了普及。

2、相关工作

本文工作建立在几个领域的之前工作的基础上:用于集合预测的二分匹配损失,基于transformer的编码器-解码器架构,并行解码和目标检测方法。

2.1、集合预测

目前还没有一个典型的深度学习模型可以直接预测集合。基本的集合预测任务是多标签分类(参见例如,[40,33]有关计算机视觉背景下的参考资料),对于这些问题,“一对其余”的基线方法不适用于元素之间存在基本结构(即几乎相同的框)的检测等问题。这些任务的第一个困难是避免近乎重复的工作。目前大多数检测器使用诸如非极大值抑制等后处理来解决这个问题,但直接集合预测是后处理无关的。它们需要全局推理方案,对所有预测元素之间的交互进行建模,以避免冗余。对于固定大小的集合预测,密集全连接网络[9]足够了,但代价很高。一种通用的方法是使用自回归序列模型,如循环神经网络[48]。在所有情况下,损失函数都应该通过预测的排列保持不变。通常的解决方案是在匈牙利算法[20]的基础上设计一个损失函数,以找到真实值和预测值之间的二分匹配。这确保了置换不变性,并确保每个目标元素都有唯一的匹配。我们遵循二分匹配损失方法。然而,与之前的大多数工作相比,本文放弃了自回归模型,使用transformer进行并行解码,我们将在下面描述。

2.2、Transformer与并行解码

Transformer是由Vaswani等人[47]提出的,作为一种新的基于注意力的机器翻译构建块。注意机制[2]是神经网络层,它从整个输入序列中聚集信息。Transformer引入了自注意力层,它与非局部神经网络[49]类似,扫描序列的每个元素,并通过聚合整个序列的信息来更新它。基于注意力的模型的主要优点之一是其全局计算和完美的记忆,这使得它比RNN更适合于长序列。在自然语言处理、语音处理和计算机视觉的许多问题上,Transformer正在取代rnn[8,27,45,34,31]。

Transformer首先用于自回归模型,遵循早期的序列到序列模型[44],一个接一个地生成输出令牌。然而,过高的推理成本(与输出长度成正比,难以批量处理)导致并行序列生成的发展,在音频[29]、机器翻译[12,10]、词表示学习[8]以及最近的语音识别[6]等领域。我们还结合了Transformer和并行解码,以便在计算成本和执行集合预测所需的全局计算能力之间进行适当的权衡。

2.3、目标检测

大多数现代目标检测方法都是根据最初的猜测做出预测的。两阶段检测器[37,5]预测方框w.r.t.提议,而单阶段方法预测w.r.t.锚点[23]或可能的对象中心网格[53,46]。最近的研究[52]表明,这些系统的最终性能在很大程度上取决于这些初始猜测的确切设置方式。在我们的模型中,我们能够消除这种手工制作的过程,并通过使用输入图像的绝对框预测而不是锚点直接预测检测集来简化检测过程。

基于集合的损失。一些目标检测器[9,25,35]使用了二部匹配损失。然而,在这些早期的深度学习模型中,不同预测之间的关系仅用卷积层或全连接层来建模,手工设计的NMS后处理可以提高它们的性能。最近的检测器[37,23,53]在基础真值和预测值之间使用非唯一分配规则以及NMS。

可学习NMS方法[16,4]和关系网络[17]明确地用注意力对不同预测之间的关系进行建模。使用直接集损失,它们不需要任何后处理步骤。然而,这些方法使用额外的手工制作的上下文特征,如提案箱坐标来有效地建模检测之间的关系,同时我们寻找减少模型中编码的先验知识的解决方案。

循环探测器。与我们的方法最接近的是目标检测[43]和实例分割[41,30,36,42]的端到端集合预测。与我们类似,他们使用基于CNN激活的编码器-解码器架构的双向匹配损失来直接生成一组边界框。然而,这些方法仅在小数据集上进行了评估,而不是根据现代基线进行评估。特别是,它们基于自回归模型(更准确地说是rnn),因此它们不利用最近的并行解码Transformer。

3、DETR模型

对于检测中的直接集预测来说,有两个要素是必不可少的:(1)集预测损失,它迫使预测值和真实值之间的唯一匹配;(2)预测(单次)一组对象并为它们之间的关系建模的架构。我们在图2中详细描述了我们的体系结构。

3.1、目标检测集合预测损失

在通过解码器的单次传递中,DETR推断出固定大小的N个预测集合,其中N被设置为明显大于图像中典型对象的数量。训练的主要困难之一是根据真实情况对预测对象(类别、位置、大小)进行评分。我们的损失在预测对象和真实对象之间产生最优的二部匹配,然后优化对象特定的(边界框)损失。

让我们用y表示对象的基础真集,用 y ^ = { y ^ i } i = 1 N \hat{y}=\left\{\hat{y}_{i}\right\}_{i=1}^{N} y^={y^i}i=1N表示N个预测集。假设N大于图像中物体的数量,我们也将y视为一个大小为N的集合,中间填充有 ∅ \varnothing (无物体)。为了找到这两个集合之间的二部匹配,我们寻找代价最小的N个元素 σ ∈ S N \sigma \in \mathfrak{S}_{N} σSN的排列:
σ ^ = arg ⁡ min ⁡ σ ∈ S N ∑ i N L match  ( y i , y ^ σ ( i ) ) (1) \hat{\sigma}=\underset{\sigma \in \mathfrak{S}_{N}}{\arg \min } \sum_{i}^{N} \mathcal{L}_{\text {match }}\left(y_{i}, \hat{y}_{\sigma(i)}\right) \tag{1} σ^=σSNargminiNLmatch (yi,y^σ(i))(1)
其中 L match  ( y i , y ^ σ ( i ) ) \mathcal{L}_{\text {match }}\left(y_{i}, \hat{y}_{\sigma(i)}\right) Lmatch (yi,y^σ(i))是基础真值 y i y_i yi与索引为 σ ( i ) \sigma(i) σ(i)的预测之间的成对匹配代价。根据先前的工作(例如[43]),匈牙利算法有效地计算了这种最优分配。

匹配成本既考虑了类预测,也考虑了预测真值框与真实真值框的相似性。地面真值集的每个元素i可以看作 y i = ( c i , b i ) y_{i}=\left(c_{i}, b_{i}\right) yi=(ci,bi),其中 c i c_{i} ci为目标类标号(可以是∅), b i ∈ [ 0 , 1 ] 4 b_{i} \in[0,1]^{4} bi[0,1]4是定义地面真框中心坐标及其相对于图像大小的高度和宽度的向量。对于指数为 σ ( i ) \sigma(i) σ(i)的预测,我们定义 c i c_{i} ci类的概率为 p ^ σ ( i ) ( c i ) \hat{p}_{\sigma(i)}\left(c_{i}\right) p^σ(i)(ci),预测框为 b ^ σ ( i ) \hat{b}_{\sigma(i)} b^σ(i)。我们用这些符号定义 L match  ( y i , y ^ σ ( i ) ) \mathcal{L}_{\text{match }}\left(y_{i},\hat{y}_{\sigma(i)}\right) Lmatch (yi,y^σ(i)) − 1 { c i ≠ ∅ } p ^ σ ( i ) ( c i ) + 1 { c i ≠ ∅ } L b o x ( b i , b ^ σ ( i ) ) -\mathbb{1}_{\left\{c_{i} \neq \varnothing\right\}} \hat{p}_{\sigma(i)}\left(c_{i}\right)+\mathbb{1}_{\left\{c_{i} \neq \varnothing\right\}} \mathcal{L}_{\mathrm{box}}\left(b_{i}, \hat{b}_{\sigma(i)}\right) 1{ci=}p^σ(i)(ci)+1{ci=}Lbox(bi,b^σ(i))

第二步是计算损失函数,在前一步中匹配的所有对的匈牙利损失。我们对损失的定义类似于普通目标检测器的损失,即类预测的负对数似然和稍后定义的框损失的线性组合:
L Hungarian  ( y , y ^ ) = ∑ i = 1 N [ − log ⁡ p ^ σ ^ ( i ) ( c i ) + 1 { c i ≠ ∅ } L box  ( b i , b ^ σ ^ ( i ) ) ] , (2) \mathcal{L}_{\text {Hungarian }}(y, \hat{y})=\sum_{i=1}^{N}\left[-\log \hat{p}_{\hat{\sigma}(i)}\left(c_{i}\right)+\mathbb{1}_{\left\{c_{i} \neq \varnothing\right\}} \mathcal{L}_{\text {box }}\left(b_{i}, \hat{b}_{\hat{\sigma}}(i)\right)\right], \tag{2} LHungarian (y,y^)=i=1N[logp^σ^(i)(ci)+1{ci=}Lbox (bi,b^σ^(i))],(2)
其中,σ是在第一步(1)中计算的最优分配。在实践中,当 c i = ∅ c_{i} = \varnothing ci=时,我们将对数概率项的权重降低10个因子以解释类不平衡。这类似于Faster R-CNN训练过程如何通过子抽样平衡正/负提议[37]。注意,对象与∅之间的匹配代价不依赖于预测,这意味着在这种情况下代价是常数。在匹配代价中,我们使用概率 p ^ σ ^ ( i ) ( c i ) \hat{p}_{\hat{\sigma}(i)}\left(c_{i}\right) p^σ^(i)(ci)代替对数概率。这使得类预测项被称为可以同单位度量的 L box  ( ⋅ , ⋅ ) \mathcal{L}_{\text {box }}(\cdot, \cdot) Lbox (,)(如下所述),并且我们观察到更好的经验性能。

边界框损失。匹配成本和匈牙利损失的第二部分是 L box  ( ⋅ ) \mathcal{L}_{\text {box }}(\cdot) Lbox (),它对边界框进行评分。与许多将框预测作为 Δ w . r . t . \Delta w.r.t. Δw.r.t.的检测器不同,我们直接进行框预测。虽然这种方法简化了实现,但也提出了一个问题,即损失的相对缩放。即使小框和大框的相对误差相似,最常用的 ℓ 1 \ell_{1} 1损失也将具有不同的尺度。为了缓解这个问题,我们使用尺度不变的 ℓ 1 \ell_{1} 1损失和广义IoU损失[38] L iou  ( ⋅ , ⋅ ) \mathcal{L}_{\text {iou }}(\cdot, \cdot) Liou (,)的线性组合。总的来说,我们的框损失是 L box  ( b i , b ^ σ ( i ) ) \mathcal{L}_{\text {box }}\left(b_{i}, \hat{b}_{\sigma(i)}\right) Lbox (bi,b^σ(i)),定义为 λ iou  L iou  ( b i , b ^ σ ( i ) ) + λ L 1 ∥ b i − b ^ σ ( i ) ∥ 1 \lambda_{\text {iou }} \mathcal{L}_{\text {iou }}\left(b_{i}, \hat{b}_{\sigma(i)}\right)+\lambda_{\mathrm{L} 1}\left\|b_{i}-\hat{b}_{\sigma(i)}\right\|_{1} λiou Liou (bi,b^σ(i))+λL1 bib^σ(i) 1其中 λ iou  , λ L 1 ∈ R \lambda_{\text {iou }}, \lambda_{\mathrm{L} 1} \in \mathbb{R} λiou ,λL1R是超参数。这两个损失通过批处理中对象的数量进行归一化。

3.2、DETR架构

整个DETR架构非常简单,如图2所示。它包含三个主要组件,我们在下面描述:一个用于提取紧凑特征表示的CNN主干,一个编码器-解码器transformer,以及一个用于进行最终检测预测的简单前馈网络(FFN)。
在这里插入图片描述

与许多现代检测器不同,DETR可以在任何深度学习框架中实现,这些框架提供了一个通用的CNN主干和一个只有几百行代码的Transformer架构实现。在PyTorch中,DETR的推理代码可以用不到50行来实现[32]。我们希望我们方法的简单性将吸引新的研究人员到检测社区。

骨干。传统的CNN主干从初始图像 x img  ∈ R 3 × H 0 × W 0 x_{\text {img }} \in \mathbb{R}^{3 \times H_{0} \times W_{0}} ximg R3×H0×W0(有3个颜色通道)开始,生成一个低分辨率的激活图 f ∈ R C × H × W f \in \mathbb{R}^{C \times H \times W} fRC×H×W。我们使用的典型值是 C = 2048 C = 2048 C=2048 H , W = H 0 32 , W 0 32 H, W=\frac{H_{0}}{32}, \frac{W_{0}}{32} H,W=32H0,32W0

Transformer 编码器。首先,1x1卷积将高级激活图f的通道维度从C降低到更小的维度d,创建一个新的特征图 z 0 ∈ R d × H × W z_{0} \in \mathbb{R}^{d \times H \times W} z0Rd×H×W。编码器期望一个序列作为输入,因此我们将z0的空间维度折叠成一维,从而得到 d × H W d \times H W d×HW特征映射。每个编码器层都有一个标准的架构,由一个多头自注意力模块和一个前馈网络(FFN)组成。由于Transformer 结构是排列不变的,我们用固定位置编码[31,3]来补充它,这些编码被添加到每个注意层的输入中。我们在补充材料中描述架构的详细定义,它遵循[47]中描述的定义。

Transformer解码器。解码器遵循transformer的标准架构,使用多头自注意力和编码器-解码器注意力机制转换大小为d的N个嵌入。与原始transformer的不同之处在于,我们的模型在每个解码器层并行解码N个对象,而Vaswani等人[47]使用一个自回归模型,每次预测一个元素的输出序列。我们建议不熟悉这些概念的读者查阅补充材料。由于解码器也是置换不变的,N个输入嵌入必须不同才能产生不同的结果。这些输入嵌入是学习到的位置编码,我们称之为对象查询,与编码器类似,我们将它们添加到每个注意力层的输入中。N个对象查询被解码器转换为一个输出嵌入。然后,它们被前馈网络独立解码为框坐标和类标签(下一小节中描述),产生N个最终预测。在这些嵌入上使用自注意力和编码器-解码器注意力,该模型利用它们之间的成对关系全局地推理所有对象,同时能够将整个图像作为上下文。

预测前馈网络(FFNs)。最终的预测由一个具有ReLU激活函数和隐藏维度d的3层感知器和一个线性投影层计算。FFN预测归一化中心坐标、框的高度和宽度相对于输入图像的权重,线性层使用softmax函数预测类别标签。因为我们预测的是一组固定大小的N个边界框,其中N通常比图像中感兴趣的对象的实际数量大得多,所以使用额外的类别标签∅表示在一个槽内没有检测到对象。这个类在标准的目标检测方法中扮演着类似于“背景”类的角色。

辅助解码损失。我们发现在训练过程中使用辅助损失[1]在解码器中是很有用的,特别是帮助模型输出每个类的正确对象数量。我们在每个解码器层后添加预测FFNs和匈牙利损失。所有预测ffn都共享它们的参数。我们使用一个额外的共享层范数将输入归一化到来自不同解码器层的预测FFNs。

4、实验

在对COCO的定量评估中,DETR与Faster R-CNN相比取得了有竞争力的结果。对架构和损失进行了详细的消融研究,给出了见解和定性结果。最后,为了表明DETR是一个通用和可扩展的模型,提出了全景分割的结果,只在固定的DETR模型上训练一个小的扩展。我们在https://github.com/facebookresearch/detr上提供了代码和预训练模型来重现我们的实验。

数据集。我们在COCO 2017检测和全景分割数据集[24,18]上进行实验,包含118k训练图像和5k验证图像。每个图像都用边界框和全景分割标注。平均每张图像有7个实例,在训练集中单个图像中最多63个实例,在相同的图像上从小到大。如果没有指定,我们将AP报告为bbox AP,即超过多个阈值的积分度量。为了与Faster R-CNN进行比较,我们报告了最后一次训练的验证AP,对于消融,我们记录了最近10次训练的验证结果的中位数。

技术细节。用AdamW[26]训练DETR,将初始transformer的学习率设置为10−4,骨干的学习率设置为10−5,权重衰减为10−4。所有transformer权重都用Xavier init[11]初始化,骨干是来自torchvision的imagenet预训练的ResNet模型[15],具有冻结的batchnorm层。本文报告了两个不同骨干的结果:ResNet50和ResNet-101。对应的模型分别称为DETR和DETR- r101。在[21]之后,我们还通过向骨干的最后一阶段添加扩张并从这一阶段的第一个卷积中删除步幅来增加特征分辨率。对应的模型分别称为DETR-DC5和DETR-DC5- r101 (dilated C5 stage)。这种修改将分辨率提高了两倍,从而提高了小物体的性能,但代价是编码器的自注意力成本提高了16倍,导致计算成本总体增加了2倍。表1给出了这些模型和Faster R-CNN的完整比较。

在这里插入图片描述

我们使用尺度增强,调整输入图像的大小,使最短的边至少为480像素,最多为800像素,最长的边最多为1333[50]。为了帮助通过编码器的自注意力学习全局关系,还在训练中应用了随机裁剪增强,将性能提高了约1 AP。具体来说,以0.5的概率将训练图像裁剪到随机矩形块,然后再次调整其大小为800-1333。transformer的训练默认dropout为0.1。在推理时,一些槽预测为空类。为了优化AP,我们使用相应的置信度,用得分第二高的类覆盖这些插槽的预测。与过滤空槽相比,这提高了2个AP点数。其他训练超参数可以在A.4节中找到。对于消融实验,使用300 epoch的训练计划,在200 epoch后学习率下降10倍,其中单个epoch是对所有训练图像的一次遍历。在16个V100 GPU上训练300次基线模型需要3天,每个GPU 4张图像(因此总批大小为64)。对于与更快的R-CNN相比使用的更长的时间表,我们训练500个epoch,学习率在400个epoch后下降。这个时间表比较短的时间表增加了1.5个AP。

4.1、与Faster R-CNN的对比

transformer通常使用Adam或Adagrad优化器进行训练,训练时间很长,会中途退出,DETR也是如此。然而,Faster R-CNN是用SGD进行训练的,数据增强很少,我们还不知道Adam或dropout的成功应用。尽管有这些差异,我们试图使更快的R-CNN基线更强。为使其与DETR对齐,将广义IoU[38]添加到框损失、相同的随机裁剪增强和已知可改善结果的长时间训练[13]中。结果如表1所示。在上面的部分中,我们展示了使用3x计划训练的模型从Detectron2 Model Zoo[50]获得的更快的R-CNN结果。在中间部分,我们展示了相同模型的结果(带有“+”),但使用9x时间表(109个epoch)和所描述的增强进行了训练,总共增加了1-2个AP。在表1的最后一节,我们展示了多个DETR模型的结果。为了在参数数量上进行比较,我们选择了一个具有6个transformer和6个宽度为256的解码器层和8个注意力头的模型。与使用FPN的Faster R-CNN一样,该模型有4130万个参数,其中23.5万个参数在ResNet-50中,17.8万个参数在transformer中。尽管Faster R-CNN和DETR仍然有可能通过更长的训练时间进一步提高,但我们可以得出结论,在相同参数数量的情况下,DETR可以与Faster R-CNN竞争,在COCO val子集上达到42 AP。DETR实现这一目标的方法是改进APL(+7.8),但请注意,该模型在APS(-5.5)中仍然落后。DETR-DC5具有相同的参数数量和相似的FLOP计数,具有更高的AP,但在AP方面仍然明显落后。以ResNet-101为骨干的Faster R-CNN和DETR也显示了类似的结果。

4.2、消融

transformer解码器中的注意力机制是建模不同检测的特征表示之间关系的关键组件。消融分析中,探讨了架构的其他组件和损失如何影响最终性能。在本研究中,我们选择了基于resnet -50的DETR模型,该模型有6个编码器,6个解码器层,宽度为256。该模型具有41.3M参数,在短调度和长调度下分别达到40.6和42.0 AP,并以28 FPS的速度运行,与具有相同骨干的Faster R-CNN-FPN类似。

在这里插入图片描述

编码器层数。我们通过改变编码器层的数量来评估全局图像级自注意力的重要性(表2)。没有编码器层,总体AP下降了3.9个点,在大对象上AP下降了6.0个点。本文假设,通过使用全局场景推理,编码器对解缠物体很重要。在图3中,我们将训练模型的最后一个编码器层的注意力图可视化,重点关注图像中的几个点。编码器似乎已经分离了实例,这可能简化了解码器的对象提取和定位。
在这里插入图片描述

在这里插入图片描述

解码器层数。我们在每个解码层之后应用辅助损失(见3.2节),因此,预测ffn通过设计来训练,以从每个解码层的输出中预测对象。我们通过评估在解码的每个阶段将要预测的对象来分析每个解码器层的重要性(图4)。AP和AP50在每一层之后都有所提高,总而言之,第一层和最后一层之间的AP提高非常显著+8.2/9.5。基于集合损失,DETR在设计上不需要NMS。为了验证这一点,我们为每个解码器后的输出运行一个带有默认参数[50]的标准NMS过程。NMS提高了第一个解码器预测的性能。这可以解释为,transformer的单个解码层无法计算输出元素之间的任何互相关,因此,它容易对同一个对象进行多次预测。在第二层和后续层中,激活上的自注意力机制允许模型抑制重复预测。本文观察到,NMS带来的改善随着深度的增加而减少。在最后一层,我们观察到AP有一个小损失,因为NMS错误地删除了真正的积极预测。

在这里插入图片描述

与可视化编码器注意力类似,我们在图6中可视化解码器注意力,将每个预测对象的注意力图着色为不同的颜色。解码器的注意力是相当局部的,这意味着它主要关注物体的四肢,如头或腿。假设在编码器通过全局注意力分离实例后,解码器只需要关注端点以提取类和对象边界。

FFN的重要性。transformer内部的FFN可以看作是1 × 1的卷积层,使得编码器类似于注意力增强卷积网络[3]。我们试图完全删除它,只在transformer层中保留注意力。通过将网络参数从4130万减少到28.7万,仅留下108万,性能下降了2.3 AP,从而得出结论,FFN对取得良好效果很重要。

在这里插入图片描述

位置编码的重要性。在我们的模型中有两种位置编码:空间位置编码和输出位置编码(对象查询)。我们对固定编码和学习编码的各种组合进行了实验,结果见表3。输出位置编码是必需的,不能删除,因此我们尝试在解码器输入时一次性传递它们,或在每个解码器注意力层添加查询。在第一个实验中,我们完全删除了空间位置编码,并在输入时传递输出位置编码,有趣的是,模型仍然达到了超过32 AP,比基线降低了7.8 AP。然后,在输入时传递固定的正弦空间位置编码和输出编码,如在原始transformer[47]中,发现与直接通过注意力传递位置编码相比,这会导致1.4 AP下降。传递给attention的学习空间编码给出了类似的结果。令人惊讶的是,我们发现在编码器中不传递任何空间编码只会导致1.3 AP的轻微下降。当我们将编码传递给attention时,它们在所有层中共享,并且总是学习输出编码(对象查询)。

鉴于这些消融,得出的结论是,transformer组件:编码器、FFN、多个解码器层和位置编码中的全局自注意力,都对最终的目标检测性能有显著贡献。
在这里插入图片描述

损失的消融。为了评估匹配成本和损失的不同组成部分的重要性,训练了几个模型,打开和关闭它们。损失有三个组成部分:分类损失、 ℓ 1 \ell_{1} 1边界框距离损失和GIoU[38]损失。分类损失对于训练至关重要,不能关闭,因此我们训练一个没有边界框距离损失的模型和一个没有GIoU损失的模型,并与基线进行比较,使用所有三种损失进行训练。结果如表4所示。GIoU loss对不同的损失进行简单的消融(每次使用相同的权重),但将它们结合的其他方法可能会取得不同的结果。

4.3、分析

解码器输出位置分析。在图7中,我们将COCO 2017 val集中所有图像的不同槽预测的框可视化。DETR为每个查询槽学习不同的专门化。我们观察到每个插槽有几种操作模式,侧重于不同的区域和框大小。特别是,所有插槽都具有预测图像范围内框的模式(可见于与图形中间对齐的红点)。我们假设这与COCO中的对象分布有关。
在这里插入图片描述

对未见过的实例数量的泛化。COCO中的一些类不能很好地表示为同一图像中相同类的许多实例。例如,在训练集中没有超过13只长颈鹿的图像。我们创建了一个合成图像来验证DETR的泛化能力(见图5)。我们的模型能够找到图像上明显超出分布的所有24只长颈鹿。实验证明,每个对象查询没有很强的类特化。

4.4、用于全景分割的DETR

全景分割[19]最近引起了计算机视觉界的广泛关注。与Faster R-CNN[37]扩展到Mask R-CNN[14]类似,可以通过在解码器输出上添加掩码头自然扩展DETR。在本节中,我们将演示这样的头可以通过以统一的方式处理东西和东西类来产生全景分割[19]。我们在COCO数据集的全景注释上进行实验,该数据集有53个填充类别以及80个物体类别。

在这里插入图片描述

我们用同样的方法训练DETR来预测COCO上的填充类别和物体类的框。因为匈牙利匹配是使用框之间的距离来计算的,所以需要预测框才能使训练成为可能。我们还添加了一个掩码头,用于预测每个预测框的二进制掩码,参见图8。它将每个对象的transformer解码器的输出作为输入,并在编码器的输出上计算该嵌入的多头(有M个头)注意力分数,以小分辨率生成每个对象的M个注意力热图。为了进行最终预测并提高分辨率,使用了类似于fpga的架构。我们将在附录中更详细地描述该体系结构。掩模的最终分辨率为4步,每个掩模使用DICE/F-1损失[28]和Focal损失[23]独立监督。

Mask头可以联合训练,也可以分两步训练,我们只训练框的DETR,然后冻结所有的权重,只训练Mask头25轮。在实验中,这两种方法给出了相似的结果,我们报告了使用后一种方法的结果,因为它导致更短的总挂钟时间训练。

为了预测最终的全视分割,我们只需在每个像素的mask分数上使用argmax,并将相应的类别分配给结果mask。这个过程保证了最终的mask没有重叠,因此,DETR不需要启发式[19],通常用于对齐不同的mask。

训练的细节。我们按照边界框检测的配方训练了DETR、DETR- dc5和DETR- r101模型,以预测COCO数据集中的填充类别和物体类周围的框。新的mask头训练了25轮(详见补充)。在推理过程中,我们首先以低于85%的置信度过滤掉检测,然后计算每个像素的argmax以确定每个像素属于哪个mask。然后,我们将相同内容类别的不同mask预测折叠成一个,并过滤空的(小于4像素)。

在这里插入图片描述

主要的结果。定性结果如图9所示。在表5中,我们将我们的统一全视分割方法与几种不同处理物体和填充类别的既定方法进行比较。我们记录全景质量(PQ)和物体(PQth)和填充类别(PQst)的分解。我们还记录maskAP(在物体类上计算),在任何panoptic后处理之前(在我们的例子中,在采取逐像素argmax之前)。我们表明,DETR优于COCO-val 2017上发表的结果,以及我们强大的PanopticFPN基线(为了公平比较,使用与DETR相同的数据增强训练)。结果分解表明,DETR在填充类上尤其占主导地位,我们假设编码器注意允许的全局推理是这一结果的关键因素。对于物体类,尽管与掩码AP计算的基线相比,存在高达8 mAP的严重缺陷,但DETR获得了具有竞争力的PQth。我们还在COCO数据集的测试集上评估了我们的方法,并获得了46个PQ。我们希望我们的方法能够在未来的工作中激发对全视分割的完全统一模型的探索。
在这里插入图片描述

5、结论

提出了一种新的基于transformer和二部匹配损失的目标检测系统,用于直接集合预测。该方法在具有挑战性的COCO数据集上获得了与优化的Faster R-CNN基线相当的结果。DETR易于实现,具有灵活的架构,易于扩展到全景分割,具有竞争力的结果。此外,它在大型对象上的性能明显优于Faster R-CNN,这可能要归功于自自注意力对全局信息的处理。

这种检测器的新设计也带来了新的挑战,特别是在小物体的训练、优化和性能方面。目前的检测器需要几年的改进才能解决类似的问题,我们希望未来的工作能够成功地解决DETR的问题。

附录 A

A.1、初步:多头注意层

由于该模型基于Transformer架构,这里提醒一下用于耗尽性的注意力机制的一般形式。注意力机制遵循[47],除了位置编码的细节(见公式8)遵循[7]。

具有M个d维头的多头注意力的一般形式是一个具有以下签名的函数(使用d 0 = d M,并在括号中给出矩阵/张量的大小):
 mh-attn :  X q ⏟ d × N q , X k v ⏟ d × N k v , T ⏟ M × 3 × d ′ × d , L ⏟ d × d ↦ X ~ q ⏟ d × N q (8) \text { mh-attn : } \underbrace{X_{\mathrm{q}}}_{d \times N_{\mathrm{q}}}, \underbrace{X_{\mathrm{kv}}}_{d \times N_{\mathrm{kv}}}, \underbrace{T}_{M \times 3 \times d^{\prime} \times d}, \underbrace{L}_{d \times d} \mapsto \underbrace{\tilde{X}_{\mathrm{q}}}_{d \times N_{\mathrm{q}}} \tag{8}  mh-attn : d×Nq Xq,d×Nkv Xkv,M×3×d×d T,d×d Ld×Nq X~q(8)
其中 X q X_q Xq是长度为 N q N_q Nq的查询序列, X k v X_{kv} Xkv是长度为Nkv的键值序列(为简单起见,通道数d相同),T是用于计算所谓的查询、键值嵌入的权重张量,L是投影矩阵。输出的大小与查询序列相同。为了在给出细节之前修复词汇表,多头自注意力(mh-s-attn)是特殊情况 X q = X k v X_q = X_{kv} Xq=Xkv,即:
 mh-s-attn  ( X , T , L ) =  mh-attn  ( X , X , T , L ) . \text { mh-s-attn }(X, T, L)=\text { mh-attn }(X, X, T, L) .  mh-s-attn (X,T,L)= mh-attn (X,X,T,L).
多头注意力只是M个单注意力头的连接,然后是l的投影。[47]的常见做法是使用残差连接、dropout和层归一化。换句话说,我们将 X ~ q = mh ⁡ attn ⁡ ( X q , X k v , T , L ) \tilde{X}_{\mathrm{q}}= \operatorname{mh} \operatorname{attn}\left(X_{\mathrm{q}}, X_{\mathrm{kv}}, T, L\right) X~q=mhattn(Xq,Xkv,T,L) X ˉ ˉ ( q ) \bar{\bar{X}}^{(q)} Xˉˉ(q)表示为attention头的拼接
X q ′ = [ attn ⁡ ( X q , X k v , T 1 ) ; … ; attn ⁡ ( X q , X k v , T M ) ] (5) X_{\mathrm{q}}^{\prime}=\left[\operatorname{attn}\left(X_{\mathrm{q}}, X_{\mathrm{kv}}, T_{1}\right) ; \ldots ; \operatorname{attn}\left(X_{\mathrm{q}}, X_{\mathrm{kv}}, T_{M}\right)\right] \tag{5} Xq=[attn(Xq,Xkv,T1);;attn(Xq,Xkv,TM)](5)

X ~ q = layernorm ⁡ ( X q + dropout ⁡ ( L X q ′ ) ) ,  (6) \tilde{X}_{\mathrm{q}}=\operatorname{layernorm}\left(X_{\mathrm{q}}+\operatorname{dropout}\left(L X_{\mathrm{q}}^{\prime}\right)\right) \text {, } \tag{6} X~q=layernorm(Xq+dropout(LXq))(6)

其中[;]表示通道轴上的连接。

单头。一个权重张量 T ′ ∈ R 3 × d ′ × d T^{\prime} \in \mathbb{R}^{3 \times d^{\prime} \times d} TR3×d×d的注意力头,用 attn ⁡ ( X q , X k v , T ′ ) \operatorname{attn}\left(X_{\mathrm{q}}, X_{\mathrm{kv}}, T^{\prime}\right) attn(Xq,Xkv,T)表示,依赖于附加的位置编码 P q ∈ R d × N q P_{\mathrm{q}} \in \mathbb{R}^{d \times N_{\mathrm{q}}} PqRd×Nq P k v ∈ R d × N k v P_{\mathrm{kv}} \in \mathbb{R}^{d \times N_{\mathrm{kv}}} PkvRd×Nkv。它在添加查询和键位置编码后,从计算所谓的查询、键和值嵌入开始:
[ Q ; K ; V ] = [ T 1 ′ ( X q + P q ) ; T 2 ′ ( X k v + P k v ) ; T 3 ′ X k v ] (7) [Q ; K ; V]=\left[T_{1}^{\prime}\left(X_{\mathrm{q}}+P_{\mathrm{q}}\right) ; T_{2}^{\prime}\left(X_{\mathrm{kv}}+P_{\mathrm{kv}}\right) ; T_{3}^{\prime} X_{\mathrm{kv}}\right] \tag{7} [Q;K;V]=[T1(Xq+Pq);T2(Xkv+Pkv);T3Xkv](7)
其中 T ′ T^{\prime} T T 1 ′ , T 2 ′ , T 3 ′ T_{1}^{\prime}, T_{2}^{\prime}, T_{3}^{\prime} T1,T2,T3的串联。然后,基于查询和键之间的点积的softmax计算注意力权重 α \alpha α,使查询序列的每个元素都关注键值序列的所有元素(i是查询索引,j是键值索引):
α i , j = e 1 d ′ Q i T K j Z i  where  Z i = ∑ j = 1 N k v e 1 d ′ Q i T K j (8) \alpha_{i, j}=\frac{e^{\frac{1}{\sqrt{d^{\prime}}} Q_{i}^{T} K_{j}}}{Z_{i}} \text { where } Z_{i}=\sum_{j=1}^{N_{\mathrm{kv}}} e^{\frac{1}{\sqrt{d^{\prime}}} Q_{i}^{T} K_{j}} \tag{8} αi,j=Zied 1QiTKj where Zi=j=1Nkved 1QiTKj(8)
在我们的例子中,位置编码可以是学习或固定的,但对于给定的查询/键值序列,在所有的注意力层中共享,因此我们没有显式地将它们编写为注意力的参数。在描述编码器和解码器时,我们给出了它们的确切值的更多细节。最终输出是由注意力权重加权的值的聚合:第i层由 attn ⁡ i ( X q , X k v , T ′ ) = ∑ j = 1 N k v α i , j V j .  \operatorname{attn}_{i}\left(X_{\mathrm{q}}, X_{\mathrm{kv}}, T^{\prime}\right)=\sum_{j=1}^{N_{\mathrm{kv}}} \alpha_{i, j} V_{j} \text {. } attni(Xq,Xkv,T)=j=1Nkvαi,jVj给出。

前馈网络(FFN)层。原始transformer交替使用多头注意力和所谓的FFN层[47],这实际上是多层1x1卷积,在我们的例子中具有M d输入和输出通道。我们考虑的FFN由具有ReLU激活的两层1x1卷积组成。在两层之后还有一个残差连接/dropout/layernorm,类似于公式6。

A.2、损失

为了完整性,详细介绍了该方法中使用的损失。所有的损失都通过批处理中对象的数量进行归一化。对于分布式训练必须格外小心:由于每个GPU接收一个子批处理,仅通过本地批处理中的对象数量进行归一化是不够的,因为通常子批处理在GPU之间是不均衡的。相反,重要的是通过所有子批次中的对象总数进行归一化。

框损失。与[41,36]类似,我们在损失函数中使用Intersection / Union的软版本,并在 b ^ \hat{b} b^上使用 ℓ 1 \ell_{1} 1损失函数:
L box  ( b σ ( i ) , b ^ i ) = λ iou  L iou  ( b σ ( i ) , b ^ i ) + λ L 1 ∥ b σ ( i ) − b ^ i ∥ 1 (9) \mathcal{L}_{\text {box }}\left(b_{\sigma(i)}, \hat{b}_{i}\right)=\lambda_{\text {iou }} \mathcal{L}_{\text {iou }}\left(b_{\sigma(i)}, \hat{b}_{i}\right)+\lambda_{\mathrm{L} 1}\left\|b_{\sigma(i)}-\hat{b}_{i}\right\|_{1} \tag{9} Lbox (bσ(i),b^i)=λiou Liou (bσ(i),b^i)+λL1 bσ(i)b^i 1(9)

其中 λ iou  , λ L 1 ∈ R \lambda_{\text {iou }}, \lambda_{\mathrm{L} 1} \in \mathbb{R} λiou ,λL1R为超参数, L iou  ( ⋅ ) \mathcal{L}_{\text {iou }}(\cdot) Liou ()为普通的IoU [38]:
L iou  ( b σ ( i ) , b ^ i ) = 1 − ( ∣ b σ ( i ) ∩ b ^ i ∣ ∣ b σ ( i ) ∪ b ^ i ∣ − ∣ B ( b σ ( i ) , b ^ i ) \ b σ ( i ) ∪ b ^ i ∣ ∣ B ( b σ ( i ) , b ^ i ) ∣ ) . (10) \mathcal{L}_{\text {iou }}\left(b_{\sigma(i)}, \hat{b}_{i}\right)=1-\left(\frac{\left|b_{\sigma(i)} \cap \hat{b}_{i}\right|}{\left|b_{\sigma(i)} \cup \hat{b}_{i}\right|}-\frac{\left|B\left(b_{\sigma(i)}, \hat{b}_{i}\right) \backslash b_{\sigma(i)} \cup \hat{b}_{i}\right|}{\left|B\left(b_{\sigma(i)}, \hat{b}_{i}\right)\right|}\right) . \tag{10} Liou (bσ(i),b^i)=1 bσ(i)b^i bσ(i)b^i B(bσ(i),b^i) B(bσ(i),b^i)\bσ(i)b^i .(10)

∣ . ∣ |.| ∣.∣表示“面积”,框坐标的并集和交集被用作框本身的简写。通过 b σ ( i ) b_{\sigma(i)} bσ(i) b ^ i \hat{b}_{i} b^i线性函数的极小/极大值计算并集或交点的面积,这使得随机梯度的损失表现得足够好。 B ( b σ ( i ) , b ^ i ) B\left(b_{\sigma(i)},\hat{b}_{i}\right) B(bσ(i),b^i)表示包含 b σ ( i ) , b ^ i b_{\sigma(i)},\hat{b}_{i} bσ(i),b^i的最大框(B的面积也根据框坐标的线性函数的最小/最大计算)。

DICE/F-1损失[28]。DICE系数与交集/联合密切相关。用m表示原始掩码logits对模型的预测,m表示二值目标掩码,则损失定义为:
L D I C E ( m , m ^ ) = 1 − 2 m σ ( m ^ ) + 1 σ ( m ^ ) + m + 1 (11) \mathcal{L}_{\mathrm{DICE}}(m, \hat{m})=1-\frac{2 m \sigma(\hat{m})+1}{\sigma(\hat{m})+m+1} \tag{11} LDICE(m,m^)=1σ(m^)+m+12(m^)+1(11)

其中σ是s型函数。这种损失是由物体的数量标准化的。

A.3、详细架构

DETR中使用的Transformer的详细描述如图10所示,在每个注意层传递位置编码。来自CNN主干的图像特征与空间位置编码一起通过Transformer编码器,这些编码被添加到每个多头自关注层的查询和键。然后,解码器接收查询(最初设置为零),输出位置编码(对象查询)和编码器内存,并通过多个多头自注意和解码器-编码器注意生成最终的预测类标签和边界框集。可以跳过第一解码器层中的第一自注意层。

image-20230810201310148

计算复杂度。编码器中的每个自关注都具有复杂度 O ( d 2 H W + d ( H W ) 2 ) : O ( d ′ d ) \mathcal{O}\left(d^{2} H W+d(H W)^{2}\right): \mathcal{O}\left(d^{\prime} d\right) O(d2HW+d(HW)2):O(dd)是计算单个查询/键/值嵌入的成本(并且 M d ′ = d M d^{\prime}=d Md=d),而 O ( d ′ ( H W ) 2 ) \mathcal{O}\left(d^{\prime}(H W)^{2}\right) O(d(HW)2)是计算一个头的注意权重的成本。其他计算可以忽略不计。在解码器中,每个自注意在 O ( d 2 N + d N 2 ) \mathcal{O}\left(d^{2} N+d N^{2}\right) O(d2N+dN2),编码器和解码器之间的交叉注意在 O ( d 2 ( N + H W ) + d N H W ) \mathcal{O}\left(d^{2}(N+H W)+d N H W\right) O(d2(N+HW)+dNHW),远低于实际中自$ N \ll H W $以来的编码器。

FLOPS的计算。考虑到更快R-CNN的FLOPS取决于图像中提案的数量,我们记录COCO 2017验证集中前100张图像的平均FLOPS数量。我们使用Detectron2[50]中的工具flop_count_operators来计算FLOPS。我们将其用于Detectron2模型而无需修改,并将其扩展到考虑DETR模型的批处理矩阵乘法(bmm)。

A.4、训练超参数

我们使用AdamW[26]训练DETR,改进了权重衰减处理,设置为10−4。我们还应用梯度裁剪,最大梯度范数为0.1。骨干和Transformer的处理略有不同,我们现在讨论两者的细节。

骨干网络。ImageNet预训练主干ResNet-50从Torchvision导入,丢弃最后一个分类层。骨干批归一化权值和统计量在训练过程中被冻结,这是在目标检测中广泛采用的做法。我们使用 1 0 − 5 10^{−5} 105的学习率对主干进行微调。我们观察到,骨干学习率比网络的其他部分大约小一个数量级,这对于稳定训练很重要,尤其是在最初的几个时期。

我们以 1 0 − 4 10^{−4} 104的学习率训练Transformer。在每一个多头注意和层归一化前的FFN之后加0.1的dropout。权重是用Xavier初始化随机初始化的。

损失。我们分别使用 λ L 1 = 5 \lambda_{\mathrm{L} 1} = 5 λL1=5 λ iou  = 2 \lambda_{\text {iou }} = 2 λiou =2权重的 ℓ 1 \ell_{1} 1和GIoU损失的线性组合进行边界框回归。所有模型都用N = 100个解码器查询槽进行训练。

基线。我们增强的Faster-RCNN+基线使用GIoU[38]损失和标准的 ℓ 1 \ell_{1} 1损失进行边界框回归。我们进行了网格搜索以找到损失的最佳权重,最终模型仅使用权重为20和1的GIoU损失分别用于box和proposal回归任务。对于基线,我们采用与DETR中使用的相同的数据增强,并以9×时间表(大约109个epoch)进行训练。所有其他设置与Detectron2模型动物园中的相同模型相同[50]。

空间位置编码。编码器激活与图像特征的相应空间位置相关联。在我们的模型中,我们使用固定的绝对编码来表示这些空间位置。我们将原始Transformer[47]编码推广到2D情况[31]。具体来说,对于每个嵌入的两个空间坐标,我们分别使用不同频率的d2正弦和余弦函数。然后我们将它们连接起来以获得最终的d通道位置编码。

A.5、其他结果

DETR-R101模型全景预测的一些额外定性结果如图11所示。

在这里插入图片描述
增加实例的数量。按照设计,DETR不能预测超过查询槽数的对象,在我们的实验中是100个。在本节中,我们将分析DETR在接近这个极限时的行为。我们选择给定类的标准平方图像,在10×10网格上重复它,并计算模型错过的实例的百分比。为了在少于100个实例的情况下测试模型,我们随机屏蔽了一些单元格。这确保了对象的绝对大小是相同的,无论有多少可见。为了考虑掩模的随机性,我们使用不同的掩模重复实验100次。结果如图12所示。跨类的行为是相似的,当模型检测到所有实例时,最多可以看到50个实例,然后它开始饱和并错过越来越多的实例。值得注意的是,当图像包含全部100个实例时,模型平均只检测到30个,这比图像只包含全部检测到的50个实例要少。模型的反直觉行为很可能是因为图像和检测远离训练分布。

请注意,这个测试是设计的泛化分布外测试,因为只有很少的示例图像具有单个类的大量实例。从实验中很难区分出两种域外泛化:图像本身和每个类的对象数量。但是由于几乎没有COCO图像只包含许多相同类别的对象,这种类型的实验代表了我们最好的努力来理解查询对象是否过拟合数据集的标签和位置分布。总的来说,实验表明,该模型不会过度拟合这些分布,因为它可以近乎完美地检测到多达50个物体。
在这里插入图片描述

A.6、PyTorch推理代码

为了演示该方法的简单性,我们在清单1中包含了PyTorch和Torchvision库的推理代码。该代码在Python 3.6+, PyTorch 1.4和Torchvision 0.5下运行。请注意,它不支持批处理,因此它只适用于每个GPU一个图像的distributeddataparlparallelinference或training。还要注意,为了清晰起见,此代码在编码器中使用学习的位置编码,而不是固定的,并且位置编码仅添加到输入中,而不是在每个Transformer层。进行这些更改需要超越PyTorch实现的转换器,这会影响可读性。复制实验的完整代码将在会议之前提供。

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

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

相关文章

广州华锐互动:电力VR安全体验让学员沉浸式感受安全危害

随着科技的不断发展,虚拟现实(VR)技术在电力安全体验中发挥着越来越重要的作用。VR技术可以提供一种沉浸式的体验,使学员更好地理解和掌握电气安全知识,从而减少意外事故的发生。 首先,VR技术可以模拟各种电气事故场景&#xff0…

最大交换(力扣)枚举 JAVA

给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。 示例 1 : 输入: 2736 输出: 7236 解释: 交换数字2和数字7。 示例 2 : 输入: 9973 输出: 9973 解释: 不需要交换。 注意: 给定数字的范围是 [0, 10^8] 解题思路: 1、数最…

Figma高效工作秘笈:10个插件助你提效!

Figma插件本质上是遵循特定接口规范开发的小程序,对设计师来说,合理选择和使用Figma插件,可以极大地优化工作流程。不同的插件具有不同的用途,设计师可以根据实际需求选择适合的插件。市面上存在各种各样的Figma插件,初学者可能会不知所措。本文将推荐10款广受设计师欢迎、功能…

[Mongodb 5.0]单机启动

安装完mongodb后,会自动生成下面两个目录(mongod.conf中设定的),用来存放日志和数据 /var/lib/mongo (数据目录) /var/log/mongodb (日志目录) 要启动一个单机版的mongodb,一般有两种方式: 第一种启动方式:直接使用…

SD NAND FLASH : 什么是pSLC?

一、什么是pSLC pSLC(Pseudo-Single Level Cell)即伪SLC,是一种将MLC/TLC改为SLC的一种技术,现Nand Flash基本支持此功能,可以通过指令控制MLC进入pSCL模式,存储时在MLC的每个单元中仅存储1bit数据&#x…

传值与传址问题

传值与传址实例 2023年上半年软考真题: 22、设函数foo和hoo的定义如下图所示,在函数foo中调用函数hoo,hoo的第一个参数采用传引用方式(call by reference),第二个参数传值方式(call by value),那么函数foo中的print(a…

试用智能编程助手

1 简介 网传有了大模型之后,很多人都要失业了,其中也包括一部分程序员,确实大模型可以减轻开发者的工作量,但是具体到减轻了多少工作量,哪种类型的工作,学习成本,使用成本如何?不捧…

【前端】CSS垂直居中的7种方法

文章目录 line-height绝对定位margin:autoflex绝对定位margin:负值定位transformvertical-align:middledisplay:table-cell思维导图 前文:【前端】CSS水平居中的6种方法_karshey的博客-CSDN博客 有很多相似的部分。 line-height 适用于单行的行内元素设置line-he…

灵眸:2023年上半年中国主要消费领域宏观数据概览报告(附下载)

关于报告的所有内容,公众【营销人星球】获取下载查看 核心观点 2023年上半年中国社会消费品零售总额22.8万化元。2023年上半年中国电商实体商品消费总额达6.1万亿元,同比增长10.8%。2023年上半年中国餐饮、汽车消费均超2万化元,餐饮、金银珠…

【网络层+数据链路层】深入理解IP协议和MAC帧协议的基本原理

文章目录 前言一、IP协议二、MAC帧协议 1.以太网2.以太网帧(MAC帧)格式报头3.基于协议讲解局域网转发的原理总结 前言 为什么经常将TCP/IP放在一起呢?这是因为IP层的核心工作就是通过IP地址来定位主机的,具有将一个数据报从A主机…

搭建B端产品帮助中心这两点很重要,从客户“帮助中心”出发思考!

一款优质的产品若想要用户体验良好,除了需要客服解答外,一个全面完善的产品帮助中心也是必不可少的,尤其是对于B端产品来说,其重要性自然不言而喻。 产品帮助中心 因为帮助中心是一个产品的重要用户自助服务模块,包括…

华为OD机试真题 Java 实现【跳格子游戏】【2023 B卷 200分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…

进销存管理系统(小杨国贸)springboot采购仓库财务java jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 进销存管理系统(小杨国贸)spri…

SpringBoot 整合Swagger2

一、Swagger简介 Swagger是一套开源工具和规范,用于设计、构建和文档化RESTful Web服务。它允许开发人员定义API的各个方面,并生成易于理解的API文档和交互式API探索界面。同时,Swagger还提供代码生成工具,可自动生成与API交互的客…

公文撰写规范:提升文档质量和专业性

1.拼写和语法检查:仔细检查文档中的拼写错误和语法错误。确保单词的正确拼写,并使用正确的语法结构和标点符号。 2.信息准确性:核对文档中的事实和数据,确保其准确性。确认所有日期、数字和引用的信息是否准确无误。 3.文档结构和…

控制国外各类电液伺服阀放大器

控制通用型不带反馈信号输入的伺服阀放大器,对射流管式电液伺服阀、喷嘴挡板式电液伺服阀及国外各类电液伺服阀进行控制。 通过系统参数有10V和4~20mA输入指令信号选择; 供电电源: 24VDC(标准) 输出电流:最大可达10…

Kuebernetes资源控制管理

第四阶段 时 间:2023年8月11日 参加人:全班人员 内 容: Kuebernetes资源控制管理 目录 Kubectl命令工具 一、kubectl 命令行的语法 二、kubectl命令列表 三、使用 Kubectl 工具容器资源 (一)创建Pod &…

并发——ThreadLocal关键字详解

文章目录 前言ThreadLocal代码演示ThreadLocal的数据结构GC 之后key是否为null?ThreadLocal.set()方法源码详解ThreadLocalMap Hash算法ThreadLocalMap Hash冲突ThreadLocalMap.set()详解ThreadLocalMap.set()原理图解ThreadLocalMap.set()源码详解 ThreadLocalMap过…

游戏选香港主机会很卡吗?

​  经常会有用户问道:做游戏服务器,使用香港主机会很卡吗?要知道,游戏运营最看重的就是用户体验,而游戏流畅不流畅要看所使用香港服务器本身的稳定性。因此,卡不卡,这样的形式提问是比较笼统的&#xf…

【EI检索】第九届建筑、土木与水利工程国际学术会议(ICACHE 2023)

第九届建筑、土木与水利工程国际学术会议(ICACHE 2023) 2023 9th International Conference on Architectural, Civil and Hydraulic Engineering 第九届建筑、土木与水利工程国际学术会议(ICACHE 2023)将于2023年10月13-15日在中…