【论文阅读】《Visual Prompt Tuning》

news2024/11/15 8:18:25

Abstract.

目前调整预训练模型的工作方式包括更新所有骨干参数,即全面微调。本文介绍了视觉提示调整(VPT),作为大规模视觉变换器模型全面微调的高效替代方案。VPT 从高效调整大型语言模型的最新进展中汲取灵感,只在输入空间中引入少量(少于模型参数的 1%)可训练参数,同时保持模型主干冻结。通过对各种下游识别任务的广泛实验,我们发现与其他参数高效调整协议相比,VPT 能显著提高性能。最重要的是,在模型容量和训练数据规模方面,VPT 在很多情况下甚至优于完全微调,同时降低了每个任务的存储成本。代码见GitHub - KMnP/vpt: ❄️🔥 Visual Prompt Tuning [ECCV 2022] https://arxiv.org/abs/2203.12119。

1 Introduction

对于各种识别应用来说,目前最准确的结果都是通过调整在海量数据或原始数据上预先训练的大型基础模型获得的,这一发现反映了自然语言处理(NLP)的发展[6]。乍一看,这是一个成功的故事:只需利用最新、最好的基础模型,就能在多个识别问题上取得快速进展。然而,在实践中,如何将这些大型模型适应下游任务也是一个挑战。最明显(通常也是最有效)的适应策略是根据手头的任务对预先训练好的模型进行端到端的全面微调。然而,这种策略需要为每个任务存储和部署一份单独的骨干参数副本。这是一个昂贵且通常不可行的提议,尤其是对于基于 Transformer 的现代架构而言,这种架构比卷积神经网络(ConvNet)要大得多,例如 ViT-Huge [19](6.32 亿个参数)与 ResNet-50 [31](2500 万个参数)。因此,我们不禁要问,从效果和效率的角度来看,怎样才能让大型预训练 Transformers 适应下游任务?

一种直截了当的方法是求助于我们已经完善的其他策略,使 ConvNets 适应新任务,如图 1(a)。一种流行的方法是只微调参数的子集,如分类器头部 [56,36,11] 或偏置项 [8]。之前的研究还探讨了在骨干网中添加额外的残差块(或适配器)[68,87]。我们也可以为Transformers实施类似的策略。不过,一般来说,这些策略的精确度都低于完全微调。

我们在本文中探索了一条不同的路径。我们不改变或微调预训练Transformer本身,而是修改Transformer的输入。我们从最近在 NLP 中的提示技术[50,48,45,51]中汲取灵感,提出了一种简单高效的新方法来调整Transformer模型,以适应下游视觉任务(图 1(b)),即视觉提示调整(VPT)。我们的方法只在输入空间中引入少量特定任务的可学习参数,同时在下游训练过程中冻结整个预训练Transformer骨干。在实践中,这些附加参数只需预置到每个Transformer层的输入序列中,并在微调过程中与线性头一起学习。

在使用经过预训练的 ViT 主干网的 24 项横跨不同领域的下游识别任务中,VPT 战胜了所有其他迁移学习基线,甚至在 20 种情况下超过了完全微调,同时保持了为每项任务存储的参数显著减少(不到主网参数的 1%)的优势(图 1(c))。这一结果表明了视觉提示的独特优势:而在 NLP 中,提示调整只有在特定情况下才能与完全微调性能相媲美[45]。VPT 在低数据量条件下尤其有效,而且在不同数据量条件下都能保持优势。最后,VPT 在各种Transformer规模和设计(ViTBase/Large/Huge,Swin)中都具有竞争力。综上所述,我们的研究结果表明,VPT 是适应不断增长的视觉骨干网的最有效方法之一。

2 Related Work

Transformer 模型 [73] 在 NLP [17,66,7] 中取得了巨大成功。Transformer 架构的成功还延伸到了各种计算机视觉任务中,包括图像分类 [19,52]、物体检测 [9,49]、语义和全视角分割 [71,89,78]、视频理解 [25,79,21] 和少镜头学习 [18],超越了以往最先进的方法。Transformer也被广泛应用于最近的自监督预训练方法中[11,30,3]。与 ConvNets 相比,Transformer性能优越,规模更大,因此如何有效地将Transformer应用于不同的视觉任务仍是一个重要的未决问题。我们提出的 VPT 提供了一条充满希望的前进道路。

针对 ConvNets [92]背景下的视觉任务,转移学习(Transfer learning)已被广泛研究,并引入了许多技术,包括侧调整 [87]、残差适配器 [67]、偏差调整 [8]等(side tuning [87], residual adapter [67], bias tuning [8], etc. )。相对而言,人们对视觉变换器适配的关注较少,上述方法在这种全新架构上的表现如何仍是未知数。另一方面,鉴于大规模预训练的基于Transformer的语言模型(LM)[17,66,7]占据主导地位,许多方法[29,28,35]已被提出,以针对不同的下游 NLP 任务[77,76]有效地微调 LM。其中,我们在实验中重点关注以下两种具有代表性的方法,以进行基准测试: Adapters [64] 和 BitFit [5]。

适配器 [34] 在每个Transformer层内插入额外的轻量级模块。一个适配器模块一般由一个线性下投影、一个非线性激活函数、一个线性上投影和一个残差连接组成 [63,64]。文献[8]建议在微调 ConvNets 时更新偏置项,冻结其余骨干参数,而不是插入新模块。BitFit [3] 将这一技术应用于 Transformers,并验证了其对 LM 调整的有效性。我们的研究表明,与上述两种在 NLP 中广为流传的方法相比,VPT 在针对视觉任务调整 Transformer 模型方面的性能普遍有所提高。

提示(Prompting )[50]最初是指在输入文本中预先添加语言指令,以便预先训练的 LM 能够 "理解 "任务。在人工选择提示的情况下,GPT-3 对下游迁移学习任务显示出很强的泛化能力,即使是在少镜头或零镜头的情况下也是如此[7]。除了关于如何构建更好的提示文本的后续工作[70,37]之外,最近的工作还提出将提示视为特定任务的连续向量,并在微调过程中通过梯度直接对其进行优化,即提示微调( Prompt Tuning )[48,45,51]。与完全微调相比,它的性能相当,但参数存储量却少 1000 倍。虽然最近也有人将提示技术应用于视觉语言模型[65,91,39,84,22],但提示技术仍局限于文本编码器的输入。由于视觉和语言模式之间的差异,我们在本文中提出:同样的方法能否成功应用于图像编码器?我们是第一项解决这个问题的研究(参见相关的并行研究 [69,80,14,2]),并通过广泛的实验研究了视觉提示的通用性和可行性,这些实验跨越了多个领域和骨干架构的多种识别任务。

3 Approach

我们提出了视觉提示调整(VPT)技术,用于调整大型预训练视觉Transformer模型。VPT 向 Transformer 的输入空间注入少量可学习参数,并在下游训练阶段保持主干冻结。整体框架如图 2 所示。我们首先在第 3.1 节中定义术语,然后在第 3.2 节中正式描述 VPT。

3.1 Preliminaries

