赞
踩
以上是transformer的最基础的计算方式,自己将以从别的地方学习到的实际从0到1的计算方式来展现transformer的具体计算过程
翻译一段话,从英文到西班牙文、
以下是计算过程的总体概览
在神经网络中,大部分都是需要将输入和输出转化为数字的这么一个操作
每一个输入被称作Token
在上面的例子中,每一个token都连接了两个激活函数,每个连接中的值都是token的数值和权重数字的乘积。
那么就有人会问了,每个token所相乘的数字,比如上面的1.87,-1.45是怎么来的呢,这个我稍后会去讨论。
接下来,我将描述如何将lets这个token转化为数字
如图所示有四个token,分别为lets,to,go和<EOS>
将lets设置为1,将其他三个token设置为0,将他们都乘以各自对应的权重,这就得到了激活函数的输入了
在上面的例子中,token“lets”分别给激活函数送去了1.87和0.09,其余的三个token都给激活函数送去了0
激活函数只是一个函数用来是否让数字生效的函数,那么对于lets这个token来说,如图所示激活函数是一个横跨一三象限的直线,那么就可以得到,当lets给激活函数传入的是1.87和0.09,那么相应的,激活函数输出的也就是1.87和0.09了
同样的,go这个token的处理同上如下
在上文所提到的,在处理token“lets”和token“go”的时候,用的是同一个word embedding权重,也就是说,无论我们的输入有多长,其实质对每一个token用的都是同一套权重去处理的,这样子就给了我们去处理不同长度输入的能力
在上面提到的word embedding的权重的具体数值取决于反向传播
刚开始这些权重的位置都是一些随机的数字,在我们用英文和西班牙语的翻译去训练模型的过程中,这些权重会逐渐更新,最终形成所需要的权重数字
现在已经可以将单词转化为数字了,接下来要考虑的就是单词的顺序问题了.
因为在一句话的处理中,每个单词的顺序也很重要,例如
“我吃苹果”和“苹果吃我”这两句话用了相同的单词但是表示的含义却的大相径庭
在transformer中,使用Positional Encoding来保持追踪单词的顺序
一般都是使用cos 和sin函数去做位置编码
如下:
上图中对每一个单词都有四个位置编码的计算过程,其实在真实的模型训练和推理中,每一个单词可能会有成百上千个位置编码来代表其位置信息,当位置编码的计算位置越来越多,sin和cos函数的图像会变得越来越宽
最后会将其word embedding的数值和Positional Encoding的数值加起来,完成输入的初处理
Transformer是如何追踪每个单词之间的关系的呢?
类似于以上的例子,it在这个位置指代的是pizaa而不是oven,毕竟烤箱是不能去吃掉它
的所以在transformer中,它必须得将it得和pizaa正确的联系之前一起
好的地方在于,transformer有一个叫做自注意力的机制,可以帮助我们达到上面的要求一般情况下自注意力机制通过看到每个单词(包括这个单词本身和其本身的)和句子中的所有单词的相似性
类似于下图
进而依次计算,如下图
在计算出相似性之后,这些相似性的信息会被用做确定tansformer如何去对每个单词进行编码
在训练阶段会给模型喂很多的语料,那么如果语料中含有很多关于pizza的一些句子的话,那么“it”这个词将更多的和pizza联系在一起,而不是“oven”,所以关于pizza这个词的相关性得分会更多的影响“it”这个词在transformer中的编码
以下是一些细节的举例
回到刚才的例子,目前要做的是,要计算lets对于其本身和go的相似度为了达成这个目标,需要用新的数值来表示lets,给其词编码和位置编码后的结果乘上权重,就得到了transformer中最基础的Q,也就是query值,现在需要计算lets对于其本身和go的相似度,那么就需要有两个新的向量去表
示,那么和生成query值一样的步骤,给其乘上权重,生成K,也就是key值
接下来就是用Q和K进行相似度的计算,在这里用到的是点积运算
lets的Q分别合其本身的K与go的K去做点积,得到两个数值11.7和-2.6,lets相较于自身的相似度
回到刚才的那个例子
对于it来讲,其K和其他单词的Q做点积之后其比较大相似度的值应该是和pizza的相似度的值,而不是和oven的相似度的值在lets和go的例子中,我们得到了lets相较于自身的相似度大于其和go的相似度的结论,那么我们现在想要去实现让lets的对其自己的encoding影响要比go要大,那么应该怎么做呢?
接下来就是softmax出场的时候了
我们可以把sofmax函数当做一个方式,去决定每个输入的单词其对lets在encode过程中的百分比
在上面的例子中,进行softmax后,假设其最终得到的相似度的值在经过somax的处理下
分别得到了1.0和0.0,那么后续将会用100%的lets去encode“lets”用0%去encode "lets”
因为在上面提到,我们想用100%的lets去encode“lets”,用0%去encode“lets”,那么我们将创造另一个值去表示lets和go也就是V,value值,它将和softmax的百分比做运算并且相加,如下图
这样子就得到了两个数值,2.5和-2.1这些和组合了两个输入单词lets和go的独立编
码,相对于它们与lets的相似性,则得到了lets的Self-Attention值。
在上面我们计算了lets的自注意力机制的值,现在就得计算go的自注意力的值了
具体过程和上面计算lets的过程一样,不需要重新计算K和V,只需要计算出go的Q,然后进行运算就可以得到go的自注意力机制的值2.5,-2.1
在上文所提到的计算出lets和go的Q,K,V值的权重是一样的而且不像我上面所提到的那样子的过程,并不是只有在计算出lets的自注意力值之后才能计算go的自注意力值,二者是可以去同时计算的
在transformer中如果想让模型捕捉到输入文字的不同特征,就可以将多个selfattention模块
堆叠在一起形成multi-head attention,每一个self-attention模块都有着其不一样的权重,就
如下图所示
为了让训练复杂的神经网络更加容易,允许自注意力机制在没有进行其他操作之前对纯输入也建立一些相关性分析,还要对上面的操作进行残差连接,将最初的word和position embedding的数值和由softmax操作输出的数值相加,就像下面这样
上图中已经揭示了我们目前所做的四个操作
分别是
(1)word embedding:将输入的单词进行编码
(2)positionalembeddig:将输入单词的位置进行编码
(3)self-attention:将输入信息的互相关系进行编码
(4)残差连接:保持相对容易而且快速的并行训练举措
这样子,我们的encoding操作就进行完成了
接下来该开始decoding操作了,也就是说,要将lets go 翻译为西班牙语
Decoder操作也是从word embedding开始的,我们在decoder中可选择的序列token有四个
分别是ir(go)vamos(lets go)y(and)<EOS>(结束符号)
因为刚刚完成了lets go的英文编码,那么现在解码器将从<EOS>这个token去开始解码,因为这个是一个常见的初始化解码序列的一个操作
接下来的操作和之前你在encoder中进行的一样
需要去计算<EOS>这个token的自注意力值要注意的是,在这里所计算出的Q,K,V三个矩阵的权重和我们刚才在encodr中用到的权重不同
添加上残差连接
因为我们目前做的是一个翻译的一个工作,那么就需要同时关注输入的原文和输出的翻
译之间的关系,就比如
上面这两句话的含义完全相反,就是因为起作用的是第一个单词,don't,在decoder翻译句子的时候,关注输入的某些重要的单词是非常重要的。就像上面的那个例子一样,如果忽略了输入中的“dont”,那么翻译出来的结果的含义将会和原文完全相反,是错误的
所以endoer-decoder attention的核心就在于,让decoder持续关注在输入中的那些重要的单词
接下来,给decoder的<EOS>token创建Q值,给之前输入中的lets和go创建K值,去进行相似度点积计算,最后计算出的结果进行softmax处理,得到的结果如下图所示:
结果显示当decoder决定应该先翻译哪一个单词的时候,我们应该使用100%的第一个输入token和0%的第二个输入
当得知哪个输入单词应该被首先翻译之后,接下来就应该计算输入的V了,计算出V之后,再经过softmax处理,就得到了encoder-decoder的注意力值
要注意的是,上面计算的encoder-decoder attention的QKV权重和之前计算的self-attentionQKV的权重是不一样的,唯一相同的是,这些权重可以被复制重复使用,就像你有很多encoder-decoder attention计算头一样,同样的,也可以将很多encoder-decoder attention组件堆叠起来,去处理复杂语句中的不同方面的信息
在上面的基础上再去加上残差连接,这一步可以做到让encoder-decoder attention专心致力于处理输入和输出之间的关系,而不是被之前所计算的word/positional embedding或者self-attention去影响到。
在上面我们经过softmax运算出了两个数值,5.9和0.5,这两个数值是代表的是<EOS>这个token,现在需要将这两个数值通过某种操作,去选择到我们的输出映射表中的四个中的一个,也就是ir(go)vamos(lets go)y(and)<EOS>(结束符号)这四个中的一个
所以接下来我们利用一个具有着对每个输入都有相对应正确表示(四个映射表元素)的全连接层,对这两个数值进行运算,全连接层由和输入相乘的权重,相乘结束后的偏置,组成
在经过全连接层的运算之后,在进行softmax操作,最后得到映射表中“vamos”的这个结果
vamos在西班牙语中对应的英文翻译为lets go
目前来看,输出的结果已经满足了我们的要求,即翻译lets go成为西班牙语,但是decoder在这里可不会停止,因为他还没遇到<EOS>(结束符号)这个token
接下来要将上面的输出vamos再次进行运算,运算过程和之前提到的一样
可以看到,现在输出了<EOS>这个token,这代表这个翻译任务结束了
这个transformer的计算过程比较核心也比较简单,你可以再去将它复杂化以适应很多不同的任务,比如在一些处理结束后加上归一化的操作,或者如果你想适应更多复杂的处理,你可以在endocer阶段加上隐藏层去处理,就像下面这样
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。