初学者理解Transformer,本文is all you need

要问现在AI领域哪个概念最热,必然是openAI推出chatGPT之后引发的大模型。然而这项技术的起源,都来自一篇google公司员工的神作“Attention Is All You Need”——本文标题也是一种致敬^_^,目前已有近12万的引用(还在增长)。

在“Attention Is All You Need”中介绍了一种新的神经网络架构,被命名为变形金刚(也可以叫变压器,只是不那么cool)的Transformer,并应用到语言翻译中取得了很好的效果。这之后,基于Transformer架构的技术层出不穷,不仅在语言翻译中,在图像处理、语音处理、问答系统中都得到了广泛应用,chatGPT就是其中的明星应用。

本文将结合一个中译英例子,通过一步步的节点计算介绍,将这篇论文中提到的Transformer模型进行阐述,后文提到的“原文”就是指代“Attention Is All You Need”这篇论文。

鸟瞰框架

Transformer的模型架构主要由两部分组成,如下图中左边的框是编码器(Encoder),右边的框是解码器(Decoder)。

我们先忽略其中的细节,从最顶层鸟瞰Transfromer结构是这样的(原文N等于6):

输入序列经过N(原文中取值6)层的编码后,产生的编码矩阵结果输入到后续的解码器中,同时将经过嵌入和线性变换处理的输出依次也输入第一层的解码器中,最终产生一个预测值。该预测值和样本之间的差用于权重矩阵的训练,最终得到我们需要的模型。

整个Transformer需要经过如下步骤的计算:

  • 数据输入编码器和解码器前的处理
  1. 输入输出序列的词嵌入(Embedding)
  2. 位置编码(Positional Encoding)
  • 编码器层
  1. 编码器中多头注意力子层
  2. 编码器中前馈子层
  • 解码器层
  1. 解码器中多头注意力(掩码)子层
  2. 解码器中多头注意力子层
  3. 解码器中前馈子层
  • 输出预测值
  1. 线性层
  2. Softmax层

下面从输入序列开始,逐层讲解Transformer的结构和计算。读者需要具备一些基础的线性代数知识(矩阵概念、向量及矩阵乘法)和神经网络知识(网络连接、激活函数、规范化等)。

我们以一个中译英的任务举例,将“我爱编程”翻译成"I love programming"。把中文“我爱编程”拆开看成“我”(位置0)“爱”(位置1)“编”(位置2)“程”(位置3),英文为"I"(位置0)"love"(位置1)"programming"(位置2),如下图所示:

输入的嵌入层

也就是下图中红框部分:

输入Embedding

我们知道计算机并不能直接处理文字,它擅长的只是数值计算,因此我们需要将输入的字符进行编码才能输入到Transformer中。那能否用1、2、3依次编号这些文字呢?答案是不行。因为这只是形式上转成了数字,但每个词之间的关系并不能得到体现。比如“苹果”和“香蕉”,假设它们的编号分别是9527,9528,这看上去他们距离很近应该属于很相近的两个东西(反之,如果编号相差很大也一样存在可能意思相近的上下文)。但“苹果”要是出现在“手机”前,那它跟水果“香蕉”就应该相差很远。

怎么在上下文中体现词与词之间的相似性呢?它的编码就需要进行大量数据的训练,使得词与词之间的关系可以通过这种编码的数值关系来表达出来,在NLP领域就叫这个为embedding(中文翻译有叫嵌入,也有叫编码,大家自行根据上下文理解,本质上都是将文字转换成一个数值向量),比如谷歌开源的Word2Vec工具包就是做这个工作的。

通过embedding,输入的一个个词(实际处理中使用token,也就是先token化,此处简化将token等同为单词)就转换成了向量。也可以先初始化为随机向量,然后在训练Transformer时更新embedding值。原文中使用的是已学习好的embedding方法。

假设我们的embedding模型将输入的词转成的向量维度是512(原文选择的d_{model}值),则“我爱编程”的每个词转成512维的向量如下所示。

实际应用中,这些向量会拼接一块作为输入矩阵X\in \mathbb{R}^{l\times d_{model}},这里的l为序列长度(这里l=4),d_{model}是embedding模型长度。

位置编码(Positional Encoding)