对于有 N 层的普通视觉Transformer (ViT)[19],输入图像被分成 m 个固定大小的补丁\{I_j\in \mathbb{R} ^{3\times h\times w}|j\in \mathbb{N} ,1\le j\le m\}h,w 分别为图像补丁的高度和宽度。然后,首先用位置编码将每个补丁嵌入 d 维潜在空间:

我们将图像补丁嵌入集合 \mathbf{E} _i=\{e_{i}^{j}\in \mathbb{R}^d|j\in \mathbb{N},1\le j \le m \}表示为第(i+1)次Transformer 层 (L_{i+1}) 的输入。加上一个额外的可学习分类标记([CLS]),整个 ViT 可表述为: 

 其中,x_i\in \mathbb{R}_ d表示[CLS] ^,L_{i+1 }^,输入空间的嵌入。[\cdot, \cdot ]表示序列长度维度上的堆叠和串联,即[x_i,\mathbf{E}_i ]\in \mathbb{R} ^{(1+m)\times d}。每个层L_i多头自注意网络(MSA)和前馈网络(FFN)以及层规范(LayerNorm)[1] 和残差连接(residual connections)[31]组成。神经分类头用于将最后一层的[CLS]嵌入\mathbf{ x} _N 映射到预测的类别概率分布\mathbf{y}中。

3.2 Visual-Prompt Tuning (VPT)

给定一个预先训练好的 Transformer 模型,我们在嵌入层之后的输入空间中引入一组维度为 d 的 p 个连续嵌入,即提示。在微调过程中,只有特定任务的提示才会被更新,而 Transformer 骨架则会被冻结。根据所涉及的Transformer层数,我们的方法有两种变体,即 VPT-浅层(SHALLOW)和 VPT-深层(DEEP),如图 2 所示。

VPT-Shallow.  提示仅插入第一个Transformer层 L_1。每个提示标记都是一个可学习的 d 维向量。\mathbf{P} = \{\mathbf{p}^k\in\mathbb{ R}^d | k\in \mathbb{N} , 1\le k\le p\},浅层提示的 ViT 为:

其中,\mathbf{Z}_i\in\mathbb{ R}^{p\times d}表示i个Transformer层计算的特征[\mathbf{x}_i,\mathbf{Z}_i,\mathbf{E}_i]\in \mathbb{R}^{(1+p+m)×d }表示第 i 个Transformer层计算的特征。红色和蓝色分别表示可学习参数和冻结参数。值得注意的是,对于 ViT 来说,\mathbf{x} _N与提示符的位置无关,因为它们是在位置编码后插入的,例如,[\mathbf{x}_0,\mathbf{P},\mathbf{E}_0][\mathbf{x}_0,\mathbf{E}_0,\mathbf{P}]在数学上是等价的。这同样适用于 VPT-Deep。 

VPT-Deep.  每个Transformer层的输入空间都会引入提示。对于第 (i+1)L_{i+1},我们将可学习的输入提示集合表示为\mathbf{P}_i = \{\mathbf{p}^k_i\in\mathbb{ R}^d | k\in \mathbb{N} , 1\le k\le m\}。深度提示 ViT 的公式为 

Storing Visual Prompts.  VPT 在存在多个下游任务的情况下大有裨益。我们只需为每个任务存储学习到的提示和分类头,并重新使用预先训练好的 Transformer 模型的原始副本,从而大大降低了存储成本。例如,给定的 ViT-Base 有 8600 万 (M) 个参数,d = 768,50 个浅提示和深提示会产生额外的p\times d = 50\times768 = 0.038MN\times p\times d =0.46M参数,分别只占 ViT-Base 所有参数的 0.04% 和 0.53%。 

4 Experiments

我们利用预先训练好的 Transformer 骨干网,对 VPT 在各种规模的下游识别任务中的应用进行了评估。在第 4.1 节中,我们首先介绍了我们的实验设置,包括预训练骨干和下游任务,并简要介绍了其他迁移学习方法。然后,我们在第 4.2 节中展示了我们方法的有效性和实用性。我们还系统地研究了不同的设计选择会如何影响性能(第 4.3 节),从而加深了对我们方法的理解。

4.1 Experiment Setup

Pre-trained Backbones. 我们试验了视觉领域的两种变换器架构:Vision Transformers (ViT) [19] 和 Swin Transformers (Swin [52])。本节中的所有骨干都是在 ImageNet-21k [16] 上预先训练的。我们沿用了最初的配置,例如划分的图像斑块数、[CLS] 的存在等。更多详情见附录 A。

Baselines.  我们将 VPT 的两个变体与其他常用的微调协议进行了比较: 

(a) Full: 全面更新所有主干和分类头参数。

(b) Methods that focus on the classification head.  它们将预先训练好的骨干网视为特征提取器,其权重在调整过程中是固定的:

  • – Linear:  只使用线性层作为分类头。
  • – Partial-k:  微调骨干层的最后 k 层,同时冻结其他层,如 [85,88,60,30] 所采用的方法。它重新定义了骨干层和分类头的边界。
  • – Mlp-k: 使用具有k层的多层感知器(MLP)作为分类头,而不是线性层。

(c) Methods that update a subset backbone parameters or add new trainable parameters to backbone during fine-tuning:

  • – Sidetune [87]: 训练一个 "侧 "网络,在输入头部之前,在预训练特征和侧调特征之间进行线性插值。
  • – Bias [8,5]: 只对预训练骨干网的偏置项进行微调。
  • – Adapter [34,63,64]:  在Transformers 层内插入具有残差连接的新 MLP 模块。

Downstream Tasks.  我们在以下两个数据集集合上进行了实验:

FGVC 由 5 个基准精细视觉分类任务组成,包括 CUB-200-2011 [75]、NABirds [72]、Oxford Flowers [59]、Stanford Dogs [41] 和 Stanford Cars [23]。如果某个数据集只公开了训练集和测试集,我们会随机将训练集分成训练集(90%)和测试集(10%),并根据测试集来选择超参数。

VTAB-1k [86] 包含 19 种不同的视觉分类任务,分为三组: 自然类--任务包含使用标准相机拍摄的自然图像;专业类--任务包含通过专业设备拍摄的图像,如医疗和卫星图像;结构类--任务需要几何理解能力,如物体计数。VTAB 的每个任务都包含 1000 个训练示例。按照文献[86],我们使用所提供的 800-200 个训练集分拆数据来确定超参数,并使用全部训练数据进行最终评估。我们报告了三次运行中测试集的平均准确率。 

我们报告了 FGVC 数据集的平均准确率,以及 VTAB 中三组数据的平均准确率。每项任务的单独结果以及上述任务的图像示例见附录 D。

4.2 Main Results

表 1 列出了对预先训练的 ViT-B/16 进行微调的结果。表 1 列出了对预先训练的 ViT-B/16 在 4 个不同下游任务组中的平均值进行微调的结果,并将 VPT 与其他 7 个微调协议进行了比较。我们可以看到

  1. 在 4 个问题类别中的 3 个(24 个任务中的 20 个)上,VPT-Deep 的表现优于 Full(表 1(a)),同时所使用的模型参数总数也少得多(1.18× vs. 24.02×)。因此,即使不考虑存储问题,VPT 也是在视觉中适配较大Transformers的一种有前途的方法。需要注意的是,这一结果与 NLP 中的类似研究形成了鲜明对比,在 NLP 中,提示调整与完全微调相匹配,但并未超过完全微调[45]。
  2. 在所有任务组中,VPT-Deep 均优于所有其他参数高效调整协议(表 1(b,c)),这表明 VPTdeep 是存储受限环境中的最佳微调策略。
  3. 在表 1(b)中,VPT-shallow 虽然比 VPT-deep 次优,但仍比面向头部的调优方法有不小的性能提升。1(b) 表明,如果存储限制严重,VPT-shallow 是部署多任务微调模型的一个值得选择的方法。

