深度学习进阶篇[7]:Transformer模型长输入序列、广义注意力、FAVOR+快速注意力、蛋白质序列建模实操。

news2024/11/13 14:37:37

在这里插入图片描述
【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等

在这里插入图片描述
专栏详细介绍:【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等

本专栏主要方便入门同学快速掌握相关知识。后续会持续把深度学习涉及知识原理分析给大家,让大家在项目实操的同时也能知识储备,知其然、知其所以然、知何由以知其所以然。

声明:部分项目为网络经典项目方便大家快速学习,后续会不断增添实战环节(比赛、论文、现实应用等)

专栏订阅:深度学习入门到进阶专栏

深度学习进阶篇[7]:

基于Transformer模型在众多领域已取得卓越成果,包括自然语言、图像甚至是音乐。然而,Transformer架构一直以来为人所诟病的是其注意力模块的低效,即长度二次依赖限制问题。随着输入序列长度的增加,注意力模块的问题也越来越突出,算力和内存消耗是输入序列长度的平方。

1.基于Transformer模型应对长输入序列

比较早期的是一方面从内存方面入手:Transformer-XL和内存压缩的Transformer,而另一种方法是各种稀疏注意力机制。稀疏注意力机制不再暴力地计算所有token之间的注意力,而仅仅计算出有限token对之间的相似度得分。这些需要重点attend的稀疏注意力项可以是人工指定,也可以是通过优化方法找到的,还可以是通过学习学到的,甚至可以是随机的。

由于稀疏矩阵也可以用图和边来表示,所以稀疏化方法也是由图神经网络文献所启发的,具体关系在图注意力网络中概述。这种基于稀疏性的架构通常需要额外的层来隐含产生完整的注意力机制。

标准的稀疏化技术。左:稀疏模式的例子,其中tokens只关注其他附近的tokens。右:在图注意力网络中,tokens只关注图中的邻居,这些邻居应该比其他节点有更高的相关性。

目前的这些稀疏注意力方法仍然有以下局限:

  • 需要高效的稀疏矩阵乘法运算,而这些运算并不是所有加速器都能提供。比如Longformer的实现采用TVM技术将计算自注意力的代码编译为CUDA核。

  • 通常缺乏严格的理论保证。这点Big Bird是有的。

  • 主要针对Transformer模型和生成式预训练进行优化。

  • 通常需要堆叠更多的注意力层来补偿稀疏表征,这使得它们很难与其他预训练模型一起使用,因此需要进行再训练,这就很费时费力。

除了上述这些缺点之外,稀疏注意机制往往还无法解决常规注意力方法所应用的全部问题,比如如 Pointer Networks。此外,还有一些操作是无法进行稀疏化的,比如softmax操作。

为了解决这些问题,Performer提出了一个具有线性复杂度的注意力,其注意力机制可线性扩展,从而实现更快的训练,同时允许模型处理较长的长度,这对于某些图像数据集(如ImageNet64)和文本数据集(如PG-19)是必需的。Performer 使用一个高效的(线性)广义注意力框架(generalized attention framework),允许基于不同相似性度量(核)的一类广泛的注意力机制。该框架通过谷歌的新算法 FAVOR+( Fast Attention Via Positive Orthogonal Random Features)来实现,后者能够提供注意力机制的可扩展低方差、无偏估计,这可以通过随机特征图分解(常规 softmax-attention)来表达。该方法在保持线性空间和时间复杂度的同时准确率也很有保证,也可以应用到独立的 softmax 运算。此外,该方法还可以和可逆层等其他技术进行互操作。

2.两种常规的注意力机制回顾

用L表示输入的token序列的长度,常规的点乘注意力就是一个映射,把矩阵Q,K, V ∈ R L × d V \in \mathbb{R}^{L \times d} VRL×d作为输入,其中d代表的是隐含维度。矩阵Q,K,V是输入的中间表示,他们的行分别表示为连续字典数据结构的queries,keys,values。双向的点乘注意力有如下的形式,其中 A ∈ R L × L A\in \mathbb{R}^{L \times L} ARL×L 叫做注意力矩阵:

A t t ⟷ ( Q , K , V ) = D − 1 A V Att_{\longleftrightarrow}(Q,K,V)=D^{-1}AV Att(Q,K,V)=D1AV

A = e x p ( Q K T d ) A=exp(\frac{QK^T}{\sqrt{d}}) A=exp(d QKT)