输入的序列通过embedding转成向量后不能直接进行后续运算,因为相较于RNN,这里体现不出每个词的位置信息。举例来说“我吃梨”跟“梨吃我”转成的是相同的3个向量,但显然前后两句的主语和宾语是不一样的。为了解决这个问题,需要引入位置信息,即“我吃梨”中的“我”在第一位,“梨”在第三位,这个信息的引入就是位置编码。原文中通过计算来获得,计算公式如下:

其中pos是单词在句子中的位置,比如“我爱编程”中的“我”的pos取值0,“爱”的pos取值1;d是位置编码后向量的维度,取跟输入embedding维度相同,所以这里是 512;i是向量维度的索引,这里的两个公式说明对第偶数维的值采用sin计算,对第奇数维的值采用cos计算。假设“我”的embedding后为(0.85, 0.34, 0.5, 0.61,......)的512维向量,分别计算每一维的位置编码后得到的向量是:

[ sin(0/10000^{(2*0/512)}), cos(0/10000^{(2*1/512)}), sin(0/10000^{(2*2/512)}), cos(0/10000^{(2*3/512)}), ......]^{T},这个位置编码向量也是512维的。

通过将词嵌入embedding向量和位置编码向量相加,得到的向量就是将输入编码器的输入向量x。如果将所有词的embedding和位置编码向量相加放到一个矩阵中,我们就可以最大化利用GPU的矩阵并行运算能力,这时的输入就是矩阵X,它是多个向量的拼接,即:

X=\begin{bmatrix} x_{1}^{t}\\ x_{2}^{t}\\ ...\\ x_{l}^{t} \end{bmatrix}

这里的l是embeding的个数即序列长度,此处为4(“我爱编程”的词序列长度),所以X是个4*512的矩阵。

编码器多头注意力机制(Multi Head Attention)

本节我们介绍多头注意力机制,也就是框架图中红框所示部分,当输入经过嵌入和位置编码后首先进入的这个节点:

这是原文的一个创新点。在这里假设读者掌握向量及矩阵乘积的数学知识,如果能了解向量距离的概念就更好了。

注意力机制(Attention)

字面上理解,注意力就是我们观察对象中的重点部分。当我们从一张图片中去找寻一个对象时,我们会先大致在图片中搜寻色块形状相近的区块,然后再细节判断刚才的区块是否我们找寻的对象,那个查找相近区块过程就是注意力机制。

再拿我们从数据库中查询信息的过程打比方,我们输入的查询语句(Query)会先查询索引(Key),找到匹配项下的值(Value)并返回。如何用数学公式来表示这个过程呢,这就是注意力机制描述的事情。我们注意到整个过程离不开怎么定义匹配,换句话说如何定义Q(文中后续用Q简单代指Query,类似K代替Key, V代替Value)与K和V的相近程度呢?越相近就越匹配,就越需要我们注意。

两个向量之间的相似度可以用他们在向量空间中的距离来表示。定义距离的方法有很多种,原文中使用的是点积,如下图所示:

细心的读者会发现这个图的标题是“Scaled” Dot-Product Attention,这个缩放是在点积结果上除以\sqrt{d_{k}}得到,d_{k}是矩阵Q、K的向量维度(原文中是512),表示成数学公式形式即为:

这里的Q、K、V分别是嵌入层处理后的输出乘以对应的权重矩阵得到的,即:

Q=XW^{q}, K=XW^{k}, V=XW^{v}

其中,X是输入序列经embedding和positional encoding之后得到的向量拼接而出的输入表示矩阵,W^{q}\in \mathbb{R}^{d_{model}\times d_{k}}W^{k}\in \mathbb{R}^{d_{model}\times d_{k}}(Q和K具有相同的d_{k})和W^{v}\in \mathbb{R}^{d_{model}\times d_{v}}为权重矩阵,这里的d_{model}是embedding时的维度(本文即为512),而d_{k}d_{v}可以任意选择(原文中应用到多头注意力机制中,选择的是值为64,介绍多头注意力机制时再解释)。初始化这些矩阵为随机矩阵,在后续的训练中会不断更新权重值。

通过注意力机制,我们就能获得每个词在句子中跟其他词之间的相似度,值越大表明相关性越高。由于这里是计算整个句子中各个词间的相关性,包含了自身的计算,所以又叫自注意力(Self-Attention)。