VPT on different downstream data size.  我们研究了训练数据量对 FGVC 任务准确性的影响(VTAB 仅有 1k 个训练示例)。我们在 10% 到 80% 之间改变训练数据,并对所有方法进行比较。同样的预训练 ViT-B 用于下游训练。图 3 显示了每种方法在不同训练数据规模下的任务平均结果。

图 3 显示,在各种数据规模下,VPT-deep 均优于所有其他基线方法。深入挖掘后,使用较少可训练参数的方法,即 VPT、Linear、Adapter、Bias,在低数据量时比 Full 更占优势。然而,当线性和适配器有更多训练数据时,这一趋势就会逆转。相比之下,VPT-deep 在不同的训练数据量下仍持续优于 Full。虽然 Bias 也有类似的优势,但它的表现仍略逊于 VPT-deep (图 3 右)。

VPT on different backbone scales.  图 4 显示了 VTAB-1k 在 3 种不同骨干网规模下的性能:ViT-Base/Large/Huge。在所有 3 种骨干网选择和 VTAB-1k 的 3 个子组中,VPT-deep 都明显优于 Linear 和 VPT-shallow。更重要的是,随着模型规模的扩大,VPT-deep 相对于 Full 的优势依然存在,即在 Natural 和 Structured 组上,VPT-deep 明显优于 Full,而在 Specialized 组上,VPT-deep 的性能几乎与 Full 相当。

VPT on hierarchical Transformers.  我们将 VPT 扩展到 Swin [52],它在局部移动窗口内采用 MSA,并在更深的层上合并补丁嵌入。为简单起见,在不失一般性的前提下,我们以最直接的方式实现 VPT:在局部窗口内关注提示,但在补丁合并阶段忽略提示。实验在 ImageNet-21k 监督预训练 Swin-Base 上进行。对于 VTAB 表 2 中的所有三个子组,VPT 仍然优于其他参数有效的微调方法(b、c)。在这种情况下,Full 的总体准确率得分最高(但总参数代价高昂)。

令人惊讶的是,VPT-deep 与 VPT-shallow 相比,对 Natural 的优势有所减弱: VPT-shallow 的准确度得分略高于完全微调。

4.3 Ablation on Model Design Variants

我们在有监督的 ImageNet-21k 预训练 ViT-Base 上消融了不同的模型设计选择,并在 VTAB 上对它们进行了评估。1. 更多信息请参见附录 B。

Prompt Location.  VPT 与其他方法的一个重要区别是,在Transformers 层的输入中引入了额外的可学习参数。图 5 展示了在输入空间中插入提示的方式和位置的不同选择,以及它们对最终性能的影响。

Prepend(前置) or Add?  另一种方法是直接将提示元素添加到这些嵌入中,并保持Transformers 的输入序列长度不变,而不是像第 3.2 节中描述的那样,将提示元素预先添加到图像补丁嵌入\mathbf{E} _i 的序列中。虽然这种变体在某些情况下(如 VTAB-Natural)比 Full 更有竞争力,但在深层和浅层设置中,其性能一般都会落后于默认的 Prepend。关于这一现象的更多讨论见附录 B。

Latent or pixel space?  我们可以在公式(1)中嵌入层之前的像素层中引入提示,即 Prepend-pixel 和 Concat-channel,而不是将提示作为潜向量插入第一个Transformers 层。图 5 显示,这两种变体的自适应性能都有所下降。例如,在 VTAB-Natural 上,在投影层之前预置浅层提示(Prepend-pixel)的准确率比默认在嵌入空间预置(Prepend)下降了 6.9%。如果我们将一个新通道连接到输入图像上(Concat-channel),性能会进一步下降(在 VTAB-Natural 上准确率甚至会下降 30%)。这些观察结果表明,在 Transformers 的潜在输入空间中,提示符更容易学习与任务相关的浓缩信号。

Prompt Length.  与完全微调相比,这是调整 VPT 所需的唯一额外超参数。为便于参考,我们还消减了其他两个基线的个别附加超参数,即 Mlp 的层数和 Adapter 的缩减率。如图 6 所示,不同任务的最佳提示长度各不相同。值得注意的是,即使只有一个提示符,VPT-deep 仍然明显优于其他两个基线,并且在 VTABStructured 和 Natural 上与完全微调相比仍然具有竞争力甚至更好。

Prompt Depth.  图 7 显示了插入提示符的层数。每个变体都报告了使用 Val 集选择的最佳提示长度。一般来说,VPT 的性能与提示深度呈正相关。然而,如果我们从上到下插入提示语,准确率就会下降,这表明Transformers较早层的提示语比较晚层的提示语更重要

Final Output.  按照 ViT 的原始配置,我们使用 [CLS] 的最终嵌入(即 xN)作为分类头输入,这也是 ViT 实验中的默认设置。如图 8 所示,如果我们使用图像补丁输出嵌入的平均池化 EN 作为最终输出(Image-pool),结果基本保持不变(例如,VTAB-Specialized 为 82.4,VTAB-Specialized 为 82.3)。但是,如果池化涉及最终提示输出 ZN(提示池和全局池),准确率可能会下降 8 个百分点。

5 Analysis and Discussion

Visualization.   图 9 显示了 VTAB 中 3 个任务(SVNH [58]、EuroSAT [32]、Clevr/count [38])的 xN 的 t-SNE [55] 可视化图,即最后一个变换层之后、分类头之前的 [CLS] 嵌入图,每个测试准确率(%)子组一个。所有图表都表明,VPT-deep 可以实现线性可分离表示,同时使用的参数比 Full 更少。我们还观察到,与只对第一层输入插入提示的 VPT-shallow 相比,每个转换器层的额外可调参数(VPT-deep)提高了性能。有趣的是,在 Clevr/count(图 9(c))上,VPT-deep 和 Full 恢复了任务的底层流形结构(图像中物体的计数与街道编号或景观识别),而 VPT-shallow 和 Linear 则不同。

Apply VPT to more vision tasks.  我们通过使用 Transformer 模型 SETR-PUP [89]评估 ADE20K [90]语义分割任务,探索了 VPT 在视觉分类之外的可行性。它在 ViT 骨干上添加了一个标准 ConvNet 头,以执行分割。事实上的方法仍然是将预训练的骨干网与 ConvNet 头一起进行完全微调(Full)。我们还采用了另外两种方案进行比较:只更新头部层(Head Only),更新头部层和骨干层中的偏置向量(Bias)。表 3 3 中,我们报告了有多尺度推断和无多尺度推断的 val mIoU 结果。虽然参数效率协议无法与 Full 协议竞争,但 VPT 仍可与 Bias 协议媲美。值得注意的是,VPT 提供的结果与完全微调的最先进 ConvNet 模型(DeepLab v3+ [10])相比具有竞争力,而调整的参数(分别为 15M 和 64M)却少得多。

