ChatGPT:ELMo,Transformer,Multitask

news2024/11/23 21:52:47

1,ELMo:Embedding新纪元

1.1,word2vec的局限性

word2vec:word2vec模型是一种可以用于各种任务的单词级别的表示学习。以单词stick为例子,它有非常多的意思:

v.
粘贴;粘住;被接受;(在某物中)卡住,陷住,动不了;
(尤指迅速或随手)放置;戳;容忍;将…刺入(或插入);
对…不感兴趣;不再要牌
n.
棍,条,签;(飞机的)操纵杆,驾驶杆;一管,一支(胶棒等);
枝条;批评;(车辆的)变速杆,换挡杆;
枯枝;球棍;指挥棒;条状物;棍状物;柴火棍儿

如果使用word2vec、GloVe的那些词嵌入,那么不管stick的上下文是什么,单词stick都将由同一个向量表示。也就是说,对一个词只有一个词嵌入,哪怕这个词其实有超级多的意思。​这其实还挺蠢的。所以就有很多学者站出来说:“stick有多种意思,而它的意思则取决于他的上下文。“Let's stick to”和“he pick up a stick so that”中的stick显然是两个意思,却用了同一个词向量。为什么不根据上下文语境进行embedding呢?这样既能捕捉该语境中的含义,又捕捉其他语境信息。”

1.2,语境化词嵌入

语境化词嵌入可以根据词语在句子语境中的含义赋予词语不同的embedding。​在问ELMo,stick的词嵌入是什么的时候,ELMo是不会像word2vec一样给一个肯定的答案的,因为ELMo没有对每个单词使用固定的词嵌入,而是在为每个单词计算embedding之前考虑整个句子。ELMo模型使用的是特定任务上训练好的双向LSTM(bi-LSTM)进行词嵌入。

1.3,ELMo模型结构

宏观上ELMo分三个主要模块:​

  • 最底层黄色标记的Embedding模块。
  • 中间层蓝色标记的两部分双层LSTM模块。
  • 最上层绿色标记的词向量表征模块。

【字符嵌入层】ELMo模型使用字符嵌入来表示每个词语,这是通过卷积神经网络来实现的。​ELMo模型中的CNN主要用于从输入文本中提取字符级别的特征,这些特征可以捕捉到单词中的前缀和后缀信息,从而提高词向量的表达能力。具体来说,ELMo使用了一个具有多个卷积核的卷积层,每个卷积核对应一个不同的字符级别窗口大小,通过对输入文本进行卷积操作,可以提取出每个字符级别窗口中的特征。这些特征经过池化和拼接操作后,可以形成一个与输入文本相同长度的字符级别特征向量,作为LSTM网络的输入之一。

【双向LSTM层】ELMo模型使用双向LSTM(Bi-LTSM)来捕捉词语在上下文中的语义信息。Bi-LSTM分别从左向右和从右向左对输入序列进行扫描,可以同时考虑到前向和后向的上下文信息,从而生成上下文相关的词向量。​在ELMo模型中,Bi-LSTM层由两个独立的LSTM单元组成,分别从前向和后向两个方向对输入文本进行建模,形成了两个独立的隐藏状态序列。

  • 对于左半部分:给定 {\small N}{\small token[t_1,t_2,...,t_N]}, Language Model通过前面 k-1 个位置的token序列来计算第 k 个token出现的概率,构成前向双层LSTM模型.​
  • 对于右半部分:给定 {\small N} 个 {\small tokens[ t (k+1), t(k+2),..., t(N)]},Language Model通过后面 {\small N-k} 个位置的 token 序列来计算第 k 个token出现的概率,构成后向双层LSTM模型。

【上下文相关词向量层】ELMo模型通过将字符嵌入和双向LSTM层的输出进行拼接,并通过一个线性变换得到最终的上下文相关词向量。这些词向量可以根据输入句子的不同上下文进行调整,从而捕捉到不同上下文中词语的语义信息。

【输出层】ELMo模型可以通过在上下文相关词向量上添加任务特定的输出层,如全连接层、Softmax层等,来进行具体的NLP任务,如文本分类、命名实体识别等。​因为ELMo给下游提供的是每个单词的特征形式,所以这一类预训练方法被称为"Feature-based Pre-Training"。