D = d i a g ( A 1 L ) D=diag(A1_{L}) D=diag(A1L)

其中这里的 e x p ( ⋅ ) exp(\cdot) exp() 是元素级别的, 1 L 1_{L} 1L是长度为L的全1向量, d i a g ( ⋅ ) diag(\cdot) diag()是对角矩阵。时间复杂度为 O ( L 2 d ) O(L^2d) O(L2d),空间复杂度为 O ( L 2 + L d ) O(L^2+Ld) O(L2+Ld) ,因为A需要显式的存储。原则上,点乘注意力的类型和端到端的长序列处理是不相容的。在Seq2Seq结构的encoder自注意力和encoder-decoder注意力应用的是双向注意力。

另一种重要的注意力类型是无向点积注意力有着如下的形式:

A t t ⟷ ( Q , K , V ) = D ~ − 1 A ~ V Att_{\longleftrightarrow}(Q,K,V)=\tilde{D}^{-1}\tilde{A}V Att(Q,K,V)=D~1A~V

A ~ = t r i l ( A ) \tilde{A}=tril(A) A~=tril(A)

D ~ = d i a g ( A ~ 1 L ) \tilde{D}=diag(\tilde{A}1_{L}) D~=diag(A~1L)

其中 t r i l ( ⋅ ) tril(\cdot) tril()返回参数矩阵的下三角部分,包括对角线。无向的注意力用于自回归生成式模型,例如生成式Transformers中的自注意力,和Seq2Seq Transformers中的decoder部分。

3. 广义注意力

在以往的注意力机制中,分别对应矩阵行与列的 query 和 key 输入相乘,通过 softmax 计算形成一个注意力矩阵,以存储相似度系数。值得注意的是,这种方法不能将 query-key 生成结果传递给非线性 softmax 计算之后,再将其分解为原始的 query 和 key。然而,将注意力矩阵分解为原始 query 和 key 的随机非线性函数的乘积是可以的,即所谓的随机特征(random feature),这样就可以更加高效地对相似度信息进行编码。

LHS:标准注意力矩阵,由 query(表示为q) 和 key(表示为k) 上的softmax计算组成,表示两两之间的相似得分。RHS:标准注意力矩阵可以通过低阶随机化矩阵Q′和K′来近似,行编码由随机化非线性函数对原始query/key进行编码而得到。对于常规的softmax-attention,变换非常紧凑,涉及指数函数以及随机高斯投影。

常规的 softmax 注意力可以看作是由指数函数和高斯投影定义的非线性函数的一个特例。在这里我们也可以反向推理,首先实现一些更广义的非线性函数,隐式定义 query-key 结果中其他类型的相似性度量或核函数。研究者基于早期的核方法(kernel method),将其定义为广义注意力(generalized attention)。尽管对于大多核函数来说,闭式解并不存在,但这一机制仍然可以应用,因为它并不依赖于闭式解。

4. FAVOR+:通过矩阵相关性实现快速注意力

上文描述的分解允许我们以线性而非二次内存复杂度的方式存储隐式注意力矩阵。我们还可以通过分解获得一个线性时间注意力机制。虽然在分解注意力矩阵之后,原始注意力机制与具有值输入的存储注意力矩阵相乘以获得最终结果,我们可以重新排列矩阵乘法以近似常规注意力机制的结果,并且不需要显式地构建二次方大小的注意力矩阵。最终生成了新算法 FAVOR+。

4.1 FAVOR+理论

FAVOR+使用矩阵 A ∈ R L × L A \in \mathbb{R}^{L \times L} ARL×L A ( i , j ) = K ( q i T , k j T ) A(i,j)=K(q_{i}^T,k_{j}^T) A(i,j)=K(qiT,kjT),其中 q i / k j q_{i}/k_{j} qi/kj代表的是Q/K中第 i t h / j t h i^{th}/j^{th} ith/jth 的query/key 行向量,核K: d d × d d → R + \mathbb{d}^d \times \mathbb{d}^d \rightarrow R_{+} dd×ddR+ 定义为映射 ϕ \phi ϕ: R d → R + r \mathbb{R}^d \rightarrow \mathbb{R}^r_{+} RdR+r,公式为:

K ( x , y ) = E [ ( ϕ ( x ) T ϕ ( y ) ) ] K(x,y)=\mathbb{E}[(\phi(x)^T \phi(y))] K(x,y)=E[(ϕ(x)Tϕ(y))]

