【论文精读】Attention is all you need

摘要
主要的序列转换模型是基于复杂的循环或卷积神经网络,其中包括一个编码器和一个解码器。性能最好的模型还通过一种注意力机制将编码器和解码器连接起来。我们提出了一种新的简单的网络架构,Transformer,完全基于注意机制,完全取消递归和卷积。在两个机器翻译任务上的实验表明,该模型在质量上更优越,同时并行能力更强,需要的训练时间明显更少。我们的模型在WMT 2014英德翻译任务上实现了28.4 BLEU,比现有的最佳结果,包括集成模型,提高了超过2 BLEU。在WMT 2014英法翻译任务中,我们的模型在8个gpu上进行了3.5天的训练,建立了一个新的最先进的单模型,其BLEU分数达到41.0,这只用了文献中最佳模型的训练成本的一小部分。
1.简介
循环神经网络,特别是长短期记忆[12]和门控循环[7]神经网络,已经成为序列建模和转导问题的最先进的方法,如语言建模和机器翻译[29,2,5]。此后,许多努力继续推动循环语言模型和编解码器架构[31,21,13]的边界。
循环模型通常是沿着输入和输出序列的符号位置进行因子计算。将这些位置与计算时间中的步骤对齐,它们生成一系列隐藏状态 h t h_t ht,作为前一个隐藏状态 h t − 1 h_{t−1} ht1和位置 t t t的因变量。这种固有的顺序性阻碍了训练中的并行化,而并行化在较长的序列长度时至关重要,因为内存限制了示例之间的批处理。最近的工作通过分解技巧[18]和条件计算[26]显著提高了计算效率,同时也提高了后者的模型性能。然而,序列计算的基本约束仍然存在。(并行计算能力天然的受到限制)
注意力机制已经成为各种任务中的序列模型和转换模型的一个重要的组成部分,允许对依赖关系进行建模,而不考虑它们在输入或输出序列[2,16]中的距离。然而,在除了少数情况[22]下的所有其他情况下,这种注意力机制都与循环网络一起使用。
在这项工作中,我们提出了Transformer,一个避开了循环模型架构而是完全依赖于注意力机制来推断输入和输出之间的全局依赖关系。Transformer允许更多的并行化,在8个P100 GPU上进行了短短12个小时的训练后,可以在翻译质量上达到领先水平。
2.背景
减少顺序计算的目标也形成了Extended Neural GPU [20]、ByteNet [15]和ConvS2S [8]的基础,所有这些方法都使用卷积神经网络作为基本的构建块,并行计算所有输入和输出位置的隐藏表示。在这些模型中,关联来自两个任意输入或输出位置的信号所需的操作数量随着位置之间的距离而增加,ConvS2S呈线性增长,ByteNet呈对数增长。这使得学习遥远位置[11]之间的依赖关系更加困难。在Transformer中,这被减少为恒定的操作次数,尽管是以平均注意力加权位置而降低有效分辨率为代价,我们用第3.2节中所述的多头注意力来抵消这个效应。
自注意力,有时被称为内注意力,是一种注意力机制,将单个序列的不同位置联系起来以计算序列表示。自注意力已成功地应用于各种任务中,包括阅读理解、摘要总结、文本隐含和学习任务独立的句子表征[4,22,23,19]。
端到端的记忆网络基于循环注意力机制,而不是序列对齐递归,并已被证明在简单语言问题回答和语言建模任务[28]上表现良好。
然而,据我们所知,Transformer是第一个不使用序列对齐的rnn或卷积而是完全依赖自注意力来计算其输入和输出的表示的转换模型。在下面的章节中,我们将描述Transformer,激活自注意力,并讨论它相对于[14,15]和[8]等模型的优势。
3.模型体系结构
大多数有竞争力的神经序列转换模型都有一个编码器-解码器结构的[5,2,29]。其中,编码器将一个符号表示的输入序列 ( x 1 , . . . , x n ) (x_1,...,x_n) x1...xn映射到一个连续表示的序列 z = ( z 1 , . . . , z n ) z =(z_1,...,z_n) z=z1...zn。给定z,解码器一次生成一个符号的输出序列 ( y 1 , . . . , y m ) (y_1,...,y_m) y1...ym。在每一步中,模型都是自回归的[9],在生成下一个符号时使用之前生成的符号作为附加的输入。
Transformer遵循这种架构,对编码器和解码器都使用堆叠的自注意力层和point-wise的全连接层,分别如图1的左半部分和右半部分所示。
在这里插入图片描述
3.1编码器和解码器堆栈
编码器: 编码器由6个相同的层组成。每个层都有两个子层。第一层是一个多头自注意力,然后第二层比较简单,逐位置的全连接前馈网络。我们在两个子层上都使用了残差连接[10],然后进行层归一化[1]。也就是说,每个子层的输出是 L a y e r N o r m ( x + S u b l a y e r ( x ) ) LayerNorm(x +Sublayer(x)) LayerNormx+Sublayer(x),其中 S u b l a y e r ( x ) Sublayer(x) Sublayer(x)是由子层本身产生的因变量。为了方便这些残差连接,模型中的所有子层以及嵌入层都会产生维度为 d m o d e l d_model dmodel= 512的输出。
解码器: 解码器也由6个相同的层组成。除了每个编码器层中的两个子层外,解码器还插入第三个子层,该子层对编码器堆栈的输出执行多头注意力。与编码器类似,我们在每个子层周围使用剩余连接,然后进行层归一化。我们还修改了解码器堆栈中的自注意力子层(解码器块中有一个Masked Multi-Head Attention),以防止位置关注后续的位置。这种掩蔽,加上输出嵌入的一个位置偏移,确保了对位置 i i i的预测只能依赖于小于 i i i的位置的已知输出。
3.2注意力
注意力函数可以描述为将查询(query)和一组键-值(key-value)对映射到输出,其中查询(query)、键(key)、值(value)和输出都是向量。输出是值的加权和,其中分配给每个值的权重由查询与相应键的兼容性函数计算。
3.2.1缩放点积注意力
我们将我们的特别注意力称为“缩放点积注意力”(图2)。
在这里插入图片描述
输入由维度为 d k d_k dk的查询和键,以及维度为 d v d_v dv的值组成。我们计算出查询和所有键的点积,用 d k \sqrt {d_k} dk 除以每一个值(scale操作),并应用一个softmax函数来获得这些值的权重。
在实际应用中,我们同时计算一组查询上的注意力因变量,并打包到一个矩阵 Q Q Q中。键和值也被打包到矩阵 K K K V V V中。我们计算输出的矩阵计算如下:
A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V)=softmax(\frac {QK^T}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dk QKT)V
两个最常用的注意函数是加性注意力[2]和点积(乘法)注意力。点积注意力与我们的算法相同,除了 1 d k \frac 1 {\sqrt {d_k}} dk 1的缩放因子。加法注意力使用单隐藏层的前馈网络计算兼容性函数。虽然这两种方法在理论复杂性上相似,但在实践中,点积注意力更快,更节省空间,因为它可以使用高度优化的矩阵乘法代码来实现。
对于较小的 d k d_k dk值,这两种机制的表现相似,在 d k d_k dk [3]值较大的情况下加性注意力优于点积注意力。我们怀疑,对于较大的 d k d_k dk,点积的增长率很大,导致softmax函数具有极小梯度。为了抵消这种效应,我们用 1 d k \frac 1 {\sqrt {d_k}} dk 1来缩放点积。
3.2.2多头注意
相比于单个 d m o d e l d_model dmodel维度的键,值和查询的注意力函数的表现,我们发现用不同的可学习线性投影分别将查询、键和值线性投影到dk、dk和dv维数,是很有益的。在每个查询、键和值的投影版本上,我们会并行地执行注意力函数,生成 d v d_v dv维的输出值。这些值被连接起来并再次投影,从而得到最终的值,如图2所示。
多头注意力允许模型在不同位置联合关注来自不同表示子空间的信息,而单个注意力头会抑制这种情况。
在这里插入图片描述
其中投影为参数矩阵 W i Q ∈ R d m o d e l ∗ d k W^Q_i∈R^{d_{model}*d_k} WiQRdmodeldk W i k W^k_i Wik R d m o d e l ∗ d k R^{d_{model}*d_k} Rdmodeldk W i V ∈ R d m o d e l ∗ d v W^V_i∈R^{d_{model}*d_v} WiVRdmodeldv W O ∈ R h d v ∗ d m o d e l W^O∈R^{hd_v*d_{model}} WORhdvdmodel
在这项工作中,我们使用了h = 8并行的注意层,或头部。对于每一个,我们都使用 d k = d v = d m o d e l / h = 64 d_k = d_v = d_{model}/h = 64 dk=dv=dmodel/h=64。由于每个头部的维数会降低,其总计算代价与完整维度的单头注意相似。
3.2.3 注意力机制在我们模型中的应用
该Transformer以三种不同的方式使用多头注意力:

  • 在“编码器-解码器注意力”层中,查询来自于上一个解码器层,键和值来自于编码器的输出。这允许解码器中的每个位置都参与输入序列中的所有位置。这模拟了sequence-to-sequence模型中典型的编码-解码器注意力机制,如[31,2,8]。
  • 该编码器包含自注意力层。在自注意力层中,所有的键、值和查询都来自同一个位置,在这种情况下,上一层的输出在编码器中。编码器中的每个位置都可以注意到编码器上一层中的所有位置。
  • 类似地,解码器中的自注意力层允许解码器中的每个位置关注解码器中的所有位置,直到并包括该位置。**我们需要防止解码器中的信息向左流,以保持自回归特性。**我们通过屏蔽(设置为−∞)softmax输入中对应于非法连接的所有值来在缩放点积注意力内部实现这一点,见图2。