Apply VPT to more pre-training methods. 除了使用标注数据预先训练的骨干外,我们还尝试了两种自监督目标: MAE [30] 和 MoCo v3 [11]。表 4 表 4 报告了 VTAB-1k 和 ViTB 的结果。我们注意到,VPT 的两个变体都超过了线性,但其他技术之间的比较则不那么有说服力。就 MAE 而言,其他参数效率高的方法(如 Partial-1)优于 VPT 和 Linear。就 MoCo v3 而言,VPT 不再保持最佳性能,但与其他方法相比仍有竞争力。这表明,这两种自监督 ViT 与前几节中的监督 ViT 有本质区别。究竟为什么会出现这些差异以及这些差异是如何产生的,这些都还是未解之谜。

Apply VPT to ConvNets.   我们研究了在 ConvNets 的输入空间中添加可训练参数的想法:在输入图像的高度和宽度上填充p个可学习的提示像素。虽然这一操作看似非常规,但由于没有明显的解决方案来添加与 Transformer 类似的位置不变提示,因此我们采用了这种方法来实现 VPT。事实上,这种方法在对抗性攻击文献 [20] 中已有过探索。我们实验中的p值比之前的工作小两个数量级:例如,5 比 263。最重要的是,我们从迁移学习的角度提出了这一想法。更多讨论见附录 C。

表 5 分别列出了 ConvNeXt-B [53](在 ImageNet21k 上进行预训练)和 ResNet-50 [31](在 ImageNet-1k 上进行预训练)的结果。VPT 在较大的 ConvNet 骨干 ConvNeXt-B 中运行良好,准确率高于其他稀疏调整协议(b、c),在 19 个案例中有 8 个优于 Full。然而,在较小的 ConvNet(ResNet50)中,VPT 的优势逐渐减弱,因为在所有 19 项 VTAB-1k 任务中,VPT 都没有明显的胜出者。

6 Conclusion

我们介绍了视觉提示调整(Visual Prompt Tuning),这是一种利用大型视觉转换器模型完成各种下游任务的新型参数高效方法。VPT 在输入空间中引入针对特定任务的可学习提示,同时保持预训练的主干固定不变。我们的实验表明,VPT 可以超越其他微调协议(通常包括完全微调),同时显著降低存储成本。我们的实验还提出了一些耐人寻味的问题:不同预训练目标的视觉变形器的微调动态,以及如何以高效的方式转移到更广泛的视觉识别任务中。因此,我们希望我们的工作能激励未来的研究,探索如何更好地挖掘大型基础模型在视觉领域的潜力。

图 1. 视觉提示调整(VPT)与其他迁移学习方法的对比。(a) 当前的迁移学习协议根据调整范围进行分组: 完全微调、面向头部和面向骨干的方法。(b) VPT 在输入空间中增加了额外参数。(c) 不同方法在适应预训练 ViT-B 主干网的各种下游分类任务上的表现,并标注了平均值和标准偏差。在 24 个案例中,VPT 在 20 个案例中的表现优于完全微调,而使用的所有模型参数不到 1%。

图 2. 我们提出的视觉提示调整概述。我们探索了两种变体:(a) 在每个Transformer 编码器层的输入中预先插入一组可学习的参数(VPT-deep);(b) 仅在第一层输入中插入提示参数(VPTshallow)。在下游任务的训练过程中,只更新提示和线性头的参数,而整个Transformer 编码器被冻结。 

图 3. 不同下游数据规模的性能比较,5 个 FGVC 任务的平均值。VPT-deep 与线性(左)、适配器(中)和偏置(右)进行了比较。高亮区域显示了 VPT-deep 与比较方法之间的精度差异。为便于参考,所有图中都显示了 VPT-shallow 的结果。标记的大小与可调参数的对数比例成正比 

 图 4. 在 3 个 VTAB 任务组中,不同模型尺度(ViT-B、ViT-L 和 ViT-H)的 VPT 与 Full 的对比。高亮区域显示了 VPT 深度微调与完全微调(Full)之间的准确率差异。标记的大小与可训练参数的对数比例成正比。

图 5. 根据提示位置进行消融。我们在顶部说明了不同的位置选择,并在底部展示了结果。为便于比较,两条蓝色虚线分别代表默认 VPT-深和 VPT-浅的性能。 

图 6. 消融对提示音长度的影响。我们改变了 VPT-deep 的提示次数,并显示了每个 VTAB 分组的平均结果。为便于参考,还显示了每个任务的 VPT-deep 最佳结果的平均值。

图 7. 消融对提示语深度的影响。i → j 表示插入提示的转换器层索引。第 1 层是指最靠近输入的一层。ViT-B 共有 12 层 

图 8. 最终输出的消融情况。顶部是不同策略的图示,底部是不同策略的结果。为便于比较,蓝色虚线代表默认 VPT-深层消融的性能。 

图 9 测试集中 3 个 VTAB 任务的最终 [CLS] 嵌入 xN 的 t-SNE 可视化(来自表 1)。1. VPT 可以在不更新主干参数的情况下生成线性可分离特征 

图 10. 所有评估分类任务的数据集示例

图 11. 扩展输入序列的效果。上部是不同策略的图示,下部是不同策略的结果。为便于比较,深蓝和浅蓝两条线分别代表默认 VPT-deep 和 VPT-shallow 的性能 

图 12. 共享提示的效果。顶部是不同策略的图示,底部是不同策略的结果。为便于比较,蓝色虚线表示默认 VPT-deep 

图 13. 提示初始化的效果。为便于比较,两条蓝色虚线分别代表默认 VPT-deep 和 VPT-shallow 的性能

 图 14. 提示深度实验对提示长度的敏感性。我们为每种变体选择了最佳的提示长度。i → j 表示插入提示的转换器层索引。第 1 层是指最靠近输入的一层。ViT-B 共有 12 层

图 15. 五次运行集合的性能。我们还报告了五次运行的平均值和最佳值。每列中的最佳性能以粗体标出 

图 16. 在每项 VTAB 任务中,VPT-deep 的性能是否优于其他方法的非配对单尾不等方差 t 检验(韦尔奇 t 检验)。结果表明,在大多数情况下,VPT-deep 都明显优于其他微调方案(P < 0.05)。 

图 17. 不同微调超参数的效果。在 VTABSpecialized: KITTI/Distance 任务进行了评估。其他调整方法的阴影为灰色 

图 18. 训练(左)和推理(右)期间 GPU 的峰值内存和延迟(ms/img)。为便于比较,灰色虚线代表完全微调时的延迟和内存。

图 19. VPT-deep 与 VPT-prefix 的对比:推理过程中 GPU 内存(左)和延迟(右)的峰值。为便于比较,灰色虚线代表完全微调的延迟和内存。 

图 20. 下游数据大小对每个 FGVC 任务的影响。标记大小与可调参数的对数比例成正比 

图 21. 更多 VTAB 任务的最终 [CLS] 嵌入 xN 的 t-SNE 可视化。我们将目标类别少于或等于 20 个的任务纳入可视化范围 