【缺点】ELMo在传统静态word embedding方法(Word2Vec,GloVe)的基础上提升了很多, 但是依然存在缺陷,有很大的改进余地。主要有以下两点:​

  • 第一点:一个很明显的缺点在于特征提取器的选择上,ELMo使用了双向双层LSTM,而不是现在横扫千军的Transformer,在特征提取能力上肯定是要弱一些的。如果ELMo的提升提取器选用Transformer,那么后来的BERT的反响将远不如当时那么火爆。
  • 第二点:ELMo选用双向拼接的方式进行特征融合,这种方法肯定不如BERT一体化的双向提取特征好。

2,大预言模型基石:Transformer

2.1,基本概述

在seq2seq把Attention机制发扬光大后,NLP领域的模型的主流架构是递归神经网络(一般是LSTM)+注意力机制,后者起到一个辅助作用。然而,LSTM再怎么样都不过是一个变种RNN,难以并行训练、发挥GPU的优势这件事让他们训练效率很慢,自然不存在大力出奇迹造出一个超级大的语言模型的可能性。Transformer模型非常非常的激进,他直接抛弃了作为模型主体的RNN,只保留了注意力机制。在做NLP的任务时,CNN、RNN和Transformer相比,并行程度CNN大于Transformer远大于RNN,信息糅合能力RNN大于Transformer远大于CNN。

原版的Transformer有六个编码器和六个解码器,是一个比较深的网络结构。可以看到,最开始的时候,Transformer主要用于神经翻译任务,所以这里先用神经翻译任务举例子。如果没有编码器,那就是Decoder-Only(GPT);如果没有解码器,那就是Encoder-Only(BERT)。

【问题】编码器如何给Token编码才能做到与RNN相同的时序能力?

【答案】首先需要把输入的每个单词通过词嵌入(embedding)转化为对应的向量。​在Attention is All You Need原文中,他们采用了512维的词嵌入,这里为了方便展示,用4个格子来代表512维的词向量们。

Transformer中的编码器不只采用了词嵌入本身的Embedding,还为每个词基于位置额外增加了一个Embedding(Positional Encoding),它的维度和词嵌入是一样的。最终输入给Transformer的是两个嵌入向量的和。这是因为:

  • Transformer激进地放弃了自带时序处理能力的RNN,而Attention本身又是不会有时序信息的(用自注意力实现全局,不等于拥有时序信息!全局不等于时序)。
  • Transformer 不采用 RNN 的结构,使用全局信息,不能利用单词的顺序信息,而顺序信息对于 NLP 来说又非常重要。所以 Transformer 中使用位置 Embedding 保存单词在序列中的相对或绝对位置。

通过Positional Encoding,模型可以确定每个单词的位置或不同单词之间的距离。而位置编码需要做到:每个位置对应的编码唯一;不论句子有多长,每两个相邻位置之间的距离都一样;所有的编码都要在一个有限的区间内,编码用到的数字不能爆炸上升(这其实真的很难做到!)。

具体的,Transformer里的位置编码:它是一个和词嵌入同维的、sin和cos交替的向量。

PE_{(pos,2i)}=sin(pos/10000^{2i/d})

PE_{(pos,2i+1)}=cos(pos/10000^{2i/d})

2.2,编码器:自注意层

【编码器:Self-Attention层 + 前馈神经网络层】6个编码器组件的结构是相同的,但是他们之间的权重是不共享的,每个编码器都可以分为2个子层。

  • 编码器的输入 x_i 首先会进入一个自注意力层,这个注意力层的作用是:当要编码某个特定的词汇的时候,它会帮助编码器关注句子中的其他词汇。
  • 自注意力层的输出 z_i 会传递给一个前馈神经网络,每个编码器组件都是在相同的位置使用结构相同(每个Encoder中的FFNN结构相同但参数不同)的前馈神经网络。

【三个矩阵】

  • 查询矩阵(Query):用于计算注意力权重,表示当前时间步需要关注哪些位置。
  • 键矩阵(Key):用于匹配查询,帮助确定输入序列中每个位置的重要性。
  • 值矩阵(Value):包含实际的输入信息,在计算注意力加权和时使用。

【自注意力层】在之前的seq2seq注意力机制里,两个做点积来计算Attention Score的向量分别在编码器和解码器里,而Transformer的自注意力层里,两个做点积的向量都是源自编码器(或者解码器)。