上图中有个Mask节点,在编码器中不使用,主要在解码器中有一个多头注意力子层在接受输出序列embedding时使用,后面再介绍。

多头注意力机制(Multi Head Attention)

上述的注意力机制是对一组(Q,K,V)的计算,原文作者发现采用多个这样的权重矩阵来处理输入会取得更好的结果。即通过多组(W^{q_{i}}W^{k_{i}}W^{v_{i}})来计算对应的Q、K、V:

Q_{i}=XW^{q_{i}}, K_{i}=XW^{k_{i}}, V_{i}=XW^{v_{i}}

如下图即使用了h个(W^{q_{i}}W^{k_{i}}W^{v_{i}}),这里原文使用的h值为8。将d_{model}进行h等分,得到d_{k}=d_{v}=d_{model}/h=64

整个过程相当于一个输入X经过h组(Q、K、V)的线性变换后分别输入对应的单头注意力进行计算,再将各个注意力计算出来的结果拼接(Concat)到一块,乘以一个矩阵W^{O}\in \mathbb{R}^{hd_{v}\times d_{model}}(本文中W^{O}为行值8*64,列值为512,即W^{O}是一个512*512的矩阵)进行线性变换后输出。W^{O}也是一个初始化为随机值的矩阵,用于训练更新。

使用公式表达即为:

其中一个head计算出来的结果为4*64的矩阵,h=8个head计算的结果拼接成一个4*512的矩阵。乘以W^{O}这个512*512的矩阵后,结果是一个4*512的矩阵。

为什么要使用多头注意力机制呢?这就类似卷积神经网络中使用多个卷积核来提取不同特征一样,多头注意力机制能够获取到输入序列中不同的信息进行学习。

同时多头注意力不同于RNN,它是可以多个head同时进行计算,这大大提高了计算的并发性,提升了计算效率。

Add&Norm

在框架图中我们看到经过多头注意力计算后的结果需要经过“Add&Norm”节点。如下图红框所示:

这里是两个计算操作:

  • 残差求和
  • 层规范化

通过残差求和与层规范化处理,能很好抑制梯度消失和爆炸,提升模型的质量。

残差求和

使用残差网络连接是一项神经网络老艺能了,主要是为了减少网络退化并提升训练效果的方法。残差求和即将输入的X和经过多头注意力机制计算的结果求和。

层规范化

Layer Normalization与Batch Normalization方法不同,它对单个样本进行规范化。具体操作就是对矩阵中每一层样本x求均值\mu和方差\sigma

\mu =\frac{1}{N}\sum_{i=1}^{N}x_{i}

\sigma=\sqrt{\frac{1}{N}\sum_{i=1}^{N}(x-\mu )^{2})}

这时计算每一个样本x规范化值的公式是:

\hat{x}_{i}=\frac{x_{i}-\mu}{\sigma}

实际使用中会引入两个学习参数\gamma\beta,在训练中进行更新,这时规范化值的计算是:

y_{i}=\hat{x}_{i} \gamma + \beta

我们例子中的X和多头注意力结果做残差求和后是4*512的矩阵,因此需要做4次在512维样本上的规范化计算。

Add&Norm层的公式表达为:

LayerNorm(X + MultiHeadAttention(X))

前馈层(Feed Forward)

通过编码器第一个子层之后,下一个编码器子层就是前馈层。

前馈层比较简单,是一个两层的全连接层,第一层使用ReLU作为激活函数,第二层不使用激活函数,仅做线性变换。数学公式表达即为:

FFN(X) = ReLU(XW_{1} + b_{1})W_{2} + b_{2}

前馈层之后又做一次Add&Norm,所以这次的Add&Norm公式是:

LayerNorm(X+FFN(X))

具体计算公式跟前面的Add&Norm是一样的,不再赘述。

至此,我们完成了编码器其中一个Layer的计算,这个Layer的输出将输入到下一个Layer中作为输入X。这样的Layer有N个(原文中N取值为6),我们只需要将前一个编码器Layer的输出作为下一个编码器Layer的输入,反复计算,得到最终的编码输出矩阵C

以上是编码器部分,在某些应用场景下,比如特征提取,可以单独拆出编码器使用。在翻译任务中,需要将编码的内容解码,下面开始计算解码器部分。