表 1. 在有监督的 ImageNet-21k 上预先训练的 ViT-B/16。对于每种方法和每个下游任务组,我们报告了与 Full 相比的平均测试准确率得分和 (-) 中的获胜次数。"总参数 "表示所有 24 个下游任务所需的总参数。"范围 "表示每种方法的调整范围。"额外参数 "表示除了预训练的主干和线性头之外的额外参数。除全精细外,所有方法中的最佳结果均以粗体标出。在 24 个案例中,VPT 在可训练参数明显较少的情况下,有 20 个案例优于完全微调法

表 2. 不同的Transformer 架构: Swin-B 以受监督的 ImageNet-21k 为骨干进行了预训练。对于每种方法和每个下游任务组,我们报告了与 Full 相比的平均测试准确率得分和(-)中的获胜次数。总参数 "一栏表示所有 19 个下游任务所需的总参数。除 Full 外,所有方法的最佳结果均以粗体显示

表 3. 语义分割: ADE20k [90] 与 SETR [89] 在 ViT-L 上的验证结果。除 Full 外,所有方法中的最佳 mIoU 分数均以粗体标出。还包括完全微调 ResNet-101 [10] 的结果。SS/MS:单尺度/多尺度推理

表 4. 不同的预训练目标: MAE [30] 和以 ViT-B 为骨干的 MoCo v3 [11]。对于每种方法和每个下游任务组,我们报告了与 Full 相比的平均测试准确率得分和(-)中的获胜次数。"总参数 "表示所有 24 个下游任务所需的总参数。除 Full 外,所有方法的最佳结果均以粗体显示

表 5. 将 VPT 应用于 ConvNets: ResNet-50 和 ConvNeXt-Base。对于每种方法和每个下游任务组,我们报告了与 Full 相比的平均测试准确率得分和(-)中的获胜次数。"总参数 "表示所有 19 个下游任务所需的总参数。除 Full 外,所有方法的最佳结果均以粗体显示

 表 6. 所评估的每种微调方法的实施细节。⋆:我们观察到,在 24 项评估任务中的 6 项任务中,VPT-shallow 有时能从更大的基础 LR 中获益,在这些任务中,我们从 {1000.0,500.0,250.0,100.0} 开始搜索。

表 7. 所评估的各种数据集的规格。⋆:我们随机抽取了 train 和 val 数据集,因为没有公开的拆分数据。

表 8. 本文中使用的不同预训练骨架的规格。参数(M)是特征提取器的参数。"批量大小 "列显示了线性/部分/{完全、偏差、适配器}/VPT(p < 100)/VPT(p ≥ 100)的批量大小。/ VPT (p < 100) / VPT (p ≥ 100)。所有骨干都在分辨率为 224×224 的 ImageNet [16] 上进行了预训练

表 9. 将带偏差的 VPT 与第 4.2 节中预先训练的 ViT-B 结合。对于每种方法和每个下游任务组,我们报告了与 Full 相比的平均测试准确率得分和(-)中的获胜次数。混合方法与其 VPT 对应方法之间的差异用不同颜色表示

表 10. 关于 VPT-deep 在 19 项 VTAB 任务中的表现是否优于其他方法的非参数配对单尾 t 检验(Wilcoxon 符号秩检验)。结果表明,VPT-deep 在统计上确实明显优于其他微调方案(P < 0.05)

表 11. 在有监督的 ImageNet-21k 上预先训练的 ViT-B/16,微调后的分辨率为 384×384。我们还包括图像分辨率为 224×224, p = 380 的 VPT,因此有效图像分辨率为 384×384。对于每种方法和每个下游任务组,我们都报告了平均测试准确率得分和(-)中与 Full 相比的获胜次数。"总参数 "表示所有 24 个下游任务所需的总参数。除 Full 外,所有方法的最佳结果均以粗体显示

表 12. 使用在有监督的 ImageNet-21k 上预先训练的 ViT-B/16 的成本分析。我们报告了每种方法和每个下游任务组在训练和推理时的延迟(ms/img)和 GPU 内存使用峰值(GB)。"调整参数 "表示所需的可学习参数分数。"范围 "表示每种方法的调整范围。"额外参数 "表示除了预训练的骨干和线性头之外的额外参数。所有实验均使用相同的 A100 GPU

表 13. 表 1 中针对 VTAB-1k 的每个任务微调结果。1 中 VTAB-1k 使用预训练 ViT-B/16 的每个任务微调结果

表 14. 表 1 中五项 FGVC 任务的每个任务微调结果。1 中针对五项 FGVC 任务的预训练 ViT-B/16

附录

A Implementation Details

我们使用PyTorch[62]在NVIDIA A100-40 GB GPU上实现所有实验。

A.1 Classification Experiments

VPT.  我们使用每个数据集的验证集来寻找最佳提示长度 p,见第 3.2 节。提示符长度是我们调整的唯一一个针对 VPT 的超参数。对于 Transformer 主干网,p的取值范围分别为{1,5,10,50,100,200};对于 ViT 和 Swin,p的取值范围分别为{1,5,10,50}。对于这两种架构而言,p的最大选择范围大致接近每个 MSA 中的图像片段标记数(ViT:196;Swin:49)。我们还对 VPT-deep 采用了 0.1 的dropout率。对于 ConvNets,p 的范围为 {1、3、5、7、9、11}。每个提示都采用 xavier 统一初始化方案[26]随机初始化。我们沿用了原有的 "骨干网 "设计方案,例如是否存在分类标记[CLS],或是否使用最终的[CLS]嵌入作为分类头输入。

Adapter.  适配器 [34] 在每个Transformer 层内插入额外的轻量级模块。一个适配器模块通常由一个线性向下投影(缩减率为r)、一个非线性激活函数和一个线性向上投影以及一个残差连接组成。文献[63,64]对所有可能的配置进行了详尽的研究,发现只有在 FFN "Add & LayerNorm "子层之后插入适配器的效果最好。因此,我们在自己的实施中也采用了这种设置。我们在{8, 64, 256}范围内扫描了缩减率r

Augmentation and other hyper-parameters.  在训练过程中,我们采用了标准的图像增强策略:使用 ImageNet 平均值和标准偏差进行归一化处理,将五个 FGVC 数据集的尺寸随机调整为 224×224,并随机进行水平翻转,将 VTAB-1k 套件的尺寸调整为 224×224。表 6 总结了我们使用的优化配置。按照文献[56]的方法,我们使用每个任务的验证集进行网格搜索,以找到特定的超参数、学习率和权重衰减值。根据线性缩放规则[42,27,11,30],学习率设定为base\_lr×b/256,其中 b是特定模型使用的批次大小,base\_lr从表 6 中指定的范围内选择。每个实验的最优超参数值见附录 D。

Datasets and pre-trained backbones specifications.   表 7 和表 8 总结了本文中使用的分类数据集和所有预训练骨干的统计数据和详细信息。图 10 包括所有 24 个评估分类任务的图像示例。

A.2 Semantic Segmentation Experiments

ADE20K [90] 是一个具有挑战性的场景解析基准,包含 150 个细粒度标签。训练集和验证集分别包含 20,210 张和 2,000 张图像。我们在实现过程中使用了公共代码库 MMSegmentation [15]。