对每一个输入的向量(512维),把它乘一个512*64的权重矩阵,最后就会得到一个64维的向量。四个格子代表了512维的向量,Q、K、V中的向量都是三个格子,三个格子代表的就是一个64维的向量。在编码器的自注意力层中,训练三个权重不共享(目的不同)的512*64的矩阵:W^QW^KW^V 。对编码器的每个输入向量,都分别乘以这三个矩阵,计算出三个64维的向量:Query向量,Key向量和Value向量。

【计算注意力得分:Query和Key的点积】在Transformer的自注意力层里,假设输入的Embedding有N个:[x_1,x_2,...,x_N] ,对于第 k 个输入 x_k,进行点积的向量分别为:x_k对应的查询向量 q_k 以及全部N个输入对应的向量:k_1,k_2,...,k_k,...,k_N以Thinking Machine个两个词的输入为例,Thinking的查询向量 q_1 会分别和句子中所有的输入 (x_1,x_2) 对应的Key向量做点积(可以判断向量相似度),得到Thinking这个词对于句子中的每一个词的注意力得分。

【计算注意力分布】标准的计算注意力分布的方法就是对注意力得分做一个Softmax。不过在原版的Transformer中,作者们先把注意力得分除以了一个8(Q、K、V向量的维度的根号值)这是因为两个64维向量做点积算出来的标量还是很大的,如果不做额外的处理就直接去softmax的话,会导致Attention Distribution高度集中于当前位置的单词,但这显然不是想要的,还想知道当前的单词和其他各种单词的联系。总之,这里的除以8更多的其实是一种基于实践的工程经验。

【计算Output】既然注意力分布是一个概率密度函数,那注意力输出 a_t 其实很类似数学期望。Transformer中的自注意力层也是一样,都是数学期望的思维。上一步计算出Attention Distribution为P(Thinking)=0.88、P(Machine)=0.12,在最后会用这个概率分布乘以对应的单词的Value向量。最终单词 Thinking的输出 z_1 等于所有单词的值 v_1,v_2 根据 attention 系数的比例加在一起得到:​z_1=0.88v_1+0.12v_2

2.3,编码器:多头注意力机制

首先,在翻译一个特定单词的时候,模型的注意力肯定主要关注这个词自身。希望翻译这个词的时候模型多去关注上下文的其他词,但上下文联系其实也有很多种,有 it 这样的指代、are这样的单复数、were这样的时态,或者说基于不同的上下文,一个单词自身也会有不同的意义(想起ELMo还有Stick了吗?)。如果多训练几个不同的权重矩阵:W^QW^KW^V 的组合,让他们各司其职,有的负责指代任务,有的负责时态任务,有的负责基于全局语境搞清楚多义词(即去探索多个不同的表征子空间),那是不是模型就可以取得更好的效果?因此,简单来说,多头注意力就是多训练几个权重矩阵:W^QW^KW^V

对于同一个输入Thinking Machine,有8个权重矩阵组,因此最终会产生8个Z矩阵:

将这些矩阵连接起来,形成了一个2*512维的矩阵;然后将其乘以一个产生最终输出的权重矩阵 W^o图中 W^o 是一个512*512的矩阵,最后得到了一个2*512的Z矩阵,他的形状和最开始的输入一样。自注意力层最终输出的一个N*512的矩阵会输入给前馈神经网络。所以它的形状和最开始的时候输入的矩阵是一样的。即:一个多头自注意力层并不改变输入的东西的形状。

2.4,解码器第一层:带掩码的多头自注意力层

【解码器:带掩码的Self-Attention层 + Self-Attention 层+一个前馈神经网络】解码器组件也含有前面编码器中提到的两个层,区别在于这两个层之间还夹了一个注意力层,多出来的这个自注意力层的连接了编码器输出的隐状态,起到了和seq2seq中的attention一样的作用。

在解码器中,第一个Self-Attention和编码器的第一个自注意力层也是不同的。它是一个带掩码的自注意力层,带掩码的意思就是,对于一个总共有N个单词的词序列,在翻译到第K个单词时候,这个自注意力层只能注意到第1到第K个单词,而注意不到第K+1到第N个单词。