Outputs嵌入层

在介绍解码器层的计算前,我们注意到输入到解码器的Outputs和输入到编码器的Inputs既相似又有不同。如红框所示:

相同的是它也需要进行Embedding和Positional Encoding两步操作,这里不再赘述,大家可以翻看前面“输入的嵌入层”内容。

与Inputs不同的是下面有个标注“(shifted right)”,这是因为在翻译任务中需要根据之前的预测来计算预测下一个输出。为了让解码器能感知到输出语句的开始和结束,需要引入<start>和<end>两个标志token,所以咱们的例子是:

上图中,首先"<start>"的嵌入及位置编码输入解码器第一个多头注意力层,预测的目标值是"I"。第二次计算预测值时,将"<start> I"的嵌入及位置编码输入解码器第一个多头注意力层,预测的目标值是"love"。如此直到遇到"<end>"完成解码计算。

实际计算中是将"<start> I love programming"编码转换后一并输入多头注意力层,但这样会出现一个问题,就是我们预测"love"的时候,它只依赖"<start> I",而不能预先知道"programming"。也就是第i个字符的预测依赖[0, i]这段的注意力值,而需要摒弃i之后的字符。这就需要引入掩码矩阵。

解码器掩码多头注意力机制(Masked Multi-Head Attention)

这是解码器的第一个多头注意力层,如下图红框中所示:

与编码器中的多头注意力计算相似,分别计算它的h组(Q、K、V)线性变换,计算过程可以参考编码器多头注意力机制一节的内容。不同的是这次在注意力计算\frac{QK^{T}}{\sqrt{d_{k}}}之后需要再进行掩码运算,也就是前面提到的一个可选Mask节点在编码器中没有使用,在解码器中这个就必须应用上,用来防止预测第i位字符时“偷看”了i之后的预测值。

具体做法可以给\frac{QK^{T}}{\sqrt{d_{k}}}运算结果乘以矩阵\begin{bmatrix} 1 & 0 & ... & 0 \\ 1& 1 &0 & ...\\ ... & 1 &1 & 0 \\ 1& ... & 1 & 1 \end{bmatrix},这样保留i及之前的注意力值。也可以像原文那样做相加运算,不过上述矩阵1的位置改为0,0的位置改为一个很大的负数-\infty,这样矩阵相加后i之后的位置影响也被消除。

编码器输入的多头注意力机制

这一层的注意力值计算方式跟编码器中的多头注意力机制类似,不同的是Q来自解码器前面掩码多头注意力层的输出计算线性变换后得到,K和V来自编码器输出的结果线性变换后得到。其他计算与之前的多头注意力计算并无二致。

这一层的作用是在解码时也引入了编码器的输入信息,将输入和第i个位置之前的输出结合起来预测第i+1位的输出。

解码器中前馈层及Add&Norm运算和前面编码器中介绍的对应内容是一样的,此处不再重复介绍。总之经过一系列的注意力值和Add&Norm及前馈运算,如此反复N次(原文中N为6),最终数据来到线性层及Softmax层。

线性和Softmax预测

完成解码器的运算之后,结果矩阵Z是一个行数与解码器输入字符数(本文为3)一致、列数为任意某一个值的矩阵。矩阵Z将进行线性运算和Softmax计算得到预测值,如下图红框中所示部分:

Linear层

线性层的目的是将解码器的输出矩阵Z计算出一个logits向量,表示词库中各词的分值。首先将Z的每行打平,假设Z\in \mathbb{R}^{l\times m},其中l是输入字符数(此处为3),m是选择的值,假设为64。则将Z打平为一个1\times 192的向量(3*64=192)。

LinearLayer=X\cdot W

上式中W\in \mathbb{R}^{192\times n},n为目标词库的大小(比如这里翻译成英文,所以词库可以设置为某英文词库大小)。

Linear层计算出logits向量,对词库中每一个对应的词都提供了表示相关性的数值。

Softmax层

经过Linear层计算的结果,需要进行softmax计算来确定每个词对应的概率,最高概率所在位置的词即为预测的词。Softmax函数定义如下:

S(x_{i}) = \frac{e^{x_{i}}}{\sum _{j=1}^{n}e^{x_{j}}}