SETR [89] 是一种使用 ViT 作为编码器的竞争性分割框架。PUP 是一种渐进式上采样策略,由连续卷积层和双线性上采样操作组成。根据 MMSegmentation 的再现,在多种解码器选择中,PUP 的效果最好,因此我们在实现过程中也使用了它。

在 SETR-PUP 中应用 VPT 时,我们只在 SETR 的 ViT 编码器主干中插入提示。对于解码器来说,只有图像补丁嵌入才被用作输入,而提示嵌入则被丢弃。与识别任务一样,在训练过程中只学习 PUP 解码头和提示,ViT 主干被冻结。

对于完全微调,我们使用与 MMSegmentation 相同的超参数。对于 HeadOnly、Bias 和 VPT,我们使用学习率 {0.05, 0.005, 0.0005, 0.001} 的超参数扫描。所有方法的最佳学习率均为 0.005。我们扫描了提示长度 p∈{1, 5, 10, 50, 100, 200}。对于 VPT,我们还将学习率乘数改为 1.0,而不是默认的 10.0,因此解码器头和提示符共享相同的学习率。其他超参数与完全微调相同。

B Extended Analysis

Effect of expanding input sequence length.  如表 1 所示。如表 1 所示,通过使用可学习的提示语扩展输入序列,VPT 在 24 个评估任务中的 20 个任务上取得了比 Full 更好的性能。为了研究 VPT 的优势是否归功于其扩大的输入序列长度,我们又对两个变体进行了实验:(1) 在微调阶段保持提示语冻结(提示语固定)。(2) 只调整 [CLS] 标记([CLS]-Learned)。从图 11 中我们可以看出,更新提示嵌入(提示-已学习)的效果显著,而提示-固定的效果与线性效果相当。这表明,VPT 的最终性能主要来自学习的提示嵌入,而不是扩大的序列长度。更新 [CLS] 标记与更新 1 个提示符([CLS] vs. Learnedp=1)的效果类似,但仍然落后于默认设置,在默认设置中,我们根据 val 集手动选择最佳的提示符数量。

Sharing prompts.  在图 12 中,我们通过在Transformer 层内(Shared-intra)、所有层间(Shared-inter)以及Transformer 中插入的所有提示(Shared-all)设置相同的提示嵌入参数,来检验共享提示参数的效果。我们可以看到 (1) 在层内共享提示(Shared-intra)的性能与使用一个提示(Defaultp=1)的性能相当,甚至略胜一筹,这进一步证明了扩展输入序列的价值。(2) 虽然 Shared-intra 的表现总体上不如 Default,但令人惊讶的是,在使用相似数量的可训练参数时,Shared-inter 的表现略微优于我们的默认 VPT-deep(所有 VTAB 任务的参数总数:1.14× vs 1.14×): Shared-inter 和默认值的参数总数分别为 1.14× 和 1.13×)。仔细研究发现,Shared-inter 的最佳提示长度 p 一般大于 Default,即所有 VTAB 任务的平均提示长度:Shared-inter 与 Default 分别为 64.58 与 60.94。(3) 在层间和层内共享相同的提示嵌入(Shared-all)会降低性能,但在三个 VTAB 分组中仍然超过了线性探测结果。

Prompt initialization.  在 NLP 中,如 [45] 所示,更复杂的提示初始化可使提示调整受益匪浅。我们研究了视觉提示是否也是这种情况。我们利用下游目标类别的原型表示,从而用列举输出空间的嵌入对提示进行初始化。由于我们希望模型能在给定测试示例的情况下生成接近于这些原型表征之一的输出嵌入,因此以这种方式初始化提示可能会给模型一些关于目标类别的提示,从而有助于改进优化过程。

具体来说,我们使用下流数据集训练拆分的每个目标类别中的平均最终[CLS]嵌入。给定具有N层的预训练 ViT 和具有 c个目标类别的下流训练集,对于每个训练示例,我们计算最终的 [CLS] 嵌入,\mathbf{x}_N\in \mathbb{R}^d。然后我们对每个CLS目标类中的这些嵌入进行平均,以得到\left\{\hat{\mathbf{x}}_{N,}^{k} \in \mathbb{R}^{d} \mid k \in \mathbb{N}, 1 \leq k \leq c\right\}。设置提示长度p = c,对于 VPT-shallow,我们用\left\{\hat{\mathbf{x}}_{N}^{k} \right\}_{k=1}^{k=c}初始化\mathbf{P},并且用\left\{\hat{\mathbf{x}}_{N}^{k} \right\}_{k=1}^{k=c}初始化每个\mathbf{P} _i,其中i = 0, 1, . ,N - 1,表示 VPT-DEEP。

在图 13 中,我们比较了使用上述初始化策略(CLS)和默认随机初始化(Random)的微调性能。我们还报告了在微调阶段固定提示(--fixed)的结果。如图 13 所示,令人惊讶的是,我们的默认随机初始化(随机)总体上效果最好,在没有上述额外预处理步骤(CLS)的情况下,在 VTAB 的不同分组中效果一致。CLS 在 "Natural "分组和 "Specialized  "分组中的效果相当。

Prompt depth vs. prompt length.  在图 7 中,我们删除了插入提示的层数。对于每个提示深度变体,图 7 报告了使用每个任务的最佳提示长度(图 14 中的"- → -(最佳)")得出的结果。在这里,我们采用了另一种设置,即在所有其他提示深度变体中使用 1 → 12 的最佳提示长度。比较"-→-(最佳)"和"-→-",我们发现不同深度的提示符长度对提示符的敏感度不同,尤其是在只插入九层提示符的情况下(3→12,12→3)。

Combine VPT with Bias Tuning.  我们在主论文中的实验表明,"偏置 "是一种具有竞争力的参数效率调整基线(例如,表 1(c))。1(c)). 基于这一观察结果,我们探索了另一种方案,即同时更新提示和预训练骨干网中的偏置项,保持骨干网中的其他内容不变(VPT+Bias)。如表 9 所示 如表 9 所示,出乎我们意料的是,将偏置项与 VPT 结合在一起并没有产生更优的结果,甚至在所有 3 个任务分组中都削弱了 VPT-deep。这表明这两种方法并不一定是互补的。

Prompt ensembling.  [45] 证明了 prompt 在模型集合中的效率。对于 k 个模型的集合,我们只需要存储学习到的提示向量,而不需要存储整个微调模型参数的 k 份副本(例如,ViT-H 的 k×2.5GB)。此外,在推理过程中,给定一个测试实例,只需执行一次前向传递,并使用专门设计的批次,复制原始数据但使用不同的提示。 

鉴于这些优势,我们还研究了 VPT 在提示语组合方面的有效性。我们针对每个 VTAB 任务使用不同的随机种子训练 5 个不同的提示,使用的预训练 ViT-B 骨干和超参数与表 1 中的相同。1. 图 15 显示,VPT-deep 的集合效果优于平均水平,甚至优于最好的单提示方法,也优于包括 Full 在内的其他集合微调方法。