3.3位置前馈网络
除了注意力子层外,我们的编码器和解码器中的每个层都包含一个全连接的前馈网络,它分别相同地应用于每个位置。这由两个线性变换组成,中间有一个ReLU激活。
F F N ( x ) = m a x ( 0 , x W 1 + b 1 ) W 2 + b 2 FFN(x)=max(0,{xW_1+b_1})W_2+b_2 FFN(x)=max(0,xW1+b1)W2+b2
虽然线性转换在不同的位置上是相同的,但它们每层都使用不同的参数。另一种描述它的方法是用核大小为1的两个卷积。输入和输出的维度为 d m o d e l d_{model} dmodel= 512,且中间层的维数为 d f f = 2048 d_{ff}=2048 dff=2048
3.4嵌入和softmax
与其他序列转换模型类似,我们使用学习到的嵌入来将输入标记和输出标记转换为维度为 d m o d e l d_model dmodel的向量。我们还使用常用的可学习线性变换和softmax函数来将解码器的输出转换为预测的下一个标记的概率。在我们的模型中,我们在两个嵌入层之间共享相同的权重矩阵和pre-softmax线性变换,类似于[24]。在嵌入层中,我们将这些权重乘以 d m o d e l \sqrt {d_{model}} dmodel
3.5位置编码
由于我们的模型不包含递归和卷积,为了使模型利用序列的顺序,我们必须注入一些关于序列中标记的相对或绝对位置的信息。为此,我们在编码器和解码器堆栈底部的输入嵌入中添加“位置编码”。位置编码与嵌入具有相同的维数 d m o d e l d_{model} dmodel,因此两者可以求和。有许多位置编码的选择,可学习的和固定的。
在这项工作中,我们使用不同频率的正弦和余弦函数:
在这里插入图片描述
其中 p o s pos pos是位置, i i i是维度。也就是说,位置编码的每个维度都对应于一个正弦曲线。波长形成了一个从2π到10000·2π的几何级数。我们选择这个函数是因为我们假设它允许模型容易地学习相对位置,因为对于任何固定的偏移量k, P E p o s + k PE_{pos+k} PEpos+k可以表示为 P E p o s PE_{pos} PEpos的线性函数。
我们还实验了使用可学习的位置嵌入[8],发现两个版本产生的几乎相同的结果(见表3行(E))。因此我们选择正弦版本,因为它可能允许模型推断比训练中遇到的更长的序列长度。