其中x_{i}x_{j}为第i和第j位上的logits值,S(x_{i})为对应logits向量第i维度上的softmax值。由此得到的向量中,以最大值所在位置为索引从词库中查找对应的词即为预测到的目标词。

后记

至此,我们完成了所有Transformer各层的计算。这里只简单介绍了每一步的计算方法,并没有讲解如何train和validation和test,只是提供一种理解Transformer这个模型架构的思路。参考资料中2和3相关示例和视频,可以相互借鉴。

当然,这是Transformer初次提出的论文内容,其结构中依然有很多需要改进的地方,还有一些更多的应用场景。关于Transformer的综述,可以看看参考资料4。

参考资料

  1. Attention Is All You Need
  2. Solving Transformer by Hand: A Step-by-Step Math Example
  3. Transformers for beginners | What are they and how do they work
  4. A Survey of Transformers

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

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

相关文章

【qt】容器的用法

容器目录 一.QVertor1.应用场景2.增加数据3.删除数据4.修改数据5.查询数据6.是否包含7.数据个数8.交换数据9.移动数据10.嵌套使用 二.QList1.应用场景2.QStringList 三.QLinkedList1.应用场景2.特殊点3.用迭代器来变量 四.QStack1.应用场景2.基本用法 五.QQueue1.应用场景2.基本…

【设计模式】JAVA Design Patterns——Abstract-document

&#x1f50d; 目的 使用动态属性&#xff0c;并在保持类型安全的同时实现非类型化语言的灵活性。 &#x1f50d; 解释 抽象文档模式使您能够处理其他非静态属性。 此模式使用特征的概念来实现类型安全&#xff0c;并将不同类的属性分离为一组接口 真实世界例子 考虑由多个部…

【Linux】在Linux中执行命令ifconfig, 报错-bash:ifconfig: command not found解决方案

一、报错信息 ifconfig 报错-bash:ifconfig: command not found 同时&#xff0c;通过ip addr查看&#xff0c;也看不到IP信息 二、解决方案 找到ifcfg-ens0文件&#xff0c;此文件的目录在/etc/sysconfig/network-scripts目录下 命令&#xff1a;cd /etc/sysconfig/network…

89C52单片机+ESP8266做的物联网+反馈 e4a手机客户端源程序

资料下载地址&#xff1a;89C52单片机ESP8266做的物联网反馈 e4a手机客户端源程序 MCU是89C52单片机 WiFi模块是ESP8266 其他 8路继电器 电源模块 使用贝壳物联做服务器 还有客户端。 也可以用花生壳做内网穿透&#xff0c;8266做服务器&#xff0c;也可以实现物联以及反馈&a…

vue多选功能

废话不多说&#xff0c;直接上代码&#xff01;&#xff01;&#xff01; <template><div class"duo-xuan-page"><liv-for"(item, index) in list":key"index"click"toggleSelection(item)":class"{ active: sel…

[前后端基础]图片详解

[前后端基础]图片传输与异步-CSDN博客 https://juejin.cn/post/6844903782959022093#heading-3 base64、file和blob用JS进行互转的方法大全【前端】_js base64转blob-CSDN博客 后端存储方式 对于第一种存储方式&#xff0c;我们前端直接将存储路径赋值给 src 属性即可轻松显示。…

react项目中封装一个通用的边界Boundary

# Boundary 通用的边界,同时是一个Suspense 和一个 ErrorBoundary 正常情况不直接用,使用一下几个封装好的: -Boundary.FullSizeLoading: 占满父容器全部高度,居中显示等待动画; -Boundary.Loading: 占满一行,显示一个普通尺寸的等待动画; -Boundary.Blank: 什么都不显示…

Hadoop3:HDFS的Shell操作(常用命令汇总)

一、简介 什么是HDFS的Shell操作&#xff1f; 很简单&#xff0c;就是在Linux的终端&#xff0c;通过命令来操作HDFS。 如果&#xff0c;你们学习过git、docker、k8s&#xff0c;应该会发现&#xff0c;这些命令的特点和shell命令非常相似 二、常用命令 1、准备工作相关命令…

let命令