我们把 ϕ ( u ) \phi(u) ϕ(u)认为是一个随机特征图(random feature map),其中 u ∈ R d u \in \mathbb{R}^d uRd Q ′ , K ′ ∈ R L × r Q^{'},K^{'} \in \mathbb{R}^{L \times r} Q,KRL×r,行分别用 ϕ ( q i T ) T \phi(q_{i}^T)^T ϕ(qiT)T ϕ ( k i T ) T \phi(k_{i}^T)^T ϕ(kiT)T表示,上述核函数直接促成了高效注意力机制:

A t t ⟷ ^ ( Q , K , V ) = D ^ − 1 ( Q ′ ( ( K ′ ) T V ) ) \widehat{Att\longleftrightarrow}(Q,K,V)=\widehat{D}^{-1}(Q^{'}((K^{'})^{T}V)) Att (Q,K,V)=D 1(Q((K)TV))

D ^ = d i a g ( Q ′ ( ( K ′ ) 1 L ) ) \widehat{D}=diag(Q^{'}((K^{'})1_{L})) D =diag(Q((K)1L))

A t t ⟷ ^ \widehat{Att\longleftrightarrow} Att 表示的是近似注意力,括号表示的是计算的顺序。很容易得到这个机制的空间复杂度为 O ( L r + L d + r d ) O(Lr+Ld+rd) O(Lr+Ld+rd),时间复杂度为 O ( L r d ) O(Lrd) O(Lrd),而常规的注意力机制的空间复杂度为 O ( L 2 + L d ) O(L^2+Ld) O(L2+Ld),时间复杂度为 O ( L 2 d ) O(L^2d) O(L2d)

4.2 双向注意力近似

左:标准注意力模块计算,其中通过执行带有矩阵 A 和值张量 V 的矩阵乘法来计算最终的预期结果;右:通过解耦低秩分解 A 中使用的矩阵 Q′和 K′以及按照虚线框中指示的顺序执行矩阵乘法,研究者获得了一个线性注意力矩阵,同时不用显式地构建 A 或其近似。

4.3 单向注意力近似

上述分析与双向注意力(即非因果注意力)相关,其中没有过去和未来的概念。对于输入序列中没有注意前后 token 的单向(即因果)注意力而言,研究者稍微修改方法以使用前缀和计算(prefix-sum computation),它们只存储矩阵计算的运行总数,而不存储显式的下三角常规注意力矩阵。

左:标准单向注意力需要 mask 注意力矩阵以获得其下三角部分;右:LHS 上的无偏近似可以通过前缀和获得,其中用于 key 和值向量的随机特征图的外积(outer-product)前缀和实现动态构建,并通过 query 随机特征向量进行左乘计算,以在最终矩阵中获得新行。

4.4 softmax-kernels近似softmax

ϕ \phi ϕ用下面的形式表示,函数为 f 1 , . . . f l : R → R f_{1},...f_{l}:\mathbb{R} \rightarrow \mathbb{R} f1,...fl:RR, 函数 g : R d → R g:\mathbb{R}^d \rightarrow \mathbb{R} g:RdR

ϕ ( x ) = h ( x ) ( m ) ( f 1 ( w 1 T x ) , . . . , f 1 ( w m T x ) , . . . , f l ( w m T x ) ) \phi(x)=\frac{h(x)}{\sqrt(m)}(f_{1}(w_{1}^Tx),...,f_{1}(w_{m}^Tx),...,f_{l}(w_{m}^Tx)) ϕ(x)=( m)h(x)(f1(w1Tx),...,f1(wmTx),...,fl(wmTx))

这可以对大多数的核方法进行建模。大多数情况下,D各向同性的,通常是高斯分布。例如

h ( x ) = 1 , l = 1 , D = N ( 0 , I d ) h(x)=1,l=1, D=N(0,I_{d}) h(x)=1,l=1,D=N(0,Id)

可以得到PNG核,配置:

h ( x ) = 1 , l = 2 , f 1 = s i n , f 2 = c o s h(x)=1,l=2,f_{1}=sin,f_{2}=cos h(x)=1,l=2,f1=sin,f2=cos

对应的是平移不变性核,特别地

D = N ( 0 , I d ) D=N(0,I_{d}) D=N(0,Id)