4.为什么使用自注意力
在本节中我们从各个方面比较了自注意层和循环以及卷积层,这些常被用于映射一个可变长序列符号表示 ( x 1 . . . , x n ) (x_1...,x_n) x1...xn到另一个等长的序列 ( z 1 . . . , z n ) (z_1...,z_n) z1...zn,其中 x i , z i ∈ R d x_i,z_i∈R^d xiziRd,就像在一个典型的序列转换编码器或解码器中的隐藏层。为了激励我们使用自注意力,我们考虑了三个需求。
一个是每层的总计算复杂度。另一个是可以并行化的计算量,通过所需的最小顺序操作数量来衡量。
第三个是网络中长期依赖关系之间的路径长度。学习长期依赖关系是许多序列转导任务中的一个关键挑战。影响学习这种依赖关系能力的一个关键因素是信号在网络中向前和向后跨越的路径的长度。在输入和输出序列中的任何位置组合之间的这些路径越短,就越容易学习长期依赖关系[11]。因此,我们也比较了由不同层类型组成的网络中的任意两个输入和输出位置之间的最大路径长度。
在这里插入图片描述
如表1所示,自注意力层用恒定数量的顺序执行操作连接所有位置,而循环层需要O (n)个顺序操作。对于计算的复杂性,自注意力层在序列长度n小于表示维度d的时候比循环层快,这是机器翻译领域使用句子表示模型的最常见的情况,如word-piece[31]和byte-pair[25]表示。为了提高涉及很长序列的任务的计算性能,可以将自注意力限制在只考虑输入序列大小为r的邻域。这将使最大路径长度增加到 O ( n / r ) O(n/r) O(n/r)。我们计划在今后的工作中进一步研究这种方法。(计算复杂度变低了)
核大小为 k k k k < n k<n k<n的单个卷积层并不能连接所有的输入和输出位置对。要实现连接所有的位置对,在使用连续核的情况下,需要堆叠 O ( n / k ) O(n/k) O(n/k)个卷积层,或者在扩展卷积[15]的情况下,需要堆叠 O ( l o g k ( n ) ) O(log_k(n)) O(logk(n)),从而增加网络中任意两个位置之间的最长路径的长度。卷积层通常比循环层昂贵k倍。然而,可分离卷积[6]大大降低了复杂度,达到 O ( k ⋅ n ⋅ d + n ⋅ d 2 ) O(k·n·d + n·d^2) O(knd+nd2)。然而,即使使用k = n,可分离卷积的复杂性也等于自注意力层和点向前馈层的组合,这是我们在我们的模型中采用的方法。
作为额外的好处,自注意力可以产生更多可解释的模型。我们检查了从我们的模型中获得的注意力分布,并在附录中提出和讨论了一些例子。不仅单个的注意力头清楚地学会了执行不同的任务,而且许多头似乎表现出与句子的句法和语义结构相关的行为。