Test of statistical significance.  我们对 VPT-deep 在 19 项 VTAB 任务中的表现是否优于其他微调方法进行了非参数配对单尾 t 检验(Wilcoxon 符号秩检验 [82])(零假设 H0 表示 VPT-deep 和备用基线方法之间的平均 VTAB 表现差异为零。备择假设 H1 表明,VPT-deep 在 VTAB 上的表现优于基线方法)。表 10 表 10 列出了每种测试的 p 值,每种比较方法的观察数均为 19(我们使用 19 个 VTAB 任务和所有微调方法的 5 次运行的平均准确率分数)。在所有比较的微调方案中,VPT-deep 的改进都具有显著的统计学意义(p < 0.05)。

我们还对每个 VTAB 任务的单次运行(观察次数 = 5)进行了不等方差的非配对单尾 t 检验(韦尔奇 t 检验 [81])(H0 表示 VPT-deep 和其他基线方法在特定 VTAB 任务中的表现相同,而 H1 表示 VPT-deep 在特定 VTAB 任务中的表现优于其他基线方法)。图 16 显示了每个任务中每对 <VPT-deep, 基线方法> 的 p 值。在 19×8 = 152 个案例中,我们拒绝了 127 个案例的 H0(p < 0.05)。与 Full 方法相比,VPT-deep 在 19 项任务中的 11 项任务上取得了统计意义上的显著提高。

Effect of different fine-tuning hyper-parameters.   在图 17 中,我们展示了不同微调协议在不同微调超参数(包括学习率和权重衰减)上的表现。对于我们提出的 VPT-deep,我们还消减了提示长度 p 的不同选择,这是唯一需要手动调整的超参数。所有实验都是在 KITTI/Distance 任务(VTAB-Specialized)的估值集上进行评估的。我们观察到 Linear 和 VPT 的不同行为。这两种方法在微调阶段都会冻结主干参数。一般来说,线性探测对权重衰减值更为敏感,而 VPT 则同时受学习率和权重衰减值的影响。提示长度较大的 VPT 对学习率的选择也不太敏感。

Effect of image resolution.   最初的 ViT 论文[19]发现,使用更高的图像分辨率(384×384)进行微调有利于下游识别任务。本文介绍的所有识别实验都是在 224×224 分辨率下进行微调的。如表 11 所示。如表 11 所示,我们使用与表 1 相同的设置重新运行了 VTAB 实验,但分辨率由 384×384 改为 224×224。1 中的相同设置重新运行 VTAB 实验,但分辨率为 384,而不是默认的 224。我们可以看到,在所有参数高效调整协议中,VPT-deep 仍然取得了最佳性能,甚至在 19 项任务中的 15 项任务上优于完全微调。虽然总体而言,图像分辨率的提高并没有带来更好的完全微调性能,但它确实略微提升了 VPT-deep 的性能。

表 11 中另一个有趣的观察结果是,在使用 224 微调分辨率和更大的 p = 380 值时,VPT 可以达到与使用 384 分辨率的 Full 算法相似甚至更好的性能,同时使用相同的输入序列长度和更少的可训练参数。

Empirical computational cost.  VPT 可能存在的一个限制是Transformers需要额外的输入序列长度。理论上,MSA 的复杂度是输入序列长度的二次方,但由于硬件细节(如车道宽度和高速缓存大小)的影响,实际速度可能并非如此[19]。在表 在表 12 和图 18 中,我们研究了所有微调协议的经验计算成本(即延迟)以及训练和推理时间的 GPU 内存使用峰值。所有实验都使用相同的 A100 GPU,训练和推理的批量大小均为 64。我们可以看到,序列长度的理论二次缩放几乎没有发生在 VPT 上。例如,长度增加一倍(p = 200 对 m = 198)基本上只会导致 2 倍(而不是 4 倍)的推理延迟和 GPU 内存峰值(在完全微调的情况下)。对于训练而言,减少提示次数将大大减少延迟。

在测试期间,VPT 的一种等效实现方式是直接将参数预置到 Transformer [48] 自我关注模块内部的键和值数组中(VPT-prefix)。虽然我们发现这种实现方式并不能提高 VTAB 数据集的准确率,但却降低了推理过程中的计算成本。图 19 显示了不同 p 值下的对比情况。VPT-prefix 可以大大减少测试时间延迟和 GPU 内存峰值,尤其是当 p 变大时。

C Further Discussion

VPT vs. Adversarial Reprogramming (AR).  不同之处在于 (1) AR 文献[20]中注入输入空间的学习参数数量是我们的近 20 倍(264k 对 13k)。VPT 的参数效率明显更高;(2) AR 在 ConvNet 中显示了其有效性,而 VPT 可以应用于更广泛的架构,包括 ViT 和 Swin。此外,VPT 的通用性更强,可以深入到预训练骨干网的更深层(图 2),而 AR 仅适用于 ConvNet 的第一输入层。(3) 另一个区别是,我们的设置同时更新提示和分类头,而 AR [20] 直接使用预训练的分类头。我们的设置更具通用性,可应用于具有更广泛预训练目标的模型(如 MAE [30],它不包括预训练分类头)和更广泛的视觉任务(如分割)。

Visual prompt vs. textual prompt.  我们的论文还发现了视觉提示和文本提示之间的差异:我们表明,在 24 个案例中,VPT 甚至在 20 个案例中优于全模型微调,这与 NLP 的相关工作[45]不谋而合。我们还发现,图 13 中的随机初始化提示效果更好,而较早层的提示更重要(图 7 和 14),这也与 NLP 方面的观察结果不同[45,51]。这些差异表明,视觉提示可能与文本提示有本质区别,因此需要进一步研究。延迟(毫秒/图像) 完全微调 延迟(毫秒/图像) 完全微调

D Supplementary Results

Numerical results of Table 1.  表 13 和表 14 列出了表 1 中评估的 24 个分类任务的每个任务结果。

Per-task results on training data ablations.   图 20 展示了五个 FGVC 数据集的每个任务结果。我们观察到与图 3 类似的趋势:在中小型数据机制中,所有参数效率方法的性能都优于完全微调方法,而在五项 FGVC 任务中,VPTdeep 在各种数据规模下的性能始终优于完全微调方法。

More t-SNE visualizations.  在图 21 中,我们展示了更多的 t-SNE 可视化效果,与图 9 类似,适用于所有小于或等于 20 个目标类别的 VTAB 数据集。

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

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

相关文章

uniapp 实现上传文件的功能