就变成了高斯核 K g a u s s K_{gauss} Kgauss。常规的注意力矩阵的softmax-kernel如下:

S M ( x , y ) = e x p ( x T y ) SM(x,y)=exp(x^Ty) SM(x,y)=exp(xTy)

不失一般性,省去了 d \sqrt{d} d ,因为我们可以对keys核queries进行规范化。

S M ( x , y ) = e x p ( ∣ ∣ y ∣ ∣ 2 2 ) K g a u s s ( x , y ) e x p ( ∣ ∣ y ∣ ∣ 2 2 ) SM(x,y)=exp(\frac{||y||^2}{2})K_{gauss}(x,y)exp(\frac{||y||^2}{2}) SM(x,y)=exp(2∣∣y2)Kgauss(x,y)exp(2∣∣y2)

通过使用三角函数,我们得到了 S M ( x , y ) SM(x,y) SM(x,y)随机特征图无偏近似:

h ( x ) = e x p ( ∣ ∣ x ∣ ∣ 2 2 ) , l = 2 , f 1 = s i n , f 2 = c o s h(x)=exp(\frac{||x||^2}{2}),l=2,f_{1}=sin,f_{2}=cos h(x)=exp(2∣∣x2),l=2,f1=sin,f2=cos

我们把它叫做 S M ^ m t r i g ( x , y ) \hat{SM}_{m}^{trig}(x,y) SM^mtrig(x,y),后面还有一堆理论的分析,有兴趣的可以翻翻论文。

4.5 正交随机特征(ORF)

上面的部分组成了FAVOR+的R+部分,还差O部分要解释。为了进一步减少估计的反差,我们引入了不通的随机样本 w 1 , . . . , w m w_{1},...,w_{m} w1,...,wm是正交的(orthogonal)。ORF是一个众所周知的方法,但事实证明它是有效的,特别是我们为softmax引入的PRF,我们的第一个理论实验结果表明ORFs可以应用于任何维数d的softmax/高斯核估计的方差的降低,而不仅仅是对足够大的d的渐近估计,这导致了大偏差上的第一个指数小界限严格小于非正交方法的概率。随机特征的正性在这些界限中起着关键作用。

5. 实验结果

对 Performer 的空间和时间复杂度进行基准测试,实验结果表明,注意力机制的加速比和内存减少在实证的角度上近乎最优,也就是说,这非常接近在模型中根本不使用注意力机制的情况。

在以时间(T)和长度(L)为度量的双对数坐标轴中,常规 Transformer 模型的双向 timing。行方向的终点是GPU内存的极限。黑线(X)表示使用;注意力块时可能的最大内存压缩和加速,它基本上绕过了注意力计算,代表着模型可能的最大效率。Performer模型在注意力部分几乎能够达到这种最佳性能。

文章进一步证明使用无偏 softmax 近似的Performer 模型,在微调之后可以向后兼容预训练 Transformer 模型,从而在提升推理速度的同时降低能耗,且无需完全重新训练已有的模型。

使用 One Billion Word Benchmark(LM1B)数据集,将原始预训练的Transformer权重直接迁移到Performer模型中,这个初始结果的精度是0.07(橙色虚线)。经过微调,Performer 的精度在很少的梯度步数之后就迅速恢复了。

6. 案例:蛋白质序列建模

蛋白质是具有复杂三维结构和特定功能的大分子,对生命来说至关重要。与单词一样,蛋白质被指定为线性序列,其中每个字符是20个氨基酸构建块中的一个。

将 Transformers 应用于大型未标记的蛋白质序列产生的模型可用于对折叠的功能性大分子进行准确的预测。

Performer-ReLU (使用基于 relu 的注意力,这是一个不同于 softmax 的广义注意力)在蛋白质序列数据建模方面有很强的表现,而 Performer-Softmax 与 Transformer 的性能相匹配,正如理论所预测的结果那样。

下面,我们可视化一个蛋白质Performer模型,使用基于 relu 的近似注意力机制进行训练,使用 Performer 来估计氨基酸之间的相似性,从序列比对中分析进化替换模式得到的替换矩阵中恢复类似的结构。

更一般地说,我们发现局部和全局注意力机制与用蛋白质数据训练的Transformer模型一致。Dense Attention的近似Performer有可能捕捉跨越多个蛋白质序列的全局相互作用。