5.训练
本节描述了我们的模型的训练机制。
5.1训练数据和批次
我们在标准的WMT 2014英-德语数据集上进行了训练,该数据集包含约450万对句子对。句子使用字节对编码方法[3]进行编码,它有大约37000个标记的共享源数据词汇表。对于英法词汇,我们使用了明显更大的WMT 2014英法数据集,其中包含3600万个句子,并将标记分解为32000个字片词汇[31]。句子对按近似的序列长度组合在一起。每个训练batch包含一组句子对,其中包含大约25000个源标记和25000个目标标记。
5.2硬件和时间表
我们在一台使用8个NVIDIA P100 gpu的机器上训练我们的模型。对于我们使用整个论文中描述的超参数的基础模型,每个训练步骤大约需要0.4秒。我们总共训练了基本模型10万步或12个小时。对于我们的大模型(如表3的最后一行所描述的),步长时间为1.0秒。这些大型模型接受了30万步(3.5天)的训练
5.3优化器
我们使用了Adam优化器,其 β 1 = 0.9 , β 2 = 0.98 , ϵ = 1 0 − 9 β_1 = 0.9,β_2 = 0.98,\epsilon= 10^{−9} β1=0.9β2=0.98ϵ=109。我们在整个训练过程中按照以下公式改变学习率,如下:
在这里插入图片描述
这表示第一步骤warmup_steps训练步骤,学习率线性增加,然后按步数的平方反比成比例降低。我们设置warmup_steps = 4000。
5.4正则化
我们在训练过程中采用了三种类型的正则化:
Residual Dropout我们在其和子层的输入相加和归一化之前将dropout[27]应用于每个子层的输出。此外,我们还将dropout应用于编码器和解码器堆栈中的嵌入和位置编码求和。对于基础模型,我们使用 P d r o p = 0.1 P_{drop} = 0.1 Pdrop=0.1的速率。
标签平滑在训练过程中,我们采用了 ϵ l s = 0.1 \epsilon _{ls} = 0.1 ϵls=0.1 [30]的标签平滑。这会造成困惑,因为模型学习的更不确定,但提高了准确性和BLEU分数。
6.结论
6.1机器翻译
在WMT 2014英德翻译任务中,Transformer(big)(表2)比之前报道的最佳模型(包括集成)多出2.0个BLEU,实现了一个新的最先进的BLEU分数28.4分。该模型的配置列于表3的最后一行中。在8个P100gpu上进行训练需要3.5天。即使是我们的基础模型也超过了之前发表的所有模型和集合,而训练成本相比只是其竞争模型的一小部分。
在这里插入图片描述
在WMT 2014年的英法翻译任务中,我们的大模型获得了41.0分的BLEU分数,优于之前发布的所有单个模型,其训练成本不到之前最先进的模型的1/4。为英语到法语训练的Transformer(大)模型使用的丢弃率为 P d r o p = 0.1 P_{drop} = 0.1 Pdrop=0.1,而不是0.3。
对于基础模型,我们使用了通过平均最后5个检查点获得的单一模型,这些检查点每10分钟记录一次。对于大型模型,我们平均了最后20个检查点。我们使用了束搜索(beam search),束大小(beam size)为4,并且使用了长度惩罚α = 0.6 [31]。这些超参数是在开发集上经过实验后选择的。我们将推理期间的最大输出长度设置为输入长度 + 50,但在可能的情况下提前终止 [31]。
表2总结了我们的结果,并将我们的翻译质量和训练成本与文献中的其他模型架构进行了比较。我们通过将训练时间、使用的GPU数量和估计每个GPU 的持续单精度浮点容量相乘来估计用于训练模型的浮点运算的数量。
6.2模型变化
为了评估Transformer不同组件的重要性,我们以不同的方式修改了我们的基础模型,并测量了其在开发集newstest2013上进行英语到德语翻译时性能的变化。我们使用了前一节描述的束搜索方法,但没有使用检查点平均。我们在表3中展示了这些结果。
在这里插入图片描述
在表3的A行中,我们改变了注意力头的数量以及注意力键和值的维度,如3.2.2节所述,保持计算量不变。虽然单头注意力比最佳设置低0.9 BLEU,但太多的头也会导致质量下降。
在表3的B行中,我们观察到减小注意力键的大小dk会损害模型质量。这表明确定兼容性并不容易,可能需要比点积更复杂的兼容性函数。我们在C行和D行进一步观察到,如预期的那样,更大的模型表现更好,且dropout在避免过拟合方面非常有帮助。在E行中,我们用学习到的位置嵌入替换了我们的正弦位置编码[8],观察到的结果与基础模型几乎相同。
7 结论
在这项工作中,我们介绍了Transformer,这是第一个完全基于注意力的序列转换模型,它取代了在编码器-解码器架构中最常用的循环层,使用了多头自注意力机制
对于翻译任务,与基于循环或卷积层的架构相比,Transformer可以被显著更快地训练。在WMT 2014年的英德和英法翻译任务上,我们都达到了新的最佳水平。在前者任务中,我们的最佳模型甚至超过了以前报道的所有模型集合。
我们对基于注意力的模型的未来感到兴奋,并计划将它们应用到其他任务上。我们计划将Transformer扩展到除文本之外的输入和输出模态的问题,并研究局部的、限制性的注意力机制,以有效处理大型输入和输出,如图像、音频和视频。让生成过程更少依赖于序列化是我们的另一个研究目标。
我们用来训练和评估模型的代码在下列网址https://github.com/
tensorflow/tensor2tensor

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