带掩码的多头自注意力层:解码器中的自注意力层和编码器中的不太一样:在解码器中,自注意力层只允许关注已输出位置的信息。所以我们称之为“带掩码的自注意力层”。Decoder block 的第一个 Multi-Head Attention 采用了 Masked 操作,因为在翻译的过程(训练)中是顺序翻译的,即翻译完第 i 个单词,才可以翻译第 i+1 个单词。通过 Masked 操作可以防止第 i 个单词知道 i+1 个单词之后的信息,从而避免抄答案的操作(防止预测试没有答案)。

Mask操作主要是在Softmax的时候实现的:如果要翻译I have a cat为中文,我们依然可以用 Q 和 K^T 做矩阵乘法的操作,这样会得到一个4*4的矩阵。

\begin{bmatrix} a_{I,I} & a_{I,Have} & a_{I,a} &a_{I,Cat} \\ a_{Have,I} & a_{Have,Have} & a_{Have,a} &a_{Have,cat} \\ a_{a,I} & a_{a,Have}& a_{a,a} & a_{a,Cat} \\ a_{Cat,I} & a_{Cat,Have}&a_{Cat,a} & a_{Cat,Cat} \end{bmatrix}

但是在解码器里,要做这样一个操作:

自注意力层只允许关注已输出位置的信息,所以对于已输出位置和未输出的位置的点积(上图中的黑色的位置),在softmax时会给他加上一个巨大的负值(GPT中为负一亿),好让他们在softmax后得到的结果为0。这样,在输出当前时间步的时候,解码器就不会去关注后面的单词的信息了。最终得到了一个4*64的矩阵,它会作为Query矩阵直接被输入给解码器的下一层Encoder-Decoder Attention。矩阵的第一列(I的z向量,也是下一个注意力层中 I 的查询向量)就只包含了I的信息。

2.5,解码器第二层:多头编码器-解码器注意力层

假定N为6,八头注意力:编码器首先处理输入序列,输入序列经过了6个Encoder之后,第六个编码器会输出一个张量。该张量会被平等的送给每个Decoder的第二个注意力层,并通过一个共享参数的权重矩阵 C 转为8个Key矩阵和8个Value矩阵。在这一层中,解码器组件使用自己的带掩码的第一层自注意力层产生的8个Z矩阵作为8种Query矩阵,并使用编码器传过来的8个Key和Value矩阵,来做前面提到过的多头自注意力的运算。在经过两个多头注意力层后,最后会经过一个全连接层,然后输出一个向量给最后的Linear和Softmax层。

Decoder输出的是一个浮点型向量,如何把它变成一个词?这就是最后一个线性层和softmax要做的事情。​线性层就是一个简单的全连接神经网络,它将解码器生成的向量映射到logits向量中。​然后,softmax层将这些分数转化为概率(全部为正值,加起来等于1.0),选择其中概率最大的位置的词汇作为当前时间步的输出。​就像seq2seq一样,transformer的解码器中当前时间步的输出会作为下一个时间步的输入。

3,Multitask Learning

3.1,NLP预训练难题

迁移学习极大地影响了计算机视觉的发展,但现有的NLP方法仍然需要针对特定任务进行修改,并从头开始训练具体的模型NLP领域迟迟没有出现像CV一样的Inductive transfer learning的原因:

  • 数据集太少(标注成本非常高;而且网络上的语言质量参差不齐,是一种挑战);
  • CV的大多数任务基本都是基于分类的,而NLP领域却有很多任务,包括基本的命名实体识别任务和句法分析任务;包括基于分类的任务,如情感分析;以及基于序列的任务,如机器翻译和自然语言生成。这些任务涉及不同的数据结构和算法,很难用同一个模型、同一个权重全部概括。
    • 对于数据集太少问题,可以用利用半监督学习(Semi-supervised Learning):用少量的有标签数据和大量的无标签数据进行训练,以提高模型的性能。
    • 对于任务太多的问题,一个重要的解决方案就是Multitask Learning,多任务学习。

3.2,Cookie Monster