作为概念的验证,对长串联蛋白质序列进行模型训练,会使得常规 Transformer 模型的内存过载,但 Performer模型的内存不会过载,因为它的空间利用很高效。

7. 总结

Google AI的这项工作有助于改进基于非稀疏的方法和基于Kernel的Transformer,这种方法也可以与其他技术互操作,研究人员甚至还将 FAVOR 与Reformer的代码集成在一起。同时研究人员还提供了论文、 Performer的代码和蛋白质语言模型的代码链接。

该研究首次证明了,任意注意力矩阵都可以通过随机特征在下游 Transformer 应用中实现有效地近似。实现这一点的的新机制是使用正随机特征,即原始 query 和 key 的正直非线性函数,这对于避免训练过程中的不稳定性至关重要,并实现了对常规 softmax 注意力的更准确近似。Performer的研究开辟了一种关于Attention、Transformer架构甚至Kernel的全新的思维方式,对于进一步的改进有巨大的启示作用。

  • 参考文献

Rethinking attention with performers

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

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

相关文章

MP3 Module 语音播放模块(Arduino和串口控制)

MP3 Module 语音播放模块(Arduino和串口控制) 前言电气参数原理图MP3文件所放位置和命名规则:接线代码串口控制通讯指令(部分)实验结果 前言 Emakefun MP3语音模块内置8 MB存储空间,无需外接SD卡&#xff…

acwing提高——迭代加深+双向dfs+IDA*

1.迭代加深 顾名思义说明迭代的层数逐渐加深&#xff0c;这样做法有点像bfs的做法层层突出&#xff0c;符合的题型是答案在层数较低的那一层里 加成序列 题目https://www.acwing.com/problem/content/description/172/ #include<bits/stdc.h> using namespace std; c…

接口测试系列之 —— 前端交互测试和后端逻辑测试

01 前端交互测试 前端页面与后端代码之间的交互测试&#xff0c;可以理解为接口功能测试的一个子集。 测试准备 在进行交互测试前&#xff0c;首先要对前端功能有明确的认知&#xff0c;能够明确区分&#xff1a; 什么功能属于前端页面逻辑功能 什么功能又属于前端与后端…

路径规划算法:基于树种优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于树种优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于树种优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法树种…

JMeter快速入门指南:轻松掌握基本操作

Jmeter 介绍 Jmeter 是一款使用Java开发的&#xff0c;开源免费的&#xff0c;测试工具&#xff0c; 主要用来做功能测试和性能测试&#xff08;压力测试/负载测试&#xff09;. 而且用Jmeter 来测试 Restful API, 非常好用。 2023Jmeter性能测试项目实战教程&#xff0c;十…

ffmpeg下载及ffmpy3安装使用

ffmpeg下载及ffmpy3安装使用 1.下载ffmpeg 进入网址&#xff1a;https://www.gyan.dev/ffmpeg/builds/ 在release builds中下载ffmpeg-release-full.7z 下载好后解压到自己想存放的目录&#xff0c;例如&#xff1a;D:\Tool\ffmpeg-6.0-full_build 2.配置环境变量 右键此电…

《最新出炉》Python+Playwright自动化测试-1-环境准备与搭建

一.简介 有很多人问能不能介绍一下Playwright这款自动化神器的相关知识&#xff0c;现在网上的资料太少了。其实在各大博客和公众号也看到过其相关的介绍和讲解。要不就是不全面、不系统&#xff0c;要不就是系统全面但是人家是收费的。当然了接下来也可能介绍的不全面或者不系…

什么是压力测试?什么是负载测试?这两个区别是什么?

前言 之前给一个客户做项目时&#xff0c;由于自己对性能测试了解并不深&#xff0c;搞不懂压力测试和负载测试的区别&#xff0c;导致后面还是由负责性能测试的同事来处理&#xff0c;他跟我说了很多关于压力测试和负载测试的区别&#xff0c;现在我总结如下。 压力测试 压…

解决node上传文件乱码问题终极方案

问题描述 今天在菜鸟教程学习node上传文件时遇到了一个中文乱码的问题&#xff0c;文件名包含中文就会显示乱码&#xff0c;上传到服务器的文件名也是乱码。试了两个方法都不行&#xff0c;最后还是问了万能的度娘才解决。 我做了一个非常简单的上传文件的界面&#xff0c; …

Java SE(十二)之多线程