每日学习笔记:C++ STL算法之容器元素排序

目录 常规排序 升序排序&#xff1a; sort(beg, end) stable_sort(beg, end, op) 自定义规则排序&#xff1a; sort(beg, end, op) stable_sort(beg, end, op) 局部排序(使前段有序) partial_sort(beg, sortEnd, end) partial_sort(beg, sortEnd, end, op) 复制并局…

【C++】日期类Date(详解)

&#x1f525;个人主页&#xff1a;Forcible Bug Maker &#x1f525;专栏&#xff1a;C 目录 前言 日期类 日期类实现地图 获取某年某月的天数&#xff1a;GetMonthDay 检查日期合法&#xff0c;构造函数&#xff0c;拷贝构造函数&#xff0c;赋值运算符重载及析构函数…

2. uni-app的一些介绍

前言 就目前的前端生态而言&#xff0c;跨端开发基本算是每一个前端开发者必备的技能点之一了&#xff0c;而在Vue这个技术栈里uni-app在跨端是独一档的&#xff0c;不信的话可以翻翻Boss之类的招聘网站.... 概述 阅读时间&#xff1a;约5~10分钟&#xff1b; 本文重点&…

linux的编译器vim

vim简介 之前我们在win下写代码&#xff0c;都是下载一些编译器VS/eclipse等 他们不仅可以写代码&#xff0c;还可以实现代码的运行调试&#xff0c;开发。这样的编译器叫做集成编译器 而linux中虽然也有这样的编译器&#xff0c;但不管是从下载&#xff0c;还是使用中都会显…