let 命令 let 与 var 二者区别&#xff1a; 作用域不同&#xff1a;变量提升&#xff08;Hoisting&#xff09;&#xff1a;临时性死区重复声明&#xff1a; 联系&#xff1a;举例说明&#xff1a; 块级作用域 块级作用域的关键字使用 var&#xff08;无块级作用域&#xff09;…

x64dbg中类似于*.exe+地址偏移

在CE和xdb中&#xff0c;形如*.exe数字偏移形式的地址被称为模块地址&#xff0c;CE附加到进程后点击查看内存&#xff0c;显示如下图 这种地址学名叫做模块地址&#xff0c;在x64dbg中显示如下图&#xff1a; CE中可以关闭&#xff0c;从而显示绝对的虚拟地址&#xff0c;如下…

Hive-URL解析函数

Hive-URL解析函数 1.实际工作需求 2.URL的基本组成 3.Hive中的Url解析函数 parse_url函数 parse_url_tuple函数

VScode通过ssh远程连接服务器被拒绝:permission denied, please try again

使用场景&#xff1a; 使用windows系统下的vscode远程连接服务器的linux系统&#xff0c;终端提示permission denied, please try again,但是使用cmd是可以远程登录的。 解决办法&#xff1a; 前提条件windows端的vscode安装了ssh远程连接的相关插件Remote - SSH&#xff0c;…

红米Turbo3小米平板6SPro澎湃OS系统强解BL锁-跳小米社区绑定-刷ROOT权限

红米Turbo3小米平板6SPro这2款设备都出厂为澎湃OS系统&#xff0c;官方提供都是小米社区申请解锁权限&#xff0c;然后自己答题解锁&#xff0c;门槛非常高&#xff0c;想要玩机root的用户&#xff0c;都在堵在门外。还在这目前这两款机型官方并没有加入强制验证&#xff0c;在…

何为基差?股指期货的升水和贴水又怎么理解?

基差是一个金融术语&#xff0c;它指的是现货价格和期货价格之间的差额。在股指期货市场中&#xff0c;现货就是指实际的股票指数&#xff0c;而期货则是基于这个指数未来某个时间点的价格预期。基差可以是正的或负的&#xff0c;具体取决于期货价格是高于还是低于现货价格。 1…

机器人种类分析

2000年前&#xff0c;机器人主要应用于工业生产&#xff0c;俗称工业机器人&#xff0c;由示教器操控&#xff0c;帮助工厂释放劳动力&#xff0c;此时的机器人并没有太多智能而言&#xff0c;完全按照人类的命令执行动作&#xff0c;更加关注电气层面的驱动器、伺服电机、减速…

Springboot集成Netflix-ribbon、Consul实现负载均衡调用-09

Consul简介 Consul是一个开源的服务发现和配置管理工具&#xff0c;具有跨平台、运行高效等特点。它由HashiCorp公司开发&#xff0c;并使用Go语言编写。Consul主要用于实现分布式系统中的服务发现、健康检查、键值存储等功能。 核心功能 服务发现&#xff1a;Consul通过DNS…

JavaScript百炼成仙自学笔记——13

函数七重关之六&#xff08;“new”一个函数&#xff09; 看个代码&#xff1a; function hello(){console.log(this); } 1、this&#xff1a;也是JavaScript中的一个关键字&#xff0c;永远指向当前函数的调用者 解释一下,有两层意思&#xff1a; ①this要嘛不出现&#…

基于SSM的“环卫工管理平台”的设计与实现(源码+数据库+文档+PPT)

基于SSM的“环卫工管理平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体设计图 注册 首页 后台登录 后台页面 环卫工管理 摘…

mac安装 php7.1/apache

1. 安装php 7.1 brew tap shivammathur/php 查看可安装版本 brew search php 安装指定版本&#xff08;禅道适用PHP运行环境(7.0/7.1/7.2版本)&#xff09; brew install php7.1 环境配置 vim ~/.zshrc export PATH"/usr/local/opt/php7.1/bin:$PATH" export …

使用Postman进行接口测试---解析postman页面

一、Postman 是一款流行的 API 测试工具&#xff0c;它提供了丰富的功能来帮助开发者测试和调试 API。以下是 Postman 页面上的主要功能及其含义和作用&#xff1a; 1. 请求详情&#xff08;Request Details&#xff09; &#xff1a; - 方法&#xff08;Method&#xff0…