Cookie Monster的三个微调技术:

  • Discriminative fine-tuning(‘Discr’) 是指在深度学习中对预训练模型进行微调,以适应新任务或数据集的过程。在这个过程中,每层的学习率被设置为不同的值。​
  • 斜三角学习率(Slanted triangular learning rates,STLR)是一种用于训练神经网络的学习率策略,旨在加速训练过程并提高模型性能。​它首先线性增加学习率,然后根据右表线性衰减。
  • 渐进式解冻(Progressive Unfreezing)是一种用于训练深度神经网络的技术,其利用了分阶段训练的方法,旨在缓解深度神经网络训练中的过拟合问题,并提高模型的性能。
    • 在传统的深度神经网络训练中,通常是先对整个网络进行训练,然后再微调各个层,这种方式可能会导致网络过拟合,即模型对训练数据过于敏感,泛化能力较差。而渐进式解冻则是一种分阶段训练的方法,可以使得网络逐步地学习到数据的更多细节信息,从而降低过拟合的风险。​
    • 具体而言,渐进式解冻的步骤如下:1、将深度神经网络的所有层进行冻结,只训练最后一层。2、在最后一层训练收敛后,解冻前一层,继续训练倒数第二层。3、在两层训练收敛后,解冻前一层,继续训练倒数第三层。依次类推,直到所有层都被解冻并训练完成。​
    • 通过这种方式,渐进式解冻可以逐步增加网络的复杂度和容量,使得网络可以逐步学习到数据的更多细节信息,并逐渐适应数据的不同特征,从而提高模型的性能。此外,渐进式解冻还可以提高模型的泛化能力,并缩短训练时间,减少过拟合的风险。

训练Cookie Monster的三步:

  • 在一般领域的Corpus上训练LM,以捕捉语言的一般特征(论文原作里,作者在Wikitext-103上预训练语言模型,前者由28,595篇预处理的维基百科文章和1.03亿个单词组成)。这个阶段是最昂贵的,但它只需要执行一次,并能提高下游模型的性能和收敛性。​
  • 在目标任务数据上使用Discr和STLR对完整的LM进行微调,以学习特定的任务特征。
    • Discr背后的思想:由于不同的层捕获不同类型的信息,它们应该被微调到不同的程度。
    • STLR的目的:希望模型在训练开始时能迅速收敛到参数空间的一个合适区域,然后完善其参数。​
  • 分类器(Classifier):在目标任务上使用渐进式解冻、"Discr "和STLR进行微调,以保留低级表征并适应高级表征(图中,阴影:解冻阶段;黑色:冻结)。

ULM-FiT是一种有效的、极其节省样本的迁移学习方法,可以应用于任何NLP任务。​ULM-FiT之前,NLP领域的Fine-tuning一直存在过拟合、灾难性遗忘、数据集不够等挑战,而ULM-FiT采用了多任务学习,提出了几种新的微调技术,有效防止了灾难性的遗忘,并在不同的任务中实现了稳健的学习。NLP领域终于有了类似CV的迁移学习方法。

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

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

相关文章

webshell应急响应

前言 webshell在应急中占了很大的比例,本篇文章就来看看当遇到webshell时如何进行应急响应。 Webshell通常指以JSP、ASP、PHP等网页脚本文件形式存在的一种服务器可执行文件,一般带有文件操作、命令执行功能,是一种网页后门。攻击者在入侵一…

Email调用接口在高并发下的性能优化策略?

Email调用接口的安全保障措施?如何优化邮件调用接口? 无论是用户注册、密码重置还是促销邮件的发送,Email调用接口都是不可或缺的一部分。当面对高并发请求时,往往会成为瓶颈。AokSend将探讨几种在高并发环境下优化Email调用接口…

超级详细,如何手动安装python第三方库?

文章目录 1,python第三方库安装包有3种类型2,python第三方库安装包whl文件如何安装?3,python第三方库安装包zip和tar.gz文件如何安装?4, python第三方库安装包exe文件如何安装? 手动安装第三方库…

Unity材质球自动遍历所需贴图

Unity材质球自动遍历所需贴图 文章目录 Unity材质球自动遍历所需贴图一、原理二、用法1.代码:2.使用方法 一、原理 例如一个材质球名为:Decal_Text_Cranes_01_Mat , 然后从全局遍历出:Decal_Text_Cranes_01_Albedo赋值给材质球的…

校园选课助手【1】

项目背景 随着高校招生规模的不断扩大,学生选课需求日益增长。为提高选课效率,降低学生选课压力,本项目旨在开发一款校园选课助手软件。 项目目标:开发一款具有以下特点的校园选课助手软件: 易用性:界面简洁&#xff…

组蛋白乳酸化和RNA甲基化如何联动?请大数据把这个思路推给科研人

在细胞生物学中,基因表达调控是决定细胞功能与命运的核心过程之一。组蛋白作为修饰性蛋白,在调控基因转录中起着至关重要的作用。近年来,科学家们发现,组蛋白的多种化学修饰(如甲基化、乙酰化、磷酸化等)影…