谷歌地球引擎Google Earth Engine下载数字高程模型DEM数据的方法

本文介绍在谷歌地球引擎&#xff08;Google Earth Engine&#xff0c;GEE&#xff09;中&#xff0c;批量下载指定时间与空间范围内的数字高程模型&#xff08;DEM&#xff09;数据的方法。 本文是谷歌地球引擎&#xff08;Google Earth Engine&#xff0c;GEE&#xff09;系列…

UltraScale+的40G/50G Ethernet Subsystem IP核使用

文章目录 前言一、设计框图二、模块说明三、上板3.1、发送端3.1、接收端 四、总结 前言 上文介绍了10G/25G Ethernet Subsystem IP核使用&#xff0c;本文将在此基础上介绍40G/50G Ethernet Subsystem IP核的使用&#xff0c;总体区别不大。 一、设计框图 由于40G以太网需要…

嵌入式 - i.MX93 Evaluation Kit介绍

MCIMX93-EVK (i.MX 93 APPLICATIONS PROCESSOR) 1, Out of the Box [ 开箱 ] Top view i.MX 93 11x11 EVK board Back view: Board kit contents: (board, power supply, cable, software, Documentation) MCIMX93-EVK board assembled with two separate boards, MCIMX93-SOM…

《MATLAB科研绘图与学术图表绘制从入门到精通》示例:绘制伊甸火山3D网格曲面图

11.4.2小节我们使用3D曲面图可视化分析伊甸火山数据&#xff0c;本小节我们采用3D网格曲面图可视化分析伊甸火山数据&#xff0c;以展示其地形&#xff0c;具体示例代码如下。 购书地址&#xff1a;https://item.jd.com/14102657.html

RabbitMQ项目实战(一)

文章目录 RabbitMQ项目实战选择客户端基础实战 前情提要&#xff1a;我们了解了消息队列&#xff0c;RabbitMQ的入门&#xff0c;交换机&#xff0c;以及核心特性等知识&#xff0c;现在终于来到了激动人心的项目实战环节&#xff01;本小节主要介绍通过Spring Boot RabbitMQ S…

HackMyVM-Hommie

目录 信息收集 arp nmap WEB web信息收集 dirsearch ftp tftp ssh连接 提权 系统信息收集 ssh提权 信息收集 arp ┌──(root㉿0x00)-[~/HackMyVM] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 08:00:27:77:ed:84, IPv4: 192.168.9.126 Starting arp-…