上传单个文件 <script setup>const handleUploadClick () > {console.log("上传文件")uni.chooseImage({success: (chooseImageRes) > {const tempFilePaths chooseImageRes.tempFilePaths;console.log("用户选择的图片&#xff1a;", temp…

华为HCIP Datacom H12-821 卷40

1.单选题 下面是台路由器BGP错误输出信息&#xff0c;关于这段信息描述错误的是 <HUAWEI>display bgp error Error Type :Peer Error Date/Time :2010-03-22 12:40:39 Peer Address :10.1.1.5 Error Info : Incorrect remote AS A、可能是由于邻居…

二叉树 —— OJ题目详解

1.二叉树的前序遍历 二叉树的前序遍历比较简单&#xff0c;但是在力扣上写这个接口需要注意几个点&#xff1a; int* preorderTraversal(struct TreeNode* root, int* returnSize) {} preorderTraversal 的返回值是动态开辟的数组&#xff0c;里面存放的是前序遍历的顺序int*…

Python 获取今天(当天)、昨天(前一天)、前天(昨天的前一天)的开始时间、结束时间

描述&#xff1a;我这里是封装成DatetimeHelper工具类来调用 1.今天(当天)开始时间、结束时间 from datetime import datetime, timedeltaclass DatetimeHelper:# 获取今天(当天)的开始时间、结束时间(datetime类型)staticmethoddef getTodayStartEnd():# 获取当前的日期now …

JVM监控及诊断工具-命令行篇--jinfo命令介绍

JVM监控及诊断工具-命令行篇02-jinfo&#xff1a;实时查看和修改JVM配置参数 一 基本情况二 基本语法2.1查看jinfo -sysprops PIDjinfo -flags PIDjinfo -flag 具体参数 PID 2.2修改 三 拓展java -XX:PrintFlagsInitialjava -XX:PrintFlagsFinaljava -XX:PrintCommandLineFlags…

IP风险画像 金融行业的安全盾牌

在当今数字化时代&#xff0c;金融行业面临着前所未有的安全挑战。随着在线交易和数字银行业务的迅猛发展&#xff0c;欺诈和网络攻击的威胁也在不断增加。金融机构需要高效、可靠的安全解决方案来保护客户的资产和个人信息&#xff0c;防止各种形式的欺诈行为。 IP风险画像是…

el-date-picker手动输入日期,通过设置开始时间和阶段自动填写结束时间

需求&#xff1a;根据开始时间&#xff0c;通过填写阶段时长&#xff0c;自动填写结束时间&#xff0c;同时开始时间和节数时间可以手动输入 代码如下&#xff1a; <el-form ref"ruleForm2" :rules"rules2" :model"formData" inline label-po…

# Redis 入门到精通(四)-- linux 环境安装 redis

Redis 入门到精通&#xff08;四&#xff09;-- linux 环境安装 redis 一、linux 环境安装 redis – 基于 Linux 安装 redis 1、基于 Center 0S7 或者 unbunt-18.04 安装 Redis 1&#xff09;下载安装包wget http://download.redis.io/releases/redis-?.?.?.tar.gz 如&…

五、 计算机网络(考点篇)试题

A、B、C都没问题&#xff0c;选D。现在基本上所有的互联网网站都是https了&#xff0c;电子支付类的更不用说了。 简单邮件传输的协议是SMTP(发)和POP3(收)&#xff0c;分别是25和110。选B和B 网络分片技术&#xff0c;分割切片嘛。 选C&#xff0c;AES加密等级比较高了&#x…

关于SQLException: Illegal mix of collations (`utf8mb4_general_ci,IMPLICIT`)...错误

希望文章能给到你启发和灵感&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏 支持一下博主吧&#xff5e; 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境 二、报错信息三、最后 开篇说明 记录一个查询错误 场景&#xff1a;数据库之间某表复…

Nginx的反向代理缓存

一 .Nginx的反向代理缓存 #代理缓存路径设置缓存保存的目录 #keys_zone设置共享内存占用的空间大小 #max_size缓存大小 #inactice 超过时间,则缓存自动清理 #use_temp_path 关闭临时目录proxy_cache_path /usr/local/nginx/upsteam_cache key_zone=mycache:5m max_size=…

51单片机STC89C52RC——19.1 SG90舵机(伺服电机)

目的/效果 独立按键K1&#xff0c;K2 实现加舵机减角度增减&#xff0c;LCD1602显示舵机转角度数&#xff08;上电默认90度&#xff09; 一&#xff0c;STC单片机模块 二&#xff0c;SG90舵机 2.1 简介 舵机只是我们通俗的叫法&#xff0c;它的本质是一个伺服电机&#xf…

活动预告|想更了解流式数据湖?亚马逊云科技数据开源软件-流式数据湖 Tech Talk来啦!

活动介绍 本次活动旨在探索在亚马逊云科技上构建和使用开源数据软件产品的一些最佳实践&#xff0c;特别关注流式数据湖的构建。活动将在线上举行&#xff0c;汇聚来自 AutoMQ Apache paimon和亚马逊云科技的顶尖专家&#xff0c;分享他们在这一领域的最新进展和实际经验。参与…

分类预测 | Matlab实现OOA-LSSVM鱼鹰算法优化最小二乘支持向量机多特征分类预测/故障诊断

分类预测 | Matlab实现OOA-LSSVM鱼鹰算法优化最小二乘支持向量机多特征分类预测/故障诊断 目录 分类预测 | Matlab实现OOA-LSSVM鱼鹰算法优化最小二乘支持向量机多特征分类预测/故障诊断分类效果基本介绍程序设计参考资料 分类效果 基本介绍 分类预测 | Matlab实现OOA-LSSVM鱼…

【Docker】Docker 的数据管理与镜像创建

目录 一.数据管理 1.数据卷 2.数据卷容器 二.端口映射 三.容器互联 四.Docker 镜像的创建 1.基于现有镜像创建 1.1.首先启动一个镜像&#xff0c;基于镜像创建容器&#xff0c;更新容器内容 1.2.将修改后的容器提交为新的镜像&#xff0c;需要使用该容器的 ID 号创建新…

git取消合并:--hard 或 --merge

第一步&#xff1a;查了git日志 git reflog如下&#xff0c;运行上述命令后&#xff0c;可以看见所有的提交哈希&#xff08;id&#xff09; 第二步 查看到上述所有的提交记录后&#xff0c;有如下方法去回退 方法1&#xff1a;--hard 确定上一次提交的哈希值 git reset…

低空经济持续发热,无人机培训考证就业市场及前景剖析

随着科技的不断进步和社会需求的日益增长&#xff0c;低空经济已成为全球及我国经济增长的新引擎。作为低空经济的重要组成部分&#xff0c;无人机技术因其广泛的应用领域和显著的经济效益&#xff0c;受到了社会各界的广泛关注。为满足市场对无人机人才的需求&#xff0c;无人…

object-C 解答算法:两数之和(leetCode-1)

两数之和(leetCode-1) 题目如下图:(也可以到leetCode上看完整题目,题号1) 解答方法一: 最简单的方法就是双指针遍历数组.代码如下 - (NSMutableArray *)sumOfTwoNumbers:(NSMutableArray *)array target:(int)target {NSMutableArray * resultArray [[NSMutableArray alloc…

怎样去除视频上的水印和文字,视频水印文本移除教程

在观看和分享视频时&#xff0c;我们经常会遇到带有水印或额外文字的情况。这些标记有时是为了版权保护&#xff0c;有时则是平台的标识&#xff0c;但在某些情况下&#xff0c;它们可能会干扰视频的观赏体验。本文将向你介绍常见的视频水印类型以及如何使用简鹿水印助手去除这…

漏洞复现 | Showdoc反序列化

非常简单的一个靶场 靶场地址&#xff1a;https://hack.zkaq.cn/ 打开靶场&#xff0c;弹出了这种登录框&#xff0c;这也成为了后面的一个坑点&#xff0c;记住这个登录框。 看到了注册功能&#xff0c;showdoc有注册功能我们就不用尝试前台SQL注入了&#xff0c;直接注册…