Java零基础之多线程篇:多线程最佳实践

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一…

diff算法的流程

diff算法? 组件并不是真是的DOM节点,而是存在与内存中的一种数据结构,叫做虚拟DOM,只有当它真正插入文档中的时候才会真的变成DOM。 React的设计时所有的DOM变动都先在虚拟的DOM上发生,然后再将实际变动的部分反映在…

来聊一个有趣的限流器RateLimiter

写在文章开头 这一篇我们来聊一个比较使用的限流工具RateLimiter,它是Google开源的Java类库guava中的一个工具类,本文将从使用和源码分析的角度介绍RateLimiter的设计与实现,希望对你有帮助。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客…

【MATLAB源码】机器视觉与图像识别技术示例报告2---铁道口夜间列车通过时速度视觉测量

系列文章目录在最后面,各位同仁感兴趣可以看看! 速度视觉测量 摘要对铁路夜晚环境情况分析视觉测量的流程步骤代码问题最后:总结系列文章目录 摘要 随着科技技术的不断发展,由于铁道口夜间交通事故频发,传统的雷达和…

铁路购票系统中的数据库技术《二》

铁路购票系统中的数据库技术《二》 缓存技术:减轻数据库压力数据一致性:确保交易公平分布式事务:跨系统的数据一致性读写分离:优化查询性能数据库备份与恢复:确保数据安全安全性:保护sensitive数据性能优化…

基于Python的鸢尾花聚类与分类

1 导入必要的库 from sklearn.datasets import load_iris import pandas as pd import matplotlib.pyplot as plt import numpy as np import seaborn as sns from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score, silhouette_samples from skl…

缓存和数据库双向写死一致性问题

我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。也就是说如果数据库写成功,缓存更新失败,或者没有更新操作,那么只要达到过期时间,则后面的读者自然会从数…

图形编辑器基于Paper.js教程12:井身结构编辑器,多条完全平行的弯曲线,使用额外平行线来作为弯曲中心线的度量尺

背景 对于弯曲的三条平行线,一开始我以为只需要使用中心线,然后复制两条,一个向右下角平移,一个向左上角平移,就能让三条线实现完全平行,每一处的距离都相等。后来仔细思考后,发现我想错了&…

数据管道为什么选择Kafka作为消息队列?

目录 关于Kafka 什么是消息队列? Kafka的特点 管道为什么需要消息队列? 管道任务为什么选择Kafka作为消息队列? 企业在构建数仓和中间库时,由于业务数据量级较大,如果使用批量定时同步数据的方式很难做到高性能的增量同…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《考虑隐私保护的虚拟电厂内部交易决策优化 》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

食源送系统项目的测试

一、对整个系统编写测试用例 功能测试 性能测试 兼容性测试 易用性测试 安全测试 二、接口测试 针对接口的功能测试,也就是检验接口是否按照接口文档输入输出 2.1 使用Postman发送HTTP请求 2.2 使用Java TestNG 编写自动化测试用例 登录界面功能 package com.sky.…

碳化硅陶瓷膜的机械强度

碳化硅陶瓷膜是一种高性能的过滤材料,它采用重结晶技术在高温条件下烧结而成。这种膜的特点是整个结构,包括多孔支撑层、过渡层和膜层,均由碳化硅(SiC)材料构成。碳化硅陶瓷膜因其独特的性能而在多个领域得到广泛应用,下面是对碳化…

【面试题解答】一个有序数组 nums ,原地删除重复出现的元素

面试题解答 仅供学习 文章目录 面试题解答题目一、python代码1.1 代码1.2 示例用法1.2.1 示例11.2.2 示例2 二、讲解2.1 初始化2.2 遍历2.3 返回 题目 要解决这个问题,可以使用双指针方法进行原地修改,以确保每个元素最多出现两次。 一、python代码 1.1…

文件上传漏洞大总结:原理与复现

文章目录 原理f8x靶场安装文件上传漏洞前端验证概念步骤: 上传特殊可解析后缀概念步骤 ::$DATA绕过概念主要流类型 点空格绕过概念代码审计**步骤:** 文件类型检测概念常见的文件类型 过程 文件头检测概念过程 黑名单绕过概念特殊文件爆破常用的文件名过…