PhpStorm2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 PhpStorm是由JetBrains公司开发的一款商业的PHP集成开发环境&#xff08;IDE&#xff09;&#xff0c;深受全球开发人员的喜爱。它旨在提高开发效率&#xff0c;通过深刻理解用户的编码习惯&#xff0c;提供智能代码补全、快速导…

14.哀家要长脑子了!

目录 1.598. 区间加法 II - 力扣&#xff08;LeetCode&#xff09; 2.419. 甲板上的战舰 - 力扣&#xff08;LeetCode&#xff09; 3.54. 螺旋矩阵 - 力扣&#xff08;LeetCode&#xff09; 4. 498. 对角线遍历 - 力扣&#xff08;LeetCode&#xff09; 5. 566. 重塑矩阵 - …

希亦、添可、追觅洗地机哪一款更好用?口碑洗地机型号多维度测试

近年来&#xff0c;随着“懒人经济”的兴起&#xff0c;商家们纷纷推出各种智能化、便捷化、高效化的家电产品&#xff0c;以提升人们的生活品质。在这些家电产品中&#xff0c;家居清洁领域的小家电发展尤为迅速&#xff0c;产品不断更新换代。在众多清洁家电产品中&#xff0…

C++ | Leetcode C++题解之第41题缺失的第一个正数

题目&#xff1a; 题解&#xff1a; class Solution { public:int firstMissingPositive(vector<int>& nums) {int n nums.size();for (int i 0; i < n; i) {while (nums[i] > 0 && nums[i] < n && nums[nums[i] - 1] ! nums[i]) {swap(…

[svelte]属性和逻辑块

属性 / Default values • Svelte 教程 | Svelte 中文网 属性 Declaring props 到目前为止&#xff0c;我们只处理了内部状态——也就是说&#xff0c;这些值只能在给定的组件中访问。 在任何实际应用程序中&#xff0c;都需要将数据从一个组件向下传递到其子组件。为此&…

Java测试编程题

题目1 1.创建5个线程对象 线程名设置为&#xff08;Thread01&#xff0c;Thread02&#xff0c;Thread03&#xff0c;Thread04&#xff0c;Thread05&#xff09;使用 代码实现5个线程有序的循环打印&#xff0c;效果如下&#xff1a; Thread01正在打印1 Thread02正在打印2 Threa…

OpenHarmony多媒体-mp3agic

简介 mp3agic 用于读取 mp3 文件和读取/操作 ID3 标签&#xff08;ID3v1 和 ID3v2.2 到 ID3v2.4&#xff09;,协助开发者处理繁琐的文件操作相关&#xff0c;多用于操作文件场景的业务应用。 效果展示&#xff1a; 下载安装 ohpm install ohos/mp3agicOpenHarmony ohpm环境配…

【Day 4】Maven + Spring入门 + HTTP 协议

开始学后端&#xff01; 1 Maven Maven 是一款用于管理和构建 Java 项目的工具&#xff0c;基于项目对象模型(POM)的概念&#xff0c;通过一小段描述信息来管理项目的构建。 作用&#xff1a; 依赖管理 方便快捷的管理项目依赖的资源(jar 包)&#xff0c;避免版本冲突问题 …

接雨水 , 给定二维图,能容多少水

42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 看着就是非常常规的题目&#xff0c;所以非常有必要掌握。 最少也把O&#xff08;n^2&#xff09;的方法写出来吧。力扣官方题解的三种方法O&#xff08;n&#xff09;都挺好&#xff0c;不过可能有点难读&#xff0c;在此…

简单的LRU本地缓存实现-Java版本

文章目录 什么是缓存缓存的种类缓存的关键特性缓存的优势与挑战优势&#xff1a;挑战&#xff1a; 缓存的应用场景什么是LRUCacheLRU 缓存的工作原理核心操作为何选择 LRU使用场景 一个简单的LRU缓存实现相关资料基础资料 什么是缓存 缓存&#xff08;Cache&#xff09;是一种…