文章目录 概述1.进程&线程2.并行&并发 线程创建方式1.第一种&#xff1a;继承Thread类2.第二种&#xff1a;实现Runnable接口3.Callable、FutureTask接口4.线程创建的三种方式对比 Thread常用方法1.构造器2.设置和获取线程名称3.线程调度4.线程控制5.线程生命周期 线程…

静态路由和默认路由的工作原理

目录 静态路由 静态路由配置 默认&#xff08;缺省&#xff09;路由 路由的高级特性 1&#xff0c;递归路由 2&#xff0c;等价路由 3&#xff0c;浮动路由 4&#xff0c;路由汇总 环路问题&#xff1a; 解决方法&#xff1a; 静态路由 在路由器手动添加路由条目 静…

基于深度学习的高精度浣熊检测识别系统(PyTorch+Pyside6+模型)

摘要&#xff1a;基于深度学习的高精度浣熊检测&#xff08;水牛、犀牛、斑马和大象&#xff09;识别系统可用于日常生活中或野外来检测与定位浣熊目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的浣熊目标检测识别&#xff0c;另外支持结果可视化与图片或视…

Spring Boot 集成支付宝、微信等支付平台API

Spring Boot 集成支付宝、微信等支付平台API 在现代的 Web 应用程序开发中&#xff0c;与第三方 API 的集成是非常常见的需求。例如&#xff0c;支付宝、微信等支付平台的支付接口、短信验证码的发送接口、邮件发送接口等。Spring Boot 提供了许多便捷的方式来集成这些第三方 …

Python实战基础17-包

1、pip的安装配置 1.1 pip命令的使用 在安装python时&#xff0c;同时还会安装pip软件&#xff0c;它是python的包管理工具&#xff0c;可以用来查找、下载、安装和卸载python的第三方资源包。 1.2 配置pip 可以直接在终端输入pip命令&#xff0c;如果出错可能会有两个原因…

接口自动化测试实战:JMeter+Ant+Jenkins+钉钉机器人群通知完美结合

目录 前言 一、本地JAVA环境安装配置&#xff0c;安装JAVA8和JAVA17 二、安装和配置Jmeter 三、安装和配置ant 四、jmeter ant配置 五、jenkins安装和配置持续构建项目 文末福利 前言 搭建jmeterantjenkins环境有些前提条件&#xff0c;那就是要先配置好java环境&#…

OS-内存管理-4种内存管理方式(连续分配,页式,段式,段页)。

一&#xff0c;内存管理四种方式。 二&#xff0c;连续分配管理方式。 连续分配方式&#xff1a;为用户分配连续的内存空间。 1.单一连续分配方式 2.固定分区分配方式 3.动态分区分配方式 4.三种连续分配方式的对比。 三&#xff0c;基于页式存储管理。 1.页式 为进一步提高…

【来不及刷题之】32、二分搜索(寻找数,寻找左右边界)

1. 基础二分搜索&#xff1a;寻找一个数 一道很基础的题目&#xff0c;主要注意一下循环条件是 left<right 即可 class Solution {public int search(int[] nums, int target) {int left0;int rightnums.length-1;while(left<right){int midleft(right-left)/2;if(nums…

第二十一章行为性模式—访问者模式

文章目录 访问者模式解决的问题结构实例存在的问题使用场景 拓展动态分派静态分派双分派 行为型模式用于描述程序在运行时复杂的流程控制&#xff0c;即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务&#xff0c;它涉及算法与对象间职责的分配。行为型模…

华为OD机试真题B卷 Java 实现【箱子之形摆放】,附详细解题思路

一、题目描述 要求将一批箱子按从上到下以‘之’字形的顺序摆放在宽度为 n 的空地上&#xff0c;输出箱子的摆放位置&#xff0c;例如&#xff1a;箱子ABCDEFG&#xff0c;空地宽为3。 摆放效果如下图&#xff1a; 则输出结果为&#xff1a; AFG BE CD 二、输入描述 一行…

智能语音交互流程

引言 用该文来讲解语音全流程涉及到的技术&#xff0c;整体语音涉及的交互流程如下图&#xff1a; Part1 唤醒 语音唤醒指的是通过预设的关键词即可将智能硬件从休眠状态唤醒&#xff0c;来执行相应操作。 1.1 交互模式 传统模式 唤醒方式&#xff1a;先唤醒设备&#xff…